Saturday, August 11, 2012

Building Bootstrap

title: Building Bootstrap date: '2012-08-11' description: Working with Twitter's Bootstrap categories: design tags: - css - javascript - html

Design Scaffolding

Twitter released Bootstrap to share a collection of best practices for web templates. They provide a packaged selection of solid web technologies including the excellent Less library and make it available via Github. Since developers often have little or no web design experience, Bootstrap provides a great way to bootstrap your front end.
We'll cover the process to get Bootstrap installed in our Ubuntu 12.04 environment.


You need to prepare your system to make Bootstrap.
$ sudo apt-get install npm
$ sudo npm -g install uglify-js
$ sudo npm -g install jshint
$ sudo npm -g install recess

Fork Bootstrap

If you haven't already, set up an account on GitHub. Then be sure to set up an SSH key to manage your commits. Finally, fork the Bootstrap repository and clone it locally into
To track the original repository, execute the following:
$ git remote add upstream git://
To pull changes from upstream, execute
$ git remote add upstream 
Navigate to your new bootstrap folder and run make. This generates a doc folder that contains an assets folder where you'll find all the css, javascript and image files you'll need.

Integration with Ruhoh

Integration of Bootstrap with Ruhoh is straightforward. Ruhoh supports themes so it's a matter of moving the compiled Bootstrap artifacts into the appropriate theme locations for Ruhoh. There is a master blog template that contains a theme, fimero that we'll use in this tutorial.


Once Bootstrap is compiled, locate the assets folder under docs. In it, you'll find
/css -> blog-master/themes/fimero/stylesheets
/ico -> blog-master/themes/fimero/media
/img -> blog-master/themes/fimero/media
/js  -> blog-master/themes/fimero/javascripts
Copy the files as listed. Then edit the theme.yml for fimero and add the appropriate resources (css and js files).

Saturday, July 28, 2012

Dropbox Setup

Dropbox Installation

Go to and set up an account. Once you’ve installed the application, you’ll have a folder $HOME\Dropbox. Create a new folder $HOME\Dropbox\config–this is where we’ll store all of our personalized configuration files.

You can store these configuration files in Github or Bitbucket–but that may be overkill for files that rarely, if ever, need to be merged. Dropbox stores prior versions of files–that should be good enough.


Create a folder for any application that you wish to configure. For example, create $HOME\Dropbox\config\vim to store all of your vim configuration files. When you move from machine to machine, you can symlink your vim configuration files from your home folder to the corresponding files in your Dropbox folder.

For example:

$HOME/.vimrc -> $HOME/Dropbox/config/vim/.vimrc

Eclipse Juno


Note that we use separate installations of Eclipse for various languages:
  • Java
  • C/C++
  • Scripting: Javascript, Bash and Python
Download Eclipse Juno JEE.
If you are setting up a Python tool chain, unzip the folder into
Create a bash script to launch this e.g. Create your new work space with a folder structure as follows:

General Plugins

Mercurial Plugin

Install the Mercurial plugin from here:
The update site is
Add this update site. Go to Help->Install New Software...

Next, add the Mercurial plugin site.

Be sure to install only the MercurialEclipse plugin. Do NOT install the Windows Binaries.

Follow the remaining instructions and you’ll have Mercurial support in Eclipse.

Scripting Languages

Note that you should create a separate installation specifically for scripting languages.


Python support has been integrated into the Aptana Studio Plugin. It’s open source and available at


Unzip Juno into $HOME/local/eclipse-juno/eclipse-java/ followed by the Mercurial plugin as outlined above.


You’ll need the m2eclipse plugin to support Maven projects. Add the following repository to Eclipse:
Once it’s installed, go to Window->Preferences->Maven->Installations and change the default to a maven2 installation (maven3 has compatibility issues with many plugins). Also, change User Interface to default to the XML editor for pom.xml files—the structured editor is sluggish.

Color Themes

Aptana provides theming for Python. For Java, you’ll need the Eclipse Color Theme plugin available at I currently use vibrant ink.

Blogger Setup

Blogger Setup for Markdown

