<?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>www.devco.net &#187; puppet</title>
	<atom:link href="http://www.devco.net/archives/tag/puppet/feed" rel="self" type="application/rss+xml" />
	<link>http://www.devco.net</link>
	<description>by r.i.pienaar</description>
	<lastBuildDate>Wed, 03 Mar 2010 18:36:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Puppet localconfig parser &#8211; 20100303</title>
		<link>http://www.devco.net/archives/2010/03/03/puppet_localconfig_parser_-_20100303.php</link>
		<comments>http://www.devco.net/archives/2010/03/03/puppet_localconfig_parser_-_20100303.php#comments</comments>
		<pubDate>Wed, 03 Mar 2010 18:36:02 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1332</guid>
		<description><![CDATA[I've had some good feedback on my previous post about the puppet localconfig parser, have implemented the requested features so here's a new version.
First the ability to limit what resources are being printed:


# parselocalconfig.rb --limit package
Classes included on this node:
        fqdn
        [...]]]></description>
			<content:encoded><![CDATA[<p>I've had some good feedback on my <a href="http://www.devco.net/archives/2010/02/26/what_does_puppet_manage_on_a_node-2.php">previous post</a> about the puppet localconfig parser, have implemented the requested features so here's a new version.</p>
<p>First the ability to limit what resources are being printed:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># parselocalconfig.rb --limit package
Classes included on this node:
        fqdn
        common::linux
&nbsp;
Resources managed by puppet on this node:
        package{redhat-lsb: }
                defined in common/modules/puppet/manifests/init.pp:15</pre></div></div>

</blockquote>
<p>You should only see package resources.  You can also disable the classes list using <em>--no-classes</em> and on 0.25.x disable the tags list with <em>--no-tags</em>.  </p>
<p>I've improved the detection of where to find the yaml file for 0.25 nodes and added an option <em>--config</em> if your config file is not in the usual place.</p>
<p>You can get the latest version <a href="http://www.devco.net/code/parselocalconfig.rb">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2010/03/03/puppet_localconfig_parser_-_20100303.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What does Puppet manage on a node?</title>
		<link>http://www.devco.net/archives/2010/02/26/what_does_puppet_manage_on_a_node-2.php</link>
		<comments>http://www.devco.net/archives/2010/02/26/what_does_puppet_manage_on_a_node-2.php#comments</comments>
		<pubDate>Fri, 26 Feb 2010 21:25:42 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1324</guid>
		<description><![CDATA[Last year I wrote a tool to parse the localconfig.yaml from Puppet 0.24 and display a list of resources and classes.  This script failed when 0.25 came out, I've updated it for 0.25 support.
The yaml cache has some added features in 0.25 so now I can also show the list of tags on a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.devco.net/archives/2009/07/30/what_does_puppet_manage_on_a_node.php">Last year I wrote</a> a tool to parse the <em>localconfig.yaml</em> from Puppet 0.24 and display a list of resources and classes.  This script failed when 0.25 came out, I've updated it for 0.25 support.</p>
<p>The yaml cache has some added features in 0.25 so now I can also show the list of tags on a node, output would be:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># parselocalconfig.rb /var/lib/puppet/client_yaml/catalog/fqdn.yaml
Classes included on this node:
        fqdn
        common::linux
        &lt;snip&gt;
&nbsp;
Tags for this node:
        fqdn
        common::linux
        &lt;snip&gt;
&nbsp;
Resources managed by puppet on this node:
        yumrepo{centos-base: }
                defined in common/modules/yum/manifests/init.pp:24
&nbsp;
        file{/root/.ssh: }
                defined in common/modules/users/manifests/root.pp:20
&nbsp;
        &lt;snip&gt;</pre></div></div>

</blockquote>
<p>You can get the script that supports both 0.24 and 0.25 <a href="http://www.devco.net/code/parselocalconfig.rb">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2010/02/26/what_does_puppet_manage_on_a_node-2.php/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Building files from fragments with Puppet</title>
		<link>http://www.devco.net/archives/2010/02/19/building_files_from_fragments_with_puppet.php</link>
		<comments>http://www.devco.net/archives/2010/02/19/building_files_from_fragments_with_puppet.php#comments</comments>
		<pubDate>Fri, 19 Feb 2010 18:14:20 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1309</guid>
		<description><![CDATA[While building up complex configs with Puppet you often need to build up one file from many fragments.  This is useful for files like older sysctl.conf files and maybe named.conf files.  
The basic pattern is you want to manage a file, but want the contents to be very different from node to node. [...]]]></description>
			<content:encoded><![CDATA[<p>While building up complex configs with Puppet you often need to build up one file from many fragments.  This is useful for files like older <em>sysctl.conf</em> files and maybe <em>named.conf</em> files.  </p>
<p>The basic pattern is you want to manage a file, but want the contents to be very different from node to node.  A fragment based system lets you register different contents into a file on different nodes.  It's exactly like the <em>conf.d</em> directory you'd find in Apache but for daemons that does not support this construct on their own.</p>
<p>I've had an older version of this floating around but had to clean it up for a client today so thought I might as well do a proper job, release it and get some more eye balls on it.  This version is specific to Puppet 0.25.x, I will soon make a >= 0.24.8 version too since that is what my client is on.</p>
<p>An example says more than words, so lets create something to manage <em>sysctl.conf</em>:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="puppet" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Initial setup</span>
<span style="color:#0000FF; font-weight:bold;">class</span> sysctl <span style="color:#006600; font-weight:bold;">&#123;</span>
   <span style="color:#9966CC; font-weight:bold;">include</span> concat<span style="color:#0066ff; font-weight:bold;">::</span>setup
&nbsp;
   <span style="color:#CC00FF; font-weight:bold;">exec</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;reload-sysctl&quot;</span><span style="color:#006600; font-weight:bold;">:</span>
      <span style="color:#CC0066; font-weight:bold;">refreshonly</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
      <span style="color:#CC0066; font-weight:bold;">command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;/sbin/sysctl -p&quot;</span>
   <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
   concat<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;/etc/sysctl.conf&quot;</span><span style="color:#006600; font-weight:bold;">:</span>
      <span style="color:#CC0066; font-weight:bold;">notify</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Exec</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;reload-sysctl&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
   <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># use this to set values</span>
<span style="color:#0000FF; font-weight:bold;">define</span> sysctl<span style="color:#0066ff; font-weight:bold;">::</span>setting<span style="color:#006600; font-weight:bold;">&#40;</span>$value<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
   concat<span style="color:#0066ff; font-weight:bold;">::</span>fragment<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;sysctl_${name}&quot;</span><span style="color:#006600; font-weight:bold;">:</span> 
      <span style="color:#CC0066; font-weight:bold;">target</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;/etc/sysctl.conf&quot;</span>,
      <span style="color:#CC0066; font-weight:bold;">content</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;${name} = ${value}<span style="color:#000099;">\n</span>&quot;</span>,
   <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

</blockquote>
<p>The above sets up a class that will create an empty <em>sysctl.conf</em> and provides an utility for setting individual values.  Whenever the <em>sysctl.conf</em> file gets changed the changes will be made live using the <em>refreshonly exec</em>.</p>
<p>Lets see how we might use it:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="puppet" style="font-family:monospace;"><span style="color:#0000FF; font-weight:bold;">node</span> <span style="color:#996600;">&quot;your.example.com&quot;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
   <span style="color:#9966CC; font-weight:bold;">include</span> sysctl
&nbsp;
   sysctl<span style="color:#0066ff; font-weight:bold;">::</span>setting<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;net.ipv4.ip_forward&quot;</span><span style="color:#006600; font-weight:bold;">:</span>
      <span style="color:#CC0066; font-weight:bold;">value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1</span>
   <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

</blockquote>
<p>You can see this looks and feels a lot like a native type but without a lot of the hassle it would take to write one, you can really get a lot of mileage out of this pattern.  The concat is clever enough to unregister the setting should you remove lines 4 to 6 in the above node block.</p>
<p>A cleaner approach would be to just make classes like <em>sysctl::ipv4_forward</em> that you can include on the nodes that need it.</p>
<p>You can grab the current code <a href="http://www.devco.net/code/concat-20100219.tgz">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2010/02/19/building_files_from_fragments_with_puppet.php/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Better way to query facts</title>
		<link>http://www.devco.net/archives/2010/01/14/better_way_to_query_facts.php</link>
		<comments>http://www.devco.net/archives/2010/01/14/better_way_to_query_facts.php#comments</comments>
		<pubDate>Thu, 14 Jan 2010 18:47:01 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1258</guid>
		<description><![CDATA[Facter has some annoying bug where it won't always print all facts when called like  facter fact, ones that require dynamic lookups etc just won't print.
This is a long standing bug that doesn't seem to get any love, so I hacked up a little wrapper that works better.


#!/usr/bin/ruby
&#160;
require 'facter'
require 'puppet'
&#160;
Puppet.parse_config
unless $LOAD_PATH.include?&#40;Puppet&#91;:libdir&#93;&#41;
    [...]]]></description>
			<content:encoded><![CDATA[<p>Facter has some annoying bug where it won't always print all facts when called like <em> facter fact</em>, ones that require dynamic lookups etc just won't print.</p>
<p>This is a long standing bug that doesn't seem to get any love, so I hacked up a little wrapper that works better.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/ruby</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'facter'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'puppet'</span>
&nbsp;
Puppet.<span style="color:#9900CC;">parse_config</span>
<span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#ff6633; font-weight:bold;">$LOAD_PATH</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Puppet<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:libdir</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#ff6633; font-weight:bold;">$LOAD_PATH</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> Puppet<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:libdir</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
facts = Facter.<span style="color:#9900CC;">to_hash</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> ARGV.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
    ARGV.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{f} =&gt; #{facts[f]}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> facts.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>f<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
    facts.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>k,v<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{k} =&gt; #{v}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</blockquote>
<p>It behaves by default as if you ran <em>facter -p</em> but you can supply as many fact names as you want on the command line to print just the ones requested.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ fctr uptime puppetversion processorcount
uptime =&gt; 8 days
puppetversion =&gt; 0.25.2
processorcount =&gt; 1</pre></div></div>

</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2010/01/14/better_way_to_query_facts.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing puppetd with mcollective</title>
		<link>http://www.devco.net/archives/2009/11/30/managing_puppetd_with_mcollective.php</link>
		<comments>http://www.devco.net/archives/2009/11/30/managing_puppetd_with_mcollective.php#comments</comments>
		<pubDate>Sun, 29 Nov 2009 23:18:12 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[mcollective]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1179</guid>
		<description><![CDATA[It's typical during maintenance windows that you would want to disable puppet, do your work, enable again and do a run.  Or perhaps you don't run puppet all the time, you just want to kick it off during your maintenance window.  Doing this with ssh for loops is slow and annoying, here's a [...]]]></description>
			<content:encoded><![CDATA[<p>It's typical during maintenance windows that you would want to disable puppet, do your work, enable again and do a run.  Or perhaps you don't run puppet all the time, you just want to kick it off during your maintenance window.  Doing this with ssh for loops is slow and annoying, here's a way to target large sums of machines for these actions using mcollective.</p>
<p>Using <a href="http://code.google.com/p/mcollective/">mcollective</a>'s discovery features and a suitable agent this is really easy, I've written such an agent and made it available on the <a href="http://code.google.com/p/mcollective-plugins/wiki/AgentPuppetd">mcollective-plugins site</a>.  </p>
<p>You can see below a sample session with it.  In all of the examples below we're constraining it to hosts with the <em>roles::dev_server</em> puppet class using mcollective discovery.   Not shown here is that you can get status as well as use the splay options provided by puppet, see the <a href="http://code.google.com/p/mcollective-plugins/wiki/AgentPuppetd">wiki page</a> for details on that.</p>
<p>First we'll make sure it's enabled.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ mc-puppetd <span style="color: #660033;">--with-class</span> roles::dev_server <span style="color: #7a0874; font-weight: bold;">enable</span>
Determining the amount of hosts matching filter <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000;">2</span> seconds .... <span style="color: #000000;">1</span>
&nbsp;
.
&nbsp;
Finished processing <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">1</span> hosts <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">9.81</span> ms</pre></div></div>

</blockquote>
<p>Now we'll disable it</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ mc-puppetd <span style="color: #660033;">--with-class</span> roles::dev_server disable
Determining the amount of hosts matching filter <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000;">2</span> seconds .... <span style="color: #000000;">1</span>
&nbsp;
.
&nbsp;
Finished processing <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">1</span> hosts <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">3252.13</span> ms</pre></div></div>

</blockquote>
<p>We'll attempt a runonce, this should fail because we just disabled the agent.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ mc-puppetd <span style="color: #660033;">--with-class</span> roles::dev_server runonce <span style="color: #660033;">-v</span>
Determining the amount of hosts matching filter <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000;">2</span> seconds .... <span style="color: #000000;">1</span>
&nbsp;
dev1.your.net                      <span style="color: #007800;">status</span>=<span style="color: #c20cb9; font-weight: bold;">false</span>
    Lock <span style="color: #c20cb9; font-weight: bold;">file</span> exists                        
&nbsp;
&nbsp;
<span style="color: #660033;">----</span> puppetd agent stats <span style="color: #660033;">----</span>
           Nodes: <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">1</span>
      Start Time: Sun Nov <span style="color: #000000;">29</span> <span style="color: #000000;">23</span>:02:<span style="color: #000000;">30</span> +0000 <span style="color: #000000;">2009</span>
  Discovery Time: 2006.38ms
      Agent Time: 47.62ms
      Total Time: 2054.00ms</pre></div></div>

</blockquote>
<p>Let's enable it and then try to run again.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ mc-puppetd <span style="color: #660033;">--with-class</span> roles::dev_server <span style="color: #7a0874; font-weight: bold;">enable</span>
Determining the amount of hosts matching filter <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000;">2</span> seconds .... <span style="color: #000000;">1</span>
&nbsp;
.
&nbsp;
Finished processing <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">1</span> hosts <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">9.81</span> ms
&nbsp;
$ mc-puppetd <span style="color: #660033;">--with-class</span> roles::dev_server runonce
Determining the amount of hosts matching filter <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000;">2</span> seconds .... <span style="color: #000000;">1</span>
&nbsp;
.
&nbsp;
Finished processing <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">1</span> hosts <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">2801.82</span> ms</pre></div></div>

</blockquote>
<p>I think this is a good way to orchestrate these type of maintenance window and I hope someone finds it useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/11/30/managing_puppetd_with_mcollective.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RightScale facts</title>
		<link>http://www.devco.net/archives/2009/11/09/rightscale_facts.php</link>
		<comments>http://www.devco.net/archives/2009/11/09/rightscale_facts.php#comments</comments>
		<pubDate>Sun, 08 Nov 2009 23:19:12 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1141</guid>
		<description><![CDATA[I'm trying to build up a nice demo of mcollective and trying to save some effort by using the RightScale CentOS AMI's.  I noticed they came with a nice script to pull down the user data and meta data so figured I might as well make some facts.


require 'find'
&#160;
if File.exists?&#40;&#34;/var/spool/ec2/meta-data&#34;&#41;
    Find.find&#40;&#34;/var/spool/ec2/meta-data&#34;&#41; do [...]]]></description>
			<content:encoded><![CDATA[<p>I'm trying to build up a nice demo of mcollective and trying to save some effort by using the RightScale CentOS AMI's.  I noticed they came with a nice script to pull down the user data and meta data so figured I might as well make some facts.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'find'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/var/spool/ec2/meta-data&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">Find</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/var/spool/ec2/meta-data&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>path<span style="color:#006600; font-weight:bold;">|</span>
        filename = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">basename</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
        factname = <span style="color:#996600;">&quot;ec2_#{filename}&quot;</span>
&nbsp;
        factname.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/-/</span>, <span style="color:#996600;">&quot;_&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">file</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
            lines = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">readlines</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
            <span style="color:#9966CC; font-weight:bold;">if</span> lines.<span style="color:#9900CC;">size</span> == <span style="color:#006666;">1</span>
                Facter.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>factname<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
                    setcode <span style="color:#006600; font-weight:bold;">&#123;</span> lines.<span style="color:#9900CC;">first</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span>.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
                <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">else</span>
                lines.<span style="color:#9900CC;">each_with_index</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>line, i<span style="color:#006600; font-weight:bold;">|</span>
                    Facter.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{factname}_#{i}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
                        setcode <span style="color:#006600; font-weight:bold;">&#123;</span> lines<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
                    <span style="color:#9966CC; font-weight:bold;">end</span>
                <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/var/spool/ec2/user-data.raw&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        lines = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">readlines</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/var/spool/ec2/user-data.raw&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
        lines.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>l<span style="color:#006600; font-weight:bold;">|</span>
                <span style="color:#9966CC; font-weight:bold;">if</span> l.<span style="color:#CC0066; font-weight:bold;">chomp</span> =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>=<span style="color:#006600; font-weight:bold;">&#40;</span>.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>
                    f = $<span style="color:#006666;">1</span>; v = $<span style="color:#006666;">2</span>
&nbsp;
                    Facter.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>f<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
                        setcode <span style="color:#006600; font-weight:bold;">&#123;</span> v <span style="color:#006600; font-weight:bold;">&#125;</span>
                    <span style="color:#9966CC; font-weight:bold;">end</span>
                <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</blockquote>
<p>If you arrange to run <em>/opt/rightscale/bin/ec2.sh</em> in <em>rc.local</em> and pop this fact above into your factdir you should be able to access all the meta data from facter.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># facter -p</span>
ec2_ami_id =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-73270c07
ec2_ami_launch_index =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span>
ec2_ami_manifest_path =<span style="color: #000000; font-weight: bold;">&gt;</span> pinetecltd-centos-clustera<span style="color: #000000; font-weight: bold;">/</span>cluster-webserver-1257783713.manifest.xml
ec2_ancestor_ami_ids_0 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-31c72258
ec2_ancestor_ami_ids_1 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-ef01e486
ec2_ancestor_ami_ids_2 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-0916f360
ec2_ancestor_ami_ids_3 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-c8ac48a1
ec2_ancestor_ami_ids_4 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-cd52b6a4
ec2_ancestor_ami_ids_5 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-19be966d
ec2_ancestor_ami_ids_6 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-65200b11
ec2_ancestor_ami_ids_7 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-3d200b49
ec2_ancestor_ami_ids_8 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-91200be5
ec2_ancestor_ami_ids_9 =<span style="color: #000000; font-weight: bold;">&gt;</span> ami-81200bf5
ec2_block_device_mapping_ami =<span style="color: #000000; font-weight: bold;">&gt;</span> sda1
ec2_block_device_mapping_ephemeral0 =<span style="color: #000000; font-weight: bold;">&gt;</span> sdb
ec2_block_device_mapping_ephemeral1 =<span style="color: #000000; font-weight: bold;">&gt;</span> sdc
ec2_block_device_mapping_ephemeral2 =<span style="color: #000000; font-weight: bold;">&gt;</span> sdd
ec2_block_device_mapping_ephemeral3 =<span style="color: #000000; font-weight: bold;">&gt;</span> sde
ec2_block_device_mapping_root =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda1
ec2_block_device_mapping_swap =<span style="color: #000000; font-weight: bold;">&gt;</span> sda3
ec2_hostname =<span style="color: #000000; font-weight: bold;">&gt;</span> ip-<span style="color: #000000;">10</span>-<span style="color: #000000;">227</span>-<span style="color: #000000;">43</span>-134.eu-west-1.compute.internal
ec2_instance_action =<span style="color: #000000; font-weight: bold;">&gt;</span> none
ec2_instance_id =<span style="color: #000000; font-weight: bold;">&gt;</span> i-9411e7e3
ec2_instance_type =<span style="color: #000000; font-weight: bold;">&gt;</span> m1.small
ec2_kernel_id =<span style="color: #000000; font-weight: bold;">&gt;</span> aki-7e0d250a
ec2_local_hostname =<span style="color: #000000; font-weight: bold;">&gt;</span> ip-<span style="color: #000000;">10</span>-<span style="color: #000000;">227</span>-<span style="color: #000000;">43</span>-134.eu-west-1.compute.internal
ec2_local_ipv4 =<span style="color: #000000; font-weight: bold;">&gt;</span> 10.227.43.134
ec2_placement_availability_zone =<span style="color: #000000; font-weight: bold;">&gt;</span> eu-west-1b
ec2_public_hostname =<span style="color: #000000; font-weight: bold;">&gt;</span> ec2-<span style="color: #000000;">79</span>-<span style="color: #000000;">125</span>-<span style="color: #000000;">33</span>-224.eu-west-1.compute.amazonaws.com
ec2_public_ipv4 =<span style="color: #000000; font-weight: bold;">&gt;</span> 79.125.33.224
ec2_public_keys_0_openssh_key =<span style="color: #000000; font-weight: bold;">&gt;</span> ssh-rsa AAA
ec2_ramdisk_id =<span style="color: #000000; font-weight: bold;">&gt;</span> ari-7d0d2509
ec2_reservation_id =<span style="color: #000000; font-weight: bold;">&gt;</span> r-c655bab1
ec2_security_groups_0 =<span style="color: #000000; font-weight: bold;">&gt;</span> rip
ec2_security_groups_1 =<span style="color: #000000; font-weight: bold;">&gt;</span> defaultcluster =<span style="color: #000000; font-weight: bold;">&gt;</span> a</pre></div></div>

</blockquote>
<p>In addition if you just pass nice <em>key=val</em> pairs in as user data it will add those as facts too, the last above is from that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/11/09/rightscale_facts.php/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Test Driven Deployment &#8211; mcollective, puppet, cucumber</title>
		<link>http://www.devco.net/archives/2009/11/06/test_driven_deployment_-_mcollective_puppet_cucumber.php</link>
		<comments>http://www.devco.net/archives/2009/11/06/test_driven_deployment_-_mcollective_puppet_cucumber.php#comments</comments>
		<pubDate>Fri, 06 Nov 2009 17:55:04 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[mcollective]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1129</guid>
		<description><![CDATA[With the release of mcollective recently I've been able to work a bit on a deploy problem I've had at a client, I was able to build up the following by combining mcollective, cucumber and the open source mcollective plugins.
The cucumber exploring is of course a result of @auxesis's brilliant cucumber talk at Devops Days [...]]]></description>
			<content:encoded><![CDATA[<p>With the release of <a href="http://code.google.com/p/mcollective/">mcollective</a> recently I've been able to work a bit on a deploy problem I've had at a client, I was able to build up the following by combining <a href="http://code.google.com/p/mcollective/">mcollective</a>, <a href="http://wiki.github.com/aslakhellesoy/cucumber">cucumber</a> and the open source <a href="http://code.google.com/p/mcollective-plugins/">mcollective plugins</a>.</p>
<p>The cucumber exploring is of course a result of <a href="http://twitter.com/auxesis">@auxesis</a>'s brilliant cucumber talk at Devops Days recently.</p>
<p><b>Note:</b> I've updated this from the initial posting, showing how I do filtering with mcollective discovery and put it all into one scenario.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Feature: Update the production systems
&nbsp;
    Background:
        Given the <span style="color:#CC0066; font-weight:bold;">load</span> balancer has ip address 192.168.1.1
        <span style="color:#9966CC; font-weight:bold;">And</span> I want to update hosts with <span style="color:#9966CC; font-weight:bold;">class</span> roles::dev_server
        <span style="color:#9966CC; font-weight:bold;">And</span> I want to update hosts with fact country=de 
        <span style="color:#9966CC; font-weight:bold;">And</span> I want to pre<span style="color:#006600; font-weight:bold;">-</span>discover how many hosts to update
&nbsp;
    Scenario: Update the website
        <span style="color:#9966CC; font-weight:bold;">When</span> I block the <span style="color:#CC0066; font-weight:bold;">load</span> balancer
        <span style="color:#9966CC; font-weight:bold;">Then</span> traffic from the <span style="color:#CC0066; font-weight:bold;">load</span> balancer should be blocked
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">When</span> I update the package mywebapp
        <span style="color:#9966CC; font-weight:bold;">Then</span> the package version <span style="color:#9966CC; font-weight:bold;">for</span> mywebapp should be 4.2.6<span style="color:#006600; font-weight:bold;">-</span>3.<span style="color:#9900CC;">el5</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">When</span> I unblock the <span style="color:#CC0066; font-weight:bold;">load</span> balancer
        <span style="color:#9966CC; font-weight:bold;">Then</span> traffic from the <span style="color:#CC0066; font-weight:bold;">load</span> balancer should be unblocked</pre></div></div>

</blockquote>
<p>This is completely like any other test driven scenario based system, if it fails to block the firewall deploy will bail out.  If it fails to update the package it will bail and finally only if those worked will it unblock the firewall.  </p>
<p>Thanks to mcollective this is distributed and parallel over large numbers of machines.  I can also apply filters to update just certain clusters using mcollective's discovery features.</p>
<p>Everything's outcome is tested and cucumber will only show the all clear when everything worked on all machines in a consistent way.</p>
<p>This is made possible in part because the mcollective plugins use the Puppet providers underneath the hood, so package and service actions are complete idempotent and repeatable, I can rerun this script 100 times and it will do the same thing.</p>
<p>I have other steps not included here to keep things simple but in a real world I would restart the webserver after the update and I would then call NRPE plugins on all the nodes to make sure their load average is in acceptable ranges before the firewall gets opened letting the load balancer in.</p>
<p>This opens up a whole lot of interesting ideas, kudos to <a href="http://twitter.com/auxesis">@auxesis</a> and his great talk at devopsdays!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/11/06/test_driven_deployment_-_mcollective_puppet_cucumber.php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Reusing Puppet Providers</title>
		<link>http://www.devco.net/archives/2009/10/19/reusing_puppet_providers.php</link>
		<comments>http://www.devco.net/archives/2009/10/19/reusing_puppet_providers.php#comments</comments>
		<pubDate>Mon, 19 Oct 2009 08:47:13 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[cody]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1091</guid>
		<description><![CDATA[Last night I was thinking about writing scripts to manage services, packages etc in a heterogeneous environment.  This is hard because the operating systems all behave differently.
This is of course a  problem that Puppet solves with it's providers system, after some chatting with Luke on IRC I now have a pretty nice solution.
Assuming [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I was thinking about writing scripts to manage services, packages etc in a heterogeneous environment.  This is hard because the operating systems all behave differently.</p>
<p>This is of course a  problem that Puppet solves with it's providers system, after some chatting with Luke on IRC I now have a pretty nice solution.</p>
<p>Assuming you don't mind shell scripting in Ruby here's a pretty decent bit of Ruby to manage a service on many different environments.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'puppet'</span>
&nbsp;
service = ARGV.<span style="color:#9900CC;">shift</span>
action = ARGV.<span style="color:#9900CC;">shift</span>
&nbsp;
ARGV.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> ? hasstatus = <span style="color:#0000FF; font-weight:bold;">true</span> : hasstatus = <span style="color:#0000FF; font-weight:bold;">false</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">begin</span>
    svc = <span style="color:#6666ff; font-weight:bold;">Puppet::Type</span>.<span style="color:#9900CC;">type</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:service</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> service, 
        <span style="color:#ff3333; font-weight:bold;">:hasstatus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> hasstatus<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">provider</span>
&nbsp;
    svc.<span style="color:#9900CC;">send</span> action
&nbsp;
    <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{service} #{action} status: #{svc.status}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> e
    <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Could not #{action} service #{service}: #{e}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</blockquote>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># service.rb httpd stop true</span>
httpd stop status: stopped
&nbsp;
<span style="color: #666666; font-style: italic;"># service.rb httpd start true</span>
httpd start status: running</pre></div></div>

</blockquote>
<p>You'd probably want to put in support for the pattern parameter to keep certain broken Operating Systems happy, but this is pretty nice and platform independent.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/10/19/reusing_puppet_providers.php/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Middleware for Systems Administration</title>
		<link>http://www.devco.net/archives/2009/10/18/middleware_for_systems_administration.php</link>
		<comments>http://www.devco.net/archives/2009/10/18/middleware_for_systems_administration.php#comments</comments>
		<pubDate>Sun, 18 Oct 2009 10:49:47 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[mcollective]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1078</guid>
		<description><![CDATA[I spoke a bit on the puppet IRC channel about my middleware based systems administration tool, I made a video to demo it below.
The concept is that I use publish / subscribe middleware - ActiveMQ with Stomp in my case - to do one-off administration.  Unlike using Capistrano or some of those tools I [...]]]></description>
			<content:encoded><![CDATA[<p>I spoke a bit on the puppet IRC channel about my middleware based systems administration tool, I made a video to demo it below.</p>
<p>The concept is that I use <a href="http://en.wikipedia.org/wiki/Publish_subscribe">publish / subscribe middleware</a> - ActiveMQ with Stomp in my case - to do one-off administration.  Unlike using Capistrano or some of those tools I do not need lists of machines or visit each machine with a request because the network supports discovery and a single message to the middleware results in 10s or 100s or 1000s of machines getting the message.</p>
<p>This means any tasks I ask to be done happens in parallel on any number of machines typically I see ~100 machines finish the task in the same time as 1 machine would and no need for SSH or anything like that.</p>
<p>The app server and client libs I wrote take away all the complexities of the middleware and takes care of crypto signing requests, only responding to requests that has been signed properly etc, serializing and deserialization of data etc.</p>
<p>Discovery is built in and it supports puppet classes and facts and a few other criteria I use for my own systems so there is no need to build any kind of system that keeps track of what machines I have with what version of operating system etc.  As long as is on the middleware I can find it.</p>
<p>The bulk - timeout handling and so forth removed - of the ping app you see in the demo can be seen here, client:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">client = <span style="color:#6666ff; font-weight:bold;">Stomphost::Client</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
client.<span style="color:#9900CC;">sendreq</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">to_f</span>, <span style="color:#996600;">&quot;echo&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">loop</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    resp = client.<span style="color:#9900CC;">receive</span> 
    elapsed = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">-</span> resp<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:body</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</blockquote>
<p>And the agent is just this:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Stomphost
    <span style="color:#9966CC; font-weight:bold;">module</span> Agent
        <span style="color:#9966CC; font-weight:bold;">class</span> Echo
            <span style="color:#9966CC; font-weight:bold;">def</span> handlemsg<span style="color:#006600; font-weight:bold;">&#40;</span>msg<span style="color:#006600; font-weight:bold;">&#41;</span>
                msg<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:body</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</blockquote>
<p>You can see that even data types like the float will flow cleanly through end to end.</p>
<p><center><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_0817090731.swf' /><param name='flashvars' value='i=19860' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_0817090731.swf' flashvars='i=19860' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></center></p>
<p>Watch the video, I mention my uses cases but it includes distributed Exim administration, package updates, services restarts, iptables management and much more.</p>
<p><strong>UPDATE:</strong> This code has now been released as an Open Source Apache 2 licenced project at <a href="http://mcollective.googlecode.com">mcollective.googlecode.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/10/18/middleware_for_systems_administration.php/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Puppet Environments</title>
		<link>http://www.devco.net/archives/2009/10/10/puppet_environments.php</link>
		<comments>http://www.devco.net/archives/2009/10/10/puppet_environments.php#comments</comments>
		<pubDate>Sat, 10 Oct 2009 15:57:08 +0000</pubDate>
		<dc:creator>R.I. Pienaar</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://www.devco.net/?p=1038</guid>
		<description><![CDATA[Puppet supports putting nodes in environments, this maps cleanly to your development, qa and production life cycles and it's a way to hand out different code to different nodes.  Before reading this post you should probably read the Puppet Wiki page first for background.
I'll present here a simple layout that is both a powerful [...]]]></description>
			<content:encoded><![CDATA[<p>Puppet supports putting nodes in environments, this maps cleanly to your development, qa and production life cycles and it's a way to hand out different code to different nodes.  Before reading this post you should probably read the <a href="http://reductivelabs.com/trac/puppet/wiki/UsingMultipleEnvironments">Puppet Wiki page first</a> for background.</p>
<p>I'll present here a simple layout that is both a powerful tool for isolating code changes while developing combined with minimizing the headaches with maintaining multiple branches of the same module for an extended period of time.</p>
<p>As with the other posts I did on puppet recently the focus here is simplicity, this will work for small sites and will hopefully give you enough inspiration to successfully model larger sites using these techniques.</p>
<p>To really use environments well I strongly suggest you use modules, I've <a href="http://www.devco.net/archives/2009/09/28/simple_puppet_module_structure.php">blogged about them before</a>, if you read this post and think "hey! that's great" and don't yet use modules, go fix that first.</p>
<p>The puppetmaster tries to find modules using it's <em>modulepath</em> setting, typically something like <em>/etc/puppet/modules</em>.  You usually just set this value once in your <em>puppet.conf </em>and that's it, all done.  Environments expand on this and give you the ability to set different settings for different environments, below a simple example.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>puppetmasterd<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/puppet/manifests/modules</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>development<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/puppet/manifests/development/modules</span></pre></div></div>

</blockquote>
<p>This is your basic multi environment setup, if you run a client with the <em>development</em> environment set modules will be served from an alternative path.</p>
<p>This is already a huge win, if you use something like below:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="puppet" style="font-family:monospace;"><span style="color:#0000FF; font-weight:bold;">class</span> ntp <span style="color:#006600; font-weight:bold;">&#123;</span>
   <span style="color:#CC00FF; font-weight:bold;">file</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;/etc/ntpd.conf&quot;</span><span style="color:#006600; font-weight:bold;">:</span>
      <span style="color:#CC0066; font-weight:bold;">source</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;puppet:///ntp/ntpd.conf.${environment}&quot;</span>, <span style="color:#996600;">&quot;puppet:///ntp/ntpd.conf&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
   <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#0000FF; font-weight:bold;">node</span> dev1 <span style="color:#006600; font-weight:bold;">&#123;</span>
   <span style="color:#9966CC; font-weight:bold;">include</span> ntp
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

</blockquote>
<p>If you put the ntp module in both production and development, the right one will be chosen depending on the nodes environment setting.  The file ntp.conf will also be served from the right modules files directory.  You could now safely make changes to the development one without affecting the rest of the machines.</p>
<p>The major drawback here is that if you have say 30 modules, you need to duplicate the lot into development if you wish to use them there, this is not great at all as it quickly becomes a maintenance nightmare.  If you made a change to ntp module in development, you need to remember to go and do the same change in all your other environments.  In cases where you give each sysadmin or developer their own environment this rapidly becomes unmaintainable.</p>
<p>The modulepath option has a trick up it's sleeve though, you can specify several search paths just like the normal Unix PATH environment variable, we can rework our config like this.</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>puppetmasterd<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/puppet/manifests/common/modules</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>development<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/.../development/modules:/etc/.../common/modules</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>production<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/.../production/modules:/etc/.../common/modules</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>johndoe<span style="">&#93;</span></span>
   <span style="color: #000099;">modulepath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /etc/.../johndoe/modules:/etc/.../common/modules</span></pre></div></div>

</blockquote>
<p>Here we've added a few more environments, even one for a developer called John Doe.   The big thing we did though is create <em>/etc/puppet/manifests/common/modules</em> as a 2nd search path. </p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">production
<span style="color: #000000; font-weight: bold;">`</span>-- modules
development
<span style="color: #000000; font-weight: bold;">`</span>-- modules
common
<span style="color: #000000; font-weight: bold;">`</span>-- modules
    <span style="color: #000000; font-weight: bold;">`</span>-- ntp
        <span style="color: #000000; font-weight: bold;">`</span>-- manifests
            <span style="color: #000000; font-weight: bold;">`</span>-- init.pp</pre></div></div>

</blockquote>
<p>The idea here is that you'd strive to keep all your modules in the common directory as their stable location but if you wished to do development on your <em>ntp</em> module that you wish to test, you just copy the ntp module into either <em>development</em> or <em>johndoe</em> directories, with that done only machines in those environments will get the new code.</p>
<p>This works especially well if you use version control, I use SVN and treat <em>common</em> as my <em>trunk</em>, whenever I need to work on a module I simply branch it into <em>development</em>, do my work there and when ready to release I merge my changes back to <em>common</em> and get rid of the branched copy so all environments gets the same version.</p>
<p>With this you can easily come up with a simple release testing strategy, do the weeks code in development and test locally, then put the changes you wish to release to production into your QA environment and do tests.  Finally when you're ready merge all the changes into common and just get rid of the development and QA copies, all environments are now running the same code ready for the next cycle.</p>
<p>This gives you the ability to create branches, do testing, isolate developers from each other - just put their desktops in individual environments - and lots of other nifty things but in the end you have only one copy of the code for your stable released versions.</p>
<p>I hope you find this useful, I'll reiterate that this is a simple setup, you should use this information and come up with a solution that will work well for your use case and teams.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devco.net/archives/2009/10/10/puppet_environments.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
