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

  <title><![CDATA[The language-puppet website.]]></title>
  <link href="http://lpuppet.banquise.net/atom.xml" rel="self"/>
  <link href="http://lpuppet.banquise.net/"/>
  <updated>2013-05-20T19:48:21+02:00</updated>
  <id>http://lpuppet.banquise.net/</id>
  <author>
    <name><![CDATA[Simon Marechal]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Incoming: Ruby bridge]]></title>
    <link href="http://lpuppet.banquise.net/blog/2013/05/20/incoming-ruby-bridge/"/>
    <updated>2013-05-20T11:35:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2013/05/20/incoming-ruby-bridge</id>
    <content type="html"><![CDATA[<p>I am working on a quick and dirty Ruby bridge <a href="https://github.com/bartavelle/hruby">library</a>, that I hope will yield a huge performance gain with template interpolation in the language-puppet library. Right now, it is capable of:</p>

<ul>
<li>Initializing a Ruby interpreter from libruby</li>
<li>Calling Ruby methods and functions</li>
<li>Registering methods or functions that will be called from Ruby code</li>
<li>Converting data between the two Worlds (right now the most complex instance is the JSON one, which means that many complex Ruby types can&#8217;t be converted, but it is more than enough for passing data)</li>
<li>Embedding native Haskell values that can be passed around in Ruby to the Haskell-provided external functions (I will use this for passing the Puppet catalog state around)</li>
</ul>


<p>There are still a few things to do before releasing it :</p>

<ul>
<li>Making compilation a bit less dependant on the system. This will probably require quite a few flags in the cabal definition &#8230;</li>
<li>Hunting for memory leaks. I am not sure how to do this with the GHC Runtime in the middle, and I do hope that <em>ruby_finalize</em> frees everything that is managed by the Ruby runtime. After all, restarting processes seems to be the only working garbage collection method for Ruby daemons &#8230;</li>
<li>Writing stubs for the Puppet library methods that might be needed by templates. I would like to be able to support custom types and functions directly written in Ruby instead of Lua, but this will probably turn into a nightmare &#8230;</li>
<li>Cleaning things up !</li>
</ul>


<p>Here is a quick code preview :</p>

<figure class='code'><figcaption><span>test.hs </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
</pre></td><td class='code'><pre><code class='hs'><span class='line'><span class="cm">{-# LANGUAGE OverloadedStrings, OverloadedStrings #-}</span>
</span><span class='line'><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
</span><span class='line'>
</span><span class='line'><span class="kr">import</span> <span class="nn">Foreign.Ruby.Bindings</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Data.Aeson</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Data.Attoparsec.Number</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- this is an external function that will be executed from the Ruby interpreter</span>
</span><span class='line'><span class="c1">-- the first parameter to the function is probably some reference to some top object</span>
</span><span class='line'><span class="c1">-- my knowledge of ruby is close to nonexistent, so I can&#39;t say for sure ...</span>
</span><span class='line'><span class="nf">extfunc</span> <span class="ow">::</span> <span class="kt">RValue</span> <span class="ow">-&gt;</span> <span class="kt">RValue</span> <span class="ow">-&gt;</span> <span class="kt">IO</span> <span class="kt">RValue</span>
</span><span class='line'><span class="nf">extfunc</span> <span class="kr">_</span> <span class="n">v</span> <span class="ow">=</span> <span class="kr">do</span>
</span><span class='line'>    <span class="c1">-- deserialize the Ruby value into some JSON Value</span>
</span><span class='line'>    <span class="n">onv</span> <span class="ow">&lt;-</span> <span class="n">fromRuby</span> <span class="n">v</span> <span class="ow">::</span> <span class="kt">IO</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="kt">Value</span><span class="p">)</span>
</span><span class='line'>    <span class="c1">-- and display it</span>
</span><span class='line'>    <span class="n">print</span> <span class="n">onv</span>
</span><span class='line'>    <span class="c1">-- now let&#39;s create a JSON object containing all kind of data types</span>
</span><span class='line'>    <span class="kr">let</span> <span class="n">nv</span> <span class="ow">=</span> <span class="n">object</span> <span class="p">[</span> <span class="p">(</span><span class="s">&quot;bigint&quot;</span> <span class="p">,</span> <span class="kt">Number</span> <span class="p">(</span><span class="kt">I</span> <span class="mi">16518656116889898998656112323135664684684</span><span class="p">))</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;int&quot;</span><span class="p">,</span> <span class="kt">Number</span> <span class="p">(</span><span class="kt">I</span> <span class="mi">12</span><span class="p">))</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;double&quot;</span><span class="p">,</span> <span class="kt">Number</span> <span class="p">(</span><span class="kt">D</span> <span class="mf">0.123</span><span class="p">))</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;null&quot;</span><span class="p">,</span> <span class="s">&quot;Null&quot;</span><span class="p">)</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;string&quot;</span><span class="p">,</span> <span class="kt">String</span> <span class="s">&quot;string&quot;</span><span class="p">)</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;true&quot;</span><span class="p">,</span> <span class="kt">Bool</span> <span class="kt">True</span><span class="p">)</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;false&quot;</span><span class="p">,</span> <span class="kt">Bool</span> <span class="kt">False</span><span class="p">)</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;array&quot;</span><span class="p">,</span> <span class="n">toJSON</span> <span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">]</span> <span class="ow">::</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]))</span>
</span><span class='line'>                    <span class="p">,</span> <span class="p">(</span><span class="s">&quot;object&quot;</span><span class="p">,</span> <span class="n">object</span> <span class="p">[</span> <span class="p">(</span><span class="s">&quot;k&quot;</span><span class="p">,</span> <span class="kt">String</span> <span class="s">&quot;v&quot;</span><span class="p">)</span> <span class="p">]</span> <span class="p">)</span>
</span><span class='line'>                    <span class="p">]</span>
</span><span class='line'>    <span class="c1">-- turn it into Ruby values, and return this</span>
</span><span class='line'>    <span class="n">toRuby</span> <span class="n">nv</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- this is the function that is called if everything was loaded properly</span>
</span><span class='line'><span class="nf">nextThings</span> <span class="ow">::</span> <span class="kt">IO</span> <span class="nb">()</span>
</span><span class='line'><span class="nf">nextThings</span> <span class="ow">=</span> <span class="kr">do</span>
</span><span class='line'>    <span class="c1">-- turn the extfunc function into something that can be called by the Ruby interpreter</span>
</span><span class='line'>    <span class="n">myfunc</span> <span class="ow">&lt;-</span> <span class="n">mkRegistered2</span> <span class="n">extfunc</span>
</span><span class='line'>    <span class="c1">-- and bind it to the global &#39;hsfunction&#39; function</span>
</span><span class='line'>    <span class="n">rb_define_global_function</span> <span class="s">&quot;hsfunction&quot;</span> <span class="n">myfunc</span> <span class="mi">1</span>
</span><span class='line'>    <span class="c1">-- now call a method in the Ruby interpreter</span>
</span><span class='line'>    <span class="n">o</span> <span class="ow">&lt;-</span> <span class="n">safeMethodCall</span> <span class="s">&quot;MyClass&quot;</span> <span class="s">&quot;testfunc&quot;</span> <span class="kt">[]</span>
</span><span class='line'>    <span class="kr">case</span> <span class="n">o</span> <span class="kr">of</span>
</span><span class='line'>        <span class="kt">Right</span> <span class="n">v</span> <span class="ow">-&gt;</span> <span class="p">(</span><span class="n">fromRuby</span> <span class="n">v</span> <span class="ow">::</span> <span class="kt">IO</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="kt">Value</span><span class="p">))</span> <span class="o">&gt;&gt;=</span> <span class="n">print</span>
</span><span class='line'>        <span class="kt">Left</span> <span class="n">r</span> <span class="ow">-&gt;</span> <span class="n">putStrLn</span> <span class="n">r</span>
</span><span class='line'>
</span><span class='line'><span class="nf">main</span> <span class="ow">::</span> <span class="kt">IO</span> <span class="nb">()</span>
</span><span class='line'><span class="nf">main</span> <span class="ow">=</span> <span class="kr">do</span>
</span><span class='line'>    <span class="c1">-- initialize stuff</span>
</span><span class='line'>    <span class="n">ruby_init</span>
</span><span class='line'>    <span class="n">ruby_init_loadpath</span>
</span><span class='line'>    <span class="c1">-- and load &quot;test.rb&quot;</span>
</span><span class='line'>    <span class="n">s</span> <span class="ow">&lt;-</span> <span class="n">rb_load_protect</span> <span class="s">&quot;test.rb&quot;</span> <span class="mi">0</span>
</span><span class='line'>    <span class="kr">if</span> <span class="n">s</span> <span class="o">==</span> <span class="mi">0</span>
</span><span class='line'>        <span class="kr">then</span> <span class="n">nextThings</span>
</span><span class='line'>        <span class="kr">else</span> <span class="n">showError</span> <span class="o">&gt;&gt;=</span> <span class="n">putStrLn</span>
</span></code></pre></td></tr></table></div></figure>