This blog is now hosted on GitHub:

It’s a collection of Markdown pages along with links to images hosted in a public Dropbox folder. This enables me to edit everything in vim.

Articles detailing the benefits of Markdown:

By hosting the source material in a GitHub project, I can rearrange the articles over time while retaining the ability to publish the content to different blogging sites. GitHub automatically processes Markdown content for easy viewing. Plus, anyone is free to fork the project and submit corrections or additional content.

Project Layout

The praxis project is laid out with a folder per article. Each folder (e.g. praxis/blogger-setup) has a file named that contains the article. There is a corresponding folder Dropbox/Public/praxis/blogger-setup that contains all images associated with the article.

Note that you can store your images with your github project—-but I prefer to edit images on a Mac (while editing text in Linux) so synchronizing via Dropbox eliminates a commit/push step for the images.

Conversion to Blogger

Following instructions from here, make sure that Edit HTML Line Breaks is set to Use
and that Compose Settings is set to Interpret typed HTML.

Posting to Blogger

The following steps convert Markdown to HTML for Blogger:

$ pandoc --no-wrap --from=markdown --to=html | xclip

A better solution is to use Google’s Blogger API (v3). But access requires permission. I’ve submitted a request but have not heard back from Google.

Saturday, March 10, 2012

Google Directory Synchronization with OpenDJ on Ubuntu 10.04 LTS

Synchronizing User Names

We use OpenDJ for authentication and we also use Google Apps for email and calendaring. We want to minimize the number of passwords that people must remember. Fortunately, Google has a utility that synchronizes our Google Apps domain with our OpenDJ LDAP server.

We've packaged it. The source code is available here.


Install the package with the following:

$ sudo apt-get install bbgads

You'll be asked a series of questions about your LDAP configuration and your Google Apps domain.

Once you've completed the installation, you must complete a few extra steps.

$ cd /opt/bbgads/current
$ sudo -u root ./config-manager

This will bring up the Configuration Manager and enable you to set two passwords: your Google Apps administrator password and your LDAP server password.

Go to File -> Open and choose /etc/gads/gads.xml

It will complain about your passwords. Just click Ok. There will be a hierarchy of settings on the left. Choose Configure -> Google Apps -> Settings and set the password for your administrator. Click the Test Connection button at the bottom. Next, go to Configure -> LDAP Settings -> LDAP Connection and set your LDAP password. There is a Test Connection button for this as well.

Finally, go to File -> Save and save your changes.

Going Live

You should use OAuth authentication to go live. Use the config-manager application to enable it.

The default configuration for /opt/bbgads/current/ does NOT push any changes to Google. Before you push changes, be sure to check /var/log/gads/directory-sync.log to see what changes will be applied.

If you are happy with the proposed changes, edit /opt/bbgads/current/ and add an -a to the command. Precise instructions are included in the file.

Non-Google Users

You may find that you want to store users in your LDAP directory that are not needed in Google Apps. My solution has been to search for sambaSamAccount users and only synchronize them. My local users generally need access to Samba services. That way, I can create posixAccount users with ldapadduser instead of smbpasswd -a that can be authenticated but are not synchronized with the Google Apps domain.

Wednesday, February 22, 2012

ReviewBoard on Ubuntu 10.04 LTS

Code Review

Code review is considered complimentary to testing and has been shown to be effective at improving software quality. We use the excellent ReviewBoard code review application.

We'll install ReviewBoard with support LDAP. The source code for this package is available here.


Ensure that you have the fimero package repository configured.

$ sudo apt-get install bbreviewboard

You'll be asked a series of questions e.g. MySQL password or the hostname you'd like to use for your self-signed certificate. The installation will then complete. Once finished, point your browser to https://{reviewboard-server}

LDAP Configuration

Log in as admin.

Click on the Admin button on the upper right.

Click on Settings.

Click on Authentication.

Select LDAP.

Enter your settings.

Note that your cn must contain a givenName and a surname separated by a space. This is an issue with the way Reviewboard generates a user and should be considered a bug.

You can now log in via your LDAP username and credentials.

