<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Steven Danna's Blog]]></title>
  <link href="http://stevendanna.github.com/atom.xml" rel="self"/>
  <link href="http://stevendanna.github.com/"/>
  <updated>2013-04-20T12:23:59-07:00</updated>
  <id>http://stevendanna.github.com/</id>
  <author>
    <name><![CDATA[Steven Danna]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Cookbook Release: xinetd 0.9.0]]></title>
    <link href="http://stevendanna.github.com/blog/2013/04/20/cookbook-release-xinetd-0-dot-9-0/"/>
    <updated>2013-04-20T10:44:00-07:00</updated>
    <id>http://stevendanna.github.com/blog/2013/04/20/cookbook-release-xinetd-0-dot-9-0</id>
    <content type="html"><![CDATA[<p>Earlier this week I released version 0.9.0 of my
<a href="https://github.com/stevendanna/cookbook-xinetd">xinetd cookbook</a>.
This cookbook provides:</p>

<ul>
<li>An LWRP for managing xinetd services,</li>
<li>Attribute driven configuration of xinetd.conf, and</li>
<li>a recipe for enabling the internal xinetd-provided services
(chargen, daytime, discard, echo, time, and tcpmux-server).</li>
</ul>


<p>This cookbook is not yet on the Opscode Community site as I am working
with the maintainer of the currently uploaded xinetd cookbook to
ensure we don&#8217;t break anyone using the existing cookbook.</p>

<p>For more details about this cookbook, please see the <a href="https://github.com/stevendanna/cookbook-xinetd/blob/master/README.md">README</a>.  If you
are interested in contributing to this cookbook, pull requests are
accepted on Github.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Passwd_min Ohai Plugin]]></title>
    <link href="http://stevendanna.github.com/blog/2013/04/13/passwd-min-ohai-plugin/"/>
    <updated>2013-04-13T13:23:00-07:00</updated>
    <id>http://stevendanna.github.com/blog/2013/04/13/passwd-min-ohai-plugin</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/stevendanna/ohai-plugins/blob/master/plugins/passwd_min.rb">passwd_min</a>
is an Ohai plugin that parses /etc/passwd and /etc/group and returns
user and group information in a format that matches the passwd plugin
shipped in Ohai.</p>

<p>This plugin may be useful to Chef users who have alternate
password databases (such as LDAP or NIS) configured and have had to
disable the default passwd plugin to avoid storing their organization&#8217;s
entire LDAP directory in their node objects.</p>

<h2>Background</h2>

<p>The passwd plugin shipped in Ohai uses Ruby&#8217;s Etc module to popular
the <code>node['etc']['passwd']</code> and <code>node['etc']['group']</code> attributes.</p>

<p>If one follows the code for the Etc module far enough, she will find
that this information is obtained by calling the getpwent() system
call:</p>

<figure class='code'><figcaption><span>ext/etc/etc.c</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="n">passwd_iterate</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">struct</span> <span class="n">passwd</span> <span class="o">*</span><span class="n">pw</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">setpwent</span><span class="p">();</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="n">pw</span> <span class="o">=</span> <span class="n">getpwent</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">rb_yield</span><span class="p">(</span><span class="n">setup_passwd</span><span class="p">(</span><span class="n">pw</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">Qnil</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>According to the Linux Manual Page for getwpent():</p>

<blockquote><p>The getpwent() function returns a pointer to a structure containing
  the broken-out fields of a record from the password database (e.g.,
  the local password file /etc/passwd, NIS, and LDAP). The first time
  getpwent() is called, it returns the first entry; thereafter, it
  returns successive entries.</p></blockquote>

<p>Thus, for users who have have LDAP or NIS configured,
<code>node['etc']['passwd']</code> will contain more than simply the contents of
<code>/etc/passwd</code>.  For some users, the data the default passwd plugin
collects will produce large node objects.  These large node objects
place additional load on the Chef Server and other chef clients that
have to process those objects later.</p>

<h2>Using the passwd_min plugin</h2>

<p>The easiest way to distribute the passwd_min plugin is via the
<a href="http://community.opscode.com/cookbooks/ohai">Opscode Ohai cookbook</a>.  From your Chef Repository:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>knife cookbook site install ohai
</span><span class='line'>wget https://raw.github.com/stevendanna/ohai-plugins/master/passwd_min.rb
</span><span class='line'>mv passwd_min.rb cookbooks/ohai/files/default/plugins/
</span><span class='line'>knife cookbook upload ohai
</span><span class='line'><span class="c"># Add the recipe to the run list of the relevant nodes</span>
</span><span class='line'><span class="c"># or roles</span>
</span><span class='line'>knife node run_list add NODENAME ohai
</span></code></pre></td></tr></table></div></figure>


<p>You will also want to disable the default passwd plugin by placing the
following in /etc/chef/client.rb on the node:</p>

<pre><code> Ohai::Config[:disabled_plugins] = ["passwd"]
</code></pre>

<p>Note that if you use the Chef-client Cookbook, this can be done via an attribute.</p>