<p>And here is the ruby program, that calls our external function :</p>

<figure class='code'><figcaption><span>test.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">MyClass</span>
</span><span class='line'>    <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">testfunc</span>
</span><span class='line'>        <span class="n">hsfunction</span><span class="p">(</span> <span class="o">[</span><span class="mi">16588</span><span class="p">,</span>
</span><span class='line'>                    <span class="s2">&quot;qsqsd&quot;</span><span class="p">,</span>
</span><span class='line'>                    <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>                    <span class="p">{</span> <span class="s1">&#39;a&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;b&#39;</span> <span class="p">},</span>
</span><span class='line'>                    <span class="ss">:symbol</span><span class="p">,</span>
</span><span class='line'>                    <span class="mi">0</span><span class="o">.</span><span class="mi">432</span><span class="p">,</span>
</span><span class='line'>                    <span class="mi">5611561561186918918918618789115616591891198189123165165889</span> <span class="o">]</span>
</span><span class='line'>                <span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">k</span><span class="p">,</span><span class="n">v</span><span class="o">|</span>
</span><span class='line'>            <span class="nb">puts</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">k</span><span class="si">}</span><span class="s2"> =&gt; </span><span class="si">#{</span><span class="n">v</span><span class="si">}</span><span class="s2"> [</span><span class="si">#{</span><span class="n">v</span><span class="o">.</span><span class="n">class</span><span class="si">}</span><span class="s2">]&quot;</span>
</span><span class='line'>        <span class="k">end</span>
</span><span class='line'>        <span class="mi">12</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the output, showing that data is properly converted from either sides :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Just (Array (fromList [Number 16588,String "qsqsd",Bool True,Object fromList [("a",String "b")],String "symbol",Number 0.432,Number 5611561561186918918918618789115616591891198189123165165889]))
</span><span class='line'>bigint =&gt; 16518656116889898998656112323135664684684 [Bignum]
</span><span class='line'>int =&gt; 12 [Fixnum]
</span><span class='line'>double =&gt; 0.123 [Float]
</span><span class='line'>array =&gt; 12345 [Array]
</span><span class='line'>true =&gt; true [TrueClass]
</span><span class='line'>null =&gt; Null [String]
</span><span class='line'>string =&gt; string [String]
</span><span class='line'>object =&gt; kv [Hash]
</span><span class='line'>false =&gt; false [FalseClass]
</span><span class='line'>Just (Number 12)</span></code></pre></td></tr></table></div></figure>


<p>EDIT: added link to the code.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[language-puppet v0.4.0]]></title>
    <link href="http://lpuppet.banquise.net/blog/2013/05/16/language-puppet-v0-dot-4-0/"/>
    <updated>2013-05-16T20:32:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2013/05/16/language-puppet-v0-dot-4-0</id>
    <content type="html"><![CDATA[<p>I just released the latest language-puppet version. For the full list of changes, please take a look at the
<a href="https://github.com/bartavelle/language-puppet/blob/master/Changelog">changelog</a>. Here are the highlights.</p>

<h3>PuppetDB code reworked</h3>

<p>The PuppetDB code and API has been completely overhauled. It is now more generic : the resource collection and puppet
query functions now work the same. Additionally, a PuppetDB stub has been created for testing use.</p>

<h3>Better diagnostic facilities</h3>

<p>As the main use of this library is to test stuff, the following features were added:</p>

<ul>
<li>Several error messages have been reworked so that they are more informative.</li>
<li>A <code>dumpvariables</code> built-in function has been added. It just prints all known variables (and facts) to stdout, and can
be quite handy.</li>
<li>The &#8220;scope stack&#8221; description is stored with the resources. This turned out to be extremely useful when debugging
resource names colisions or to find out where some resource is defined.</li>
</ul>


<p>Here is an example, let&#8217;s say you do not remember which package installs the <code>collectd</code> package. Just run this :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>» puppetresources . default.domain 'Package[collectd]'
</span><span class='line'>
</span><span class='line'>package {
</span><span class='line'>    "collectd": #"./modules/collectd/manifests/base.pp" (line 4, column 9) ["::","site::baseconfig","collectd","collectd::client","collectd::base"]
</span><span class='line'>        ensure          =&gt; "installed",
</span><span class='line'>        require         =&gt; [Class["collectd"], Class["collectd::base"], Class["collectd::client"], Class["site::baseconfig"]];
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>You now know exactly where the <code>package</code> resource is declared, and the list of &#8220;scopes&#8221; that have been traversed in
order to do so. Note that this information is displayed when resources names collide.</p>

<h3>Easier to setup</h3>

<p>This library doesn&#8217;t depend from a newish <code>bytestring</code> anymore, and should build with the package provided with a GHC
compiler of the 7.6.x serie.</p>

<p>This is not yet done, but I will certainly soon publish a debian-style repository of the compiled <code>puppetresources</code> binary. I am interested in suggestions for an automated building system.</p>

<h3>Better testing</h3>

<p>The testing API seems sufficient to write pretty strong tests, but would still benefit from a few more helper functions.
The testing &#8220;daemon&#8221; has been reworked to use the new PuppetDB stub. It makes it possible to test complex interactions
between hosts using the exported resource or PuppetDB query features.</p>

<h3>Work in progress</h3>

<p>I will probably <a href="http://hackage.haskell.org/package/lens">lensify</a> the code until I get a descent understanding of it.</p>

<p>I do not intend to work on Hiera emulation just yet, as I am probably the only user of this library for now and I do not
use this feature.</p>

<p>One area of improvement would be to embed the ruby interpreter in the library. I am not sure how to do this, but as
there are quite a few projects of lightweight interpreters sprouting from the earth, it might be possible in the near
future. The only problem would be figuring out how to build a large C project with cabal.</p>

<h3>Some other considerations</h3>

<p>I recently ported the code from <code>random.c</code> to Haskell
(<a href="https://github.com/bartavelle/language-puppet/blob/master/Puppet/Interpreter/RubyRandom.hs">here</a>). This has been
quite tedious, and is quite hard to read. This is an almost naive port of the code found in the Ruby interpreter,
without the useless loop variables. For some reason, there are many loops like this :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>i=1; j=0;
</span><span class='line'>k = (N&gt;key_length ? N : key_length);
</span><span class='line'>for (; k; k--) {
</span><span class='line'>    mt-&gt;state[i] = (mt-&gt;state[i] ^ ((mt-&gt;state[i-1] ^ (mt-&gt;state[i-1] &gt;&gt; 30)) * 1664525U))
</span><span class='line'>        + init_key[j] + j; /* non linear */
</span><span class='line'>    mt-&gt;state[i] &= 0xffffffffU; /* for WORDSIZE &gt; 32 machines */
</span><span class='line'>    i++; j++;
</span><span class='line'>    if (i&gt;=N) { mt-&gt;state[0] = mt-&gt;state[N-1]; i=1; }
</span><span class='line'>    if (j&gt;=key_length) j=0;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>As you can see, the value of k is never used in the loop. I am not sure why the author didn&#8217;t go for something like :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>for(i=1;i&lt;k;i++) {</span></code></pre></td></tr></table></div></figure>


<p>Anyway, the Haskell code is pretty bad, and will certainly only work for 64-bit builds. I am not sure how I should have
written it. I suppose staying in the ST monad would have lead to nicer code, and I am open to suggestions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The hslogstash package]]></title>
    <link href="http://lpuppet.banquise.net/blog/2013/02/08/the-hslogstash-package/"/>
    <updated>2013-02-08T22:23:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2013/02/08/the-hslogstash-package</id>
    <content type="html"><![CDATA[<p>This blog post is not about language-puppet, but might be of interest to my fellow sysadmins with an interest in Haskell. I recently worked with Logstash in a way that might not be typical, as all my messages are emitted by services that are Logstash-aware: they directly write JSON messages to the TCP input of the Logstash server. This means that most of the features (and some would say, the whole point) of Logstash were of no use to me.</p>

<p>I stuck with my grand mission of rewriting the handful of useful Ruby programs, and wrote a new <a href="http://hackage.haskell.org/package/hslogstash">package</a>. I based almost everything around the excellent <a href="http://hackage.haskell.org/package/conduit">conduit</a> abstraction. It has the following features:</p>

<ul>
<li>Haskell types for representing Logstash messages, along with the type-classes necessary for converting them from and to JSON</li>
<li>An ElasticSearch conduit, using the bulk insert API</li>
<li>A Redis source using the pipelining features of the <a href="http://hackage.haskell.org/package/hedis">hedis</a> package, and a simple Redis sink</li>
<li>A Logstash listener, based on the TCP listener from <a href="http://hackage.haskell.org/package/network-conduit">network-conduit</a>, able to accept latin1 and UTF-8 messages at the same time</li>
<li>A pair of &#8220;retrying&#8221; sinks, one using a <code>Socket</code> and the other establishing TCP connections. They are used for garanteed delivery of a whole <code>ByteString</code> segment, retrying to connect until it is sent (this is obviously useful for JSON messages)</li>
<li>A few functions for handling bulk APIs in Conduits</li>
<li>And finally, the coolest part, a few helper functions that will let you route between conduits !</li>
</ul>


<p>The last part was made after a little discussion on the Haskell-Cafe mailing list. It is built with with <a href="http://hackage.haskell.org/package/stm-conduit">stm-conduit</a>, which already has a helper function for merging sources. This package introduces the other useful functionnality: the ability to &#8220;route&#8221; items coming from a source to several sinks. The main function, <code>branchConduits</code>, works by taking a <code>Source</code>, a routing function, and a <code>Sink</code> list. The routing function associates a (possibly empty) list of integers to every item coming from the <code>Source</code>. These integers directly map to the corresponding <code>Sink</code>, letting you define the routing policy.</p>

<p>The package includes a few examples of common tasks, all of them with acceptable runtime performance, such as :</p>

<ul>
<li>Moving messages from a TCP server to Redis</li>
<li>Moving messages from Redis to Elasticsearch</li>
<li>Routing messages between conduits</li>
</ul>


<p>So if you need more control, or much better performance, than what you would get from Logstash, and you are not afraid to write (a lot of) code, please use this package and let me know what is missing and/or buggy!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sneak peak at the language-puppet PuppetDB testing features]]></title>
    <link href="http://lpuppet.banquise.net/blog/2013/01/30/sneak-peak-at-the-language-puppet-puppetdb-testing-features/"/>
    <updated>2013-01-30T17:16:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2013/01/30/sneak-peak-at-the-language-puppet-puppetdb-testing-features</id>
    <content type="html"><![CDATA[<p>I always thought that one of the most rewarding effect of Puppet is that the whole system gets configured automatically as nodes are added.
For me, the main, and for a long time sole, manifestation of this property is in the configuration of the Nagios servers. The built-in types lend themselves pretty well to this exercice.</p>

<p>Now, with PuppetDB, we have a simple and powerful way to create new effects, beyond what could be achieved with just exported resources (I believe it used to be possible before PuppetDB, but required black magic in the template files). I will demonstrate a typical use case, along with a sneak peak of the testing features that will appear in the next version of language-puppet.</p>

<p>Let&#8217;s say we have an HTTP proxy and several groups of servers acting as backends. You wish to be able to add servers to the pool just by running the agent on them. The <code>site.pp</code> should look like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>node 'proxy' {
</span><span class='line'>    include haproxy
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>node 'back1' {
</span><span class='line'>    haproxy::backend { $hostname:
</span><span class='line'>        backend_type   =&gt; 'web',
</span><span class='line'>        backend_server =&gt; $hostname,
</span><span class='line'>        backend_port   =&gt; 80;
</span><span class='line'>    }
</span><span class='line'>}
</span><span class='line'>node 'back2' {
</span><span class='line'>    haproxy::backend { $hostname:
</span><span class='line'>        backend_type   =&gt; 'web',
</span><span class='line'>        backend_server =&gt; $hostname,
</span><span class='line'>        backend_port   =&gt; 80;
</span><span class='line'>    }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The <code>haproxy::backend</code> defines are empty, and the interesting part is in the <code>haproxy</code> class:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>class haproxy {
</span><span class='line'>    $backends = pdbresourcequery(
</span><span class='line'>        ['and',
</span><span class='line'>            ['=',['node','active'],true],
</span><span class='line'>            ['=','type','Haproxy::Backend']
</span><span class='line'>        ],'parameters')
</span><span class='line'>
</span><span class='line'>    file { '/etc/haproxy/haproxy.cfg':
</span><span class='line'>        content =&gt; template('haproxy/config.erb');
</span><span class='line'>    }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The <code>pdbresourcequery</code> function comes from <a href="https://github.com/dalen/puppet-puppetdbquery">this excellent module</a>, and has been included natively in language-puppet for a while. Its effect here is to fill the <code>$backends</code> variable with an array containing all resources that are of type <code>Haproxy::Backend</code> on any active node.</p>

<p>But now comes the complicated part: how are you supposed to write, and, more importantly, to test, the <code>config.erb</code> template ? As far as I know you can&#8217;t pull this off with <code>puppet-rspec</code> (and it is way too slow anyway). With the new testing API, you can write a simple program like this:</p>

<figure class='code'><figcaption><span>Main.hs </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='hs'><span class='line'><span class="kr">module</span> <span class="nn">Main</span> <span class="kr">where</span>
</span><span class='line'>
</span><span class='line'><span class="kr">import</span> <span class="k">qualified</span> <span class="nn">Data.Map</span> <span class="k">as</span> <span class="n">Map</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Control.Monad</span> <span class="p">(</span><span class="nf">void</span><span class="p">)</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Puppet.Testing</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Puppet.Interpreter.Types</span>
</span><span class='line'><span class="kr">import</span> <span class="nn">Facter</span>
</span><span class='line'>
</span><span class='line'><span class="nf">main</span> <span class="ow">::</span> <span class="kt">IO</span> <span class="nb">()</span>
</span><span class='line'><span class="nf">main</span> <span class="ow">=</span> <span class="kr">do</span>
</span><span class='line'>    <span class="n">qfunction</span> <span class="ow">&lt;-</span> <span class="n">testingDaemon</span> <span class="kt">Nothing</span> <span class="s">&quot;.&quot;</span> <span class="n">allFacts</span>
</span><span class='line'>    <span class="n">void</span> <span class="o">$</span> <span class="n">qfunction</span> <span class="s">&quot;back1&quot;</span>
</span><span class='line'>    <span class="n">void</span> <span class="o">$</span> <span class="n">qfunction</span> <span class="s">&quot;back2&quot;</span>
</span><span class='line'>    <span class="p">(</span><span class="n">proxycatalog</span><span class="p">,</span> <span class="kr">_</span><span class="p">,</span> <span class="kr">_</span><span class="p">)</span> <span class="ow">&lt;-</span> <span class="n">qfunction</span> <span class="s">&quot;proxy&quot;</span>
</span><span class='line'>    <span class="kr">case</span> <span class="kt">Map</span><span class="o">.</span><span class="n">lookup</span> <span class="p">(</span><span class="s">&quot;file&quot;</span><span class="p">,</span><span class="s">&quot;/etc/haproxy/haproxy.cfg&quot;</span><span class="p">)</span> <span class="n">proxycatalog</span> <span class="kr">of</span>
</span><span class='line'>        <span class="kt">Nothing</span> <span class="ow">-&gt;</span> <span class="ne">error</span> <span class="s">&quot;could not find config file&quot;</span>
</span><span class='line'>        <span class="kt">Just</span> <span class="n">f</span>  <span class="ow">-&gt;</span> <span class="kr">case</span> <span class="kt">Map</span><span class="o">.</span><span class="n">lookup</span> <span class="s">&quot;content&quot;</span> <span class="p">(</span><span class="n">rrparams</span> <span class="n">f</span><span class="p">)</span> <span class="kr">of</span>
</span><span class='line'>                       <span class="kt">Just</span> <span class="p">(</span><span class="kt">ResolvedString</span> <span class="n">s</span><span class="p">)</span> <span class="ow">-&gt;</span> <span class="n">putStrLn</span> <span class="n">s</span>
</span><span class='line'>                       <span class="kr">_</span> <span class="ow">-&gt;</span> <span class="ne">error</span> <span class="s">&quot;could not find content&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Line by line, this program does:</p>

<ul>
<li>lines 1-10 : various headers</li>
<li>line 11 : the catalog computing function is initialized, using the new testing system</li>
<li>line 12 : the catalog for the node <code>back1</code> is computed, and stored into the fake PuppetDB</li>
<li>line 13 : same thing for <code>back2</code></li>
<li>line 14 : same thing for <code>proxy</code>, but we keep the final catalog this time</li>
<li>lines 15-19 : the content of the <code>/etc/haproxy/haproxy.cfg</code> is displayed. This part is terrible and will be replaced by some helper soon.</li>
</ul>


<p>The template groups the resources by their &#8220;backend_type&#8221; attribute, creates a backend block for each of them, and populates the blocks with the corresponding backends.</p>

<figure class='code'><figcaption><span>modules/haproxy/templates/config.erb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='erb'><span class='line'><span class="cp">&lt;%-</span> <span class="n">backends</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">lookupvar</span><span class="p">(</span><span class="s1">&#39;haproxy::backends&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">group_by</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span><span class="o">[</span><span class="s2">&quot;backend_type&quot;</span><span class="o">]</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%-</span> <span class="n">backends</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">backendname</span><span class="p">,</span> <span class="n">backends</span><span class="o">|</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">backend </span><span class="cp">&lt;%=</span> <span class="n">backendname</span> <span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">    </span><span class="cp">&lt;%-</span> <span class="n">backends</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">backend</span><span class="o">|</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">        server </span><span class="cp">&lt;%=</span><span class="n">backend</span><span class="o">[</span><span class="s2">&quot;backend_server&quot;</span><span class="o">]</span><span class="cp">%&gt;</span><span class="x"> </span><span class="cp">&lt;%=</span><span class="n">backend</span><span class="o">[</span><span class="s2">&quot;backend_server&quot;</span><span class="o">]</span><span class="cp">%&gt;</span><span class="x">:</span><span class="cp">&lt;%=</span><span class="n">backend</span><span class="o">[</span><span class="s2">&quot;backend_port&quot;</span><span class="o">]</span><span class="cp">%&gt;</span><span class="x"></span>
</span><span class='line'><span class="x">    </span><span class="cp">&lt;%-</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span><span class='line'><span class="cp">&lt;%-</span> <span class="k">end</span> <span class="cp">-%&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>And the output is :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>backend web
</span><span class='line'>        server back2 back2:80
</span><span class='line'>        server back1 back1:80</span></code></pre></td></tr></table></div></figure>


<p>It works! With this feature, it will soon be possible to test and experiment with the most complex aspects of inter-node interactions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hspuppetmaster alpha release]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/12/20/hspuppetmaster-alpha-release/"/>
    <updated>2012-12-20T12:18:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/12/20/hspuppetmaster-alpha-release</id>
    <content type="html"><![CDATA[<p>Grab the <a href="http://www.banquise.net/bin/hspuppetmaster.tar.bz2">alpha</a> version of
Hspuppetmaster (compiled for x64 Linux)! It will become a full-fledged
replacement for the default puppetmaster, but is still not ready for prime-time.
In order to use it, you must:</p>

<ul>
<li><p>untar everything on your puppetmaster host</p></li>
<li><p>run it with <code>./hspuppetmaster /etc/puppet +RTS -N</code> (the first argument is the
location of your puppet repository) as the puppet user</p></li>
<li><p>modify your web server configuration to redirect requests for
<code>/production/catalog</code> to <code>127.0.0.1:3000</code>. This can be done in Apache by
<strong>disabling the &#8220;High Performance mode&#8221;</strong> (wasted a few hours on this one), and
adding something like that to your vhost configuration:</p></li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ProxyPass /production/catalog http://localhost:3000/production/catalog</span></code></pre></td></tr></table></div></figure>


<p>There are quite a few things it will not do (such as updating the facts in
PuppetDB), but you should experience much better catalog compilation times (I
have right now catalogs that take more than the default two minutes timeout to
compile with Puppet), sometimes much clearer error messages. As it is based on
<code>language-puppet</code>, it is generally much more strict than Puppet. For example it
will fail on any variable that cannot be resolved.</p>

<p>Please have a try and let me know how it worked for you (do use <code>--noop</code>!).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Non-strict IO surprises]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/12/18/non-strict-io-surprises/"/>
    <updated>2012-12-18T13:35:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/12/18/non-strict-io-surprises</id>
    <content type="html"><![CDATA[<p>The <code>language-puppet</code> library has been created when I started to learn Haskell. As
a consequence, it uses the dreaded <code>String</code> type to store all kind of textual
values. It also uses the <code>System.IO</code> module for performing I/O. I was aware of
the file descriptor leak problem that happens when you use <code>readFile</code>, so I
chose for the following implementation for the Puppet <code>file</code> function:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="nf">file</span> <span class="ow">::</span> <span class="p">[</span><span class="kt">String</span><span class="p">]</span> <span class="ow">-&gt;</span> <span class="kt">IO</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="kt">String</span><span class="p">)</span>
</span><span class='line'><span class="nf">file</span> <span class="kt">[]</span> <span class="ow">=</span> <span class="n">return</span> <span class="kt">Nothing</span>
</span><span class='line'><span class="nf">file</span> <span class="p">(</span><span class="n">x</span><span class="kt">:</span><span class="n">xs</span><span class="p">)</span> <span class="ow">=</span> <span class="n">catch</span> <span class="p">(</span><span class="n">fmap</span> <span class="kt">Just</span> <span class="p">(</span><span class="n">withFile</span> <span class="n">x</span> <span class="kt">ReadMode</span> <span class="n">hGetContents</span><span class="p">))</span> <span class="p">(</span><span class="nf">\</span><span class="kr">_</span> <span class="ow">-&gt;</span> <span class="n">file</span> <span class="n">xs</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>This should return <code>Just</code> the content of the first readable file in the
parameter list, or <code>Nothing</code> if there are none, and should not leak any file
descriptor. Now that I am finalizing the <code>hspuppetmaster</code> binary, I can use my
library to (try to) compute catalogs on my production systems, using the
standard <code>puppet agent -t --noop</code>. It turned out that the <code>file</code> function was
misbehaving. Testing it in GHCi illustrates the problem:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="o">&gt;</span> <span class="n">file</span> <span class="p">[</span><span class="s">&quot;/nothing&quot;</span><span class="p">]</span>
</span><span class='line'><span class="kt">Nothing</span>
</span><span class='line'><span class="o">&gt;</span> <span class="n">file</span> <span class="p">[</span><span class="s">&quot;/nothing&quot;</span><span class="p">,</span> <span class="s">&quot;/etc/hosts&quot;</span><span class="p">]</span>
</span><span class='line'><span class="kt">Just</span> <span class="s">&quot;&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>It seems to work fine, except all file contents are empty. This behavior seems
to be common knowledge among Haskellers, and is due to the fact that the file
descriptor is closed before the output is evaluated. This is pretty horrible
(and surprising), and what is even worse is my solution:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="nf">file</span> <span class="p">(</span><span class="n">x</span><span class="kt">:</span><span class="n">xs</span><span class="p">)</span> <span class="ow">=</span> <span class="n">catch</span>
</span><span class='line'>    <span class="p">(</span><span class="n">fmap</span> <span class="kt">Just</span> <span class="p">(</span><span class="n">withFile</span> <span class="n">x</span> <span class="kt">ReadMode</span> <span class="p">(</span><span class="nf">\</span><span class="n">fh</span> <span class="ow">-&gt;</span> <span class="kr">do</span>
</span><span class='line'>                                        <span class="p">{</span> <span class="n">y</span> <span class="ow">&lt;-</span> <span class="n">hGetContents</span> <span class="n">fh</span>
</span><span class='line'>                                        <span class="p">;</span> <span class="n">evaluate</span> <span class="p">(</span><span class="n">length</span> <span class="n">y</span><span class="p">)</span>
</span><span class='line'>                                        <span class="p">;</span> <span class="n">return</span> <span class="n">y</span> <span class="p">})))</span>
</span><span class='line'>    <span class="p">((</span><span class="nf">\</span><span class="kr">_</span> <span class="ow">-&gt;</span> <span class="n">file</span> <span class="n">xs</span><span class="p">)</span> <span class="ow">::</span> <span class="kt">SomeException</span> <span class="ow">-&gt;</span> <span class="kt">IO</span> <span class="p">(</span><span class="kt">Maybe</span> <span class="kt">String</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>It is a bit longer because of the use of the non-deprecated version of <code>catch</code>,
and because it explicitly forces evaluation of the output of <code>hGetContents</code>.
This behavior was extremely surprising to me, and I would like to thank the
people on <code>#haskell</code> for their help in devising a correct version (mine was
along the lines of <code>!y &lt;- hGetContents</code>, which worked for my simple examples,
but was certain to fail at some point). This is the <strong>only</strong> IRC channel I know
of where people are at the same time active, always helpful, and knowledgeable.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing whole Puppet catalogs]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/12/13/testing-whole-puppet-catalogs/"/>
    <updated>2012-12-13T19:16:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/12/13/testing-whole-puppet-catalogs</id>
    <content type="html"><![CDATA[<p>The main goal of this project is, for now, to assist sysadmins editing their catalogs. The best illustration is, for now, the <code>puppetresources</code> application. It can:</p>

<ul>
<li>Check a file syntax, and print what it <em>thinks</em> it is.</li>
<li>Compute a whole catalog and display it in human readable format or JSON.</li>
<li>Display details about a specific resource in a catalog, including special support for file contents (useful for debugging templates).</li>
<li>And do the two previous items using facts and/or queried data from a real PuppetDB.</li>
</ul>


<p>It is also fast enough to compute the catalogs of <em>all</em> your nodes in reasonable time, which opens possibilities you would not even dream of in the Ruby Puppet world. One of them is writing &#8220;integration tests&#8221; that let you check properties related to complex environmental interactions between hosts.</p>

<p>In order to facilitate this, I am in the process of writing a fully fledged testing API (it is still <a href="http://lpuppet.banquise.net/docs/language-puppet/Puppet-Testing.html#t:Test">a bit lacking</a>). It is strongly inspired by other testing APIs and should quickly evolve into something that is very easy to use. It is not the current focus (which is to replace an actual Puppet Master with my software), but I already implemented a test that is built in the <code>puppetresources</code> executable: it now checks that each <code>source</code> parameter in each <code>file</code> resources points to an actual file. This is a common error pattern to me (forgetting to create the file, mistyping its name, or placing it in the wrong directory) that has now disappeared.</p>

<p>Oh by the way, a new version is out ! Version 0.3.2 mainly changes the license, from GPL3 to BSD3. The choice was dictated by the sudden outburst of horribly uninteresting posts about licensing that has plagued Haskell-cafe during the last few hours. I hope this will end soon, or it will not be possible to differentiate this mailing list from that of Debian.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Language-puppet v0.3.1 - JSon catalogs]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/11/23/language-puppet-v0-dot-3-1-json-catalogs/"/>
    <updated>2012-11-23T13:55:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/11/23/language-puppet-v0-dot-3-1-json-catalogs</id>
    <content type="html"><![CDATA[<p>A new version is already out, this time with JSon catalogs generation. It is not
properly tested, but Puppet seems to accept them. If someone knows how to get
<code>puppet catalog apply</code> to download files from a Puppet server, I am interested.</p>

<p>I will probably write a sample application on top of WARP and modify the
configuration of my Puppetmaster to redirect catalog requests towards it. This
means that there could be an efficient replacement to the Puppetmaster soon.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Language-puppet v0.3.0 - resource relationships]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/11/19/language-puppet-v0-dot-3-0-resource-relationships/"/>
    <updated>2012-11-19T13:38:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/11/19/language-puppet-v0-dot-3-0-resource-relationships</id>
    <content type="html"><![CDATA[<p>This version introduces resource relationships handling. It is also full of
nasty bugs :) An improved version is already in the works, along with great
features.</p>

<p>First of all, you will now get notifications when a resource is missing or when
you have created cycles. There are still some bugs :</p>

<ul>
<li><p>The aliases are not taken into account.</p></li>
<li><p>The relationship metaparameters on classes are ignored.</p></li>
<li><p>With the released version, nothing is actually working. Sorry &#8230; I realized
too late how broken it was. You might want to check github, or the
<a href="http://www.banquise.net/bin/puppetresources-prof-0.4.0.tar.gz">updated binary packages</a>.</p></li>
</ul>


<p>This is the kind of error messages you will get when cycles are found :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>puppetresources: The following cycles have been found:
</span><span class='line'>  File[/a]
</span><span class='line'>       -&gt; File[/b] ["./manifests/site.pp" (line 557, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 556, column 9))
</span><span class='line'>       -&gt; File[/c] ["./manifests/site.pp" (line 558, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 557, column 9))
</span><span class='line'>       -&gt; File[/d] ["./manifests/site.pp" (line 559, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 558, column 9))
</span><span class='line'>       -&gt; File[/e] ["./manifests/site.pp" (line 560, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 559, column 9))
</span><span class='line'>       -&gt; File[/f] ["./manifests/site.pp" (line 561, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 560, column 9))
</span><span class='line'>       -&gt; File[/g] ["./manifests/site.pp" (line 562, column 9)] link is Just (RRequire,UNormal,"./manifests/site.pp" (line 561, column 9))</span></code></pre></td></tr></table></div></figure>


<p>Please note how each resource and link position is displayed. This is a lot more
verbose than what the vanilla Puppet spouts, but I believe it is also much more
useful. Chasing after links defined as a resource chain gets old very fast.</p>

<p>This is the current error message when a relationship points to (or from) an
unknown resource:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>puppetresources: Unknown relation ("file","/b") -&gt; ("file","/a") used at "./manifests/site.pp" (line 556, column 9) debug: (False,True,False,False)</span></code></pre></td></tr></table></div></figure>


<p>This one is terrible, and will need to be reworked. There is still quite a bit
of work, but I am fairly pleased at how everything seems to fold in place.</p>

<p>I started this project at the end of April, 7 months ago. The project is
incredibly useful as it is right now, and I am confident I will be able to
provide a robust and vastly more efficient puppetmaster, with a ton of helpful
tools, before the first anniversary of this project.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version 0.2.2 - Better performances and testing]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/11/12/version-0-dot-2-2-better-performances-and-testing/"/>
    <updated>2012-11-12T14:22:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/11/12/version-0-dot-2-2-better-performances-and-testing</id>
    <content type="html"><![CDATA[<p>A new version is out. Actually, a pair of versions have been released. The most
important change is an important bug with how default values worked that has
been fixed. The other visible improvements will be felt on the performance side,
as discussed in the previous <a href="http://lpuppet.banquise.net/blog/2012/11/09/performance-improvements/">entry</a>.</p>

<h2>v0.2.2</h2>

<ul>
<li>New features

<ul>
<li>A few statistics are exported.</li>
</ul>
</li>
</ul>


<h2>v0.2.1</h2>

<ul>
<li>Bugs fixed

<ul>
<li>The defaults system was pretty much broken, it should be better now.</li>
</ul>
</li>
<li>New features

<ul>
<li>Basic testing framework started.</li>
<li><code>create_resources</code> now supports the defaults system.</li>
<li><code>defined()</code> function works for resource references.</li>
<li><code>in</code> operator implemented for hashes.</li>
<li>Multithreading works.</li>
<li>The ruby &lt;> daemon communication is now over <code>ByteStrings</code>.</li>
<li>The <code>toRuby</code> function has been optimized, doubling the overall speed for
rendering complex catalogs.</li>
<li>Various internal changes.</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Performance improvements]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/11/09/performance-improvements/"/>
    <updated>2012-11-09T21:11:00+01:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/11/09/performance-improvements</id>
    <content type="html"><![CDATA[<p>One of the worst decision that was taken when designing <code>language-puppet</code> was
to use the <code>String</code> type. It is well known that this type is horribly slow. I
had a few tests to run and they were taking forever : it took about 11 seconds
to compute 5 catalogs, which is annoying when you are doing this often. As a
comparison, the puppetmaster on faster computer (it is a X5660, whereas my
workstation uses a i7 860), running the latest Puppet, takes 23 seconds to
compute those 5 catalogs sequentially.</p>

<p>A quick profiling revealed the following :</p>

<ul>
<li>The program couldn&#8217;t use more than a CPU.</li>
<li>Almost all the time was spent computing templates.</li>
</ul>


<p>I refactored the code a bit during lunch. The <code>Daemon</code> code was supposed to be
multithreaded, and has been designed as such. The only problem was that I forgot
to start several worker threads. This is now
<a href="https://github.com/bartavelle/language-puppet/commit/5870c8c21f605665b8541e6d274f3ace03c1c701">fixed</a>.</p>

<p>The template computing time was reduced by spawning several threads for this
task (see previous commit), and converting the <code>String</code> code to <code>ByteString</code>,
using builders. The time is now mostly spent in the <code>renderString</code> function,
defined as :</p>

<figure class='code'><figcaption><span>test.hs </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='hs'><span class='line'><span class="nf">renderString</span> <span class="ow">::</span> <span class="kt">String</span> <span class="ow">-&gt;</span> <span class="kt">BB</span><span class="o">.</span><span class="kt">Builder</span>
</span><span class='line'><span class="nf">renderString</span> <span class="n">x</span> <span class="ow">=</span> <span class="kr">let</span> <span class="o">!</span><span class="n">y</span> <span class="ow">=</span> <span class="kt">BB</span><span class="o">.</span><span class="n">stringUtf8</span> <span class="p">(</span><span class="n">show</span> <span class="n">x</span><span class="p">)</span> <span class="kr">in</span> <span class="n">y</span>
</span></code></pre></td></tr></table></div></figure>


<p>I went with the definition in
<a href="http://hackage.haskell.org/packages/archive/bytestring/0.10.2.0/doc/html/Data-ByteString-Builder.html">here</a>,
but it is much slower. If somebody has a better implementation, please let me
know.</p>

<p>The <code>ByteString</code> move reduced the time it took to compute the catalogs to about
6 seconds, and parallelisation reduced it to about 2 seconds. It is a 5.5x speed
upgrade for a few minutes of work, not too bad. The template generation still
takes most of the running time (50% of the time is spent spawning and waiting
for the Erb code, 20% preparing the inputs for the Ruby processes).
Nice speedups could arise from parsing more complex Ruby expressions from the
Haskell code, but it is not a priority now that the performance is acceptable.</p>

<p>You can grab the latest github repo to test it, but you will need a very recent
bytestring, and you will need to fix the cabal file for luautils.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Everything is on github]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/10/19/everything-is-on-github/"/>
    <updated>2012-10-19T22:13:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/10/19/everything-is-on-github</id>
    <content type="html"><![CDATA[<p>As the title implies:</p>

<ul>
<li><p><a href="https://github.com/bartavelle/language-puppet">language-puppet</a></p></li>
<li><p><a href="https://github.com/bartavelle/hsfacter">hsfacter</a></p></li>
<li><p><a href="https://github.com/bartavelle/puppetresources">puppetresources</a></p></li>
</ul>


<p>A tentative test framework is included. It took a few minutes of hacking, and
now the <code>puppetresources</code> application checks that file sources are valid. It
doesn&#8217;t work for &#8220;private&#8221; stuff.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version 2.0.0 - The Lua integration]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/10/10/version-0-dot-2-0-the-lua-integration/"/>
    <updated>2012-10-10T19:50:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/10/10/version-0-dot-2-0-the-lua-integration</id>
    <content type="html"><![CDATA[<p>Quick note on versionning. The official version number is 0.2.0, but I have
been omitting the first zero on this blog. Anyway, this version includes two
features, one of them built on the
<a href="http://hackage.haskell.org/package/hslua">hslua</a> library.</p>

<p>A huge bug was fixed: defaults finishing with a comma were interpreted as a
function working on a hash! For example:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">File</span> <span class="p">{</span> <span class="nt">owner</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Was seen as:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nf">file</span><span class="p">({</span> <span class="s1">&#39;owner&#39;</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span> <span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Custom functions</h2>

<p>Testing custom functions was almost impossible until now, as they required being
compiled with the library to be used. It is now possible to include lua
implementations of your functions alongside the ruby version.</p>

<p>It is a bit harder to write than the ruby versions as it can&#8217;t (for now) access
anything from the &#8220;Puppet&#8221; side, such as facts, and you have to put up with the
Lua syntax.</p>

<p>The other caveat is that it is stored right next to the ruby function right now,
and Puppet tries to interpret it (and find syntax errors in it), so it isn&#8217;t
very clean. I will move it for the next version, and will rewrite a few
functions from Puppetlabs stdlib too.</p>

<p>From the implementation point of view, the difficult part was the fact that
there were no instance for <code>Data.Map</code>. I wrote it and it is now part of the
<a href="http://hackage.haskell.org/package/luautils">luautils</a> package.</p>

<h2>Custom types</h2>

<p>As there was all the infrastructure to find files into subfolders, I also added
a very weak custom type system. It will detect the file names in the usual
places and will know these are valid Puppet types. It doesn&#8217;t perform any
additional checks for now.</p>

<p>I might add a lua functionnality for fine grained verifications.</p>

<h2>What&#8217;s next</h2>

<p>The fabled dependency handling is not coming soon, but there is a few things
that are already implemented and will be released next time:</p>

<ul>
<li><p>Support for the <code>defined</code> function. Just like the real thing it is parse order
dependant.</p></li>
<li><p>the <code>create_resources</code> function now accepts the third parameter (default
(values).</p></li>
<li><p>The <code>in</code> operator now works with hashes. I am not sure why the Puppet stdlib
implements <code>has_key</code> &#8230;</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Types used in the interpretation stage]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/10/08/types-used-in-the-interpretation-stage/"/>
    <updated>2012-10-08T21:43:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/10/08/types-used-in-the-interpretation-stage</id>
    <content type="html"><![CDATA[<p>In order to celebrate the entry of this blog into <a href="http://planet.haskell.org/">planet haskell</a>,
I will talk a bit about the implementation of the interpretation stage of the
program. I also ripped the eggplant color from the puppetlabs.com site.</p>

<h2>Module structure</h2>

<p>The whole interpretation process could be separated in the following parts
(fitting the modules hierarchy):</p>

<ul>
<li><p>The parser. This is an ugly part, is it is the first part I wrote when I had
no clue about monads, applicative functors, or that the do notation was just
syntactic sugar.</p></li>
<li><p>The interpreter, which will be discussed here. It is also an ugly part, but
for other reasons.</p></li>
<li><p>The &#8220;daemon&#8221;, which is a piece of code that glues everything together and
provides a simple API for using them. It should scale on multiple cores too, but
this hasn&#8217;t been tested yet.</p></li>
<li><p>The PuppetDB communication facilities, that need to be reworked.</p></li>
<li><p>The native types support, with checks about the consistency of their
parameters.</p></li>
<li><p>The plugin system, which currently handles user defined functions and types.</p></li>
</ul>


<h2>The catalog monad</h2>

<p>Most functions in the catalog monad are of type
<a href="http://lpuppet.banquise.net/docs/language-puppet/Puppet-Interpreter-Types.html#t:CatalogMonad">CatalogMonad</a>,
which is just an error/state monad over IO :</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='haskell'><span class='line'><span class="kr">type</span> <span class="kt">CatalogMonad</span> <span class="ow">=</span> <span class="kt">ErrorT</span> <span class="kt">String</span> <span class="p">(</span><span class="kt">StateT</span> <span class="kt">ScopeState</span> <span class="kt">IO</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>The fact that IO is needed is unfortunate, but cannot really be avoided, as
templates are computed and PuppetDB is queried during catalog evaluation. It
would have been possible to return partially evaluated catalogs to an outer
function that lives in IO and that would be responsible with handling this, but
I thought it would just make things complicated.</p>

<p>Template computation is another matter. It is theorically possible to run it as
a pure function (if you accept to only use a subset of the Ruby language), but
it would require a full fledged Ruby interpreter. This is not an option here,
and templates are computed by spawning a Ruby process every time. Now that a LUA
interpreter is embarked, it would be possible to write lua versions of the
templates and have them interpreted in the same process.</p>

<h2>Achieving position independency with a single pass</h2>

<p>The catalog computing function basically goes through the AST (following
includes and defines) and tries to resolve everything it processes. The problem
is that the Puppet language is supposed to be referentially transparent,
especially according to the the <a href="http://docs.puppetlabs.com/guides/language_guide.html">language guide</a>,
which was the only documentation for quite a long time.</p>

<blockquote><p>Puppet language is a declarative language, which means that its scoping and<br/>assignment rules are somewhat different than a normal imperative language. The<br/>primary difference is that you cannot change the value of a variable within a<br/>single scope, because that would rely on order in the file to determine the<br/>value of the variable. Order does not matter in a declarative language.</p><footer><strong>The language guide</strong> <cite><a href='http://docs.puppetlabs.com/guides/language_guide.html#variables'>docs.puppetlabs.com/guides/&hellip;</a></cite></footer></blockquote>


<p>Reading this, I presumed that the position of a variable assignment, like
everything else, did not matter. It turns out it
<a href="http://docs.puppetlabs.com/puppet/2.7/reference/lang_variables.html#parse-order-dependence">does</a>,
but it is now a bit late to correct this.</p>

<p>In order to satisfy this false assumption, all data and resource types exist in
two flavors. For example, with values we have <a href="http://lpuppet.banquise.net/docs/language-puppet/Puppet-DSL-Types.html#t:Value">Value</a>
and <a href="http://lpuppet.banquise.net/docs/language-puppet/Puppet-Interpreter-Types.html#t:ResolvedValue">ResolvedValue</a>.
It would be a good idea to remove all this cruft right now, but I am not in a
hurry to touch it, as it represents quite a bit of code and seems to work
alright for now.</p>

<p>It presents several challenges, as values are supposed to be transformable
into their resolved counterpart at any time, but many things are context
dependant (such as variable scoping, local variable presence, variables in
defines, etc.). It also doesn&#8217;t work at all (just like with Puppet) with control
structures or templates that rely on not-yet-defined values.</p>

<p>If somebody knows what the &#8220;proper&#8221; way to do this is, I would be quite
interested. I am almost certain this exists as it seems related to writing fast
compilers, which is a subject that has certainly been explored by smart people.</p>

<h2>Room for extension</h2>

<p>Finally, the most important type, besides that of the state, is the type of the
main function <a href="http://lpuppet.banquise.net/docs/language-puppet/Puppet-Interpreter-Catalog.html">getCatalog</a>.
One can notice there are quite a few functions that must be passed along. The
reason is that it should be possible to swap backends easily. An example that
might be written shortly would be to give two implementations for the puppetDB
function:</p>

<ul>
<li><p>A generalization of the current version, that queries a real puppetDB.</p></li>
<li><p>An emulated puppetDB that is populated with other runs.</p></li>
</ul>


<p>This would need passing around more functions (a function to query arbitrary
values to start with, and a function to store the exported resources), but would
be immensely useful. It would make it possible to write test suites that cover
the whole node list, including exported resources between hosts.</p>

<p>Now that would be pretty cool, right ?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Custom functions and language-puppet]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/10/01/custom-functions-and-language-puppet/"/>
    <updated>2012-10-01T13:16:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/10/01/custom-functions-and-language-puppet</id>
    <content type="html"><![CDATA[<p>For now using custom functions, such as those from the
<a href="https://github.com/puppetlabs/puppetlabs-stdlib">puppetlabs-stdlib</a>,
required that they were implemented in language-puppet. I do not believe there
are a lot of users, and received no complaints. But this might change, and I do
not want the current situation to go on :</p>

<ul>
<li><p>New users will need to meddle with the source code to add their own functions.</p></li>
<li><p>These functions will ne be easy to distribute.</p></li>
<li><p>Everybody will have access to the custom functions used in the manifests I
work with.</p></li>
</ul>


<p>In order to make things a bit better, I used the Lua module in Haskell to
provide a small scripting language for people to use. It might have been easier
for them  to just add a full ruby interpreter, but that would have been against
my convictions and is probably pretty difficult. Note that this is not yet
released.</p>

<p>Now that this is done, it might be possible to add custom types in the same way,
as well as one of the lua templating systems. This will make it possible to get
rid of the ruby dependency and largely increase the performances.</p>

<p>In the next few posts I will describe some of the inner workings of this module
and implementation samples.</p>

<p>By the way, there are now links for the <a href="http://lpuppet.banquise.net/docs">documentation</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Binary distribution]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/09/25/binary-distribution/"/>
    <updated>2012-09-25T09:59:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/09/25/binary-distribution</id>
    <content type="html"><![CDATA[<p>You can now get a compiled version of <code>puppetresources</code> on the <a href="http://lpuppet.banquise.net/download">Download</a> page.</p>

<p>It is not as cool as the compiled version because you lack the interactive features, but is still pretty powerfull and much easier to setup.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version 1.8.0 - exciting features !]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/09/20/version-1-dot-8-0-exciting-features/"/>
    <updated>2012-09-20T19:44:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/09/20/version-1-dot-8-0-exciting-features</id>
    <content type="html"><![CDATA[<p>Version 1.8.0 is out, and breaks the existing API. On the other hand, it is now
very well integrated with PuppetDB ! The following new features are now
available :</p>

<ul>
<li>Facts can be retrieved from PuppetDB.</li>
<li>Exported resources can also be retrieved from PuppetDB.</li>
<li>The resource query function from <a href="https://github.com/dalen/puppet-puppetdbquery">this</a>
module has been implemented.</li>
</ul>


<p>This means you can now test all your higher order Puppet recipes. A typical
use case is for the configuration of proxy servers. It gets really easy to
declare something like this on a host:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>@@backend { $::hostname:
</span><span class='line'>    port =&gt; 1234,
</span><span class='line'>    type =&gt; 'static_content',
</span><span class='line'>    tag  =&gt; 'productionproxy';
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Then you can get them in a hash with :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$h = pdbresourcequery(
</span><span class='line'>        ['and',
</span><span class='line'>            ['=', ['node','active'], true],
</span><span class='line'>            ['=', 'type', 'Backend']]
</span><span class='line'>        , 'parameters')</span></code></pre></td></tr></table></div></figure>


<p>And use it in a template with :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;%
</span><span class='line'>scope.lookupvar('myclass::h').sort.each ...
</span><span class='line'>%&gt;</span></code></pre></td></tr></table></div></figure>


<p>This is the kind of things that drives people to Puppet. On the other hand, it
quickly gets tricky to test. How are you supposed to check that your template
will look the way you expect it to ?</p>

<p>Previously I used to just hardcode the result of the <code>pdbresourcequery</code> function
during the testing phase, and use <code>puppetresources</code> to look at the rendered
template. Now with PuppetDB integration you get the <em>actual</em> facts and exported
resources that Puppet will use when computing a catalog.</p>

<p>So how do you use it ? It requires having access to a clear text HTTP port that
answers PuppetDB queries. Typically, you will want to use a SSH tunnel if you
test on your workstation, just like that:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ssh -L 8080:localhost:8080 your.puppet.master</span></code></pre></td></tr></table></div></figure>


<p>Once this is done, you have the following options, depending on how you use the
language-puppet library :</p>

<ul>
<li>With <code>puppetresources</code>, start with the new <code>-r</code> switch, like this :</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ puppetresources -r http://localhost:8080 ./puppet/ node.test</span></code></pre></td></tr></table></div></figure>


<ul>
<li>With the <code>puppetresources</code> in interactive mode, initialize the Daemon with the
<code>initializedaemonWithPuppet</code> function, like this :</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&gt; queryfunc &lt;- initializedaemonWithPuppet (Just "http://localhost:8080") "./puppet/"</span></code></pre></td></tr></table></div></figure>


<ul>
<li>With the <code>Daemon</code> API, modify the <code>Prefs</code> records so as to add the correct
URL:</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>let prefs = genPrefs "./puppet/"
</span><span class='line'>queryfunc &lt;- initDaemon (prefs { puppetDBurl = Just "http://localhost:8080" })</span></code></pre></td></tr></table></div></figure>


<p>If you wish to use the lower level APIs, you might want to check the new
PuppetDB modules (unfortunately hackage doesn&#8217;t seem to generate documentation
at the moment so I can&#8217;t link it). You might use the built-in PuppetDB query
function, use your own or just mock their output.</p>

<p>There are probably bugs, and the URL to access to <code>pdbresourcequery</code> is
currently hardcoded (won&#8217;t take long to makes it right), but this is a major
milestone for this project.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version 1.7.2, with more PuppetDB]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/09/17/version-1-dot-7-2-and-puppetdb/"/>
    <updated>2012-09-17T19:18:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/09/17/version-1-dot-7-2-and-puppetdb</id>
    <content type="html"><![CDATA[<p>A new maintenance version is out. The long awaited resource relationship update
will still have to wait, but there are exciting promises in this upgrade, such
as the early PuppetDB support. I will blog later about it, but this will rock.</p>

<p>First of all, quite a few bugs were fixed since 1.7.0, and a few nice features
have been added. A lot of minor enhancements have been added now that the
official language documentation is published. The behaviour of the library
should now more closely match that of Puppet. The problem is that there is a
huge difference in behaviour that might bite you.</p>

<p>When I started this project, all that was available was the language tutorial
and the Puppet source code. As I explained already, I find it less troublesome
to just rewrite it from scratch than to try to follow Ruby code. I recently
wrote a pair of resource providers, so I can attest this still holds true. It
seemed to me at that time that the various statements could be inserted at any
place in a manifest and without changing its meaning.</p>

<p>Some effects would be undefined obviously (putting two conflicting defaults in
the same class for example), but everything seemed doable with little effort.
One of the early design decisions was to support this feature fully, except in
conditionnals where I couldn&#8217;t see how to handle them efficiently.</p>

<p>The cost of this decision is that all data types have been doubled : one version
for the &#8220;raw&#8221; or &#8220;unresolved&#8221; version, and one version for the &#8220;final&#8221; or
&#8220;resolved&#8221; version. Everytime a statement is interpreted, it might be left in an
unresolved state, which leads to all kind of performance and logic problems (for
example, when you can&#8217;t resolve a variable you have to store some pointer to its
scope to resolve it later).</p>

<p>It turns out that this was not needed to be Puppet-perfect, as Puppet doesn&#8217;t
even attempt to do this for variable assignements. This means that every data
types could be fully resolved when first found.</p>

<p>This means that the following code fragment will work as you might expect in
language-puppet, but not in Puppet:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>file { $filename: ensure =&gt; present; }
</span><span class='line'>$filename = 'foo'</span></code></pre></td></tr></table></div></figure>


<p>And while language-puppet is <em>much</em> faster than Puppet, despite spawning a ruby
process for (almost) every template evaluation, it could have been even more.
Also the internals would be much cleaner &#8230;</p>

<p>Anyway, here goes the changelog:</p>

<p><em>New features</em></p>

<ul>
<li>Amending attributes with a collector.</li>
<li>Stdlib functions : chomp</li>
<li>Resource pretty printer now aligns =>.</li>
<li>Case statements with regexps.</li>
</ul>


<p><em>Bugs fixed</em></p>

<ul>
<li>Various details have been modified since the official language documentation
has been published.</li>
<li>Better handling of collector conditions.</li>
<li>Solves bug with interpolable strings that are not resolved when first found.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version 0.1.7 is out]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/08/24/version-0-dot-1-7-is-out/"/>
    <updated>2012-08-24T21:30:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/08/24/version-0-dot-1-7-is-out</id>
    <content type="html"><![CDATA[<p>The promised work on relationships hasn&#8217;t been done, only minor bugfixes for
this release. The main difference with the previous version is that some
resource types are now better validated. This is not Puppet-perfect, but it
should catch a few bugs.</p>

<p><em>New features</em></p>

<ul>
<li>Fix bug with &#8216;&lt;&#8217; in the Erb parser !</li>
<li>Assignments can now be any valid Puppet expression.</li>
<li>Proper list of metaparameters.</li>
</ul>


<p><em>Bugs fixed</em></p>

<ul>
<li>Quick resolution of boolean conditions.</li>
<li>Start of the move to a real PCRE library.</li>
<li>Function is_domain_name.</li>
<li>New native types : file, zone_record, cron, exec, group, host, mount.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Migrating machines between puppetmasters]]></title>
    <link href="http://lpuppet.banquise.net/blog/2012/08/07/migrating-machines-between-puppetmasters/"/>
    <updated>2012-08-07T21:03:00+02:00</updated>
    <id>http://lpuppet.banquise.net/blog/2012/08/07/migrating-machines-between-puppetmasters</id>
    <content type="html"><![CDATA[<p>I am currently in the process of migrating machines to a new puppetmaster setup.
This is something that also might happen to you, especially when you would like
to start with fresh, clean, manifests.</p>

<p>In order to facilitate this process, you can use the diffing feature of the
<code>puppetresources</code> program. The following lines describe a typical session, where
one would like to check that the set of resources described in the old catalogs
for host <code>oldhost</code> somehow match that of <code>newhost</code>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ghci Main.hs
</span><span class='line'>
</span><span class='line'>&gt; queryold &lt;- initializedaemon "/path/to/old/manifests"
</span><span class='line'>&gt; querynew &lt;- initializedaemon "/path/to/new/manifests"
</span><span class='line'>&gt; oldcatalog &lt;- queryold "oldhost.domain"
</span><span class='line'>&gt; querynew "newhost.domain" &gt;&gt;= diff oldcatalog
</span><span class='line'>...
</span><span class='line'>&gt; querynew "newhost.domain" &gt;&gt;= diff oldcatalog
</span><span class='line'>...
</span><span class='line'>&gt; querynew "newhost.domain" &gt;&gt;= diff oldcatalog
</span><span class='line'>...
</span><span class='line'>&gt; querynew "newhost.domain" &gt;&gt;= diff oldcatalog
</span><span class='line'>...</span></code></pre></td></tr></table></div></figure>


<p>Note that there will almost always be a difference, as the list of classes is,
for now, part of the catalog. On the other hand, the relationships between
resources will not be checked as it is not (yet) handled by the tool.</p>
]]></content>
  </entry>
  
</feed>