Note that if you're installing ReviewBoard on a machine that hosts Mindtouch, you'll need to update your /etc/apache2/ports.conf

There is a good example of ReviewBoard work flow with Mercurial available here.

With additional documentation available here.

Mercurial Integration

You'll need to download the source for the Mercurial integration for ReviewBoard.

$ mkdir -p hgdev/com.googlecode
$ cd hgdev/com.googlecode
$ hg clone

Now update your Mercurial $HOME/.hgrc file to include the following:


We had to experiment with several approaches before we came up with a usable workflow for Mercurial. It seems that ReviewBoard was designed for pre-commit reviews although with a little tweaking, a usable Mercurial workflow is possible.

We'll assume your username is asmith.

  1. Create a master repository e.g. acme on Bitbucket. This should be under a user that holds the golden copies of your source code. Let's call this user kroboto. Give asmith read access to this repository.
  2. Create a repository on ReviewBoard that points to this golden repository.
  3. Clone this repository locally into $HOME/hgdev/org.bitbucket/kroboto/acme with hg clone This serves as your baseline.
  4. User asmith then creates a personal acme repo on BitBucket. She then clones the golden acme into $HOME/hgdev/org.bitbucket/asmith/acme. Finally, she edits .hg/hgrc to point to her personal acme repository.
  5. asmith begins working on her code base committing and push as needed until she is ready for a code review.
  6. She first does an hg pull -u on her golden copy. She then pulls her changes from $HOME/org.bitbucket/asmith/acme into $HOME/org.bitbucket/kroboto/acme and performs any necessary merges.
  7. She submits a code review with hg postreview tip. This produces a code review id (e.g. 17). She submit subsequent reviews with hg postreview -l -e 17 tip until her code is accepted.
  8. Her code is then merged with the kroboto repository.

Backup And Restore

To backup ReviewBoard, dump the MySQL database. You can automate this process with one of several options for MySQL.

Wednesday, February 15, 2012

Mindtouch Wiki on Ubuntu 10.04


We use the open source core version of the Mindtouch wiki for internal collaboration. Mindtouch has several attractive features including:


Mono Runtime from Badgerports

You'll need the Badgerports backports repository to get the latest Mono runtime. Add the following to your /etc/apt/sources.list:

deb lucid main

Next, add the key for the repository:

$ sudo gpg --keyserver --recv-key  C90F9CB90E1FAD0C
$ sudo gpg -a --export C90F9CB90E1FAD0C | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install mono-runtime

Installing Mindtouch

You'll need the fimero repository enabled.

Ensure the Mindtouch repository has been added to your /etc/apt/sources.list:

deb xUbuntu_10.04/

Finally, install Mindtouch with

$ sudo apt-get install bbmindtouch

When the install process completes, point your browser to http://<your wikihost> and complete the installation process. Finally run sudo /usr/local/bin/ to complete the installation.

Backup and Restore

The source for the backup script is available here:

The bbmindtouch package installs a copy at /usr/local/bin/ This generates a backup file in /tmp

Add the following crontab entry for backup:

# m h  dom mon dow   command
0 2 * * * /usr/local/bin/ -b
30 2 * * * /bin/cp /tmp/backupWiki-10.1.3.tar.gz ${BACKUP_FOLDER}

Change ${BACKUP_FOLDER} to an appropriate path.

To restore your wiki, simply run

$ sudo /usr/local/bin/ -r ${BACKUP_FILE}

Wednesday, February 8, 2012

WKS Server

We outline the process to create a core WKS server for a private subnet.

Ubuntu 10.04 LTS Server

Download and install the 64-bit Ubuntu 10.04 LTS server ISO from Ubuntu.

Common Packages

We have a collection of packages that are deployed on all machines:


Both Ubuntu server and desktop provide an option to install an SSH server. We use the default configuration.

Mercurial (via bbpython2)

Mercurial is included via pip when bbpython2 is installed. bbpython2 is installed on all machines.

LDAP client

bbldapclient is used to authenticate against a bbopendj LDAP server.

Well-Known Services (WKS)

