Tweaking Boxen on OS/X

What Is Boxen?

Boxen is a package which lets you automate the setup your Mac. You can install whatever packages you want, set up services, install config files for your favorite tools. It's pretty amazing, really.

On a more technical level, Boxen is based on Puppet, Homebrew, and a plethora of contributed modules.

Setting up Boxen

Full instructions can be found on the repo, but here's the TL;DR:

sudo mkdir -p /opt/boxen
sudo chown ${USER}:staff /opt/boxen
git clone https://github.com/boxen/our-boxen /opt/boxen/repo
cd /opt/boxen/repo
script/boxen

Along the way you'll be asked to enter your GitHub username and password. Please do so, because your GitHub username plays a big part in the next section.

Setting up a Personal Manifest

In order to customize your install of Boxen, you'll need to set up a personal manifest. In Puppet, manifests are files which contain directives to install/uninstall certain packages, configuration files, and the like. The manifests for specific users can be found in the directory modules/people/manifests/$YOUR_GITHUB_NAME.pp. To create my manifest, I'd do the following:

touch modules/people/manifests/dmuth.pp

I cannot stress this enough: The name of the file should NOT be your login name on your Mac, it should be your GitHub username. They may not be the same!

We'll come back your personal manifest shortly.

Next Step: Disabling Unwanted Services

I do most of my development in Vagrant, so I have no need to run Nginx on my Mac. I'm also not the biggest fan of DNSmasq, so I'm going to turn that off, too. Here's how:

First, edit the file manifests/site.pp. This is the repo-wide Boxen manifest. Just goahead and disable the lines that mention nginx and dnsmasq:

#include dnsmasq
#include nginx

A hash mark in front of them is all you need.

Next, go into your personal manifest that you created in the last section and add this:

class people::dmuth { # Change "dmuth" to your GitHub username
    
    #
    # Remove services we don't want
    #
    service {"dev.nginx":
        ensure => "stopped",
    }
  
    service {"dev.dnsmasq":
        ensure => "stopped",
    }

}

Next, run Boxen, and you should see some confirmation that the services have been turned off:

$ boxen
Boxen is up-to-date.
Notice: Compiled catalog for cheetah.local in environment production in 1.16 seconds
Notice: /Stage[main]/People::Dmuth/Service[dev.dnsmasq]/ensure: ensure changed 'running' to 'stopped'
Notice: /Stage[main]/People::Dmuth/Service[dev.nginx]/ensure: ensure changed 'running' to 'stopped'
$ 

That's it! Nginx and Dnsmasq are no longer running!

Installing Additional Software


#
# Install Node.js
#
class {"nodejs::global":
    version => "v0.10.13"
}
 
#
# Install Go via Homebrew
# (the Boxen repo only goes up to Go 1.1
#
package { "go":
    ensure => present,
}

#
# These packages will also be installed via Homebrew
#
package { "pstree":
    ensure => present,
}

package { "watch":
    ensure => present,
}

package { "mtr":
    ensure => present,
}

Be sure to re-run the boxen script again. If everything goes well, several new packages will be installed on your machine.

Bonus Points: Installing PHP 5.5

Now we're going to try something a little exotic: we'll install PHP 5.5, which Homebrew does not do at the time of this writing.

The first thing we'll do is go back into our personal manifest and add Puppet code to create 2 new taps, or repositories for Homebrew to talk to:

exec { "tap-homebrew-dupes":
    command => "brew tap homebrew/dupes",
    creates => "${homebrew::config::tapsdir}/homebrew-dupes",
}

exec { "josegonzalez/homebrew-php":
    command => "brew tap josegonzalez/homebrew-php",
    creates => "${homebrew::config::tapsdir}/josegonzalez-php",
    require => Exec["tap-homebrew-dupes"],
}

To go into a little more detail on what we just did, we're telling puppet to execute "brew tap" twice, with a different tap location for each run. The "creates" keyword tells Puppet to look for that file first, and if it exists to assume the command already ran once. This ensures that the tap commands will only ever execute once! (That's an important part of Puppet) Finally, the "require" keyword tells Puppet not to execute the second tap command until the first one has finished.

We're almost there! We have one more piece to put into our manifest:

package { "php55":
    ensure => present,
    require => [
        Exec["josegonzalez/homebrew-php"],
        Package["pstree"],
        Package["watch"],
        ],
}

This piece of Puppetry should look somewhat familiar. We're telling Homebrew to install a package, but we have an array of dependencies so that Puppet will wait until all of those items are present before attempting to install PHP 5.5.

So why did we install pstree and watch? PHP5.5 can take many minutes to install. And these two tools are great for monitoring what your machine is doing:

watch -d -n1 "pstree -s boxen"

The above command will run the pstree command and display the process tree for any process with "boxen" in the name. It will do this once per second, and if the output changes the offending characters will be highlighted. It's hard to show how this looks in a blog post, but watching the effect as it happens is a rather neat way of watching what your machine is doing as it installs PHP.

Questions? Comments? Feel free to reach out to me or leave a comment below. Enjoy!

5
Average: 5 (1 vote)
Your rating: None