<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Freenode Infra-Talk Channel</title>
	<atom:link href="http://infra-talk.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://infra-talk.org</link>
	<description>Syndicator</description>
	<lastBuildDate>Wed, 15 May 2013 20:46:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Facter 1.7+ and External facts</title>
		<link>http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/external-facter-facts.html</link>
		<comments>http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/external-facter-facts.html#comments</comments>
		<pubDate>Wed, 15 May 2013 20:46:00 +0000</pubDate>
		<dc:creator>Dean Wilson</dc:creator>
				<category><![CDATA[/tools/puppet]]></category>

		<guid isPermaLink="false">http://external-facter-facts</guid>
		<description><![CDATA[
While Puppet may get all the glory, Facter,
the hard working information gathering library that can, seldom gets much
exciting new functionality. However with the release of Facter 1.7
Puppetlabs have standardised and included a couple of useful facte...]]></description>
			<content:encoded><![CDATA[
While Puppet may get all the glory, <a
href='https://puppetlabs.com/puppet/related-projects/facter/'>Facter</a>,
the hard working information gathering library that can, seldom gets much
exciting new functionality. However with the release of Facter 1.7
Puppetlabs have standardised and included a couple of useful facter
enhancements that make it easier than ever to add custom facts to your
puppet runs.</p>

<p>
These two improvements come under the banner of 'External Facts'. The first
allows you to surface your own facts from a static file, either
plain text key value pairs or a specific YAML / JSON format. These static
files should be placed under <code>/etc/facter/facts.d</code></p>

<pre>
<code>
$ sudo mkdir -p /etc/facter/facts.d

# note - the .txt file extension
$ echo 'external_fact=yes' | sudo tee /etc/facter/facts.d/external_test.txt
external_fact=worked

$ facter external_fact
worked
</code>
</pre>

<p>
At its simplest this is a way to surface basic, static, details from
system provisioning and other similar large events but it's also an easy
way to include details from other daemon and cronjobs. One of my first
use cases for this was to create 'last_backup_time' and
'last_backup_status' facts that are written at the conclusion of my
backup cronjob. Having the values inserted from out of band is a much nicer
prospect that writing a custom fact that parses the cron logs.</p>

<p>
If that's a little too static for you then the second usage might be what
you're looking for. Any executable scripts dropped in the same directory
that produce the same output formats as allowed
above will be executed by facter when it's invoked.</p>

<pre>
<code>
# scripts must be executable!
$ sudo chmod a+rx /etc/facter/facts.d/process_count

$ cat /etc/facter/facts.d/process_count
#!/bin/bash

count=$(ps -efwww | wc -l | tr -s ' ')
echo "process_count=$count"

$ facter process_count
209
</code>
</pre>

<p>
The ability to run scripts that provide facts and values makes
customisation easier in situations where ruby isn't the best language for
the job. It's also a nice way to reuse existing tools or for including
information from further afield - such as the current binary log in
use by MySQL or Postgres or the hosts current state in the load
balancer.</p>

<p>
While there have been third party extensions that provided this
functionality for a while it's great to see these enhancements get
included in core facter.</p><p class="posted">Like this post? - <a href="http://www.digg.com/submit?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/external-facter-facts.rss20&amp;title=Facter%201.7+%20and%20External%20facts&amp;phase=3">Digg Me!</a> | <a href="http://del.icio.us/post?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/external-facter-facts.rss20&amp;title=Facter%201.7+%20and%20External%20facts">Add to del.icio.us!</a> | <a href="http://reddit.com/submit?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/external-facter-facts.rss20&amp;title=Facter%201.7+%20and%20External%20facts">reddit this!</a>]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/15/facter-1-7-and-external-facts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Escalating Complexity</title>
		<link>http://feedproxy.google.com/~r/AuxesisMusings/~3/Ujdt8FOpJ8Q/</link>
		<comments>http://feedproxy.google.com/~r/AuxesisMusings/~3/Ujdt8FOpJ8Q/#comments</comments>
		<pubDate>Tue, 14 May 2013 14:00:00 +0000</pubDate>
		<dc:creator>Lindsay Holmwood</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://holmwood.id.au/~lindsay/2013/05/15/escalating-complexity-af447</guid>
		<description><![CDATA[Back in 2009 when I was backpacking around Europe I remember waking up on the morning of June 1 and reading about how an Air France flight had disappeared somewhere over the Atlantic.

The lack of information on what happened to the flight intrigued me...]]></description>
			<content:encoded><![CDATA[<p>Back in 2009 when I was backpacking around Europe I remember waking up on the morning of June 1 and reading about how an Air France flight had disappeared somewhere over the Atlantic.</p>

<p>The lack of information on what happened to the flight intrigued me, and given the traveling I was doing, I was left wondering "what if I was on that plane?"</p>

<p>Keeping an ear out for updates, in December 2011 I stumbled upon the <a href="http://www.popularmechanics.com/technology/aviation/crashes/what-really-happened-aboard-air-france-447-6611877">Popular Mechanics article</a> describing the final moments of the flight. I was left fascinated by how a technical system so advanced could fail so horribly, apparently because of the faulty meatware operating it.</p>

<p>Around the same time I began reading the works of <a href="http://sidneydekker.com/">Sidney Dekker</a>. I was left in a state of cognitive dissonance, trying to reconcile the mainstream explanation of what happened in the final moments of AF447 (the pilots were poorly trained, inexperienced, and simply incompetent) with the New View that the operators were merely locally rational actors within a complex system, and that "root cause is simply the place you stop looking further" - with that cause far too commonly attributed to humans.</p>

<p>I decided to do my own research, which resulted in me producing a talk that has received the strongest reaction of any talk I've ever given.</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/P8hZOHtrHn0" frameborder="0" allowfullscreen></iframe>


<blockquote><p>On June 1, 2009 Air France 447 crashed into the Atlantic ocean killing all 228 passengers and crew. The 15 minutes leading up to the impact were a terrifying demonstration of the how thick the fog of war is in complex systems.</p>

<p>Mainstream reports of the incident put the blame on the pilots - a common motif in incident reports that conveniently ignore a simple fact: people were just actors within a complex system, doing their best based on the information at hand.</p>

<p>While the systems you build and operate likely don't control the fate of people's lives, they share many of the same complexity characteristics. Dev and Ops can learn an abundance from how the feedback loops between these aviation systems are designed and how these systems are operated.</p>

<p>In this talk Lindsay will cover what happened on the flight, why the mainstream explanation doesn't add up, how design assumptions can impact people's ability to respond to rapidly developing situations, and how to improve your operational effectiveness when dealing with rapidly developing failure scenarios.</p></blockquote>

<iframe src="http://www.slideshare.net/slideshow/embed_code/18183459" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe>


<p></p>

<p>The subject matter is heavy, and I while it's something I'm passionate about, it was an emotionally taxing talk to prepare, and a talk that angers me when presenting.</p>

<p>Time to let it sit and rest.</p>
<img src="http://feeds.feedburner.com/~r/AuxesisMusings/~4/Ujdt8FOpJ8Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/14/escalating-complexity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why there is a future in cloud futures</title>
		<link>http://www.agilesysadmin.net/why-there-is-a-future-in-cloud-futures</link>
		<comments>http://www.agilesysadmin.net/why-there-is-a-future-in-cloud-futures#comments</comments>
		<pubDate>Tue, 14 May 2013 00:00:00 +0000</pubDate>
		<dc:creator>Agile Sysadmin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[
      Earlier this month, at the Cloud 2020 summit, in Las Vegas, a group of service providers, vendors, buyers and pundits met to discuss the future of cloud infrastructure. One of the tracks was on the economics of infrastructure services, and inclu...]]></description>
			<content:encoded><![CDATA[
      <p>Earlier this month, at the <a href='http://cloud2020summit.com'>Cloud 2020 summit</a>, in Las Vegas, a group of service providers, vendors, buyers and pundits met to discuss the future of cloud infrastructure. One of the tracks was on the economics of infrastructure services, and included John Cowan from <a href='http://www.6fusion.com'>6Fusion</a>, whose cloud metering technology is a key piece of the puzzle if cloud is to be treated as a commodity, James Mitchell, founder and CEO of <a href='http://www.cloudoptions.com'>Strategic Blue</a>, and former Morgan Stanley commodities trader, and Joe Weinman, author of the fascinating book <a href='http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118229967.html'>Cloudonomics</a>.</p>
      
      <p>Out of this track emerged some interesting debate around the viability of the whole notion of a cloud futures market. Jonathan Murray, EVP &amp; Chief Technology Officer at Warner Music Group, followed up with an <a href='http://www.adamalthus.com/blog/2013/05/11/why-theres-no-future-in-cloud-futures/'>article</a> presenting his perspective, from the skeptical end of the spectrum. This article presents a view from the optimistic side.</p>
      
      <p>I&#8217;m indebted to John Woodley, investor and board advisor at Strategic Blue, for his insights and comments. John is a former Managing Director at Morgan Stanley, where he was co-Head of non-oil commodities for EMEA. He was the first person to be hired by a Wall Street bank from a power utility, becoming a founder member of the Morgan Stanley electricity trading desk. As one of the world’s foremost authorities on commodity market development and the pricing of non-standard pseudo-commodity products, his perspective is fascinating.</p>
      
      <h2 id='the_challenge'>The challenge</h2>
      
      <p>Jonathan explicitly self-identifies as one who is unconvinced about the prospect of a futures market for cloud. His article is fairly long, and his argument well made. The core point he puts forward is essentially: <em>&#8220;There is no volatility or friction so we don&#8217;t need intermediation.&#8221;</em></p>
      
      <h2 id='is_there_friction_in_the_cloud_market'>Is there friction in the cloud market?</h2>
      
      <p>Jonathan doesn&#8217;t explicitly define friction, but I think he means that in today&#8217;s world, primary buyers can easily find primary sellers, and as such there&#8217;s no need for an intermediary. This is a fair point. In the old world, this was impossible. In a market without intermediaries, in order to get the best price, you need each of the buyers to make as many calls as are there are sellers. Let the number of buyers in the market be &#8216;b&#8217; and the number of sellers be &#8216;s&#8217;. In a tiny market, with 10 buyers and 10 sellers, you need b*s calls in order to achieve the best price, or 100 calls in total.</p>
      
      <p>However, in a world in which buyers are also resellers, the number of calls needed in order to secure the best price becomes much larger - somewhere around the factorial of the number of buyers plus the number of sellers - (b+s)!. In our tiny market, (10+10)! is 2432902008176640000. If one entity in the middle takes calls and keeps note you only need b+s calls and not (b+s) factorial. This is a conventional argument for the existence of a market - it offers huge savings. On these grounds, it&#8217;s hard to imagine Jonathan thinks there isn&#8217;t a market, a forum for price comparison, but certainly in today&#8217;s world the web is that intermediary near as dammit is to swearing. Jonathan correctly describes markets as places where supply is matched to demand, and indeed, we use markets because they have proven better than manual or -so far- computational planners in correctly matching supply and demand efficiently.</p>
      
      <p>There is, of course, very significant friction in the cloud market, per a different definition. Look at the way cloud providers sell their services. They want long-term commitment, in their own currency, by credit card. By contrast, the cloud user wants minimal commitment, the best flexibility to move should a better deal emerge, or a better technology offering appear. They&#8217;d rather not have to keep a credit card on file, and in many cases, for example in India, currency fluctuations make a huge impact, and they&#8217;d greatly prefer to pay in their own local currency. In this situation, an intermediary who buys from the providers on terms which suit the provider, and sells to the buyers on terms which suit the buyers is very attractive.</p>
      
      <h2 id='is_there_a_need_for_intermediation'>Is there a need for intermediation?</h2>
      
      <p>Let&#8217;s examine whether there&#8217;s a need for intermediation against the assertion that there is no volatility. I think that assertion is false. It strikes me as similar to the assertion that there was no petrol price volatility in the US in 1979 or more recently in the Northeastern US after Hurricane Sandy, because the posted price at the pump did not change. The reality of course is that the underlying value changed so radically that people would queue for hours to get the scarce commodity and even threaten each other with violence to get precedence.</p>
      
      <p>To be sure we have not seen that in cloud yet but we have seen scarcities. John Woodley cited an exemplary case with which he was particularly familiar. The Morgan Stanley IT department was approached to lend space at a datacenter because a major movie producer could not get enough capability on the open market to render a movie before the all-important Christmas release date. Had the IT department called a Fixed Income trader before agreeing to the deal I am fairly sure the producer would have had to pay more in cash or kind than a few T Shirts for the deal.</p>
      
      <p>So, I have to ask: Is there no state of the world in which a sudden demand for many thousands or millions of instances might occur? Are there that many sitting idle? No, a far more productive and interesting line of thought is how the demand surge might occur and how to be in the right place at the right time to benefit. For an interesting example, consider the events surrounding Silver Thursday, in 1980, in which the Hunt Brothers had hoarded a third of the world&#8217;s supply of silver, inflating the price by a whopping 700%. At the same time, anecdotally, a certain bank held for some strange reason a large part of the silver smelting capability, and thus were able to charge greatly increased prices for people wanting to melt down the family silver, to sell as ingots. In John Woodley&#8217;s view, it is tremendously likely that we will see scarcity and volatility in the cloud markets, and a wealth of opportunity and demand to intermediate.</p>
      
      <h2 id='what_about_contractual_preference'>What about contractual preference?</h2>
      
      <p>I touched on this when discussing the idea of friction in the cloud market. A second but no less important driver for intermediation was not addressed in Jonathon&#8217;s article. In certain markets, the contractual preferences of buyers and sellers diverge dramatically. In such cases the insertion of a financial intermediary is very helpful and both parties are prepared to pay the rather minimal cost such intermediation causes. An example that is blindingly obvious can be found in electricity. Power plants are only used when the demand is sufficiently high to cover the operating expenses of the power plant. Power plants are built on borrowed money. A power plant owner needs to finance the debts used to build the plant, and so wants a fixed payment per month from their customers. By contrast, a retailer of electricity simply wants to be charged on a per use basis, and wants nothing to do with fuel cost pass-through, or a fixed monthly fee. Think about the way datacenters are funded. It&#8217;s exactly the same model - why do you think cloud providers offer such a huge discount for a commitment to usage? It&#8217;s the same! In the electricity markets, intermediation provides a welcome service, in which the intermediary is the buyer to every seller and the seller to every buyer, ironing out the contractual wrinkles, and benefiting the market as a whole. There&#8217;s already evidence of demand for this kind of service in the cloud market today.</p>
      
      <h2 id='summary'>Summary</h2>
      
      <p>The fundamental point Jonathan makes in his argument is that because there is no volatility or friction, there&#8217;s no need for intermediation. However, there is already evidence of price fluctuation and scarcity, and in terms of the delta between the way buyers want to buy and sellers want to sell, there is clearly friction. The cloud market behaves like and looks like a blend of the electricity and coal market, both of which are highly intermediated and heavily traded. Yes, it&#8217;s early days, but it seems very likely indeed that we&#8217;ll see the same kind of behavior in the cloud.</p>
    ]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/14/why-there-is-a-future-in-cloud-futures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building RPMs from ruby gems with fpm</title>
		<link>http://blog.yo61.com/building-rpms-from-ruby-gems-with-fpm.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=building-rpms-from-ruby-gems-with-fpm</link>
		<comments>http://blog.yo61.com/building-rpms-from-ruby-gems-with-fpm.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=building-rpms-from-ruby-gems-with-fpm#comments</comments>
		<pubDate>Mon, 13 May 2013 19:46:40 +0000</pubDate>
		<dc:creator>Robin Bowes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[rpm]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.yo61.com/?p=354</guid>
		<description><![CDATA[Some time ago, I wrote up how I created RPMs for ruby gems to simplify installation on EL-flavoured distributions. In the comments for that article, Jordan Sissel pointed me at his fpm tool which I said I&#8217;d check out if I ever needed to build any more rubygem RPMs. Well, that time has come. I wanted&#8230; <a href="http://blog.yo61.com/building-rpms-from-ruby-gems-with-fpm.html">Continue reading <span>&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some time ago, I wrote up how I <a title="Building RPMs from Ruby gems" href="http://blog.yo61.com/building-rpms-from-ruby-gems.html" >created RPMs for ruby gems</a> to simplify installation on EL-flavoured distributions. In the comments for that article, <a href="https://github.com/jordansissel" >Jordan Sissel</a> pointed me at his <a href="https://github.com/jordansissel/fpm" >fpm</a> tool which I said I&#8217;d check out if I ever needed to build any more rubygem RPMs.</p>
<p>Well, that time has come. I wanted to deploy a later version of capistrano across a client&#8217;s infrastructure and my previous approach didn&#8217;t work so I grabbed fpm and did this:</p>
<pre>mkdir ~/tmp/gems
cd ~/tmp/gems
gem install --no-ri --no-rdoc --install-dir . capistrano
find ./cache -name '*.gem' | xargs -rn1 fpm -s gem -t rpm
ls *.rpm
rubygem-capistrano-2.15.4-1.noarch.rpm	rubygem-net-scp-1.1.0-1.noarch.rpm   rubygem-net-ssh-2.6.7-1.noarch.rpm
rubygem-highline-1.6.19-1.noarch.rpm	rubygem-net-sftp-2.1.2-1.noarch.rpm  rubygem-net-ssh-gateway-1.2.0-1.noarch.rpm
</pre>
<p>Nice and easy. Kudos whack!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yo61.com/building-rpms-from-ruby-gems-with-fpm.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting ChefSpec Example</title>
		<link>http://jtimberman.housepub.org/blog/2013/05/09/starting-chefspec-example/</link>
		<comments>http://jtimberman.housepub.org/blog/2013/05/09/starting-chefspec-example/#comments</comments>
		<pubDate>Fri, 10 May 2013 03:10:00 +0000</pubDate>
		<dc:creator>Joshua Timberman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jtimberman.housepub.org/blog/2013/05/09/starting-chefspec-example</guid>
		<description><![CDATA[This is a quick post to introduce what I&#8217;m starting on testing with
ChefSpec. This is from Opscode&#8217;s
Java cookbook. While the recipe tested is really trivial, it actually
has some nuances that require detailed testing.

First off, the whole...]]></description>
			<content:encoded><![CDATA[<p>This is a quick post to introduce what I&#8217;m starting on testing with
<a href="http://acrmp.github.io/chefspec/">ChefSpec</a>. This is from Opscode&#8217;s
Java cookbook. While the recipe tested is really trivial, it actually
has some nuances that require detailed testing.</p>

<p>First off, the whole thing is in
<a href="https://gist.github.com/jtimberman/5552182">this gist</a>. I&#8217;m going to
break it down into sections below. The file is <code>spec/default_spec.rb</code>
in the java cookbook (not committed/pushed yet).</p>

<p>The chefspec gem is where all the magic comes from. You can read about
ChefSpec on <a href="http://acrmp.github.io/chefspec/">its home page</a>. You&#8217;ll
need to install the gem, and from there, run <code>rspec</code> to run the tests.</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="nb">require</span> <span class="s1">&#39;chefspec&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, we&#8217;re going to describe the default recipe. We&#8217;re using the
regular rspec &#8220;let&#8221; block to set up the runner to converge the recipe.
Then, because we know/assume that the openjdk recipe is the default,
we can say that this chef run should include the <code>java::openjdk</code> recipe.</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">describe</span> <span class="s1">&#39;java::default&#39;</span> <span class="k">do</span>
</span><span class=’line’>  <span class="n">let</span> <span class="p">(</span><span class="ss">:chef_run</span><span class="p">)</span> <span class="p">{</span> <span class="no">ChefSpec</span><span class="o">::</span><span class="no">ChefRunner</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">converge</span><span class="p">(</span><span class="s1">&#39;java::default&#39;</span><span class="p">)</span> <span class="p">}</span>
</span><span class=’line’>  <span class="n">it</span> <span class="s1">&#39;should include the openjdk recipe by default&#39;</span> <span class="k">do</span>
</span><span class=’line’>    <span class="n">chef_run</span><span class="o">.</span><span class="n">should</span> <span class="n">include_recipe</span> <span class="s1">&#39;java::openjdk&#39;</span>
</span><span class=’line’>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, this cookbook supports Windows. However, we have to set up the
runner with the correct platform and version (this comes from
<a href="https://github.com/customink/fauxhai">fauxhai</a>), and then set
attributes that are required for it to work.</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>
</pre></td><td class=’code’><pre><code class=’ruby’><span class=’line’><span class="n">context</span> <span class="s1">&#39;windows&#39;</span> <span class="k">do</span>
</span><span class=’line’>    <span class="n">let</span><span class="p">(</span><span class="ss">:chef_run</span><span class="p">)</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">runner</span> <span class="o">=</span> <span class="no">ChefSpec</span><span class="o">::</span><span class="no">ChefRunner</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
</span><span class=’line’>        <span class="s1">&#39;platform&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;windows&#39;</span><span class="p">,</span>
</span><span class=’line’>        <span class="s1">&#39;version&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;2008R2&#39;</span>
</span><span class=’line’>        <span class="p">)</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;install_flavor&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;windows&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;windows&#39;</span><span class="o">][</span><span class="s1">&#39;url&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;http://example.com/windows-java.msi&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">converge</span><span class="p">(</span><span class="s1">&#39;java::default&#39;</span><span class="p">)</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>    <span class="n">it</span> <span class="s1">&#39;should include the windows recipe&#39;</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">chef_run</span><span class="o">.</span><span class="n">should</span> <span class="n">include_recipe</span> <span class="s1">&#39;java::windows&#39;</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next are the contexts for other install flavors. The default recipe
will include the right recipe based on the flavor, which is set by an
attribute. So we set up an rspec context for each recipe, then set the
install flavor attribute, and test that the right recipe was included.</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>
</pre></td><td class=’code’><pre><code class=’ruby’><span class=’line’>  <span class="n">context</span> <span class="s1">&#39;oracle&#39;</span> <span class="k">do</span>
</span><span class=’line’>    <span class="n">let</span><span class="p">(</span><span class="ss">:chef_run</span><span class="p">)</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">runner</span> <span class="o">=</span> <span class="no">ChefSpec</span><span class="o">::</span><span class="no">ChefRunner</span><span class="o">.</span><span class="n">new</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;install_flavor&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;oracle&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">converge</span><span class="p">(</span><span class="s1">&#39;java::default&#39;</span><span class="p">)</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>    <span class="n">it</span> <span class="s1">&#39;should include the oracle recipe&#39;</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">chef_run</span><span class="o">.</span><span class="n">should</span> <span class="n">include_recipe</span> <span class="s1">&#39;java::oracle&#39;</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>  <span class="k">end</span>
</span><span class=’line’>  <span class="n">context</span> <span class="s1">&#39;oracle_i386&#39;</span> <span class="k">do</span>
</span><span class=’line’>    <span class="n">let</span><span class="p">(</span><span class="ss">:chef_run</span><span class="p">)</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">runner</span> <span class="o">=</span> <span class="no">ChefSpec</span><span class="o">::</span><span class="no">ChefRunner</span><span class="o">.</span><span class="n">new</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;install_flavor&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;oracle_i386&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">converge</span><span class="p">(</span><span class="s1">&#39;java::default&#39;</span><span class="p">)</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>    <span class="n">it</span> <span class="s1">&#39;should include the oracle_i386 recipe&#39;</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">chef_run</span><span class="o">.</span><span class="n">should</span> <span class="n">include_recipe</span> <span class="s1">&#39;java::oracle_i386&#39;</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, a recent addition to this cookbook is support for
<a href="http://tickets.opscode.com/browse/COOK-2897">IBM&#8217;s Java</a>. In addition
to setting the install flavor, we must set the URL where the IBM Java
package is (see the README in the commit linked in that ticket for
detail), and we can see that the <code>ibm</code> recipe is in fact included.</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=’ruby’><span class=’line’>  <span class="n">context</span> <span class="s1">&#39;ibm&#39;</span> <span class="k">do</span>
</span><span class=’line’>    <span class="n">let</span><span class="p">(</span><span class="ss">:chef_run</span><span class="p">)</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">runner</span> <span class="o">=</span> <span class="no">ChefSpec</span><span class="o">::</span><span class="no">ChefRunner</span><span class="o">.</span><span class="n">new</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;install_flavor&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;ibm&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">node</span><span class="o">.</span><span class="n">set</span><span class="o">[</span><span class="s1">&#39;java&#39;</span><span class="o">][</span><span class="s1">&#39;ibm&#39;</span><span class="o">][</span><span class="s1">&#39;url&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;http://example.com/ibm-java.bin&#39;</span>
</span><span class=’line’>      <span class="n">runner</span><span class="o">.</span><span class="n">converge</span><span class="p">(</span><span class="s1">&#39;java::default&#39;</span><span class="p">)</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>    <span class="n">it</span> <span class="s1">&#39;should include the ibm recipe&#39;</span> <span class="k">do</span>
</span><span class=’line’>      <span class="n">chef_run</span><span class="o">.</span><span class="n">should</span> <span class="n">include_recipe</span> <span class="s1">&#39;java::ibm&#39;</span>
</span><span class=’line’>    <span class="k">end</span>
</span><span class=’line’>  <span class="k">end</span>
</span><span class=’line’><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is just the start of the testing for this cookbook. We&#8217;ll need to
test each individual recipe. However as I&#8217;ve not written that code
yet, I don&#8217;t have examples. Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/10/starting-chefspec-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Kitchen and Jenkins</title>
		<link>http://jtimberman.housepub.org/blog/2013/05/08/test-kitchen-and-jenkins/</link>
		<comments>http://jtimberman.housepub.org/blog/2013/05/08/test-kitchen-and-jenkins/#comments</comments>
		<pubDate>Thu, 09 May 2013 05:53:00 +0000</pubDate>
		<dc:creator>Joshua Timberman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jtimberman.housepub.org/blog/2013/05/08/test-kitchen-and-jenkins</guid>
		<description><![CDATA[I&#8217;ve been working more with test-kitchen 1.0 alpha lately. The most
recent thing I&#8217;ve done is set up a Jenkins build server to run
test-kitchen on cookbooks. This post will describe how I did this for
my own environment, and how you can use...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working more with test-kitchen 1.0 alpha lately. The most
recent thing I&#8217;ve done is set up a Jenkins build server to run
test-kitchen on cookbooks. This post will describe how I did this for
my own environment, and how you can use my new test-kitchen cookbook
in yours&#8230; if you&#8217;re using Jenkins, anyway.</p>

<p>This is all powered by a relatively simple cookbook, and some
click-click-clicking in the Jenkins UI. I&#8217;ll walk through what I did
to set up my Jenkins system.</p>

<p>First, I started with Debian 7.0 (stable, released this past weekend).
I installed the OS on it, and then bootstrapped with Chef. The initial
test was to make sure everything installed correctly, and the commands
were functioning. This was done in a VM, and is now handled by
test-kitchen itself (how meta!) in the cookbook, kitchen-jenkins.</p>

<p>The cookbook, <a href="http://ckbk.it/kitchen-jenkins">kitchen-jenkins</a> is
available on the Chef Community site. I started with a recipe, but
extracted it to a cookbook to make it easier to share with you all.
This is essentially a site cookbook that I use to customize my Jenkins
installation so I can run test-kitchen builds.</p>

<p>I apply the recipe with a role, because I love the roles primitive in
Chef :-). Here is the role I&#8217;m using:</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>
</pre></td><td class=’code’><pre><code class=’javascript’><span class=’line’><span class="p">{</span>
</span><span class=’line’>  <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;jenkins&quot;</span><span class="p">,</span>
</span><span class=’line’>  <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Jenkins Build Server&quot;</span><span class="p">,</span>
</span><span class=’line’>  <span class="s2">&quot;run_list&quot;</span><span class="o">:</span> <span class="p">[</span>
</span><span class=’line’>    <span class="s2">&quot;recipe[kitchen-jenkins]&quot;</span>
</span><span class=’line’>  <span class="p">],</span>
</span><span class=’line’>  <span class="s2">&quot;default_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class=’line’>    <span class="s2">&quot;jenkins&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class=’line’>      <span class="s2">&quot;server&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class=’line’>        <span class="s2">&quot;home&quot;</span><span class="o">:</span> <span class="s2">&quot;/var/lib/jenkins&quot;</span><span class="p">,</span>
</span><span class=’line’>        <span class="s2">&quot;plugins&quot;</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;git-client&quot;</span><span class="p">,</span> <span class="s2">&quot;git&quot;</span><span class="p">],</span>
</span><span class=’line’>        <span class="s2">&quot;version&quot;</span><span class="o">:</span> <span class="s2">&quot;1.511&quot;</span><span class="p">,</span>
</span><span class=’line’>        <span class="s2">&quot;war_checksum&quot;</span><span class="o">:</span> <span class="s2">&quot;7e676062231f6b80b60e53dc982eb89c36759bdd2da7f82ad8b35a002a36da9a&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><span class=’line’>  <span class="s2">&quot;json_class&quot;</span><span class="o">:</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="o">:</span> <span class="s2">&quot;role&quot;</span>
</span><span class=’line’><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The run list is only slightly different here than my actual role, I
have a few other things in the run list, which are other site-specific
recipes. Don&#8217;t worry about those now. The jenkins attributes are set
to ensure the right plugins I need are available, and the right
version of jenkins is installed.</p>

<p>(I&#8217;m going to leave out the details such as uploading cookbooks and
roles, if you&#8217;re interested in test-kitchen, I&#8217;ll assume you&#8217;ve got
that covered :-).)</p>

<p>Once Chef completes on the Jenkins node, I can reach the Jenkins UI,
conveniently enough, via &#8220;http://jenkins:8080&#8221; (because I&#8217;ve made a
DNS entry, of course). The next release of the Jenkins cookbook will
have a resource for managing jobs, but for now I&#8217;m just going to
create them in the webui.</p>

<p>For this example, I want to have two kinds of cookbook testing jobs.
The first, is to simply run foodcritic and fail on any correctness
matches. Second, I want to actually run test-kitchen.</p>

<p>A foodcritic job is simple:</p>

<ol>
<li>New job -> Build a free-style software project
&#8220;foodcritic-COOKBOOK&#8221;.</li>
<li>Source Code Management -> Git, supply the repository and the master
branch.</li>
<li>Set a build trigger to Poll SCM every 5 minutes, once an hour,
whenever you like.</li>
<li>Add a build step to execute a shell, &#8220;foodcritic . -f correctness&#8221;</li>
</ol>


<p>I created a view for foodcritic jobs, and added them all to the view
for easy organizing.</p>

<p>Next, I create a test-kitchen job:</p>

<ol>
<li>New job -> Copy existing job &#8220;foodcritic-COOKBOOK&#8221;, name the new
job &#8220;test-COOKBOOK&#8221;.</li>
<li>Uncheck Poll SCM, check &#8220;Build after other projects are built&#8221; and
enter &#8220;foodcritic-COOKBOOK&#8221;.</li>
<li>Replace the foodcritic command in the build shell command with
&#8220;kitchen test&#8221;.</li>
</ol>


<p>Now, the test kitchen test will only run if the foodcritic build
succeeds. If the cookbook has any correctness lint errors, then the
foodcritic build fails, and the kitchen build won&#8217;t run. This will
help conserve resources.</p>

<p>Hopefully the <code>kitchen-jenkins</code> cookbook is helpful and this blog post
will give you some ideas how to go about adding cookbook tests to your
CI system, even if it&#8217;s not Jenkins.</p>
]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/09/test-kitchen-and-jenkins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TDD Cookbook Ticket</title>
		<link>http://jtimberman.housepub.org/blog/2013/05/03/tdd-cookbook-ticket/</link>
		<comments>http://jtimberman.housepub.org/blog/2013/05/03/tdd-cookbook-ticket/#comments</comments>
		<pubDate>Fri, 03 May 2013 20:36:00 +0000</pubDate>
		<dc:creator>Joshua Timberman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jtimberman.housepub.org/blog/2013/05/03/tdd-cookbook-ticket</guid>
		<description><![CDATA[This post will briefly describe how I did a TDD update to Opscode&#8217;s
runit to resolve an
issue reported last night.

First, the issue manifests itself only on Debian systems. The runit
cookbook&#8217;s runit_service provider will write an
LSB init...]]></description>
			<content:encoded><![CDATA[<p>This post will briefly describe how I did a TDD update to Opscode&#8217;s
<a href="http://ckbk.it/runit">runit</a> to resolve an
<a href="https://tickets.opscode.com/browse/COOK-2867">issue reported last night</a>.</p>

<p>First, the issue manifests itself only on Debian systems. The runit
cookbook&#8217;s <code>runit_service</code> provider will write an
<a href="http://tickets.opscode.com/browse/COOK-1576">LSB init.d script</a> on
Debian, rather than symlinking to <code>/usr/bin/sv</code>. The problem raised in
the new ticket is that the template will follow the link and write to
<code>/usr/bin/sv</code>. This is bad, as it will end up in a forkbomb as
runsvdir attempts to restart sv on
<a href="http://drupal.org/files/x-all-the-things-template.png">all the things</a>.
Oops! Sorry about that. Let&#8217;s get it fixed, and practice some TDD.</p>

<p>The runit cookbook includes support for test-kitchen, though I did
need to
<a href="https://github.com/opscode-cookbooks/runit/commit/8d2e0fcb9d6becf99c0d30694164e57d59fb667b">update it</a>
for this effort. Part of this change was adding a box for Debian in
the <code>.kitchen.yml</code>. I set about resolving this with TDD in mind.</p>

<p>First, the runit cookbook includes a couple
<a href="https://github.com/opscode-cookbooks/runit/tree/master/test/cookbooks">&#8220;test&#8221; cookbooks</a>
to facilitate setting up the system with the <code>runit_service</code> resource
so the outcome can be tested to ensure the behavior is correct. I
started by adding a &#8220;failing test&#8221; in the <code>runit_test::service</code>
recipe, meaning a link resource, and a <code>runit_service</code> resource that
would overwrite <code>/usr/bin/sv</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>
</pre></td><td class=’code’><pre><code class=’ruby’><span class=’line’><span class="n">link</span> <span class="s2">&quot;/etc/init.d/cook-2867&quot;</span> <span class="k">do</span>
</span><span class=’line’>  <span class="n">to</span> <span class="s2">&quot;/usr/bin/sv&quot;</span>
</span><span class=’line’><span class="k">end</span>
</span><span class=’line’>
</span><span class=’line’><span class="n">runit_service</span> <span class="s2">&quot;cook-2867&quot;</span> <span class="k">do</span>
</span><span class=’line’>  <span class="n">default_logger</span> <span class="kp">true</span>
</span><span class=’line’><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then I ran <code>kitchen test</code> on the Debian box. As expected, the link was
created, and then the runit service was configured. The service&#8217;s
provider will wait until the service is up. Since we&#8217;ve destroyed the
sv binary, that will never happen, so I destroyed it. I manually
confirmed the behavior too, to make sure I wasn&#8217;t seeing something
weird. Due to its very nature, this is <em>really</em> hard to test for
automatically, but it will happen consistently.</p>

<p>Next, I had to write the code to implement the fix for this bug.
Essentially, this means checking if the <code>/etc/init.d/cook-2867</code> file
is a symbolink link, and removing it.</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>
</pre></td><td class=’code’><pre><code class=’ruby’><span class=’line’><span class="n">initfile</span> <span class="o">=</span> <span class="o">::</span><span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> <span class="s1">&#39;/etc&#39;</span><span class="p">,</span> <span class="s1">&#39;init.d&#39;</span><span class="p">,</span> <span class="n">new_resource</span><span class="o">.</span><span class="n">service_name</span><span class="p">)</span>
</span><span class=’line’><span class="o">::</span><span class="no">File</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">initfile</span><span class="p">)</span> <span class="k">if</span> <span class="o">::</span><span class="no">File</span><span class="o">.</span><span class="n">symlink?</span><span class="p">(</span><span class="n">initfile</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Simple enough. Next I tested again by destroying the existing
environment and rerunning it from scratch. This takes some time, but
it verifies that everything is working properly. Here&#8217;s the output on
Debian:</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>
</pre></td><td class=’code’><pre><code class=’ruby’><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">link</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">runit_test</span><span class="o">::</span><span class="n">service</span> <span class="n">line</span> <span class="mi">147</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">link</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">created</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">service</span><span class="o">[</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">nothing</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">runit_service</span><span class="o">[</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">enable</span> <span class="p">(</span><span class="n">runit_test</span><span class="o">::</span><span class="n">service</span> <span class="n">line</span> <span class="mi">151</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">directory</span><span class="o">[</span><span class="sr">/etc/s</span><span class="n">v</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/s</span><span class="n">v</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">/</span><span class="n">run</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">directory</span><span class="o">[</span><span class="sr">/etc/s</span><span class="n">v</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">/</span><span class="n">log</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">directory</span><span class="o">[</span><span class="sr">/etc/s</span><span class="n">v</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">main</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">directory</span><span class="o">[</span><span class="sr">/var/</span><span class="n">log</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">file</span><span class="o">[</span><span class="sr">/etc/s</span><span class="n">v</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">run</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Processing</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">action</span> <span class="n">create</span> <span class="p">(</span><span class="n">dynamically</span> <span class="n">defined</span><span class="p">)</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">updated</span> <span class="n">content</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">owner</span> <span class="n">changed</span> <span class="n">to</span> <span class="mi">0</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">group</span> <span class="n">changed</span> <span class="n">to</span> <span class="mi">0</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">template</span><span class="o">[</span><span class="sr">/etc/ini</span><span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">mode</span> <span class="n">changed</span> <span class="n">to</span> <span class="mi">755</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="n">runit_service</span><span class="o">[</span><span class="n">cook</span><span class="o">-</span><span class="mi">2867</span><span class="o">]</span> <span class="n">configured</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Chef</span> <span class="no">Run</span> <span class="n">complete</span> <span class="k">in</span> <span class="mi">7</span><span class="o">.</span><span class="mi">267132764</span> <span class="n">seconds</span>
</span><span class=’line’><span class="no">INFO</span><span class="p">:</span> <span class="no">Running</span> <span class="n">report</span> <span class="n">handlers</span>
</span></code></pre></td></tr></table></div></figure>


<p>I didn&#8217;t feel I needed a specific test for this in minitest-chef,
because it wouldn&#8217;t have finished converging (earlier behavior I saw
in the &#8220;failing&#8221; test).</p>

<p>If you&#8217;re contributing to cookbooks, and they have support for
test-kitchen, it&#8217;s awesome if you can open a bug report with a failing
test. In this case, it was fairly easy to reproduce the bug.</p>
]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/05/03/tdd-cookbook-ticket/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Centralized Log analysis &amp; Logging in JSON – PART 1</title>
		<link>http://piyush.me/2013/05/03/centralized-log-analysis-logging-in-json-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=centralized-log-analysis-logging-in-json-part-1</link>
		<comments>http://piyush.me/2013/05/03/centralized-log-analysis-logging-in-json-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=centralized-log-analysis-logging-in-json-part-1#comments</comments>
		<pubDate>Fri, 03 May 2013 02:57:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[devops]]></category>

		<guid isPermaLink="false">http://piyush.me/?p=283</guid>
		<description><![CDATA[Centralized Log analysis (Real Time) &#038; Logging in JSON – PART 1 Logs are one of the most useful things when it comes to analysis; in simple terms Log analysis is making sense out of system/app-generated log messages (or just LOGS). &#8230; Conti...]]></description>
			<content:encoded><![CDATA[Centralized Log analysis (Real Time) &#38; Logging in JSON – PART 1 Logs are one of the most useful things when it comes to analysis; in simple terms Log analysis is making sense out of system/app-generated log messages (or just LOGS). &#8230; <a href="http://piyush.me/2013/05/03/centralized-log-analysis-logging-in-json-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://piyush.me/2013/05/03/centralized-log-analysis-logging-in-json-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deprecation Warnings From Puppet Resources</title>
		<link>http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/deprecation-warnings-from-puppet-resources.html</link>
		<comments>http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/deprecation-warnings-from-puppet-resources.html#comments</comments>
		<pubDate>Sat, 27 Apr 2013 11:53:00 +0000</pubDate>
		<dc:creator>Dean Wilson</dc:creator>
				<category><![CDATA[/tools/puppet]]></category>

		<guid isPermaLink="false">http://deprecation-warnings-from-puppet-resources</guid>
		<description><![CDATA[
Over time parts of your puppet manifests will become unneeded. You might
move a cronjob or a users in to a package or no longer need a service to be
enabled after a given release. I've recently had this use case and had two
options - either rely on co...]]></description>
			<content:encoded><![CDATA[
Over time parts of your puppet manifests will become unneeded. You might
move a cronjob or a users in to a package or no longer need a service to be
enabled after a given release. I've recently had this use case and had two
options - either rely on comments in the Puppet code and write an out of
band tool to scan the code base and present a report or add them to the
puppet resources themselves. I chose the latter.</p>

<p>
Below you'll find a simple metaparameter (a parameter that works with any
resource type) that adds this feature to puppet. As this is an early
prototype I've hacked it directly in to my local puppet fork. Below you'll
see a sample resource that declares a deprecation date and message, the
code that implements it and a simple command line test you can run to
confirm it works.</p>

<pre>
<code>

# sample puppet resource using :deprecation

  file { '/ec/cron.d/remove_foos':
    ensure      => 'file',
    source      => 'puppet:///modules/foo/foo.cron',
    deprecation => '20130425:Release 6 removes the need for the foo cronjob',
  }


  $ sudo vi puppet-3.1.1/lib/puppet/type.rb

  newmetaparam(:deprecation) do
    desc "
      Add a deprecation warning to resources.

      file { '/etc/foo':
        content     => 'Bar',
        deprecation => '20130425:We no longer need the foo'
      }

      The deprecation comes in two parts, separated by a :
      The date is in format YYYYMMDD and the message is a free form string.
    "

      munge do |deprecation|
        date, message = deprecation.split(':')

        # YYY MM DD - one true timestamp
        now = Time.now.strftime('%Y%m%d')

        if (now >= date)
          rsrc = "#{@resource.type.capitalize}[#{@resource.name}]"

          Puppet.warning "#{rsrc} expired on #{date}: #{message}"
        end
      end
    end

# command line test


$ puppet apply -e 'file { "/tmp/dep": content => "foo\n", deprecation =>
"20120425:We can remove this file after release 4" }' 
Warning: File[/tmp/dep] expired on 20120425: We can remove this file after release 4
Notice: Finished catalog run in 0.06 seconds

</code>
</pre>

<p>Using the metaparameter is easy enough, just specify 'deprecation' as a
property on a resource and provide a string that contains the date to start
flagging the deprecation on (in YYYYMMDD format) and the message puppet
should show. I don't currently fail the run on an expired resource but this
is an option.</p>

<p>The are some other aspects of this to consider - 
<a href='http://unixbeard.net/'>Richard Clamp</a> raised the idea of having
a native type that could indicate this for an entire class (I'd rather use
a function, but only because they are much easier to write) and Trevor
Vaughan suggested a Puppet face that could present a report of the expired,
and soon to be expired, code.</p>

<p>I don't know how widely useful this is but it made a nice change to
write some puppet code. The small size of the example will hopefully
show how easy it is to extend nearly every part of puppet - including
more 'complicated' aspects like metaparameters. Although not the
relationship ones, those are horrible ;) I've submitted the idea to the
upstream development list so we'll see what happens.</p><p class="posted">Like this post? - <a href="http://www.digg.com/submit?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/deprecation-warnings-from-puppet-resources.rss20&amp;title=Deprecation%20Warnings%20From%20Puppet%20Resources&amp;phase=3">Digg Me!</a> | <a href="http://del.icio.us/post?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/deprecation-warnings-from-puppet-resources.rss20&amp;title=Deprecation%20Warnings%20From%20Puppet%20Resources">Add to del.icio.us!</a> | <a href="http://reddit.com/submit?url=http://blog.unixdaemon.net/cgi-bin/blosxom.pl/tools/puppet/deprecation-warnings-from-puppet-resources.rss20&amp;title=Deprecation%20Warnings%20From%20Puppet%20Resources">reddit this!</a>]]></content:encoded>
			<wfw:commentRss>http://infra-talk.org/2013/04/27/deprecation-warnings-from-puppet-resources/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Calculate Customer Lifetime Value : Infographics</title>
		<link>http://piyush.me/2013/04/22/how-to-calculate-customer-lifetime-value-infographics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-calculate-customer-lifetime-value-infographics</link>
		<comments>http://piyush.me/2013/04/22/how-to-calculate-customer-lifetime-value-infographics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-calculate-customer-lifetime-value-infographics#comments</comments>
		<pubDate>Mon, 22 Apr 2013 09:43:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Infographics]]></category>

		<guid isPermaLink="false">http://piyush.me/?p=274</guid>
		<description><![CDATA[++ Click Image to Enlarge ++ Source: How To Calculate Lifetime Value]]></description>
			<content:encoded><![CDATA[++ Click Image to Enlarge ++ Source: How To Calculate Lifetime Value]]></content:encoded>
			<wfw:commentRss>http://piyush.me/2013/04/22/how-to-calculate-customer-lifetime-value-infographics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