Our servers run in one of two environments: bare metal and virtualized. Bare metal servers act as hosts for both virtualized guests and for well-known services. We define well-known services as stable, standards-based core services that don't change very much:

  • DNS+
  • DHCP+
  • SMTP
  • LDAP server+
  • Samba
  • Cups
  • NFS
  • VirtualBox
  • Webmin
  • CFEngine

(+) Indicate that these services need regular backups.

Creating a WKS Server

Any subnet needs at least one WKS server to host DNS, DHCP, SMTP, LDAP server, Samba, NFS and Webmin (optional).

  1. Install apt-cacher-ng and its client.
  2. Install the bbpython2 libraries
  3. Install an SMTP server
  4. Install a Bind9 server
  5. Install a DHCP3 server
  6. Install an LDAP server
  7. Install an LDAP client
  8. Install a Samba server
  9. Install a CUPS server

You now have a server that can provide all of the basic services (eg authentication, file sharing, printing) for Windows, Mac and Linux machines on your network.

Tuesday, January 31, 2012

Debian Package Cache on Ubuntu 10.04

Package Caching

If you run multiple machines on a network, it makes sense to cache your package downloads. The bbacngclient package and apt-cacher-ng are used to facilitate this.

Choose a machine on your network to be your server. We prefer to use a CNAME to identify this machine e.g. debcache so we can move this service among machines without affecting clients.

$ sudo apt-get install apt-cacher-ng

You don't need to change anything but if you're interested, the manual for the configuration is available here.

That's it! Your server is ready.

To take advantage of your cache, you'll need to configure your client. You can install the bbacngclient with package source available here.

$ sudo apt-get install bbacngclient

You'll be asked for the name of your package cache server and the port (default 3142). It simply adds a proxy to /etc/apt/apt.conf.d/ in the form of 02proxy. If you run into any trouble with your cache server, you can simply remove this file.

NOTE: I haven't been able to find a way to support repositories that are on ports other than 80.

Wednesday, January 11, 2012

Bonding Network Interfaces on Ubuntu 10.04 LTS

From Ubuntu documentation.

Bonding is also called port trunking or link aggregation and it will let you combine several network ports to make a single group. This combines the bandwidth from several interfaces as a single connection.

Set up

$ sudo apt-get install ifenslave

This example bridges eth0 and eth1 together.

Modify /etc/network/interfaces as follows:
Then create /etc/modprobe.d/bonding.conf

You must now reboot the machine for the changes to take effect.

Tuesday, January 10, 2012

CUPS Printer Server on Ubuntu 10.04 LTS

Adding a Printer

Point your browser to your CUPS server on port 631 e.g. http://cups:631

This is an example for a Canon printer. Please consult documentation for your printer.

Click on Administration

Click on Add Printer

Select Other Network Printers - AppSocket/HP JetDirect

Choose type: socket://your-printer-ip:9100

Give your new printer a name. Note that to integrate with Samba, you'll have to use the same Samba Printer Share name as defined here:

for example from smb.conf

    comment = cups printer
    printer = CANON_C2030
    path = /var/spool/samba
    printable = yes
    guest ok = yes

Select the manufacturer of your printer.

Select the printer driver to use.

Click on Query Printer for Default Options.

You should see the following:

Samba with LDAP on Ubuntu 10.04 LTS

Windows Integration

The bbsamba package enables Windows clients to authenticate against the LDAP server we set up earlier.

The source code for the package is available here.

$ sudo apt-get install bbsamba

You'll be asked a series of questions about the layout of the samba files and shares:

