<?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>Kartar.Net &#187; type</title>
	<atom:link href="http://www.kartar.net/tag/type/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kartar.net</link>
	<description>the truth about a man lies in what he hides</description>
	<lastBuildDate>Fri, 30 Jul 2010 00:25:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Puppet Module Repository isn&#8217;t just for modules</title>
		<link>http://www.kartar.net/2010/06/puppet-module-repository-isnt-just-for-modules/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=puppet-module-repository-isnt-just-for-modules</link>
		<comments>http://www.kartar.net/2010/06/puppet-module-repository-isnt-just-for-modules/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 00:08:15 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[provider]]></category>
		<category><![CDATA[repo]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2329</guid>
		<description><![CDATA[You can store more than just your modules at the Forge.   I just added my types and providers to my collection of modules at the new Puppet Module Forge.  I&#8217;d love to all those people maintaining types and providers, functions, and facts add theirs to the Forge also.  It&#8217;s a cool way to share [...]]]></description>
			<content:encoded><![CDATA[<p>You can store more than just your modules at the Forge. <img src='http://www.kartar.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   I just added my types and providers to <a title="James' modules at the Forge" href="http://forge.puppetlabs.com/users/jamtur01" target="_blank">my collection of modules</a> at the new <a title="Puppet module forge" href="http://forge.puppetlabs.com" target="_blank">Puppet Module Forge</a>.  I&#8217;d love to all those people maintaining types and providers, functions, and facts add theirs to the Forge also.  It&#8217;s a cool way to share your <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> (and the site allows you to provide links back to your <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> repository and ticketing system so user&#8217;s can report bugs).  In time I hope most people&#8217;s environments will consist of the core types and providers bundled with Puppet and a selection of cool <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> generated by the <a href="http://www.kartar.net/tag/community/" class="st_tag internal_tag" rel="tag" title="Posts tagged with community">community</a> and sourced from the Puppet Forge.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/06/puppet-module-repository-isnt-just-for-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Puppet Forge in beta!</title>
		<link>http://www.kartar.net/2010/05/puppet-forge-in-beta/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=puppet-forge-in-beta</link>
		<comments>http://www.kartar.net/2010/05/puppet-forge-in-beta/#comments</comments>
		<pubDate>Thu, 27 May 2010 12:14:55 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[provider]]></category>
		<category><![CDATA[repo]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2325</guid>
		<description><![CDATA[The Puppet Forge AKA the Puppet Module Repository is live and operational.  It&#8217;s a store of Puppet modules (and types and providers) that allows you to share your awesome code and modules with others. It also comes with the puppet-module tool that allows you to build modules for, manage and install modules from the forge.  [...]]]></description>
			<content:encoded><![CDATA[<p>The Puppet Forge AKA the<a href="http://forge.puppetlabs.com/"> Puppet Module Repository</a> is live and operational.  It&#8217;s a store of Puppet modules (and types and providers) that allows you to share your awesome <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> and modules with others.</p>
<p>It also comes with the puppet-module tool that allows you to build modules for, manage and install modules from the forge.  You can install puppet-module via a gem:</p>
<pre>
$ sudo gem install puppet-module
</pre>
<p>Both the site and tool are in public beta right now so hammer away at it and tell us what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/05/puppet-forge-in-beta/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Puppet ParsedFile types and providers</title>
		<link>http://www.kartar.net/2010/02/puppet-parsedfile-types-and-providers/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=puppet-parsedfile-types-and-providers</link>
		<comments>http://www.kartar.net/2010/02/puppet-parsedfile-types-and-providers/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 12:26:52 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[parsedfile]]></category>
		<category><![CDATA[provider]]></category>
		<category><![CDATA[shells]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2213</guid>
		<description><![CDATA[In a recent post I talked about how easy it is to generate Puppet types and providers. In that post I used the example of a very simple Subversion and Git repository type, called repo. I&#8217;d like to show another example of a type and provider, this one used to manage the contents of the [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.kartar.net/2010/02/puppet-types-and-providers-are-easy/">recent post</a> I talked about how easy it is to generate Puppet types and providers.  In that post I used the example of a very simple Subversion and <a href="http://www.kartar.net/tag/git/" class="st_tag internal_tag" rel="tag" title="Posts tagged with git">Git</a> repository <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, called <code>repo</code>. I&#8217;d like to show another example of a <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>, this one used to manage the contents of the <code>/etc/shells</code> file.  This <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> makes use of some built-in Puppet functionality that allows the simple parsing of files and the management of their contents.  To do this Puppet has a <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> called <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> that can be included into your own providers to provide this functionality.</p>
<p>Let&#8217;s start with our <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">Puppet::Type</span>.<span style="color:#9900CC;">newtype</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shells</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@doc</span> = <span style="color:#996600;">&quot;Manage the contents of /etc/shells
&nbsp;
            shells { &quot;</span><span style="color:#006600; font-weight:bold;">/</span>bin<span style="color:#006600; font-weight:bold;">/</span>newshell<span style="color:#996600;">&quot;:
                ensure =&gt; present,
            }&quot;</span>
&nbsp;
    ensurable
&nbsp;
    newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shell</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;The shell to manage&quot;</span>
&nbsp;
        isnamevar
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    newproperty<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:target</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;Location of the shells file&quot;</span>
&nbsp;
        defaultto <span style="color:#006600; font-weight:bold;">&#123;</span>
            <span style="color:#9966CC; font-weight:bold;">if</span>
                <span style="color:#0066ff; font-weight:bold;">@resource</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">defaultprovider</span>.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9966CC; font-weight:bold;">include</span>? <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">Puppet::Provider::ParsedFile</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                <span style="color:#0066ff; font-weight:bold;">@resource</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">defaultprovider</span>.<span style="color:#9900CC;">default_target</span>
            <span style="color:#9966CC; font-weight:bold;">else</span>
                <span style="color:#0000FF; font-weight:bold;">nil</span>
            <span style="color:#9966CC; font-weight:bold;">end</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></pre></div></div>

<p>So &#8211; pretty simple.  We create a block <code>Puppet::<a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">Type</a>.newtype(:shells) do</code> that creates a new <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, which we&#8217;ve called shells. Inside the block we&#8217;ve got a <code>@doc</code> string.  This is the documentation for the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>. Add whatever level of detail and examples in here that is required.</p>
<p>We&#8217;ve also got the <code>ensurable</code> statement.  Ensurable provides some &#8220;automagic&#8221; that creates a basic <code>ensure</code> property.  Puppet types use the ensure property to determine the state of a configuration item.  In our <a href="http://www.kartar.net/2010/02/puppet-types-and-providers-are-easy/">previous example</a>, ensurable resulted in three methods in the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>: <code>create</code>, <code>destroy</code>, and <code>exists?</code>.  In a <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> we don&#8217;t use these methods at all as we&#8217;ll see shortly but rather specify how to handle each record in the file.</p>
<p>We&#8217;ve defined a new parameter &#8211; this one called <code>shell</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shell</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;The shell to manage&quot;</span>
&nbsp;
        isnamevar
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The <code>shell</code> parameter is the shell we&#8217;re going to manage in the <code>/etc/shells</code> file.  We&#8217;ve also used another piece of Puppet automagic, <code>isnamevar</code>, to make this parameter the &#8220;name&#8221; variable for this <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  In Puppet-speak, the value of this parameter is used as the name of the resource.</p>
<p>Lastly in our <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> we&#8217;ve specified an optional parameter, <code>target</code>, that allows us to override the default location of the shells file, usually <code>/etc/shells</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">newproperty<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:target</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;Location of the shells file&quot;</span>
&nbsp;
        defaultto <span style="color:#006600; font-weight:bold;">&#123;</span>
            <span style="color:#9966CC; font-weight:bold;">if</span>
                <span style="color:#0066ff; font-weight:bold;">@resource</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">defaultprovider</span>.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9966CC; font-weight:bold;">include</span>? <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">Puppet::Provider::ParsedFile</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                <span style="color:#0066ff; font-weight:bold;">@resource</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">defaultprovider</span>.<span style="color:#9900CC;">default_target</span>
            <span style="color:#9966CC; font-weight:bold;">else</span>
                <span style="color:#0000FF; font-weight:bold;">nil</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The <code>target</code> parameter is optional and would only be specified if the <code>shells</code> file wasn&#8217;t located in the <code>/etc/</code> directory.  It uses the <code>defaultto</code> structure to specify that the default value for the parameter is the value of <code>default_target</code> variable in the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.</p>
<p>The <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> for our <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> is also very simple:</p>

<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/provider/parsedfile'</span>
shells = <span style="color:#996600;">&quot;/etc/shells&quot;</span>
&nbsp;
<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;">:shells</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">provide</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:parsed</span>, <span style="color:#ff3333; font-weight:bold;">:parent</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">Puppet::Provider::ParsedFile</span>, <span style="color:#ff3333; font-weight:bold;">:default_target</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> shells, <span style="color:#ff3333; font-weight:bold;">:filetype</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:flat</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    desc <span style="color:#996600;">&quot;The shells provider that uses the ParsedFile class&quot;</span>
&nbsp;
    text_line <span style="color:#ff3333; font-weight:bold;">:comment</span>, <span style="color:#ff3333; font-weight:bold;">:match</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#008000; font-style:italic;">#/;</span>
    text_line <span style="color:#ff3333; font-weight:bold;">:blank</span>, <span style="color:#ff3333; font-weight:bold;">:match</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^\s<span style="color:#006600; font-weight:bold;">*</span>$<span style="color:#006600; font-weight:bold;">/</span>;
&nbsp;
    record_line <span style="color:#ff3333; font-weight:bold;">:parsed</span>, <span style="color:#ff3333; font-weight:bold;">:fields</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#123;</span>name<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The shells <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> is stored in a file called <code>parsed.rb</code> in a directory named for the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> in the <code><a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a></code> directory, for example:</p>
<pre>
/usr/lib/ruby/site_ruby/1.8/puppet/<a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>/shells.rb
/usr/lib/ruby/site_ruby/1.8/puppet/<a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>/shells/parsed.rb
</pre>
<p>The file needs to be named <code>parsed.rb</code> to allow Puppet to load the <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> <a href="http://www.kartar.net/tag/support/" class="st_tag internal_tag" rel="tag" title="Posts tagged with support">support</a>.</p>
<p>We first include the <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> at the top of our <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>, <code>require 'puppet/<a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>/<a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">parsedfile</a>'</code> and set a variable called <code>shells</code> to the location of the <code>/etc/shells</code> file.  We&#8217;re going to use this variable a bit later.</p>
<p>Then we tell Puppet that this is a <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> called <code>shells</code>.  We specify a <code>:parent</code> value that tells Puppet that this <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> should inherit the <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> and make its functions available.  We then specify the <code>:default_target</code> value to the <code>shells</code> variable we&#8217;ve just created.  This tells the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>, that unless it is overridden by the <code>target</code> attribute, that the file to act upon is <code>/etc/shells</code>.</p>
<p>Then we use a <code>desc</code> method that allows us to add some documentation to our <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.  </p>
<p>The next lines are the core of the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>. They tell the Puppet how to manipulate the target file to add or remove the required shell.  The first two lines, both <code>text_lines</code>, tell Puppet how to match comments and blank lines respectively.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    text_line <span style="color:#ff3333; font-weight:bold;">:comment</span>, <span style="color:#ff3333; font-weight:bold;">:match</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#008000; font-style:italic;">#/;</span>
    text_line <span style="color:#ff3333; font-weight:bold;">:blank</span>, <span style="color:#ff3333; font-weight:bold;">:match</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^\s<span style="color:#006600; font-weight:bold;">*</span>$<span style="color:#006600; font-weight:bold;">/</span>;</pre></div></div>

<p>We specify these to let Puppet know to ignore these lines as unimportant.</p>
<p>The next line performs the actual parsing of the relevant line in the <code>/etc/shells</code> file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    record_line <span style="color:#ff3333; font-weight:bold;">:parsed</span>, <span style="color:#ff3333; font-weight:bold;">:fields</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#123;</span>name<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>The <code>record_line</code> parses each line and divides it into fields, in our case we only have one field: <code>name</code>.  The name in this case is the shell we want to manage.  So if we specify:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">shells <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;/bin/newshell&quot;</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> present,</pre></div></div>

<p>Then Puppet would use the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> to add the <code>/bin/newshell</code> by parsing each line of the <code>/etc/shells</code> file and checking if the newshell is present.  If it is, then Puppet will do nothing.  If not, then Puppet will add newshell to the file.  If we changed the <code>ensure</code> attribute to <code>absent</code> then Puppet would go through the file and remove the newshell if it is present.</p>
<p>It is important to remember that <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> providers do have some limitations, they aren&#8217;t good at managing complex files such as configuration files with multi-line options, they are best for simple files that contain single line lists of entries such as the cron file entries or the <code>/etc/hosts</code> and <code>/etc/shells</code> files.  </p>
<p>You can see the complete <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> for this <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and its providers at my <a href="http://github.com/jamtur01/puppet/tree/features/shells">Puppet repository on GitHub</a>.  Quite a lot of the existing Puppet types and providers use <a href="http://www.kartar.net/tag/parsedfile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with parsedfile">ParsedFile</a> providers (the cron <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> for example) and you can use these as examples of how to create your own providers.  You can also find further documentation (in a lot more detail!) <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> <a href="http://reductivelabs.com/trac/puppet/wiki/DocumentationStart#ExtendingPuppet">creating your own types and providers at the Puppet wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/02/puppet-parsedfile-types-and-providers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Puppet types and providers is easy&#8230;</title>
		<link>http://www.kartar.net/2010/02/puppet-types-and-providers-are-easy/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=puppet-types-and-providers-are-easy</link>
		<comments>http://www.kartar.net/2010/02/puppet-types-and-providers-are-easy/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 06:24:31 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[provider]]></category>
		<category><![CDATA[repo]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2196</guid>
		<description><![CDATA[Puppet types are used to manage individual configuration items.  Puppet has a package type, a service type, a user type, etc.  Each type has providers. Each provider handles the management of that configuration on a different platform or tool, for example the package type has aptitude, yum, RPM, and DMG providers (amongst 22 others &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Puppet types are used to manage individual configuration items.  Puppet has a package <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, a service <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, a user <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, etc.  Each <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> has providers. Each <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> handles the management of that configuration <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> a different platform or tool, for example the package <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> has aptitude, yum, RPM, and DMG providers (amongst 22 others &#8211; what is wrong with people that they need to invent new packaging systems&#8230; but I digress).</p>
<p>There are a lot of types, in fact I think Puppet covers a pretty good spectrum of configuration items that need to be managed.  I don&#8217;t know of anything in particular that is missing that I can&#8217;t live without.  But there are little gaps that are annoying, I&#8217;d like network and firewall types for example, but creating both these types in a generic enough way to <a href="http://www.kartar.net/tag/support/" class="st_tag internal_tag" rel="tag" title="Posts tagged with support">support</a> multiple platforms would be, IMHO, a non-trivial problem.  </p>
<p>Another gap is VCS/DVCS management. A lot of people use source <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> in repositories to do things with (including install stuff from you bad people &#8211; package things &#8230; it&#8217;s healthier). Puppet currently relies <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> creating and removing these repositories with the exec <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> (which <strong>exec</strong>utes scripts or binaries), for example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">exec</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;svn co http://core.svn.wordpress.org/trunk/ /var/www/wp&quot;</span>:
    creates <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;/var/www/wp&quot;</span>,
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>This is a bit ugly and it&#8217;d be a lot easier to write a Puppet <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> to manage repositories. But Puppet types and providers are written in Ruby and really, really complex and hard to develop. Right? Right?</p>
<p>No. No, they are not&#8230; and I&#8217;m going to create a simple <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> to show you. <img src='http://www.kartar.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Here&#8217;s a very (very!) simple Puppet <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, called <strong>repo</strong>, for managing repositories. I&#8217;ve created providers for SVN and <a href="http://www.kartar.net/tag/git/" class="st_tag internal_tag" rel="tag" title="Posts tagged with git">Git</a> as examples also.  The first part of the repo <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> is the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> itself &#8211; these are usually stored in lib/puppet/<a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> or distributed via modules (see the <a href="http://reductivelabs.com/trac/puppet/wiki/PluginsInModules">PluginsInModules</a> page in the Puppet <a href="http://www.kartar.net/tag/wiki/" class="st_tag internal_tag" rel="tag" title="Posts tagged with wiki">wiki</a>).  I&#8217;ll create a file called repo.rb.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">touch</span> repo.rb</pre></div></div>

<p>And then populate the file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">Puppet::Type</span>.<span style="color:#9900CC;">newtype</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:repo</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@doc</span> = <span style="color:#996600;">&quot;Manage repos&quot;</span>
&nbsp;
    ensurable
&nbsp;
    newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:source</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;The repo source&quot;</span>
&nbsp;
        validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>value<span style="color:#006600; font-weight:bold;">|</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> value =~ <span style="color:#006600; font-weight:bold;">/</span>^git<span style="color:#006600; font-weight:bold;">/</span>
                resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:provider</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#ff3333; font-weight:bold;">:git</span>
            <span style="color:#9966CC; font-weight:bold;">else</span>
                resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:provider</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#ff3333; font-weight:bold;">:svn</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        isnamevar
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;Destination path&quot;</span>
&nbsp;
        validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>value<span style="color:#006600; font-weight:bold;">|</span>
            <span style="color:#9966CC; font-weight:bold;">unless</span> value =~ <span style="color:#006600; font-weight:bold;">/</span>^\<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+/</span>
                <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">ArgumentError</span> , <span style="color:#996600;">&quot;%s is not a valid file path&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> value
            <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>

<p>So &#8211; pretty simple.  We create a block <code>Puppet::<a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">Type</a>.newtype(:repo) do</code> that creates a new <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>, which we&#8217;ve called repo.</p>
<p>Inside the block we&#8217;ve got a <code>@doc</code> string.  This is the documentation for the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>. Add whatever level of detail and examples in here that is required.</p>
<p>We&#8217;ve also got the <code>ensurable</code> statement.  Ensurable provides some &#8220;automagic&#8221; that creates a basic <code>ensure</code> property.  Puppet types use the ensure property to determine the state of a configuration item.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">service <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;sshd&quot;</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> present,
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>The <code>ensurable</code> statement tells Puppet to expect three methods: create, destroy and exists? in our <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.  These methods, allow, respectively:</p>
<ul>
<li>A command to create the resource</li>
<li>A command to delete the resource, and</li>
<li>A command to check for the existence of the resource</li>
</ul>
<p>All we then need to do is specify these methods and their contents and Puppet creates the supporting infrastructure around them but more <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> this when we look at our providers.</p>
<p>Next, we&#8217;ve defined a new parameter &#8211; this one called <code>source</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:source</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;The repo source&quot;</span>
&nbsp;
        validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>value<span style="color:#006600; font-weight:bold;">|</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> value =~ <span style="color:#006600; font-weight:bold;">/</span>^git<span style="color:#006600; font-weight:bold;">/</span>
                resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:provider</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#ff3333; font-weight:bold;">:git</span>
            <span style="color:#9966CC; font-weight:bold;">else</span>
                resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:provider</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#ff3333; font-weight:bold;">:svn</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        isnamevar
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The source parameter will tell the repo <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> where to go to retrieve/clone/checkout our source repository.</p>
<p>In this parameter we&#8217;re also using a hook called <code>validate</code>.  Normally used to check the value for appropriateness here we&#8217;re using it to take a guess at what <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> to use.  Our <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> says, if the source parameter starts with <code><a href="http://www.kartar.net/tag/git/" class="st_tag internal_tag" rel="tag" title="Posts tagged with git">git</a></code> then use the <a href="http://www.kartar.net/tag/git/" class="st_tag internal_tag" rel="tag" title="Posts tagged with git">Git</a> <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>, if not default to the Subversion <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.  This is obviously fairly crude as a default and we can override this by defining the <code><a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a></code> attribute in our resources:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">provider <span style="color:#006600; font-weight:bold;">=&gt;</span> git,</pre></div></div>

<p>We&#8217;ve also used another piece of Puppet automagic, <code>isnamevar</code>, to make this parameter the &#8220;name&#8221; variable for this <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  In Puppet-speak, the value of this parameter is used as the name of the resource.</p>
<p>(Types have two kinds of values &#8211; properties and parameters.  Properties &#8220;do things&#8221;. They tell us HOW the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> works. We&#8217;ve only defined one property, ensure, by using the <code>ensurable</code> statement.  Parameters are more like variables, they contain information relevant to configuring the resource the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> manages rather than &#8220;doing things&#8221;.)</p>
<p>Finally, we&#8217;ve defined another parameter, <code>path</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    newparam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        desc <span style="color:#996600;">&quot;Destination path&quot;</span>
&nbsp;
        validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>value<span style="color:#006600; font-weight:bold;">|</span>
            <span style="color:#9966CC; font-weight:bold;">unless</span> value =~ <span style="color:#006600; font-weight:bold;">/</span>^\<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+/</span>
                <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">ArgumentError</span> , <span style="color:#996600;">&quot;%s is not a valid file path&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> value
            <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>

<p>This is a variable value that specifies where the repo <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> should put the cloned/checked-out repository.  In this parameter we&#8217;ve again used the <code>validate</code> hook to create a block that checks the value for appropriateness.  Here we&#8217;re just checking, very crudely, to make sure it looks like the destination path is a valid fully-qualified file path.  We could also use this validation for the source parameter to confirm a valid source URL/location was being provided.</p>
<p>(You can also use another hook called <code>munge</code> to adjust the value of the parameter rather than validating it before passing it to the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.)</p>
<p>And that is it for the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  </p>
<p>Next, we need to create a <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> for our <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  Let&#8217;s start with a Subversion <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> like so:</p>

<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;">'fileutils'</span>
&nbsp;
<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;">:repo</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">provide</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:svn</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    desc <span style="color:#996600;">&quot;SVN Support&quot;</span>
&nbsp;
    commands <span style="color:#ff3333; font-weight:bold;">:svncmd</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;svn&quot;</span>
    commands <span style="color:#ff3333; font-weight:bold;">:svnadmin</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;svnadmin&quot;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> create
        svncmd <span style="color:#996600;">&quot;checkout&quot;</span>, resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>, resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> destroy
        <span style="color:#CC00FF; font-weight:bold;">FileUtils</span>.<span style="color:#9900CC;">rm_rf</span> resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> exists?
        <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">directory</span>? resource<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path</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></pre></div></div>

<p>Up front we&#8217;ve required the <code>fileutils</code> library, which we&#8217;re going to use a method from.  Next, we&#8217;ve defined the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> as a block:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><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;">:repo</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">provide</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:svn</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span></pre></div></div>

<p>We tell Puppet that this is a <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> called <code>svn</code> for the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> called <code>repo</code>.</p>
<p>Then we use a <code>desc</code> method that allows us to add some documentation to our <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.</p>
<p>Next, we define the commands that this <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> will use, here the svn and svnadmin binaries, to manipulate our resource&#8217;s configuration.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    commands <span style="color:#ff3333; font-weight:bold;">:svncmd</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;svn&quot;</span>
    commands <span style="color:#ff3333; font-weight:bold;">:svnadmin</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;svnadmin&quot;</span></pre></div></div>

<p>Puppet uses these commands to determine if the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a> is appropriate to use <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> a client, if Puppet can&#8217;t find these commands in the local path then it will disable the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>.</p>
<p>Next, we&#8217;ve defined three methods &#8211; <code>create</code>, <code>destroy</code> and <code>exists?</code>.  Sounds familiar?  Yep, these are the methods that the <code>ensurable</code> statement expects to find in the <a href="http://www.kartar.net/tag/provider/" class="st_tag internal_tag" rel="tag" title="Posts tagged with provider">provider</a>:</p>
<p>The <code>create</code> method ensures our resource is created.  It uses the svn command to create a repository with a source of <code>resource[:name]</code> (remember the <code>source</code> parameter in our <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> is also the name variable of the <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> &#8211; we could also specify <code>resource[:source]</code> here too) and a destination of <code>resource[:path]</code> (the value of the path attribute).</p>
<p>The <code>delete</code> method ensures the deletion of the resource.  In this case, it deletes the directory and files specified in the <code>resource[:path]</code> parameter.</p>
<p>Lastly, the <code>exists?</code> method checks to see if the resource exists. Its operation is pretty simple and closely linked with the value of the <code>ensure</code> attribute in the resource: </p>
<ul>
<li>If <code>exists?</code> is false and <code>ensure</code> is present, then <code>create</code> method will be called.</li>
<li>If <code>exists?</code> is true and <code>ensure</code> is set to <code>absent</code>, then the <code>destroy</code> method will be called.</li>
</ul>
<p>In this case the <code>exists?</code> method checks if there is already a directory at the location specified in the <code>resource[:path]</code> parameter.  </p>
<p>So, let&#8217;s put all this together and create a resource with our new <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  I&#8217;ve assumed you&#8217;ve already distributed your <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and providers to Puppet.  We can then create a resource like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">repo <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;wp&quot;</span>:
    source <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;http://core.svn.wordpress.org/trunk/&quot;</span>,
    path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;/var/www/wp&quot;</span>,
    <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> present,
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>Simple eh?  We specify a repo resource, the source we wish to check out or clone from, the destination path and the ensure attribute (present or absent) and that&#8217;s it.</p>
<p>You can see the complete <a href="http://www.kartar.net/tag/code/" class="st_tag internal_tag" rel="tag" title="Posts tagged with code">code</a> for this <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> and its providers at my <a href="http://github.com/jamtur01/puppet/tree/feature/svn">Puppet repository on GitHub</a>.  It&#8217;s obviously very basic but should be easy to extend to provide additional capabilities (and currently has no tests &#8211; my bad). You can find further documentation (in a lot more detail!) <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> <a href="http://reductivelabs.com/trac/puppet/wiki/DocumentationStart#ExtendingPuppet">creating your own types and providers at the Puppet wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/02/puppet-types-and-providers-are-easy/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Hello Drupal</title>
		<link>http://www.kartar.net/2008/04/hello-drupal/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=hello-drupal</link>
		<comments>http://www.kartar.net/2008/04/hello-drupal/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[book]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[type]]></category>
		<category><![CDATA[war]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[So after many, many years (5 at least!) my blog is moving away from Expression Engine to Drupal.  There are a number of reasons for this but briefly they are:

1.  The “Book” content type.  I am a writer and I am thinking my next book will be authored between a bunch of us online.  Drupal offers the ability to do that and export the resulting content as DocBook. I had a look to see if EE could do this but I don’t have the time to develop something.

2.  My preference is generally open source software - I sit on the executive council of Linux Australia - and I don’t see EE as truly FOSS.  Drupal makes me feel intellectually more comfortable.

3.  The ease of theme application - I don’t have to design or tweak HTML/CSS anymore.  (well only a little)

Now I get the annoying feeling though that I will end up tweaking PHP in a few places but *shrugs* it's all good learning. :)]]></description>
			<content:encoded><![CDATA[<p>So after many, many years (5 at least!) my blog is moving away from Expression Engine to Drupal.  There are a number of reasons for this but briefly they are:</p>
<p>1.  The “<a href="http://www.kartar.net/tag/book/" class="st_tag internal_tag" rel="tag" title="Posts tagged with book">Book</a>” content <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a>.  I am a writer and I am thinking my next <a href="http://www.kartar.net/tag/book/" class="st_tag internal_tag" rel="tag" title="Posts tagged with book">book</a> will be authored between a bunch of us online.  Drupal offers the ability to do that and export the resulting content as DocBook. I had a look to see if EE could do this but I don’t have the time to develop something.</p>
<p>2.  My preference is generally open source software &#8211; I sit <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> the executive council of Linux Australia &#8211; and I don’t see EE as truly FOSS.  Drupal makes me feel intellectually more comfortable.</p>
<p>3.  The ease of theme application &#8211; I don’t have to design or tweak HTML/CSS anymore.  (well only a little)</p>
<p>Now I get the annoying feeling though that I will end up tweaking PHP in a few places but *shrugs* it&#8217;s all good learning. <img src='http://www.kartar.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2008/04/hello-drupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lucksmiths</title>
		<link>http://www.kartar.net/2007/09/lucksmiths/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=lucksmiths</link>
		<comments>http://www.kartar.net/2007/09/lucksmiths/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[Ruth]]></category>
		<category><![CDATA[support]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[As it is my birthday, and my girlfriend is a very nice person, she bought us tickets to go see Hand Held (Kirsty Stegwazi's latest thing), The Smallgoods and The Lucksmiths at The Corner last night.  It was their new double CD retrospective album launch - which you know I didn't buy but well you know bah.  

I haven't been to a Lucksmith's gig in .. well a very long time ... I am thinking the last time I saw them play was at the Punters but that part of my life is a little blurry.  It was very amusing watching the crowd - still mostly full of nice middle-class private school girls and their cardigan wearing floppy-haired, thick black rimmed square glasses wearing boyfriends.  Of course, these days there is a much broader cross-section of ages now - some of those private school girls are now early thirty somethings and some of the floppy hair is looking a little thin.

I don't know how much Ruth liked it - might have been a little happy, cheery, hopeful pop for her - but I had a good time.  The support was good, barring Kirsty Stegwazi having some serious guitar problems early in in her set and their drummer being "in jail", and the Smallgoods are very late Brian Wilson.  The Lucksmith's did a good set - I don't know a lot of the later stuff - but they played some early stuff - though not enough of the early, early stuff which is my favourite.  But I guess bands evolve away from their older stuff (except the Rolling Stones who really need to retire already) and I'll just have to burn some CDs onto my iPod to get that all time Lucksmith's sound.  

Finally, the Corner is a little juxtaposed these days - Ruth took me upstairs and that is a weird crowd up there - at least compared to the scruffy types like me downstairs.  And the no smoking thing in the band room is good but does mean the smell of BO is bloody strong.  I am of two minds about which smell I hate more...

P.S.  Girlfriend also bought me Lego Mindstorm!  Hmmmmm robots... Very happy.  :P
]]></description>
			<content:encoded><![CDATA[<p>As it is my birthday, and my girlfriend is a very nice person, she bought us tickets to go see Hand Held (Kirsty Stegwazi&#8217;s latest thing), The Smallgoods and The Lucksmiths at The Corner last night.  It was their new double CD retrospective album launch &#8211; which you know I didn&#8217;t buy but well you know bah.  </p>
<p>I haven&#8217;t been to a Lucksmith&#8217;s gig in .. well a very long time &#8230; I am thinking the last time I saw them play was at the Punters but that part of my life is a little blurry.  It was very amusing watching the crowd &#8211; still mostly full of nice middle-class private school girls and their cardigan wearing floppy-haired, thick black rimmed square glasses wearing boyfriends.  Of course, these days there is a much broader cross-section of ages now &#8211; some of those private school girls are now early thirty somethings and some of the floppy hair is looking a little thin.</p>
<p>I don&#8217;t know how much Ruth liked it &#8211; might have been a little happy, cheery, hopeful pop for her &#8211; but I had a good time.  The <a href="http://www.kartar.net/tag/support/" class="st_tag internal_tag" rel="tag" title="Posts tagged with support">support</a> was good, barring Kirsty Stegwazi having some serious guitar problems early in in her set and their drummer being &#8220;in jail&#8221;, and the Smallgoods are very late Brian Wilson.  The Lucksmith&#8217;s did a good set &#8211; I don&#8217;t know a lot of the later stuff &#8211; but they played some early stuff &#8211; though not enough of the early, early stuff which is my favourite.  But I guess bands evolve away from their older stuff (except the Rolling Stones who really need to retire already) and I&#8217;ll just have to burn some CDs onto my iPod to get that all time Lucksmith&#8217;s sound.  </p>
<p>Finally, the Corner is a little juxtaposed these days &#8211; Ruth took me upstairs and that is a weird crowd up there &#8211; at least compared to the scruffy types like me downstairs.  And the no smoking thing in the band room is good but does mean the smell of BO is bloody strong.  I am of two minds about which smell I hate more&#8230;</p>
<p>P.S.  Girlfriend also bought me Lego Mindstorm!  Hmmmmm robots&#8230; Very happy.  <img src='http://www.kartar.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2007/09/lucksmiths/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Moved</title>
		<link>http://www.kartar.net/2007/04/moved/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=moved</link>
		<comments>http://www.kartar.net/2007/04/moved/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[support]]></category>
		<category><![CDATA[type]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Oh yes - moved house.  Now in new home sans Internet (*bites knuckles*) for a little while.  Well not totally sans Internet - I am connecting my Linux box to the world via PPP over dial-up.  Yes - welcome back to my childhood.  In case anyone is interested iinet provided <a href="http://archive.iinet.net.au/support/linux/index.html" title="some old instructions for ppp over dial-up">some old instructions</a> for running up a ppp connection.  That was useful because it's been about ten years since I last did it.  And <a href="http://en.wikipedia.org/wiki/AT_commands" title="AT commands">AT commands</a> (otherwise known as the Hayes command set)?  Wow.  It's been a long time since I typed AT anything.  But I got there in the end.

This, however, does mean I am not on IM nor Skype.  If you want to chat - call my mobile. :)

P.S.  Oh yes - house good, lots of little things that need to be fixed, cats come home this weekend, etc, etc.]]></description>
			<content:encoded><![CDATA[<p>Oh yes &#8211; moved house.  Now in new home sans Internet (*bites knuckles*) for a little while.  Well not totally sans Internet &#8211; I am connecting my Linux box to the world via PPP over dial-up.  Yes &#8211; welcome back to my childhood.  In case anyone is interested iinet provided <a href="http://archive.iinet.net.au/support/linux/index.html" title="some old instructions for ppp over dial-up">some old instructions</a> for running up a ppp connection.  That was useful because it&#8217;s been about ten years since I last did it.  And <a href="http://en.wikipedia.org/wiki/AT_commands" title="AT commands">AT commands</a> (otherwise known as the Hayes command set)?  Wow.  It&#8217;s been a long time since I typed AT anything.  But I got there in the end.</p>
<p>This, however, does mean I am not <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> IM nor Skype.  If you want to chat &#8211; call my mobile. <img src='http://www.kartar.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>P.S.  Oh yes &#8211; house good, lots of little things that need to be fixed, cats come home this weekend, etc, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2007/04/moved/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Interview Goes Horribly Wrong&#8230; :)</title>
		<link>http://www.kartar.net/2006/11/google-interview-goes-horribly-wrong/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-interview-goes-horribly-wrong</link>
		<comments>http://www.kartar.net/2006/11/google-interview-goes-horribly-wrong/#comments</comments>
		<pubDate>Mon, 06 Nov 2006 01:12:01 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[repo]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[So I had an interview with Google in which I turned into a total gibbering idiot.  Tongue-tied, lost for words, forgot simple things.  I had worked myself up about it - read so many scary reports about it that I was a nervous wreck.  Totally fluffed it - the guy was so nice - I was stammering at one point and he said "Look I know what you mean to say but you're obviously a bit flustered - is this what you meant?"  And I said "SYN, SYN-ACK, ACK" about three times in a row and was unable to start the next sentence because I kept doing it.  And then I forgot the basic data types in Perl and then I couldn't remember what the definition of a 'salt' was - all I could think of was condiments.  Which didn't help.  

Ah well.  Interviews have always been my weakest point - I get stomach cramps, panic and my normally reasonably articulate self goes totally to shit.  I did have a vague plan of having a nerve-steadying drink beforehand.  I was all sensible and decided not to.  Am now rather regretting that decision.  At least I would have gone down with a higher-than-zero blood alcohol level.... :)  

]]></description>
			<content:encoded><![CDATA[<p>So I had an interview with Google in which I turned into a total gibbering idiot.  Tongue-tied, lost for words, forgot simple things.  I had worked myself up about it &#8211; read so many scary reports about it that I was a nervous wreck.  Totally fluffed it &#8211; the guy was so nice &#8211; I was stammering at one point and he said &#8220;Look I know what you mean to say but you&#8217;re obviously a bit flustered &#8211; is this what you meant?&#8221;  And I said &#8220;SYN, SYN-ACK, ACK&#8221; about three times in a row and was unable to start the next sentence because I kept doing it.  And then I forgot the basic data types in Perl and then I couldn&#8217;t remember what the definition of a &#8216;salt&#8217; was &#8211; all I could think of was condiments.  Which didn&#8217;t help.</p>
<p>Ah well.  Interviews have always been my weakest point &#8211; I get stomach cramps, panic and my normally reasonably articulate self goes totally to shit.  I did have a vague plan of having a nerve-steadying drink beforehand.  I was all sensible and decided not to.  Am now rather regretting that decision.  At least I would have gone down with a higher-than-zero blood alcohol level&#8230;. <img src='http://www.kartar.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2006/11/google-interview-goes-horribly-wrong/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>CRAM-MD5 authentication with Dovecot IMAP</title>
		<link>http://www.kartar.net/2006/10/cram-md5-authentication-with-dovecot-imap/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cram-md5-authentication-with-dovecot-imap</link>
		<comments>http://www.kartar.net/2006/10/cram-md5-authentication-with-dovecot-imap/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[ci]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I recently migrated my IMAP server from Courier-IMAP to Dovecot.  It's part of a whole simplification process I am engaging in.  I cut-over the IMAP server and then last week enabled the Dovecot authentication in Postfix to allow me to stop using a separate SASL daemon for authentication.  Now both SMTP and IMAP are authenticated from the one source - Dovecot.  

But one thing I discovered when setting up Dovecot is that there is very limited documentation on using CRAM-MD5 authentication with Dovecot.  As a result I am going to quickly document the process I used to get this up and running.  

Firstly you need to enable the mechanism and specify a passwd database file in Dovecot.  The mechanism and passdb file are specified in the <i>dovecot.conf</i> configuration file, on my system this is located in the <i>/usr/local/etc/</i> directory.

<i>auth default {
  # Space separated list of wanted authentication mechanisms:
  #   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi
  mechanisms = plain login cram-md5

  # passwd-like file with specified location
  passdb passwd-file {
    # Path for passwd-file
    args = /etc/cram-md5.pwd
  }

....

}</i>

I've added the <i>cram-md5</i> mechanism to the mechanisms statement and then added a passdb file, <i>/etc/cram-md5.pwd</i>.

Next, you need to create this passdb file and set appropriate permissions.

<i># touch /etc/cram-md5.pwd
# chmod 0600 /etc/cram-md5.pwd</i>

After creating the file you need to add your users and hashed passwords to the passdb file.  The users and passwords are added in the format:

<i>user:passwordhash</i>

Dovecot has a utility that allows you to convert passwords to the appropriate hashes.  This utility is called <i>dovecotpw</i> and is installed into the <i>/usr/local/sbin</i> directory or is available in the source package in the <i>src/util</i> directory.  You can run dovecotpw like so:

<i># dovecotpw
Enter new password:
Retype new password:
{HMAC-MD5}26b633ec8bf9dd526293c5897400bddeef9299fad
</i>

Enter the user's password when prompted and it will be converted and outputted as a hash.  The default hashed output is in the HMAC-MD5 scheme (which is appropriate for CRAM-MD5).  You can change the scheme of the outputted hashes using the <i>-s</i> command line switch.  Now add the generated password to the passdb file, <i>/etc/cram-md5.pwd</i>.

<i>kartar:{HMAC-MD5}26b633ec8bf9dd526293c5897400bddeef9299fad</i>

Finally, restart Dovecot and test authentication by enabling the appropriate mechanism in your email client.  For example, to enable CRAM-MD5 authentication in Thunderbird you need to check the "Use secure authentication" checkbox in the Account Settings page.

Obviously I recommend that you use TLS/SSL to encrypt the authentication process as well.]]></description>
			<content:encoded><![CDATA[<p>I recently migrated my IMAP server from Courier-IMAP to Dovecot.  It&#8217;s part of a whole simplification process I am engaging in.  I cut-over the IMAP server and then last week enabled the Dovecot authentication in Postfix to allow me to stop using a separate SASL daemon for authentication.  Now both SMTP and IMAP are authenticated from the one source &#8211; Dovecot.  </p>
<p>But one thing I discovered when setting up Dovecot is that there is very limited documentation <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> using CRAM-MD5 authentication with Dovecot.  As a result I am going to quickly document the process I used to get this up and running.  </p>
<p>Firstly you need to enable the mechanism and specify a passwd database file in Dovecot.  The mechanism and passdb file are specified in the <i>dovecot.conf</i> configuration file, <a href="http://www.kartar.net/tag/on/" class="st_tag internal_tag" rel="tag" title="Posts tagged with on">on</a> my system this is located in the <i>/usr/local/etc/</i> directory.</p>
<p><i>auth default {<br />
  # Space separated list of wanted authentication mechanisms:<br />
  #   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi<br />
  mechanisms = plain login cram-md5</p>
<p>  # passwd-like file with specified location<br />
  passdb passwd-file {<br />
    # Path for passwd-file<br />
    args = /etc/cram-md5.pwd<br />
  }</p>
<p>&#8230;.</p>
<p>}</i></p>
<p>I&#8217;ve added the <i>cram-md5</i> mechanism to the mechanisms statement and then added a passdb file, <i>/etc/cram-md5.pwd</i>.</p>
<p>Next, you need to create this passdb file and set appropriate permissions.</p>
<p><i># touch /etc/cram-md5.pwd<br />
# chmod 0600 /etc/cram-md5.pwd</i></p>
<p>After creating the file you need to add your users and hashed passwords to the passdb file.  The users and passwords are added in the format:</p>
<p><i>user:passwordhash</i></p>
<p>Dovecot has a utility that allows you to convert passwords to the appropriate hashes.  This utility is called <i>dovecotpw</i> and is installed into the <i>/usr/local/sbin</i> directory or is available in the source package in the <i>src/util</i> directory.  You can run dovecotpw like so:</p>
<p><i># dovecotpw<br />
Enter new password:<br />
Retype new password:<br />
{HMAC-MD5}26b633ec8bf9dd526293c5897400bddeef9299fad<br />
</i></p>
<p>Enter the user&#8217;s password when prompted and it will be converted and outputted as a hash.  The default hashed output is in the HMAC-MD5 scheme (which is appropriate for CRAM-MD5).  You can change the scheme of the outputted hashes using the <i>-s</i> command line switch.  Now add the generated password to the passdb file, <i>/etc/cram-md5.pwd</i>.</p>
<p><i>kartar:{HMAC-MD5}26b633ec8bf9dd526293c5897400bddeef9299fad</i></p>
<p>Finally, restart Dovecot and test authentication by enabling the appropriate mechanism in your email client.  For example, to enable CRAM-MD5 authentication in Thunderbird you need to check the &#8220;Use secure authentication&#8221; checkbox in the Account Settings page.</p>
<p>Obviously I recommend that you use TLS/SSL to encrypt the authentication process as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2006/10/cram-md5-authentication-with-dovecot-imap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nagios source code file &#8211; file formats wrong</title>
		<link>http://www.kartar.net/2006/05/nagios-source-code-file-file-formats-wrong/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=nagios-source-code-file-file-formats-wrong</link>
		<comments>http://www.kartar.net/2006/05/nagios-source-code-file-file-formats-wrong/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[book]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[is]]></category>
		<category><![CDATA[Logies]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Damn - just had to replace the bloody source file zip for the Nagios book - a lot of the files in the one online seem to have become DOS type files rather than Unix ones.  Bloody CRs and other crap all the way through them.  I checked my copy and all was fine and then provided a new file to Apress.  Most annoying.  If you've experienced this - then my apologies and go to the Apress site in a couple of days to download a new version.]]></description>
			<content:encoded><![CDATA[<p>Damn &#8211; just had to replace the bloody source file zip for the Nagios <a href="http://www.kartar.net/tag/book/" class="st_tag internal_tag" rel="tag" title="Posts tagged with book">book</a> &#8211; a lot of the files in the one online seem to have become DOS <a href="http://www.kartar.net/tag/type/" class="st_tag internal_tag" rel="tag" title="Posts tagged with type">type</a> files rather than Unix ones.  Bloody CRs and other crap all the way through them.  I checked my copy and all was fine and then provided a new file to Apress.  Most annoying.  If you&#8217;ve experienced this &#8211; then my apologies and go to the Apress site in a couple of days to download a new version.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2006/05/nagios-source-code-file-file-formats-wrong/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