<p>Bug reports and improvements happily accepted on Github.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Simple Tools: do.times and summarize]]></title>
    <link href="http://stevendanna.github.com/blog/2012/03/10/simple-tools-do-times-and-summarize/"/>
    <updated>2012-03-10T00:00:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2012/03/10/simple-tools-do-times-and-summarize</id>
    <content type="html"><![CDATA[<p>Recently, a coworker has been sharing some higher-order shell
functions he has been writing, inspired by the first of these
articles:</p>

<ul>
<li><a href="http://yannesposito.com/Scratch/en/blog/Higher-order-function-in-zsh">Higher Order Functions in Zsh</a></li>
<li><a href="http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Higher-order_shell/">Higher-order shell</a></li>
</ul>


<p>Both discuss small scripts and shell functions that allow you to more
easily compose simple unix tools to complete complex task.</p>

<p>My own <code>~/bin</code> contains similar higher-order functions and other
simple tools.  Like most unix tools, they do a single task and are
composable with other tools on the command line.  However, I am often
surprised by the number of heavy command-line users I see who don&#8217;t
regularly encapsulate repetitive tasks or constructions into shell
functions or aliases.</p>

<p>In my experience, the majority of such tools</p>

<ul>
<li>take less than 5 minutes to write,</li>
<li>require almost no maintenance, and</li>
<li>prove repeatably useful after their initial creation.</li>
</ul>


<p>This post shares two tools in my <code>~/bin</code> that I used this weekend.  I
created both while ago for entirely different purposes, but was still
able to easily use them together without modification.</p>

<h2>do.times N COMMAND</h2>

<p><code>do.times</code> executes COMMAND, N times.  For example,</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ do.times 5 echo hello
</span><span class='line'>hello
</span><span class='line'>hello
</span><span class='line'>hello
</span><span class='line'>hello
</span><span class='line'>hello</span></code></pre></td></tr></table></div></figure>


<p>The <a href="https://gist.github.com/2014470">tool itself</a> is little more than
a wrapper to a shell <code>for</code> loop, but the typing it saves and the
semantic value it provides when constructing a command line has proven
valuable on numerous occasions.</p>

<h2>summarize [OPTIONS] [FILE]</h2>

<p><code>summarize</code> reads columns of data from either a file given as an
argument or its standard input and provides basic summary statistics.
I originally wrote this to do quick spot checks of data files I was
working on before sending them off to collaborators.</p>

<p>Here is an example of its output:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ summarize --sep="," --header data_file
</span><span class='line'>    wombats            frogs
</span><span class='line'> Min.   :0.01911   Min.   :0.02979
</span><span class='line'> 1st Qu.:0.22101   1st Qu.:0.32504
</span><span class='line'> Median :0.51178   Median :0.50530
</span><span class='line'> Mean   :0.51318   Mean   :0.51650
</span><span class='line'> 3rd Qu.:0.79354   3rd Qu.:0.71484
</span><span class='line'> Max.   :0.99561   Max.   :0.99827
</span><span class='line'> It requires
</span><span class='line'>Covariance Matrix:
</span><span class='line'>            wombats       frogs
</span><span class='line'>wombats 0.084647845 0.006553818
</span><span class='line'>frogs   0.006553818 0.074872790
</span><span class='line'>
</span><span class='line'>Column Sums:
</span><span class='line'> wombats    frogs
</span><span class='line'>51.31770 51.65021
</span><span class='line'>
</span><span class='line'>Number of Rows:
</span><span class='line'>[1] 100
</span><span class='line'>
</span><span class='line'>First 6 Rows:
</span><span class='line'>     wombats     frogs
</span><span class='line'>1 0.15767016 0.3545217
</span><span class='line'>2 0.42022851 0.5092576
</span><span class='line'>3 0.22144630 0.6796292
</span><span class='line'>4 0.84320607 0.6749124
</span><span class='line'>5 0.07491303 0.3430995
</span><span class='line'>6 0.65910419 0.3053271</span></code></pre></td></tr></table></div></figure>


<p>While it doesn&#8217;t seem like much, these basic statistics are often all
one needs to ensure they are sending the correct data to a teammate or
to quickly answer a basic question.</p>

<p><a href="https://gist.github.com/2014462">summarize</a> uses Rscript, an
executable shipped with R that allows one to create scripts using R.
Recently, I added a dependency on the CRAN package <code>optparse</code> to make
handling options a bit more straightforward.  With the exception of
the option parsing, the R code itself is likely easily understood by
anyone who has used R.</p>

<h1>Smoke Testing Speed Improvements</h1>

<p>This weekend I have been working on a small set of improvements to
make some not-so-simple tools I use on a regular basis a bit
faster. Combining <code>do.times</code> and <code>summarize</code> allowed me to quickly
generate a smoke test for whether the speed improvements I was
implementing were working.  To protect the innocent, I&#8217;ll use <code>git
--version</code> as an example of the command I wanted to test:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ do.times 100 time git --version 2&gt;&1 | awk '/real/ {print substr($2,3,5)}' | summarize
</span><span class='line'>       V1
</span><span class='line'> Min.   :0.00100
</span><span class='line'> 1st Qu.:0.00100
</span><span class='line'> Median :0.00100
</span><span class='line'> Mean   :0.00116
</span><span class='line'> 3rd Qu.:0.00100
</span><span class='line'> Max.   :0.00400
</span><span class='line'>
</span><span class='line'>Covariance Matrix:
</span><span class='line'>             V1
</span><span class='line'>V1 2.771717e-07
</span><span class='line'>
</span><span class='line'>Column Sums:
</span><span class='line'>   V1
</span><span class='line'>0.116
</span><span class='line'>
</span><span class='line'>Number of Rows:
</span><span class='line'>[1] 100
</span><span class='line'>
</span><span class='line'>First 6 Rows:
</span><span class='line'>     V1
</span><span class='line'>1 0.004
</span><span class='line'>2 0.004
</span><span class='line'>3 0.001
</span><span class='line'>4 0.002
</span><span class='line'>5 0.001
</span><span class='line'>6 0.001</span></code></pre></td></tr></table></div></figure>


<p>While this isn&#8217;t scientific testing by any means, it was enough to
keep me moving in the right direction, and simple enough that the cost
of creating and running the test was practically zero.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Shef Tips and Tricks: Stepping Through Chef-client Runs with Shef]]></title>
    <link href="http://stevendanna.github.com/blog/2012/01/28/shef-debugging-tips-1/"/>
    <updated>2012-01-28T15:13:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2012/01/28/shef-debugging-tips-1</id>
    <content type="html"><![CDATA[<p>Recently, I&#8217;ve used <a href="http://wiki.opscode.com/display/chef/Shef">Shef</a>,
the interactive Chef console, to get to the bottom of some rather
tricky problems.  In the process, I developed a number of tricks and
tools for productively debugging problems using Shef.  This is the first
in a series of articles I&#8217;d like to write on the most useful of these
tips.</p>

<p>In this article I will discuss how I use Shef and a handful of
additional functions to debug Chef-client runs by stepping through a
node&#8217;s run list, breaking before or after specific resources in order
to inspect the state of the system.  Note that this is not intended
to be an introduction to Shef.  For that, you should head over to the
<a href="http://wiki.opscode.com/display/chef/Getting+Started+with+Shef">Chef Wiki</a>.</p>

<h1>Setup</h1>

<p>Some of the functions I mention in this article are in the <code>shef/</code>
directory of my <a href="https://github.com/stevendanna/knife-hacks">knife-hacks</a> repository.  If you&#8217;d like to use them,
you can download this repository from Github:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mkdir ~/src
</span><span class='line'><span class="nb">cd</span> ~/src
</span><span class='line'>git clone git://github.com/stevendanna/knife-hacks.git
</span></code></pre></td></tr></table></div></figure>


<p>To make it easy to include files from this repository inside Shef, you
can use the following in the relevant configuration file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">unless</span> <span class="n">defined?</span><span class="p">(</span><span class="no">Shef</span><span class="p">)</span><span class="o">.</span><span class="n">nil?</span>
</span><span class='line'>  <span class="vg">$:</span> <span class="o">&lt;&lt;</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s2">&quot;~/src/knife-hacks/&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>All of the examples I will be doing will be on my local workstation.
For ease, I have placed this in my <code>knife.rb</code> file, which I will
pass to Shef using the <code>-c</code> command line option.  However, a similar
approach will work within a <code>client.rb</code> for a node or a custom <code>shef.rb</code>
file.</p>

<h1>Introduction</h1>

<p>Shef is an interactive console for Chef.  Essentially, it is IRB with
support for recipe and attribute syntax and a number of Chef-relevant
functions.</p>

<p>Here&#8217;s a typical Shef session that you might find in an introduction
to Shef.  We add some resources, including a <em>breakpoint</em> resource and
start a chef-run.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span> <span class="o">&gt;</span> <span class="n">recipe</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">echo</span> <span class="n">off</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">log</span> <span class="s2">&quot;a&quot;</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">breakpoint</span> <span class="s2">&quot;STOP&quot;</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">log</span> <span class="s2">&quot;b&quot;</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">run_chef</span>
</span><span class='line'><span class="no">DEBUG</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">log</span><span class="o">[</span><span class="n">a</span><span class="o">]</span> <span class="n">on</span> <span class="n">sdanna</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="no">Processing</span> <span class="n">log</span><span class="o">[</span><span class="n">a</span><span class="o">]</span> <span class="n">action</span> <span class="n">write</span> <span class="p">((</span><span class="n">irb</span><span class="c1">#1) line 3)</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="n">a</span>
</span><span class='line'><span class="no">DEBUG</span><span class="p">:</span> <span class="no">Processing</span> <span class="o">[</span><span class="sr">/home/s</span><span class="n">danna</span><span class="o">/.</span><span class="n">rvm</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="n">ruby</span><span class="o">-</span><span class="mi">1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">3</span><span class="o">-</span><span class="n">p0</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="n">chef</span><span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">10</span><span class="o">.</span><span class="mi">8</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">chef</span><span class="o">/</span><span class="n">mixin</span><span class="o">/</span><span class="n">recipe_definition_dsl_core</span><span class="o">.</span><span class="n">rb</span><span class="p">:</span><span class="mi">61</span><span class="ss">:in</span> <span class="sb">`new&#39;] on sdanna</span>
</span><span class='line'><span class="sb">INFO:  Processing [/home/sdanna/.rvm/gems/ruby-1.9.3-p0/gems/chef-0.10.8/lib/chef/mixin/recipe_definition_dsl_core.rb:61:in `</span><span class="kp">new</span><span class="err">&#39;</span><span class="o">]</span> <span class="n">action</span> <span class="k">break</span> <span class="p">((</span><span class="n">irb</span><span class="c1">#1) line</span>
</span></code></pre></td></tr></table></div></figure>


<p>The breakpoint stops the chef-client run, allowing you to
investigate the state of the system and then resume the run with <code>chef_run.resume</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">chef_run</span><span class="o">.</span><span class="n">resume</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="no">Processing</span> <span class="n">log</span><span class="o">[</span><span class="n">b</span><span class="o">]</span> <span class="n">action</span> <span class="n">write</span> <span class="p">((</span><span class="n">irb</span><span class="c1">#1) line 6)</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="n">b</span>
</span></code></pre></td></tr></table></div></figure>


<p>With these basic features, Shef can be great for running quick tests
of recipe code.  However, it is not immediately clear how you get from
here to being able to step through an actual chef-client run.  To
effectively step through a chef-client run, we need to be able to:</p>

<ul>
<li>Load resources from the recipes in the node&#8217;s run_list, and</li>
<li>Insert breakpoints between the loaded resources.</li>
</ul>


<p>The remainder of this article covers how to accomplish these two
tasks.</p>

<h2>Loading Resources from the RunList</h2>

<p>Invoking Shef with the <code>-z</code> argument enables client-mode, forcing it to
download the relevant recipes from the node&#8217;s run_list just as
chef-client would, but it does not processes these recipes and add
their resources to the resource collection.</p>

<p>Because Shef&#8217;s recipe context allows you to use the recipe DSL, we can
add the resources from an individual recipe using the <code>include_recipe</code>
function.  We can only use <code>include_recipe</code> on recipes that Shef
downloaded when we started it up.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">resources</span>
</span><span class='line'><span class="o">[]</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">include_recipe</span> <span class="s2">&quot;ssh_known_hosts&quot;</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">resources</span>
</span><span class='line'><span class="o">[</span><span class="s2">&quot;template[/etc/ssh/ssh_known_hosts]&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>In order to load all of the recipes we need to iterate over a list of
all the recipes in the run_list and call <code>include_recipe</code> on each of
them.  Since the run_list can contain roles, we also need to ensure we
get the expanded run_list.  There are a number of ways to get the
expanded run_list.  Here is one:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">node</span><span class="o">.</span><span class="n">run_list</span><span class="o">.</span><span class="n">expand</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">chef_environment</span><span class="p">)</span><span class="o">.</span><span class="n">recipes</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span>
</span><span class='line'>  <span class="n">include_recipe</span> <span class="n">r</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This simple bit of Ruby is much like the <em>resource compilation</em> phase of
a chef-client run.  Just as within a chef-client run, you may
encounter an error as you try to include the recipes. In a future
article, I may discuss better ways to step through this compilation
phase.</p>

<p>Since I&#8217;d rather not type the above every time I want to debug a
chef-client run, I encapsulated this into a function within my
ShefExtras library: <a href="https://github.com/stevendanna/knife-hacks/blob/master/shef/extras.rb#L11"><code>load_node_run_list</code></a>.</p>

<h2>Inserting Breakpoints between Resources</h2>

<p>A large run_list can easily contain hundreds of resources.  While we
could step through the resources one-by-one, we often want to run
through a large number of the resources, and then stop just before a
resource that exhibiting some errant behavior.To do this, we need a
way to insert breakpoints between the resources we are loading from
recipes.</p>

<p>Since &#8220;breakpoint&#8221; is a fully-fledged Chef resource, we could place
the breakpoint resources directly in the relevant recipe. Within a
normal chef-client run, the breakpoint resources will have no effect,
allowing us to do this without much fear of endangering other
nodes using the same recipe.</p>

<p>However, I&#8217;ve found that it is more useful to be able to add the
breakpoints via Shef, since we will often want to add new breakpoints
as we gain new information.</p>

<p>To accomplish this, I&#8217;ve created an <code>insert_break</code> function to do just
that within my ShefExtras library.  Since it is a bit uglier than I
would like and depends on mucking about in the depths of Chef&#8217;s data
structures, I am not going to walk through how the function works.
However, here is an example of how to use it:</p>

<ul>
<li>First, we load the ShefExtras library and switch to recipe mode.</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span> <span class="o">&gt;</span> <span class="n">echo</span> <span class="n">off</span>
</span><span class='line'><span class="n">chef</span> <span class="o">&gt;</span> <span class="nb">require</span> <span class="s1">&#39;shef/extras&#39;</span>
</span><span class='line'><span class="n">chef</span> <span class="o">&gt;</span> <span class="no">ShefExtras</span><span class="o">.</span><span class="n">load</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span> <span class="no">ShefExtras</span> <span class="n">loaded!</span>
</span><span class='line'><span class="n">chef</span> <span class="o">&gt;</span> <span class="n">recipe</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Next, we load the resources from the recipe in the node&#8217;s run list
and insert a break point before one of them.</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">load_node_run_list</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">resources</span>
</span><span class='line'><span class="o">[</span><span class="s2">&quot;log[Please set the set_fqdn attribute to desired hostname]&quot;</span><span class="p">,</span>
</span><span class='line'><span class="s2">&quot;template[/etc/ssh/ssh_known_hosts]&quot;</span><span class="o">]</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">insert_break</span> <span class="ss">:before</span><span class="p">,</span> <span class="s2">&quot;template[/etc/ssh/ssh_known_hosts]&quot;</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="no">Breakpoint</span> <span class="n">added</span> <span class="n">before</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ss</span><span class="n">h</span><span class="o">/</span><span class="n">ssh_known_hosts</span><span class="o">]</span>
</span><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">ordered_resources</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="s2">&quot;log[Please set the set_fqdn attribute to desired hostname]&quot;</span><span class="p">,</span>
</span><span class='line'><span class="s2">&quot;break[break-before-template[/etc/ssh/ssh_known_hosts]]&quot;</span><span class="p">,</span>
</span><span class='line'><span class="s2">&quot;template[/etc/ssh/ssh_known_hosts]&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Finally, we run chef.</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">chef</span><span class="ss">:recipe</span> <span class="o">&gt;</span> <span class="n">run_chef</span>
</span><span class='line'><span class="no">DEBUG</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">log</span><span class="o">[</span><span class="no">Please</span> <span class="n">set</span> <span class="n">the</span> <span class="n">set_fqdn</span> <span class="n">attribute</span> <span class="n">to</span> <span class="n">desired</span> <span class="n">hostname</span><span class="o">]</span> <span class="n">on</span> <span class="n">sdanna</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="no">Processing</span> <span class="n">log</span><span class="o">[</span><span class="no">Please</span> <span class="n">set</span> <span class="n">the</span> <span class="n">set_fqdn</span> <span class="n">attribute</span> <span class="n">to</span> <span class="n">desired</span> <span class="n">hostname</span><span class="o">]</span> <span class="n">action</span> <span class="n">write</span> <span class="p">(</span><span class="n">hostname</span><span class="o">::</span><span class="n">default</span> <span class="n">line</span> <span class="mi">64</span><span class="p">)</span>
</span><span class='line'><span class="no">WARN</span><span class="p">:</span>  <span class="no">Please</span> <span class="n">set</span> <span class="n">the</span> <span class="n">set_fqdn</span> <span class="n">attribute</span> <span class="n">to</span> <span class="n">desired</span> <span class="n">hostname</span>
</span><span class='line'><span class="no">DEBUG</span><span class="p">:</span> <span class="no">Processing</span> <span class="k">break</span><span class="o">[</span><span class="k">break</span><span class="o">-</span><span class="n">before</span><span class="o">-</span><span class="n">template</span><span class="o">[</span><span class="sr">/etc/ss</span><span class="n">h</span><span class="o">/</span><span class="n">ssh_known_hosts</span><span class="o">]]</span> <span class="n">on</span> <span class="n">sdanna</span>
</span><span class='line'><span class="no">INFO</span><span class="p">:</span>  <span class="no">Processing</span> <span class="k">break</span><span class="o">[</span><span class="k">break</span><span class="o">-</span><span class="n">before</span><span class="o">-</span><span class="n">template</span><span class="o">[</span><span class="sr">/etc/ss</span><span class="n">h</span><span class="o">/</span><span class="n">ssh_known_hosts</span><span class="o">]]</span> <span class="n">action</span> <span class="k">break</span> <span class="p">(</span><span class="sr">/home/s</span><span class="n">danna</span><span class="o">/</span><span class="n">src</span><span class="o">/</span><span class="n">knife</span><span class="o">-</span><span class="n">hacks</span><span class="o">/</span><span class="n">shef</span><span class="o">/</span><span class="n">extras</span><span class="o">.</span><span class="n">rb</span> <span class="n">line</span> <span class="mi">38</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>As you can see, the chef-client run halts before running the template
resources.  At this point we could investigate elements of the system
state that we believe may be having an effect on the template
resource. When we are ready to continue, we can call <code>chef_run.resume</code>
to continue the run.</p>

<p>In this example, I&#8217;ve used three custom functions from the ShefExtras
module:</p>

<ul>
<li><p><code>load_node_run_list</code> loads the resources from the
node&#8217;s run list in the same way as we did in the previous section.</p></li>
<li><p><code>ordered_resources</code> returns a list of the resources in the order that
chef-client would run them.</p></li>
<li><p><code>insert_break(preposition, resource)</code> will place a break resource
either before or after the given resource.</p></li>
</ul>


<h1>When Do I Use This</h1>

<p>Using these tools to step through the resource list is particularly
useful in the following types of situations:</p>

<ul>
<li>The run list contains recipes which are heavily dependent on execute
or script resources that may not be behaving as you expect.</li>
<li>A recipe makes significant run time modifications of node attributes.</li>
<li>A recipe&#8217;s behavior non-trivially branches based on pieces of the
system&#8217;s state that is not easily observed before or after the
chef-client run has completed.</li>
</ul>


<p>While I still prefer to start with reading the relevant recipe and
reasoning about what will happen, having the ability to quickly run a
portion of the recipe and confirm a hypothesis about the state of the
system has proven incredibly valuable.</p>

<h1>More to Come</h1>

<p>Future articles in this series may cover:</p>

<ul>
<li>Customizing your Shef configuration,</li>
<li>Using Shef to make bulk changes to node data,</li>
<li>Analyzing API responses using Shef,</li>
<li>Running Shef as an inferior process in Emacs, and</li>
<li>Debugging errors with resource compilation.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[R ohai plugin]]></title>
    <link href="http://stevendanna.github.com/blog/2012/01/01/r-ohai-plugin/"/>
    <updated>2012-01-01T15:44:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2012/01/01/r-ohai-plugin</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/opscode/ohai">Ohai</a> is a library used by Chef to collect information about nodes
within your infrastructure.  Information is collected by a set of Ohai
plugins, most of which parse the output of system commands.</p>

<p>During lunch on Friday, I create a simple Ohai plugin to collect some basic
information about R. You can find the plugin here:</p>

<p>  <a href="https://github.com/stevendanna/ohai-plugins/blob/master/r.rb">https://github.com/stevendanna/ohai-plugins/blob/master/r.rb</a></p>

<p>Currently, this plugin collects:</p>

<ul>
<li>The version of R,</li>
<li>The installed packages, and</li>
<li>The output of <code>capabilities()</code></li>
</ul>


<p>To use this plugin right away, the easiest course of action is to use
the <a href="http://community.opscode.com/cookbooks/ohai">Opscode Ohai cookbook</a>.  From your chef repository:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>knife cookbook site install ohai
</span><span class='line'>wget https://raw.github.com/stevendanna/ohai-plugins/master/r.rb
</span><span class='line'>mv r.rb cookbooks/ohai/files/default/plugins/
</span><span class='line'>knife cookbook upload ohai
</span><span class='line'><span class="c"># Add the recipe to the run list of the relevant nodes</span>
</span><span class='line'><span class="c"># or roles</span>
</span><span class='line'>knife node run_list add NODENAME ohai
</span><span class='line'><span class="c"># The ohai plugin will run on the next chef-client run</span>
</span><span class='line'>knife ssh <span class="s1">&#39;name:NODENAME&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In order to avoid unnecessary runs of Ohai within a chef-client run
you can add the following line to the <code>client.rb</code> configuration file on your nodes:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Ohai</span><span class="o">::</span><span class="no">Config</span><span class="o">[</span><span class="ss">:plugin_path</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="s1">&#39;/etc/chef/ohai_plugins&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you are using Opscode&#8217;s chef-client cookbook, this will already be
taken care of for you.</p>

<p>The following is an example of the information it collects:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">&gt;</span> <span class="n">knife</span> <span class="n">node</span> <span class="n">show</span> <span class="n">snow</span><span class="o">-</span><span class="n">master</span> <span class="o">-</span><span class="n">a</span> <span class="n">languages</span><span class="o">.</span><span class="n">r</span> <span class="o">-</span><span class="no">Fj</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;languages.r&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;capabilities&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>      <span class="s2">&quot;tiff&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;cledit&quot;</span><span class="p">:</span> <span class="kp">false</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;tcltk&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;X11&quot;</span><span class="p">:</span> <span class="kp">false</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;sockets&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;fifo&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;iconv&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;cairo&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;png&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;http/ftp&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;libxml&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;jpeg&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;aqua&quot;</span><span class="p">:</span> <span class="kp">false</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;NLS&quot;</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;profmem&quot;</span><span class="p">:</span> <span class="kp">true</span>
</span><span class='line'>    <span class="p">},</span>
</span><span class='line'>    <span class="s2">&quot;packages&quot;</span><span class="p">:</span> <span class="o">[</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;Rmpi&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;0.5-9&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;built&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.1&quot;</span>
</span><span class='line'>      <span class="p">},</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;snow&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;0.3-8&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;built&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.1&quot;</span>
</span><span class='line'>      <span class="p">},</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;KernSmooth&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;2.23-7&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;built&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.0&quot;</span>
</span><span class='line'>      <span class="p">},</span>
</span><span class='line'><span class="o">[</span> <span class="o">.</span><span class="n">.</span><span class="o">.</span> <span class="no">SNIP</span> <span class="no">MANY</span> <span class="no">MORE</span> <span class="no">PACKAGE</span> <span class="o">.</span><span class="n">.</span><span class="o">.]</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;boot&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;1.3-3&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;built&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.0&quot;</span>
</span><span class='line'>      <span class="p">},</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;utils&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.1&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;built&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.1&quot;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    <span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;2.14.1&quot;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Also, Happy New Year!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Snow and Chef]]></title>
    <link href="http://stevendanna.github.com/blog/2011/12/26/snow-and-chef/"/>
    <updated>2011-12-26T09:32:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2011/12/26/snow-and-chef</id>
    <content type="html"><![CDATA[<p>One of my major interests is programming in R.  I took a few days off
for Christmas break, and in between talking with family, watching old
movies, opening presents, and spreading Christmas cheer, I decided it
would be fun to use Chef to create a parallel computing environment
suitable for use with R.  As part of this project, I wrote:</p>

<ul>
<li>A Chef cookbook to install and configure R.</li>
<li>An R package provider to easily install packages from CRAN.</li>
<li>A Chef cookbook to install and configure MPI.</li>
</ul>


<p>This blog post outlines some of the highlights of this fun little
project. It isn&#8217;t a step-by-step tutorial for creating such
an environment.  I assume that already have:</p>

<ul>
<li>General familiarity with R and Chef.  I talk about cookbooks,
recipes, and roles and assume you know what to do with them.</li>
<li>A means of provisioning computation nodes, each already configured
with hostnames that are resolvable to network addresses by other
computation nodes.</li>
</ul>


<p>I used vagrant to provision a few VMs for testing these recipes and a
small set of vagrant-specific cookbooks to ensure that each node had a
resolvable hostname.</p>

<h1>R Cookbook</h1>

<p>The first item every node in the cluster will need is R.  The R
cookbook on the Opscode Community site is a bit out of date.  I&#8217;ve
created a newer version that can be found here:</p>

<p><a href="http://github.com/stevendanna/cookbook-r">http://github.com/stevendanna/cookbook-r</a></p>

<p>This cookbook does the following:</p>

<ul>
<li>Installs R from either the CRAN APT repository or from source depending
on the platform.</li>
<li>Defines a system-wide default CRAN mirror using an Rprofile.site
template.</li>
<li>Contains an R package provider that can install R packages available
on CRAN.</li>
</ul>


<p>Currently this cookbook is linux-centric and best suited for use on
Ubuntu or Debian.</p>

<h2>R Package Provider</h2>

<p>My R parallel computing environment relies on the &#8216;snow&#8217; and &#8216;Rmpi&#8217;
packages to manage communication with computation nodes.  Further, I
often need additional packages from CRAN when working with my cluster.
The R package provider in my R cookbook allows for easy, automated
installation of R packages.  It was written using Chef&#8217;s Light-weight
Resource and Provider DSL.  The current version provides the minimal
necessary functionality:</p>

<figure class='code'><figcaption><span>&#8220;R package provider.  Corresponding resource description not shown.&#8221;</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">action</span> <span class="ss">:install</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">execute</span> <span class="s2">&quot;Install R Package&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">command</span> <span class="n">r_package_install</span><span class="p">(</span><span class="n">new_resource</span><span class="o">.</span><span class="n">package</span><span class="p">)</span>
</span><span class='line'>    <span class="n">not_if</span> <span class="n">r_package_is_installed</span><span class="p">(</span><span class="n">new_resource</span><span class="o">.</span><span class="n">package</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">action</span> <span class="ss">:upgrade</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">execute</span> <span class="s2">&quot;Upgrade R Package&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">command</span> <span class="n">r_package_install</span><span class="p">(</span><span class="n">new_resource</span><span class="o">.</span><span class="n">package</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">action</span> <span class="ss">:remove</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">r_package_remove</span> <span class="o">=</span> <span class="s2">&quot;remove.packages(&#39;</span><span class="si">#{</span><span class="n">new_resource</span><span class="o">.</span><span class="n">package</span><span class="si">}</span><span class="s2">&#39;)&quot;</span>
</span><span class='line'>  <span class="n">execute</span> <span class="s2">&quot;Remove R Package&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">command</span> <span class="s2">&quot;echo </span><span class="se">\&quot;</span><span class="si">#{</span><span class="n">r_package_remove</span><span class="si">}</span><span class="se">\&quot;</span><span class="s2"> | R --no-save --no-restore -q&quot;</span>
</span><span class='line'>    <span class="n">only_if</span> <span class="n">r_package_is_installed</span><span class="p">(</span><span class="n">new_resource</span><span class="o">.</span><span class="n">package</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># The following helper functions construct strings that can be run as</span>
</span><span class='line'><span class="c1"># Bash commands. For example, as the input of not_if or only_if</span>
</span><span class='line'><span class="c1"># statements</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">r_package_is_installed</span><span class="p">(</span><span class="n">package_name</span><span class="p">)</span>
</span><span class='line'>  <span class="n">r_code</span> <span class="o">=</span> <span class="s2">&quot;if (any(installed.packages()[,1] == &#39;</span><span class="si">#{</span><span class="n">package_name</span><span class="si">}</span><span class="s2">&#39;)) { quit(&#39;no&#39;, 0, FALSE) }; quit(&#39;no&#39;, 1, FALSE)&quot;</span>
</span><span class='line'>  <span class="s2">&quot;echo </span><span class="se">\&quot;</span><span class="si">#{</span><span class="n">r_code</span><span class="si">}</span><span class="se">\&quot;</span><span class="s2"> | R --no-save --no-restore -q&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">r_package_install</span><span class="p">(</span><span class="n">package_name</span><span class="p">)</span>
</span><span class='line'>  <span class="n">r_code</span> <span class="o">=</span> <span class="s2">&quot;install.packages(&#39;</span><span class="si">#{</span><span class="n">package_name</span><span class="si">}</span><span class="s2">&#39;)&quot;</span>
</span><span class='line'>  <span class="s2">&quot;echo </span><span class="se">\&quot;</span><span class="si">#{</span><span class="n">r_code</span><span class="si">}</span><span class="se">\&quot;</span><span class="s2"> | R --no-save --no-restore -q&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>It supports three actions: <code>:install</code>, <code>:upgrade</code>, and
<code>:remove</code>; however, it is not very feature-rich.  A few features I
would like to add include:</p>

<ul>
<li>The ability to specify the CRAN mirror or repository.</li>
<li>The ability to install local packages</li>
<li>The ability to install packages on a per-user basis.</li>
</ul>


<p>Despite these shortcomings, the current provider works well enough for
my purposes and is a good example of Chef&#8217;s high-level of
&#8216;Whip-It-Up-itude.&#8217;  Within a few minutes, I was able to go from some
quick-and-dirty R code to a Chef provider that I can iteratively
improve as my needs become more complex.  While I did not include it
in the repository linked above, I was able to create a small <code>R::snow</code>
recipe that does little more than use this provider:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">R_package</span> <span class="s2">&quot;snow&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">case</span> <span class="n">node</span><span class="o">[</span><span class="s1">&#39;R&#39;</span><span class="o">][</span><span class="s1">&#39;snow&#39;</span><span class="o">][</span><span class="s1">&#39;cluster_type&#39;</span><span class="o">]</span>
</span><span class='line'><span class="k">when</span> <span class="s1">&#39;mpi&#39;</span>
</span><span class='line'>  <span class="n">include_recipe</span> <span class="s1">&#39;mpi&#39;</span>
</span><span class='line'>  <span class="no">R_package</span> <span class="s1">&#39;Rmpi&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h1>MPI Cookbook</h1>

<p>The R package &#8216;snow&#8217; can use various backends to communicate with
computation nodes.  The default method for most commands is &#8220;Message
Passing Interface&#8221; (MPI).  MPI is also generally useful outside of R
as you can easily use MPI utilities such as mpirun to execute a
command on multiple computation nodes and use MPI&#8217;s C libraries to
write programs designed for parallel computation.</p>

<p>MPI has multiple implementation.  I&#8217;ve written an MPI cookbook that
can install <a href="http://www.open-mpi.org/">openmpi</a> on Ubuntu.  It can be found here:</p>

<p><a href="https://github.com/stevendanna/cookbook-mpi">https://github.com/stevendanna/cookbook-mpi</a></p>

<p>This cookbook does the following:</p>

<ul>
<li>Installs openmpi on Ubuntu</li>
<li>Constructs a list of computation nodes within your environment using
search and then renders a default hostfile that is used by MPI
commands such as mpirun.</li>
<li>Sets basic configuration options that I have found useful.</li>
</ul>


<p>While MPI does not natively contain the concepts of master and slaves
(every MPI node can talk to any other MPI node), I found it useful to
include the concept of a node&#8217;s &#8220;MPI role.&#8221;  I use this role to
populate the default hostfile, since there are often cases where you
might want MPI installed on a machine within your environment but
would not want that machine being used for computation.</p>

<h1>Putting it all Together</h1>

<p>I put this all together using two roles: snow_master and snow_slave</p>

<figure class='code'><figcaption><span>roles/snow_master.json</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;name&quot;</span> <span class="p">:</span> <span class="s2">&quot;snow_master&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;json_class&quot;</span> <span class="p">:</span> <span class="s2">&quot;Chef::Role&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;chef_type&quot;</span> <span class="p">:</span> <span class="s2">&quot;role&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;run_list&quot;</span> <span class="p">:</span> <span class="o">[</span> <span class="s2">&quot;recipe[R]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[R::snow]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[mpi]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[ssh_known_hosts]&quot;</span> <span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;default_attributes&quot;</span> <span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;mpi&quot;</span> <span class="p">:</span> <span class="p">{</span>
</span><span class='line'>            <span class="s2">&quot;role&quot;</span><span class="p">:</span> <span class="s2">&quot;master&quot;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>roles/snow_slave.json</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;name&quot;</span> <span class="p">:</span> <span class="s2">&quot;snow_slave&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;json_class&quot;</span> <span class="p">:</span> <span class="s2">&quot;Chef::Role&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;chef_type&quot;</span> <span class="p">:</span> <span class="s2">&quot;role&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;run_list&quot;</span> <span class="p">:</span> <span class="o">[</span> <span class="s2">&quot;recipe[R]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[R::snow]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[mpi]&quot;</span><span class="p">,</span> <span class="s2">&quot;recipe[ssh_known_hosts]&quot;</span> <span class="o">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>By applying the snow_slave role to all of the nodes I wanted within
my computation cluster and the snow_master role to the machine I will
use to launch jobs in my cluster, I can quickly bring up a new cluster
of machines suitable for doing parallel computation in R using snow.</p>

<p>The ssh_known_hosts recipe is directly from the Opscode community
site and helps make ssh connections between the nodes a bit smoother.</p>

<h1>Twelve Days of Chistmas</h1>

<p>As an example of how easy it is to do simple parallel computation
using snow, consider the following Chistmas-themed R function.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='r'><span class='line'>twelve_days_of_christmas <span class="o">&lt;-</span> <span class="kr">function</span> <span class="p">(</span>n<span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">if</span> <span class="p">(</span>!any<span class="p">(</span><span class="m">1</span>:<span class="m">12</span> <span class="o">==</span> n<span class="p">))</span> stop<span class="p">(</span><span class="s">&quot;Not a day of Chirstmas!&quot;</span><span class="p">)</span>
</span><span class='line'>  LYRICS <span class="o">&lt;-</span> c<span class="p">(</span><span class="s">&quot;a Partridge in a Pear Tree.&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Two Turtle Doves&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Three French Hens&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Four Colly Birds&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Five Golden Rings&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Six Geese-a-Laying&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Seven Swans-a-Swimming&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Eight Maids-a-Milking&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Nine Ladies Dancing&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Ten Lords-a-Leaping&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Eleven Pipers Piping&quot;</span><span class="p">,</span>
</span><span class='line'>              <span class="s">&quot;Twleve Drummers Drumming&quot;</span><span class="p">)</span>
</span><span class='line'>  append <span class="o">=</span> c<span class="p">(</span><span class="s">&quot;st&quot;</span><span class="p">,</span> <span class="s">&quot;nd&quot;</span><span class="p">,</span> <span class="s">&quot;rd&quot;</span><span class="p">,</span> rep<span class="p">(</span><span class="s">&quot;th&quot;</span><span class="p">,</span><span class="m">9</span><span class="p">))</span>
</span><span class='line'>  <span class="kr">if</span> <span class="p">(</span>n <span class="o">&gt;</span> <span class="m">1</span><span class="p">)</span> LYRICS<span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> paste<span class="p">(</span><span class="s">&quot;and&quot;</span><span class="p">,</span> LYRICS<span class="p">[</span><span class="m">1</span><span class="p">])</span>
</span><span class='line'>  paste<span class="p">(</span><span class="s">&quot;On the&quot;</span><span class="p">,</span>
</span><span class='line'>        paste<span class="p">(</span>n<span class="p">,</span> append<span class="p">[</span>n<span class="p">],</span> sep<span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">),</span>
</span><span class='line'>        <span class="s">&quot;day of Christmas, my true love gave to me&quot;</span><span class="p">,</span>
</span><span class='line'>        paste<span class="p">(</span>LYRICS<span class="p">[</span>n:<span class="m">1</span><span class="p">],</span> collapse<span class="o">=</span><span class="s">&quot;, &quot;</span><span class="p">))</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Assuming chef-client has been run on all of our nodes, we can simply
log into our &#8216;snow master&#8217;, boot up R, and run the following code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class='r'><span class='line'><span class="o">&gt;</span> library<span class="p">(</span><span class="s">&#39;snow&#39;</span><span class="p">)</span>
</span><span class='line'><span class="o">&gt;</span> source<span class="p">(</span><span class="s">&#39;twelve_days.r&#39;</span><span class="p">)</span>
</span><span class='line'><span class="o">&gt;</span> cl <span class="o">&lt;-</span> makeCluster<span class="p">(</span><span class="m">2</span><span class="p">)</span>
</span><span class='line'><span class="o">&gt;</span> clusterApply<span class="p">(</span>cl<span class="p">,</span> <span class="m">1</span>:<span class="m">12</span><span class="p">,</span> twelve_days_of_christmas<span class="p">)</span>
</span><span class='line'><span class="p">[[</span><span class="m">1</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 1st day of Christmas, my true love gave to me a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">2</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 2nd day of Christmas, my true love gave to me Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">3</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 3rd day of Christmas, my true love gave to me Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">4</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 4th day of Christmas, my true love gave to me Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">5</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 5th day of Christmas, my true love gave to me Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">6</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 6th day of Christmas, my true love gave to me Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">7</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 7th day of Christmas, my true love gave to me Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">8</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 8th day of Christmas, my true love gave to me Eight Maids-a-Milking, Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">9</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 9th day of Christmas, my true love gave to me Nine Ladies Dancing, Eight Maids-a-Milking, Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">10</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 10th day of Christmas, my true love gave to me Ten Lords-a-Leaping, Nine Ladies Dancing, Eight Maids-a-Milking, Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">11</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 11th day of Christmas, my true love gave to me Eleven Pipers Piping, Ten Lords-a-Leaping, Nine Ladies Dancing, Eight Maids-a-Milking, Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="p">[[</span><span class="m">12</span><span class="p">]]</span>
</span><span class='line'><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="s">&quot;On the 12th day of Christmas, my true love gave to me Twleve Drummers Drumming, Eleven Pipers Piping, Ten Lords-a-Leaping, Nine Ladies Dancing, Eight Maids-a-Milking, Seven Swans-a-Swimming, Six Geese-a-Laying, Five Goldedn Rings, Four Colly Birds, Three French Hens, Two Turtle Doves, and a Partridge in a Pear Tree.&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h1>Conclusion</h1>

<p>Overall this was a fun project to do over break.  It took a handful of
hours to complete, most of which was dedicated to a few problems not
discussed in this post:</p>

<ul>
<li>Making hostnames resolvable and other network oddities within my
Vagrant test environment.</li>
<li>Deciding which implementation of MPI to use.</li>
</ul>


<p>I personally would like to see further work done around using Chef to
manage large R environments. Some work I hope to do in the not to
distant future includes:</p>

<ul>
<li>Expand the R cookbook to better support OS X.</li>
<li>Add support to detect the latest version when doing a source install.</li>
<li>Expand the R package provider to include more of the features available
when installing package from within R.</li>
<li>Write an R Ohai plugin that would collect information about:

<ul>
<li>R version and capabilities</li>
<li>R packages installed</li>
</ul>
</li>
</ul>


<p>Happy Holidays!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Emacs Configuration Rewrite]]></title>
    <link href="http://stevendanna.github.com/blog/2011/11/26/emacs-configuration-rewrite/"/>
    <updated>2011-11-26T00:00:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2011/11/26/emacs-configuration-rewrite</id>
    <content type="html"><![CDATA[<p>I am in the process of rebooting my GTD workflow.  Since I do most of
my work in Emacs, I decided it was also time to refactor and improve my Emacs
configuration.  What was wrong with my configuration?</p>

<ul>
<li>I was living in the past (Emacs 23) and wanted to live in the future
(Emacs 24).</li>
<li>My configuration file was not under version control.  And, because
of the differences between Fedora and OS X, the configuration on my
work laptop and personal laptop had drifted significantly.</li>
<li>My <code>.emacs</code> file was poorly structured and easily broken.</li>
</ul>


<p>I&#8217;ve documented my work on my Emacs configuration here, mostly as a
means of reminding my future self what I did.  Overall the experience
was pleasant.  Emacs 24 brings many long-needed features to Emacs.</p>

<p>The end result can be seen below.</p>

<p><img src="http://stevendanna.github.com/assets/emacs-desktop.png"></p>

<h1>Installing Emacs 24:</h1>

<p>On Fedora, I installed directly from git:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># Install Dependencies</span>
</span><span class='line'>sudo yum-builddep emacs
</span><span class='line'>sudo yum install
</span><span class='line'><span class="c"># Get source</span>
</span><span class='line'><span class="nb">cd</span> ~/src
</span><span class='line'>git clone git://git.savannah.gnu.org/emacs.git
</span><span class='line'><span class="nb">cd </span>emacs
</span><span class='line'><span class="c"># Install</span>
</span><span class='line'>./autogen.sh
</span><span class='line'>./configure
</span><span class='line'>make
</span><span class='line'>sudo make install
</span></code></pre></td></tr></table></div></figure>


<p>On my Mac, I installed Emacs 24 via Homebrew:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>brew uninstall emacs
</span><span class='line'>brew install emacs --cocoa --use-git-head --HEAD
</span><span class='line'>ln -s /usr/local/Cellar/emacs/HEAD/Emacs.app /Applications/
</span></code></pre></td></tr></table></div></figure>


<h1>Rebuilding My Emacs Configuration</h1>

<p>A number of high-quality, pre-built Emacs configurations are available
online, including:</p>

<ul>
<li><a href="https://github.com/technomancy/emacs-starter-kit">Emacs Starter Kit</a></li>
<li><a href="https://github.com/bbatsov/emacs-prelude">Emacs Prelude</a></li>
<li><a href="https://github.com/bbatsov/emacs-dev-kit">Emacs Dev Kit</a></li>
</ul>


<p>A few Opscoders use configurations based around Emacs Starter
Kit. However, since I have fairly simple configuration needs, I decided
to borrow a few ideas from each and forge ahead on my own.  The result
can be found in my
<a href="https://github.com/stevendanna/emacs-config">emacs-config</a>
repository.  It is still very much a work in progress.</p>

<p>I&#8217;ve structured my new <code>.emacs.d</code> directory as follows:</p>

<pre><code>.
|-- init.el
|-- modules/
|-- snippets/
|-- themes/
`-- vendor/
</code></pre>

<ul>
<li><p><code>init.el</code>: The main entry point of the Emacs configuration.  I&#8217;ve
taken a bit of code from the README of Emacs Starter Kit that
automatically installs packages from ELPA.</p></li>
<li><p><code>modules/</code>: This is the heart of my emacs config.  Any <code>.el</code> files
in this directory are automatically loaded.</p></li>
<li><p><code>snippets/</code>: Used to store snippets for yasnippet.  Currently empty.</p></li>
<li><p><code>themes/</code>: Color themes.</p></li>
<li><p><code>vendor/</code>: Any 3rd party Emacs packages that are not yet distributed
via ELPA.</p></li>
</ul>


<p>The auto-installation of packages is great for sharing my
configuration between workstations; but, it can be brutally slow the
first time you run it.</p>

<h2>Highlights</h2>

<p>The majority of my emacs configuration consists of minor
customizations to popular, pre-built packages. The following are the
packages that I use on a daily basis:</p>

<ul>
<li><p><a href="http://www.emacswiki.org/emacs/InteractivelyDoThings">ido-mode</a>: I
 honestly don&#8217;t know how I used Emacs before discovering ido-mode.</p></li>
<li><p><a href="http://orgmode.org/">org-mode</a>: Org-mode is my go-to application
anytime I need to take notes in a meeting, outline a new project, or
author a simple document.</p></li>
<li><p><a href="http://ess.r-project.org/">ess</a>: Emacs Speaks Statistics (ESS) is a
 must-have for any user of R and Emacs. Kieran Healy has created
 <a href="http://kieranhealy.org/packages/">a repository for ESS</a>, making
 ESS easily installable via Emacs 24&#8217;s package management features.</p></li>
<li><p><a href="http://www.gnu.org/s/auctex/">auctex</a>: AucTeX provides a number a
features useful to those who love LaTeX.  If you haven&#8217;t fallen in
love with LaTeX yet, I highly recommend trying it!</p></li>
</ul>


<p>In addition to the tried-and-true packages above and a handful of
popular programming modes, I added the following packages to my
standard configuration:</p>

<ul>
<li><p><a href="https://github.com/defunkt/gist.el">Gist</a>: I use Github&#8217;s gists all
the time; I can&#8217;t believe I didn&#8217;t look for this before.</p></li>
<li><p><a href="http://jblevins.org/projects/deft/">Deft</a>: Deft allows you quickly
create, edit, and view plain-text notes.  I&#8217;ve configured it to use
org-mode as its default text-mode and hope to use it to easily
collect tasks throughout the day.</p></li>
<li><p><a href="http://www.emacswiki.org/emacs/HippieExpand">hippie-expand</a>: I
previously used predictive-mode extensively, but eventually found it
too slow to use productively.  So far, hippie-expand has been
filling the auto-completion void that I&#8217;ve been feeling since remove
predictive-mode.</p></li>
</ul>


<p>All of these packages are either shipped with Emacs or available as
packages using the new package management features in Emacs 24.  I was
initially skeptical of the package management features.  However, I&#8217;ve
found that a large amount of the complexity in managing my previous
configuration was the result of manually managing packages.  With this
complexity removed, moving to Emacs 24 was relatively painless.</p>

<p>I was also pleased to see improvements to clipboard integration. My
old <code>.emacs</code> file had a number of ugly workarounds for properly
interacting with the clipboard on multiple platforms.  I&#8217;ve found this
completely unnecessary in Emacs 24.</p>

<p>The only problem I encountered during this transition was finding a
suitable color theme.  Low-contrast color themes such as zenburn seem
to be in vogue at the moment.  I prefer higher-contrast themes.  In
Emacs 23, I used dark-laptop, but it appears that this theme has not
yet been ported to Emacs 24&#8217;s built-in color theme support.  My
current theme is a small color theme based heavily on dark-laptop.</p>

<h2>Deploy!</h2>

<p>I&#8217;ve deployed my new configuration to all of my workstations via a
simple <code>git pull</code>.  My hope is that a few weeks of real-world use will
find the rough edges that remain.  Comments and suggestions welcome!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[gsd: A small utility to get stuff done]]></title>
    <link href="http://stevendanna.github.com/blog/2011/11/06/gsd-a-small-utility-to-get-stuff-done/"/>
    <updated>2011-11-06T09:48:00-08:00</updated>
    <id>http://stevendanna.github.com/blog/2011/11/06/gsd-a-small-utility-to-get-stuff-done</id>
    <content type="html"><![CDATA[<p>In preparation for moving more of my personal laptop&#8217;s setup into git
and Chef, I spent a few minutes this morning taking stock of what I
had floating around my home folder on my personal laptop.</p>

<p>I found a small script I wrote when working on my thesis to help me
avoid distractions.  Since I thought others might be interested, I put
it up on Github and added a bit more user friendliness:</p>

<p><em><a href="https://github.com/stevendanna/gsd">gsd: A small utility to get stuff done</a></em></p>

<p><code>gsd</code> helps you get work done by replacing your host file with a
custom host file kept in <code>~/.gsd/</code>.  The custom host file prevents you
from visiting sites that distract you from the work you need to get done.</p>

<p>To start using the filter, simply clone the git repo and install the
script</p>

<pre><code>&gt; git clone git@github.com:stevendanna/gsd.git
&gt; cd gsd
&gt; sudo make install
</code></pre>

<p>Then, enable the filter</p>

<pre><code>&gt; sudo gsd enable
</code></pre>

<p>Finally, add sites to the filter and reload when you find yourself
being distracted by them:</p>

<pre><code>&gt; gsd add lkml.org
&gt; sudo gsd reload
</code></pre>

<p>With a bit of searching, one can find a number of these types of
scripts online.  My favorite that I&#8217;ve come across so far is <a href="https://github.com/leftnode/get-shit-done">Get Shit Done</a>, which works on
Windows and includes some logic to restart your systems networking
services.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[First Post]]></title>
    <link href="http://stevendanna.github.com/blog/2011/10/16/first-post/"/>
    <updated>2011-10-16T00:00:00-07:00</updated>
    <id>http://stevendanna.github.com/blog/2011/10/16/first-post</id>
    <content type="html"><![CDATA[<p>Introductory blog posts are awkward.  Come back in the future to read less
awkward blog posts.  Possible topics for such blog posts
include:</p>

<ul>
<li>Linux and Unix systems administration</li>
<li>Technical writing</li>
<li>Programming projects I&#8217;m working on in my free time</li>
<li>Free software</li>
<li>Chef and Opscode</li>
<li>Running</li>
<li>Cooking</li>
</ul>


<p>I recently finished school and am beginning a career in technology.
Most of my formal education is in Mathematics and Economics; I hope to
chronicle parts of my informal, on-the-job education here.</p>

<p>I live in Seattle, WA with my wife Theresa.  I enjoy running, cooking,
and movies and may occasionally write posts on these topics as well.</p>

<p>I work for <a href="www.opscode.com">Opscode, Inc</a>.  The opinions expressed
here are my own and do not reflect those of my employer.  Or, in other
words,</p>

<figure class='code'><figcaption><span>An Excuse for Playing with Syntax Highlighting</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>   <span class="nb">require</span> <span class="s1">&#39;disclaimer&#39;</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
</feed>