path to netlogon scripts { /var/lib/samba/netlogon }: 
samba administrator email { sysadmin@lab.lan }: 
samba domain { LAB }: 
path to common samba shares { /opt/smb }: 
base distinguished name (dn) { dc=lab,dc=lan }: 
ldap uri for authentication { ldap:// }: 
netbios name { stemsrv01 }: 
machine relative distinguished name (rdn) { ou=Machines }: 
user relative distinguished name (rdn) { ou=Users }: 
ldap admin distinguished name (dn) { cn=djadmin,dc=lab,dc=lan }: 
parent folder for home folders { /home }: 
group relative distinguished name (rdn) { ou=Groups }: 
Please enter ldap root password:

The script will then attempt to create an administrator account for your Windows domain:

Creating the 'administrator' account for Samba. Please enter a password.
New SMB password:
Retype new SMB password:

You can verify that everything as worked by checking the administrator account:

$ groups administrator
administrator : domainusers domainadmins domainguests domainmachines

Creating New Users

At this point, you should create your new users with

$ smbpasswd -a {newuser}

LDAP Client on Ubuntu 10.04 LTS

LDAP Client

The bbldapclient package allows an Ubuntu 10.04 LTS machine to authenticate against an LDAP service.

Note that there is some repetition of parameters. This will be fixed in a future release.

The source code for this package is available here. This package also depends on bbldapscripts that is available here.

Be sure you have the ip address of the LDAP server your configured earlier.

You'll first be presented with an interactive session:

Enter your LDAP server ip address.
Next enter your basedn.
Choose LDAP version 3.
Make the local root a Database admin.
Don't require login.
Enter the LDAP root user.
Enter the password for the LDAP root user.

bbldapscripts Interactive Session

Unfortunately, you will now be prompted for overlapping details for bbldapscripts (this will be changed soon.) Portion will try to guess reasonable defaults for all of the questions.

ldap root distinguished name { cn=djadmin,dc=lab,dc=lan }: 
machines relative distinguished name { ou=Machines }: 
ldap server ip address { }: 
ldap base distinguished name { dc=lab,dc=lan }: 
groups relative distinguished name { ou=Groups }: 
ldap server port { 389 }: 
users relative distinguished name { ou=Users }: 
Please enter your ldap admin password:

PAM Configuration

You will then start another interactive session:

Do NOT override local changes.

bbldapclient Interactive Session

Finally, you'll be asked for the bbldapclient parameters. Again, Portion will attempt to guess reasonable defaults.

ldap server ip address { }: 
ldap root distinguished name { cn=djadmin,dc=lab,dc=lan }: 
ldap base distinguished name { dc=lab,dc=lan }: 
ldap server port { 389 }:

Test Installation

You're done. Let's create a sample user to ensure everything is working:

ubuntu@stemsrv01:~$ sudo ldapadduser esark employees
Successfully added user esark to LDAP
Successfully set password for user esark
Successfully created home directory for user esark
 * Restarting Name Service Cache Daemon nscd ... [ OK ] 

Now you should be able to query your new user:

ubuntu@stemsrv01:~$ groups esark
esark : employees


We need to eliminate the interactive sessions:

sudo DEBIAN_FRONTEND=noninteractive apt-get install bbldapclient -f -y --force-yes --quiet --yes

Monday, January 9, 2012

LDAP Services with OpenDJ on Ubuntu 10.04 LTS

OpenDJ Directory Server

We use the excellent OpenDJ directory server for LDAP services.

The Blackbox OpenDJ package configures an LDAP server for Ubuntu 10.04 LTS. Combined with an ldap client package, you'll be able to authenticate all of your services (Linux, Windows, Macintosh and web applications) against a central LDAP directory.

The source for this package is available here.

Begin with

$ sudo apt-get install bbopendj

You'll be asked a series of questions about your configuration:

ldap server port { 389 }: 
ldap admin port { 4444 }: 
ldap machine ip address { }: 
ldap secure port { 636 }: 
base distinguised name { dc=lab,dc=lan }: 
ldap server uri { ldap:// }: 
admin password { XXXXXX }: 
admin user name (RDN--do not include basedn) { cn=djadmin }: 
fully qualified domain { lab.lan }: 

You can stick with the defaults. After a brief pause (ca. 45 sec) your OpenDJ instances will be ready. To confirm, run the following:

$ ldapsearch -x

You should get a multipage dump of the contents of your directory:

# search result
search: 2
result: 0 Success

# numResponses: 16
# numEntries: 15

You now have a working LDAP server. You can restart the service with

$ sudo /etc/init.d/bbopendj restart