<?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>BlogCompiler</title>
	<atom:link href="http://www.blogcompiler.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blogcompiler.com</link>
	<description>{collecting solutions}</description>
	<lastBuildDate>Thu, 11 Oct 2012 01:53:45 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Scalability of CFEngine 3.3.5 and Puppet 2.7.19</title>
		<link>http://www.blogcompiler.com/2012/09/30/scalability-of-cfengine-and-puppet-2/</link>
		<comments>http://www.blogcompiler.com/2012/09/30/scalability-of-cfengine-and-puppet-2/#comments</comments>
		<pubDate>Sun, 30 Sep 2012 19:22:21 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=522</guid>
		<description><![CDATA[Introduction CFEngine and Puppet are configuration management tools that can help you automate IT infrastructure. Practical examples include adding local users, installing Apache, and making sure password-based authentication in sshd is turned off. The more servers and complexity you have, &#8230; <a href="http://www.blogcompiler.com/2012/09/30/scalability-of-cfengine-and-puppet-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a title="CFEngine" href="http://www.cfengine.com">CFEngine</a> and <a title="Puppet Labs" href="http://puppetlabs.com/">Puppet</a> are configuration management tools that can help you automate IT infrastructure. Practical examples include adding local users, installing Apache, and making sure password-based authentication in sshd is turned off. The more servers and complexity you have, the more interesting such a solution becomes for you.</p>
<p>In this test, we set out to explore the performance of the tools as the environment scales, both in terms of nodes and policy/manifest size. Amazon EC2 is used to easily increase the size of the environment. This test is primarily a response to the comments in <a title="Older scalability test of CFEngine and Puppet" href="http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/">this older test</a>.</p>
<p>I want to start with a few disclaimers:</p>
<ul>
<li>I am affiliated with CFEngine (the company), and so it is extremely important for me to provide all the details so the test procedure and results can be scrutinized and reproduced. I would love for some of you to create independent and alternative tests.</li>
<li>The exact numbers in this test do probably not map directly to your environment, as everybody&#8217;s environment is a little different (especially in hardware, node count, policy/manifest). The goal is therefore to identify trends and degree of differences, not so much exact numbers.</li>
</ul>
<h2>Test setup</h2>
<p>Instance types:</p>
<ul>
<li>t1.micro: 2 ECUs, 1 core, 615 MB memory  &#8212; for CFEngine client / Puppet node</li>
<li>m1.xlarge: 8 ECUs, 4 cores, 15 GB memory &#8212; for CFEngine policy server / Puppet master</li>
</ul>
<p>Operating system</p>
<ul>
<li>Ubuntu 12.04 64-bit (all hosts).</li>
</ul>
<p>Software versions</p>
<ul>
<li>CFEngine 3.3.5 (package from the <a title="CFEngine packages" href="https://cfengine.com/inside/myspace">CFEngine web site</a>)</li>
<li>Puppet 2.7.19 (using apt-get with http://apt.puppetlabs.com)</li>
</ul>
<p>For simplicity, all ports were left open during the tests (the &#8220;Everything&#8221; security group by Amazon was used).</p>
<p>Both tools were set to run every 5 minutes.</p>
<h2>Test procedure</h2>
<p>The policy server/puppet master were set up manually first, as described in detail below. For test efficiency reasons, they were set to accept new clients automatically (trusting all keys or autosigning).</p>
<p>Clients were added in steps of 50, up to 300 every 15 minutes (there wasn&#8217;t enough time to go higher). The manifest/policy was changed twice during the test, to see what impact this had. These were the exact steps taken:</p>
<table>
<tbody>
<tr>
<th>Time</th>
<th>Client count</th>
<th>Policy/manifest</th>
</tr>
<tr>
<td>0:00</td>
<td>50</td>
<td>Apache</td>
</tr>
<tr>
<td>0:15</td>
<td>100</td>
<td>Apache</td>
</tr>
<tr>
<td>0:30</td>
<td>150</td>
<td>Apache</td>
</tr>
<tr>
<td>0:45</td>
<td>200</td>
<td>Apache</td>
</tr>
<tr>
<td>1:00</td>
<td>200</td>
<td>Apache, 100 echo commands</td>
</tr>
<tr>
<td>1:15</td>
<td>250</td>
<td>Apache, 100 echo commands</td>
</tr>
<tr>
<td>1:30</td>
<td>250</td>
<td>Apache, 200 echo commands</td>
</tr>
<tr>
<td>1:45</td>
<td>300</td>
<td>Apache, 200 echo commands</td>
</tr>
</tbody>
</table>
<p>CPU usage at the policy server/master was measured with Amazon CloudWatch. Client run-time was measured by picking a random client and invoking a manual run of each tool in the <code>time</code> utility. Each run-time was measured three times and the average was taken.</p>
<p>The policy/manifest was changed twice, by adding 100 echo commands each time (run /bin/echo 1, /bin/echo 2,&#8230; /bin/echo 100) to see how the tools handled a simple increase in work-size.</p>
<h2>Setting up the CFEngine policy server</h2>
<p>The Ubuntu 12.04 package was found and downloaded at <a title="CFEngine packages" href="https://cfengine.com/inside/myspace">the CFEngine web site</a>. In order to save time and money, this package was uploaded to the Amazon S3 for the clients to download (internal Amazon communication is free on EC2). Note that I could have used the <a title="CFEngine apt repository" href="http://cfengine.com/pub/apt/">CFEngine apt repository</a>, but since CFEngine is just one package I chose to install it directly with dpkg. The following steps were carried out:</p>
<ol>
<li>wget https://s3.amazonaws.com/my-amazon-s3-bucket/cfengine-community_3.3.5_amd64.deb</li>
<li>dpkg -i cfengine-community_3.3.5_amd64.deb</li>
<li>Install <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/cfengine-config.tar.gz">the policy</a> to /var/cfengine/masterfiles</li>
<li>/var/cfengine/bin/cf-agent &#8211;bootstrap &#8211;policy-server 10.4.67.126</li>
</ol>
<p>The policy contains three promises.cf files, as described in the test procedure above (one for Apache-only, one for Apache and 100 echo commands, one for Apache and 200 echo commands).</p>
<p>The installation size was 7.8 MB (1 package).</p>
<h2>Adding CFEngine nodes</h2>
<p>The following steps were carried out to bootstrap a CFEngine node to the policy server.</p>
<ol>
<li>wget https://s3.amazonaws.com/my-amazon-s3-bucket/cfengine-community_3.3.5_amd64.deb</li>
<li>dpkg -i cfengine-community_3.3.5_amd64.deb</li>
<li>/var/cfengine/bin/cf-agent &#8211;bootstrap &#8211;policy-server 10.4.67.126</li>
</ol>
<p>A Amazon <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/user-data-cfengine-ubuntu124.gz">user-data script</a> was created and used to bootstrap new nodes. The installation size was 7.8 MB (1 package). The exact command used to create new instances was the following:</p>
<p># ec2-run-instances ami-137bcf7a -key amazon-key &#8211;user-data-file ./user-data-cfengine-ubuntu124 &#8211;instance-type t1.micro &#8211;instance-count 50 &#8211;group sg-52f5103a -availability-zone us-east-1d</p>
<h2>Setting up the Puppet master</h2>
<p>It is important to note that the default Puppet master configuration is not production ready according to <a href="http://docs.puppetlabs.com/guides/installation.html#post-install">the documentation</a>: &#8220;The default web server is simpler to configure and better for testing, but <strong>cannot</strong> support real-life workloads&#8221;.</p>
<p>The main reason for this is that Ruby does not support multi-threading, so puppetmasterd can only handle one connection at the time. This would limit the scale to just tens of clients, which is too low for our purposes.</p>
<p>The recommended way to get around this is to create an <code>Apache</code> proxy balancer with the <code>passenger</code> extension that receives all connections and hands them over Puppet. There are some documents that describe this for <a title="Puppet and Mongrel on Red Hat" href="http://projects.puppetlabs.com/projects/1/wiki/Using_Mongrel_On_Enterprise_Linux">Red Hat</a> and <a title="Puppet and Mongrel on Debian" href="http://projects.puppetlabs.com/projects/puppet/wiki/Using_Mongrel_On_Debian">Debian</a>. The configuration is quite complex, so I used a Ubuntu 12.04, which supports a package that contains the necessary configuration.</p>
<p>These steps were taken to install and set up the Puppet master with passenger:</p>
<ol>
<li>#  wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb</li>
<li># dpkg -i puppetlabs-release-precise.deb</li>
<li># apt-get update</li>
<li># echo &#8220;10.4.217.221      puppet&#8221;  &gt;&gt; /etc/hosts</li>
<li># apt-get install puppetmaster-passenger</li>
<li>Install <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/puppet-config.tar.gz">the manifest</a> to /etc/puppet.</li>
</ol>
<p>The manifest contains three site.pp files, as described in the test procedure above (one for Apache-only, one for Apache and 100 echo commands, one for Apache and 200 echo commands).</p>
<p>The installation size was 55 packages, 135 MB.</p>
<h2>Adding Puppet nodes</h2>
<p>The following steps were carried out to add a puppet node to the master.</p>
<ol>
<li>wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb</li>
<li>dpkg -i puppetlabs-release-precise.deb</li>
<li>apt-get update</li>
<li>apt-get &#8211;assume-yes install puppet</li>
<li>echo &#8220;10.4.217.221      puppet&#8221;  &gt;&gt; /etc/hosts</li>
<li>puppet agent &#8211;verbose &#8211;onetime &#8211;no-daemonize &#8211;waitforcert 120</li>
<li>echo &#8220;START=yes<br />
DAEMON_OPTS=\&#8221;\&#8221;"  &gt; /etc/default/puppet</li>
<li>echo &#8220;[main]<br />
logdir=/var/log/puppet<br />
vardir=/var/lib/puppet<br />
ssldir=/var/lib/puppet/ssl<br />
rundir=/var/run/puppet<br />
factpath=$vardir/lib/facter<br />
templatedir=$confdir/templates<br />
runinterval=300<br />
splay=true[master]<br />
# These are needed when the puppetmaster is run by passenger<br />
# and can safely be removed if webrick is used.<br />
ssl_client_header = SSL_CLIENT_S_DN<br />
ssl_client_verify_header = SSL_CLIENT_VERIFY<br />
&#8221; &gt; /etc/puppet/puppet.conf</li>
<li>/etc/init.d/puppet start</li>
</ol>
<p>This was all incorporated into a <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/user-data-puppet-ubuntu124.gz">script</a>, which was run with Amazon user-data (at boot) to quickly deploy new clients. The installation size was 11.9 MB, 14 packages.</p>
<p>The exact command line used was this:</p>
<p># ec2-run-instances ami-137bcf7a -key amazon-key &#8211;user-data-file ./user-data-puppet-ubuntu124 &#8211;instance-type t1.micro &#8211;instance-count 50 &#8211;group sg-52f5103a -availability-zone us-east-1d</p>
<h2> Results</h2>
<h3>Server-side CPU usage</h3>
<p>These graphs were taken directly from Amazon CloudWatch at the master/server instance.</p>
<figure id="attachment_557" aria-labelledby="figcaption_attachment_557" class="wp-caption aligncenter" style="width: 764px"><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/cpu-sum-annotate2.png"><img class="size-full wp-image-557" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/cpu-sum-annotate2.png" alt="CFEngine policy server CPU usage" width="754" height="363" /></a><figcaption id="figcaption_attachment_557" class="wp-caption-text">CFEngine policy server CPU usage</figcaption></figure>
<figure id="attachment_558" aria-labelledby="figcaption_attachment_558" class="wp-caption aligncenter" style="width: 673px"><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/cpu-sum-annotate3.png"><img class=" wp-image-558 " src="http://www.blogcompiler.com/wp-content/uploads/2012/09/cpu-sum-annotate3.png" alt="Puppet master CPU usage" width="663" height="318" /></a><figcaption id="figcaption_attachment_558" class="wp-caption-text">Puppet master CPU usage</figcaption></figure>
<p>From the graphs, we can see that the Puppet master instance uses about <strong>10 times as much CPU</strong> at 50 clients. At 300 clients with 200 echo commands, the Puppet master uses about <strong>18 times as much CPU</strong>.</p>
<p>The most interesting points, though, are not when we increase the client count, but increase client work in the policy/manifest.</p>
<p>This happens where we add 100 extra echo commands and the following 15 minutes when they are run. These areas are indicated by red lines in both graphs:</p>
<ul>
<li>200 clients, 100 echo commands (until we go to 250 clients)</li>
<li>250 clients, 200 echo commands (until we go to 300 clients)</li>
</ul>
<p>The reason this is more interesting is that users will probably extend the policy/manifest more frequently than add nodes. How does changing the policy/manifest impact the <strong>server</strong>?</p>
<p>We can clearly see that the Puppet master is heavily impacted by changing the manifest, while the CFEngine policy server seems unaffected by the changes (the load increase at the red lines).</p>
<h3>Client-side execution time</h3>
<p>The data for the client execution time was captured with three runs of <code>time /var/cfengine/bin/cf-agent -K</code> and <code>time puppet apply --onetime --no-daemonize</code>, respectively. The resulting data-files for <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-cfengine.gz">CFEngine</a> and <a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-puppet-passenger.gz">Puppet</a> are also provided. If we calculate averages, the graph for comparing will look like the following (<a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-results.ods">the ods file is available here</a>).</p>
<p><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-compared.png"><img class="aligncenter size-full wp-image-549" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-compared.png" alt="" width="536" height="424" /></a></p>
<p>At 50 hosts with just the Apache configuration, CFEngine agents run <strong>20 times faster</strong> than Puppet agents. At 300 hosts, with 200 echo commands, CFEngine agents run <strong>166 times faster</strong> than Puppet agents.</p>
<p>Note that some spikes at 200c,100e and 250c,200e are to be expected since we added 100 more echo commands in the policy/manifest at these points. At 100c,a the Puppet agent had one very long run (as shown in the data files), which caused a spike there for Puppet.</p>
<p><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-cfengine.png"><img class="aligncenter size-full wp-image-550" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-cfengine.png" alt="" width="482" height="372" /></a><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-puppet.png"><img class="aligncenter size-full wp-image-551" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/client-execution-puppet.png" alt="" width="453" height="380" /></a></p>
<p>The individual charts compare each tool to itself more easily &#8212; does the client execution time increase much when only the number of nodes increases?</p>
<p>For completeness, the client execution results are provided in tabular form below.</p>
<table>
<tbody>
<tr>
<th>Environment</th>
<th>CFEngine time (seconds)</th>
<th>Puppet time (seconds)</th>
</tr>
</tbody>
<tbody>
<tr>
<td>50c,a</td>
<td>0.172</td>
<td>3.427</td>
</tr>
<tr>
<td>100c,a</td>
<td>0.173</td>
<td>19.24</td>
</tr>
<tr>
<td>150c,a</td>
<td>0.172</td>
<td>3.63</td>
</tr>
<tr>
<td>200c,a</td>
<td>0.178</td>
<td>3.63</td>
</tr>
<tr>
<td>200c,100e</td>
<td>0.481</td>
<td>22.408</td>
</tr>
<tr>
<td>250c,100e</td>
<td>0.459</td>
<td>32.56</td>
</tr>
<tr>
<td>250c,200e</td>
<td>0.742</td>
<td>106.4</td>
</tr>
<tr>
<td>300c,200e</td>
<td>0.732</td>
<td>121.86</td>
</tr>
</tbody>
</table>
<h2>Final remarks</h2>
<p>It is clear that CFEngine is much more efficient and vertically scalable than Puppet. This is probably due to two items:</p>
<ul>
<li>Puppet&#8217;s architecture is heavily centralised, the Puppet master does a lot of work for every client &#8211; especially with cataloge compilation. In contrast, CFEngine agents will interpret the policy in a distributed fashion. The CFEngine policy server is just a file server.</li>
<li>Puppet runs under the Ruby interpreter, which is far less efficient than running natively on the operating system.</li>
</ul>
<p>The most interesting observation, I think, is that the Puppet master and agent performance were heavily influenced by the <strong>manifest complexity</strong>. When the manifest is small, increasing the agent count did not have much impact on the agent performance. However, as the manifest grew, the performance of all the agents (and the master) degraded significantly. It is also evident that as the master gets more loaded, <strong>all the Puppet agents run slower</strong>. This can also probably be attributed to the heavily centralised architecture of Puppet.</p>
<p>It would be interesting to create a more real-world policy/manifest to explore this further. The manifest in this test did not have much dependencies, and so the Puppet resource dependency graph was quite simple. If the dependency graph was more realistic &#8211; would that have had impact on the test results?</p>
<p>This post was primarily created due to feedback gotten from <a title="Older scalability test of CFEngine and Puppet" href="http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/">an older post</a> on the same matter. Please don&#8217;t hesitate to add your comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2012/09/30/scalability-of-cfengine-and-puppet-2/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Scalability of CFEngine and Puppet</title>
		<link>http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/</link>
		<comments>http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/#comments</comments>
		<pubDate>Sat, 15 Sep 2012 18:02:38 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[scalability]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=504</guid>
		<description><![CDATA[UPDATE: Please see this updated post instead. NOTE: These tests were carried out in the beginning of 2011, with the newest stable versions of CFEngine and Puppet back then (CFEngine web site and Suse Linux repository, respectively). New versions of &#8230; <a href="http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>UPDATE: Please see this <a href="http://www.blogcompiler.com/2012/09/30/scalability-of-cfengine-and-puppet-2/">updated post</a> instead.</p>
<p>NOTE: These tests were carried out in the beginning of 2011, with the newest stable versions of CFEngine and Puppet back then (CFEngine web site and Suse Linux repository, respectively). New versions of both solutions have been released since.</p>
<h2>Introduction</h2>
<p><a title="CFEngine" href="http://www.cfengine.com">CFEngine</a> and <a title="Puppet Labs" href="http://puppetlabs.com/">Puppet</a> are configuration management solutions that can help you automate IT infrastructure. Practical examples include adding local users, installing Apache, and making sure password-based authentication in sshd is turned off. The more servers and complexity you have, the more interesting such a solution becomes for you.</p>
<p>The companies and communities behind CFEngine and Puppet frequently make claims that their solution &#8220;is scalable&#8221;. They point to some users managing hundreds, thousands, even tens of thousands of servers with the tools. But what does all this mean? Is CFEngine and Puppet indistinguishable with respect to scalability?</p>
<p>In this post, we will highlight one aspect of scalability: how many clients a server can handle. As always, to find useful answers, we should do measurements &#8212; and stop listening to the marketing departments.</p>
<p>&nbsp;</p>
<h2>Test setup</h2>
<p>Amazon EC2 is used to measure performance at the server while the number of clients is being increased in steps every 30 minutes. We start up with 25 clients, then go to 50, 100, 200, 400.</p>
<p>CPU usage at the central server and client execution time is being measured. The Amazon CludWatch system is being used to monitor resource usage.</p>
<p>The following cloud instances were used,</p>
<ul>
<li>Clients: t1.micro. up to 2 ECUs, 1 core, 613MB memory, SuSE 11.1, 64-bit</li>
<li>Server: m1.large. 4 ECUs, 2 cores, 7.5GB memory, SuSE 11.1, 64-bit</li>
</ul>
<p>and these versions of each tool:</p>
<ul>
<li>CFEngine 3.1.5 (with Enterprise extensions)</li>
<li>Puppet 0.24.8</li>
</ul>
<p>Both tools were set to run every 5 minutes.</p>
<p>&nbsp;</p>
<h2>Policy/manifest details</h2>
<p>Neither CFEngine nor Puppet will perform any action if you do not tell it to. During these tests, a policy or manifest to copy 20 configuration files from the server (totalling 140 kb) was used to have something realistic to test.</p>
<p>Doing file copies and templating is very common in the space of configuration management, merely because all Unix systems can be configured in terms of various configuration files.</p>
<p>&nbsp;</p>
<h2>Results</h2>
<p>The CFEngine server was not much affected by the extra load of more clients. At 400 clients, the average server CPU usage is below 10%. Client execution time is pretty much constant at 7.85 seconds independent of the number of clients.</p>
<figure id="attachment_505" aria-labelledby="figcaption_attachment_505" class="wp-caption aligncenter" style="width: 650px"><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/cfengine_total_stats.png"><img class="size-full wp-image-505" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/cfengine_total_stats.png" alt="CFEngine server CPU usage" width="640" height="332" /></a><figcaption id="figcaption_attachment_505" class="wp-caption-text">CFEngine server CPU usage</figcaption></figure>
<p>&nbsp;</p>
<p>For Puppet, the story looks different. The Puppet server worked up to 50 clients, but stopped responding to client requests at 100. Reducing the amount of clients back down to 50 made the Puppet server start responding again.</p>
<p>Another thing to note is that the CPU graph for Puppet has much more spikes than the smoother graph for CFEngine.</p>
<figure id="attachment_506" aria-labelledby="figcaption_attachment_506" class="wp-caption aligncenter" style="width: 650px"><a href="http://www.blogcompiler.com/wp-content/uploads/2012/09/puppet_total_stats.png"><img class="size-full wp-image-506" src="http://www.blogcompiler.com/wp-content/uploads/2012/09/puppet_total_stats.png" alt="Puppet server CPU usage" width="640" height="341" /></a><figcaption id="figcaption_attachment_506" class="wp-caption-text">Puppet server CPU usage</figcaption></figure>
<p>&nbsp;</p>
<h2>Conclusions</h2>
<p>We did not manage to find the maximum client count for CFEngine servers, but if you extrapolate the CPU graph, it should lie somewhere between 4000 &#8211; 5000 clients. The Puppet server started failing between 50 &#8211; 100 clients. The difference is mind-blowing!</p>
<p>We have just discussed the amount of clients per server. Scalability is a abstract term, so there are definitively other interesting aspects to highlight. One example is, <a title="Scaling CFEngine and Puppet to multiple servers" href="http://my.opera.com/marcomarongiu/blog/2012/06/17/why-i-gave-up-puppet-and-chose-cfengine-3">how easy is it to scale to multiple servers</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2012/09/15/scalability-of-cfengine-and-puppet/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Terminate all EC2 instances</title>
		<link>http://www.blogcompiler.com/2012/02/06/terminate-all-ec2-instances/</link>
		<comments>http://www.blogcompiler.com/2012/02/06/terminate-all-ec2-instances/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 04:18:45 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[all]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[instances]]></category>
		<category><![CDATA[terminate]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=469</guid>
		<description><![CDATA[The Amazon Elastic Compute Cloud (EC2) allows you to quickly launch virtual servers in the cloud. If you create an AMI (Amazon Machine Image), you can deploy many instances of this image, only limited by your instance limit (20 initially, &#8230; <a href="http://www.blogcompiler.com/2012/02/06/terminate-all-ec2-instances/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The <a title="Amazon EC2" href="http://aws.amazon.com/ec2/">Amazon Elastic Compute Cloud</a> (EC2) allows you to quickly launch virtual servers in the cloud. If you create an AMI (Amazon Machine Image), you can deploy many instances of this image, only limited by your instance limit (20 initially, but you can <a title="Amazon Instance request" href="http://aws.amazon.com/contact-us/ec2-request/">request more</a>).</p>
<figure id="attachment_470" aria-labelledby="figcaption_attachment_470" class="wp-caption aligncenter" style="width: 620px"><a href="http://www.blogcompiler.com/wp-content/uploads/2012/02/amc.png"><img class=" wp-image-470 " src="http://www.blogcompiler.com/wp-content/uploads/2012/02/amc.png" alt="Amazon Management Console" width="610" height="240" /></a><figcaption id="figcaption_attachment_470" class="wp-caption-text">Amazon Management Console</figcaption></figure>
<p>The instances can be manged through the <a title="AWS management console" href="http://aws.amazon.com/console/">AWS management console</a> web-interface, for example to create multiple instances as shown above.</p>
<p>However, this console does not have a convenient method to terminate all the running instances &#8211; you have to <strong>terminate them one-by-one</strong>! This becomes a big problem if you, like me, are launching 1000s of instances for a few hours and then want to take them all down again. Since you are getting charged by the instance hour, you don&#8217;t want them running longer than necessary.</p>
<h3>EC2 API tools</h3>
<p>Fortunately, the <a title="Amazon EC2 API Tools" href="http://aws.amazon.com/developertools/351">EC2 API Tools</a> provide an alternate interface to EC2. These tools rely on a Java runtime, and a few environment variables to install. They seem to work best with Linux, but I have not tested them on Windows myself. There are some guides available on how to install them, for example the <a title="Ubuntu EC2 Starters Guide" href="https://help.ubuntu.com/community/EC2StartersGuide">Ubuntu EC2 Starters Guide</a>. If you already have an AWS account, you should get them working within 10 minutes on Ubuntu.</p>
<p>Now that you have command-line access to managing the instances, you have much more power to do mass-management of them.</p>
<h3>Terminating all instances</h3>
<p>Assuming you&#8217;ve got EC2 API tools installed and working correctly above, you probably noticed a command that can help terminate the instances: <code>ec2-terminate-instances</code>. However, this command assumes the instance IDs that are to be terminated as parameters &#8212; there is no option to terminate all. Looking further at the tools, there is a command called <code>ec2-describe-instances</code> that returns the instance IDs of the running instances (among other things).</p>
<p>So our task is to get the running instance IDs from <code>ec2-describe-instances</code> and pass them as a parameter to <code>ec2-terminate-instances</code>. With some helper commands, this can be achieved as follows.</p>
<blockquote><p><code>ec2-describe-instances | grep INSTANCE | awk '{print $2}' | xargs ec2-terminate-instances</code></p></blockquote>
<p>Be careful: this will terminate all your running instances, so don&#8217;t run it if you don&#8217;t mean it! If you have a lot of instances to terminate, <code>ec2-terminate-instances</code> may report that reading from the network socket failed (due to a timeout). But the termination will nonetheless succeed, as you can confirm from the AWS management console.</p>
<p>This has saved me hours of one-by-one termination from the web interface, and I hope it can help you too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2012/02/06/terminate-all-ec2-instances/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenSSL for Windows</title>
		<link>http://www.blogcompiler.com/2011/12/21/openssl-for-windows/</link>
		<comments>http://www.blogcompiler.com/2011/12/21/openssl-for-windows/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 18:37:29 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[GCC Windows]]></category>
		<category><![CDATA[64-bit]]></category>
		<category><![CDATA[cross-compile]]></category>
		<category><![CDATA[mingw-w64]]></category>
		<category><![CDATA[openssl]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=408</guid>
		<description><![CDATA[In earlier articles, we have looked at how to create a gcc build environment on Windows, and also how to compile binaries for Windows on Linux, using the MinGW-w64 suite to be able to support native 64-bit Windows builds. But &#8230; <a href="http://www.blogcompiler.com/2011/12/21/openssl-for-windows/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In earlier articles, we have looked at how to create a <a title="gcc for Windows" href="http://www.blogcompiler.com/2010/06/13/gcc-for-windows/">gcc build environment on Windows</a>, and also how to<a title="Compile for Windows on Linux" href="http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/"> compile binaries for Windows on Linux</a>, using the <a title="MinGW-w64" href="http://mingw-w64.sourceforge.net/">MinGW-w64</a> suite to be able to support native 64-bit Windows builds.</p>
<p>But in order to build useful applications in these environments, we often need some common libraries. In this article, we will have a look at how to compile the <a title="The OpenSSL project" href="http://www.openssl.org">OpenSSL library</a> and make a small application that uses it. Compiled OpenSSL libraries are available for download (see the link at the bottom), in case you don&#8217;t want to do the compilation yourself.</p>
<p>&nbsp;</p>
<h3>Prerequisites</h3>
<p>We will be cross-compiling from Linux. If you want to use Windows only, please consider downloading the compiled OpenSSL binaries near the bottom of the page, or adjust the paths accordingly when building the library.</p>
<p>I have my 64-bit Windows build environment installed in <code>/opt/mingw64</code>, and the cross-compiler prefix is <code>x86_64-w64-mingw32</code>. I will target (build binaries for) 64-bit Windows in this article. Please adjust these variables according to your own build environment. <code>i686-w64-mingw32</code> is the prefix for the 32-bit Windows cross-compiler.</p>
<p>&nbsp;</p>
<h3>Compiling OpenSSL</h3>
<ol>
<li>Follow the simple instructions on how to set up a <a title="Compile for Windows on Linux" href="http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/">Windows build environment on Linux</a>. It is also possible to do this on Windows, but it is simpler and faster using Linux. Please leave a comment if you would like me to describe how to build on Windows.</li>
<li>Grab the desired <a title="OpenSSL source code" href="http://openssl.org/source/">OpenSSL source tarball</a>. Use OpenSSL version 1.0.0 or newer; OpenSSL versions older than v1.0.0 are a bit harder to build on Windows, but let me know if you want to see how to do this.  I&#8217;ll use OpenSSL version 1.0.0e in the following, but the steps should be identical for any version newer than 1.0.0.</li>
<li>Put your tarball in a temporary directory, e.g. /tmp and unpack it:<br />
<code><code>$ tar zxvf openssl-1.0.0e.tar.gz</code></code></li>
<li>Run the configure script to use the 64-bit Windows compiler.<br />
<code>$ cd openssl-1.0.0e<br />
$ CROSS_COMPILE="x86_64-w64-mingw32-" ./Configure mingw64 no-asm shared --prefix=/opt/mingw64</code><br />
&#8230;<br />
Configured for mingw64.</li>
<li>Compile. Make sure the the cross-compiler is in your path, or add it explicitly as show below.<br />
<code>$ PATH=$PATH:/opt/mingw64/bin make</code><br />
&#8230;</li>
<li>Install it.<br />
<code>$ sudo PATH=$PATH:/opt/mingw64/bin make install</code></li>
</ol>
<p>We now have the OpenSSL libraries and headers for 64-bit Windows installed. Repeat the steps above with <code>CROSS_COMPILE="i686-w64-mingw32-"</code> and prefix <code>/opt/mingw32</code> to build and install the 32-bit libraries for Windows.</p>
<p>&nbsp;</p>
<h3>A simple application</h3>
<p>To confirm OpenSSL is working correctly, let&#8217;s create  a small C application that generates a SHA-256 digest of a character string. It reads a string given as the argument, generates the digest and shows the computed digest. The digest-generating code is shown below, while the complete code is <a title="sha256 generating code" href="http://www.blogcompiler.com/wp-content/uploads/2011/12/sha256.c">available for download</a>.</p>
<blockquote><p>void SHA256Hash(unsigned char digest[EVP_MAX_MD_SIZE], char *stringToHash)<br />
{<br />
OpenSSL_add_all_digests();</p>
<p>const EVP_MD *md = EVP_get_digestbyname(&#8220;sha256&#8243;);</p>
<p>EVP_MD_CTX context;<br />
EVP_MD_CTX_init(&amp;context);<br />
EVP_DigestInit_ex(&amp;context, md, NULL);<br />
EVP_DigestUpdate(&amp;context, (unsigned char *)stringToHash, strlen(stringToHash));</p>
<p>unsigned int digestSz;<br />
EVP_DigestFinal_ex(&amp;context, digest, &amp;digestSz);<br />
EVP_MD_CTX_cleanup(&amp;context);</p>
<p>EVP_cleanup();<br />
}</p></blockquote>
<ol>
<li>Save the file <a title="sha256 generating code" href="http://www.blogcompiler.com/wp-content/uploads/2011/12/sha256.c">sha256.c </a>in a working directory.</li>
<li>Compile it.<br />
$ /opt/mingw64/bin/x86_64-w64-mingw32-gcc -I/opt/mingw64/include -L/opt/mingw64/lib -Wall sha256.c -lcrypto -o sha256.exe</li>
<li>Check that the executable has the correct binary format (PE32+ is 64-bit).<br />
$ file sha256.exe<br />
sha256.exe: PE32+ executable for MS Windows (console) Mono/.Net assembly</li>
<li>Copy our new program to a 64-bit Windows machine, and run it in the Windows Command Prompt.<br />
&gt; sha256.exe 12345</li>
</ol>
<p>The last step should generate the following dialog box, which contains the SHA-256 digest of the string &#8220;12345&#8243;.</p>
<p><a href="http://www.blogcompiler.com/wp-content/uploads/2011/12/openssl-sha256-win64.png"><img class="aligncenter size-full wp-image-416" src="http://www.blogcompiler.com/wp-content/uploads/2011/12/openssl-sha256-win64.png" alt="sha256.exe sample run" width="667" height="327" /></a></p>
<h2></h2>
<p>&nbsp;</p>
<h3>OpenSSL Windows binaries</h3>
<p>In case you don&#8217;t want to compile the OpenSSL library yourself, I have compiled version 1.0.0e and made it available for download below.</p>
<ul>
<li><a title="OpenSSL library for 32-bit Windows" href="http://www.blogcompiler.com/wp-content/uploads/2011/12/openssl-1.0.0e-mingw32.tar.gz">OpenSSL 1.0.0e for 32-bit MinGW-w64</a> (prefix i686-w64-mingw32)</li>
<li><a title="OpenSSL library for 64-bit Windows" href="http://www.blogcompiler.com/wp-content/uploads/2011/12/openssl-1.0.0e-mingw64.tar.gz">OpenSSL 1.0.0e for 64-bit MinGW-w64</a> (prefix x86_64-w64-mingw32)</li>
</ul>
<p>Just unpack each tarball to your respective MinGW-w64 installation directory. They should work both if you are running the <a title="gcc for Windows" href="http://www.blogcompiler.com/2010/06/13/gcc-for-windows/">gcc compiler on Windows</a>, as well as <a title="Compile for Windows on Linux" href="http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/">cross-compiling for Windows</a> like we have done above.</p>
<p>Please leave a comment if you found this interesting or have suggestions for improvements!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/12/21/openssl-for-windows/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Excluding files in CFEngine copies</title>
		<link>http://www.blogcompiler.com/2011/09/21/excluding-files-in-cfengine-copies/</link>
		<comments>http://www.blogcompiler.com/2011/09/21/excluding-files-in-cfengine-copies/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 00:06:54 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[.svn]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[copy]]></category>
		<category><![CDATA[exclude]]></category>
		<category><![CDATA[ignore]]></category>
		<category><![CDATA[recursive]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=395</guid>
		<description><![CDATA[I frequently encounter people trying to do a recursive copy with CFEngine, but want to ignore some subdirectories or files. A typical example is that /var/cfengine/masterfiles is under version control on the policy server, and a lot of meta-data is &#8230; <a href="http://www.blogcompiler.com/2011/09/21/excluding-files-in-cfengine-copies/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I frequently encounter people trying to do a recursive copy with CFEngine, but want to ignore some subdirectories or files.</p>
<p>A typical example is that <code>/var/cfengine/masterfiles</code> is under version control on the policy server, and a lot of meta-data is copied down to the clients during policy updates. Fortunately, it is very easy to ignore certain subdirectories during copies with CFEngine. Consider the following example.</p>
<blockquote><p>bundle agent test_copy<br />
{<br />
files:</p>
<p>&#8220;/tmp/dest&#8221;<br />
copy_from =&gt; local_cp(&#8220;/tmp/src&#8221;),<br />
depth_search =&gt; recurse_ignore(&#8220;inf&#8221;, &#8220;.svn&#8221;);<br />
}</p></blockquote>
<p>This will copy everything recursively, except the Subversion meta-directories. A self-contained example is available <a href="http://www.blogcompiler.com/wp-content/uploads/2011/09/nosvn.tar.gz">for download</a>.</p>
<p>A sample run is shown below.</p>
<blockquote><p>$ find /tmp/src/<br />
/tmp/src/<br />
/tmp/src/subdir<br />
/tmp/src/subdir/file3<br />
/tmp/src/subdir/.svn<br />
/tmp/src/file2<br />
/tmp/src/.svn<br />
/tmp/src/file1</p>
<p>$ cf-agent -KIf ./nosvn.cf</p>
<p>-&gt; Copying from localhost:/tmp/src/subdir/file3<br />
-&gt; Copying from localhost:/tmp/src/file2<br />
-&gt; Copying from localhost:/tmp/src/file1</p>
<p>$ find /tmp/dest/<br />
/tmp/dest/<br />
/tmp/dest/subdir<br />
/tmp/dest/subdir/file3<br />
/tmp/dest/file2<br />
/tmp/dest/file1</p></blockquote>
<p>Of course, this can be integrated into your <code>update.cf</code> in order to avoid getting those pesky .svn directories everywhere.</p>
<p>Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/09/21/excluding-files-in-cfengine-copies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFEngine 3.2.0 extended change log</title>
		<link>http://www.blogcompiler.com/2011/08/29/cfengine-3-2-0-extended-change-log/</link>
		<comments>http://www.blogcompiler.com/2011/08/29/cfengine-3-2-0-extended-change-log/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 02:32:46 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[and]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[cfengine 3.2.0]]></category>
		<category><![CDATA[concat]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[emacs-mode]]></category>
		<category><![CDATA[extended change log]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[ifvarclass]]></category>
		<category><![CDATA[not]]></category>
		<category><![CDATA[or]]></category>
		<category><![CDATA[package cache]]></category>
		<category><![CDATA[packages update]]></category>
		<category><![CDATA[policy-server]]></category>
		<category><![CDATA[release notes]]></category>
		<category><![CDATA[syntax highlighting]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=302</guid>
		<description><![CDATA[Highlights Finally, we are ready for the CFEngine 3.2.0 release and we&#8217;ll have a look at the major changes. In 3.2.0, an exciting CFEngine Nova feature is brought into the community edition, and a set of out-of-the-box policies are released &#8230; <a href="http://www.blogcompiler.com/2011/08/29/cfengine-3-2-0-extended-change-log/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Highlights</h3>
<p>Finally, we are ready for the CFEngine 3.2.0 release and we&#8217;ll have a look at the major changes. In 3.2.0, an exciting <a title="CFEngine Nova" href="http://cfengine.com/nova">CFEngine Nova</a> feature is brought into the community edition, and a set of out-of-the-box policies are released to standardise and simplify CFEngine installations. This will make bootstrapping new CFEngine&#8217;d hosts a breeze. Also, as usual, a bunch of new features and bug fixes also made it into the release.</p>
<p>We will cover the following items this time.</p>
<ul>
<li>The brand new <code>cf-agent</code> bootstrap feature</li>
<li>More convenient use of ifvarclass</li>
<li>Package-promises improvements</li>
<li>Editors to support the CFEngine language</li>
</ul>
<p>&nbsp;</p>
<h3>Bootstrapping</h3>
<p>If you look at <code>cf-agent --help</code>, you will notice that a new option, <code>--boostrap (-B)</code>, has been added to the community edition. Also note the <code>--policy-server (-s)</code> option &#8211; they go hand-in-hand. These options, when combined, allows you to specify the IP address of a policy server on the command line. The IP address will then be used when the bootstrapped node pulls for policy updates. So this is easier than the conventional way  to put a new node under management; manually deploying a custom policy and running <code>cf-agent</code>.</p>
<p>So say we have a policy server running at 192.168.1.1. On a fresh client, we run <code>/var/cfengine/bin/cf-agent -Bs 192.168.1.1</code>. Let&#8217;s break <code>cf-agent</code>&#8216;s actions down into a series of steps, to see what is actually happening.</p>
<ol>
<li>Write the address from the <code>--policy-server (-s)</code> option to <code>/var/cfengine/policy_server.dat</code></li>
<li>Check if <code>/var/cfengine/inputs/failsafe.cf</code> exists, run it and exit if it does</li>
<li>Write an embedded failsafe policy to <code>/var/cfengine/inputs/failsafe.cf</code> (we&#8217;ll explore this in a moment)</li>
<li>Run the embedded failsafe policy</li>
<li>The embedded failsafe pulls down a new policy from <code>192.168.1.1:/var/cfengine/masterfiles</code> and starts <code>cf-execd</code></li>
<li>Bootstrapping is now finished and the new node is under CFEngine management!</li>
</ol>
<p>This means that all you need to have is a policy server sharing a policy under <code>/var/cfengine/masterfiles</code> and then run <em>one</em> command at the clients to put them under management!</p>
<p>&nbsp;</p>
<h3>Embedded policy</h3>
<p>So how does this embedded policy look? It is actually a very simple policy mainly consisting of a  file-copy promise and a promise to start <code>cf-execd</code>. You can actually see the embedded failsafe as failsafe.cf.cfsaved after a host has been successfully bootstrapped.</p>
<p>Since it is embedded in the CFEngine binaries, it is not very pretty with respect to indentation and Knowledge Management features, but it does the job. For your convenience and curiosity needs, I have uploaded the <a title="CFEngine 3.2.0 embedded bootstrap failsafe.cf" href="http://www.blogcompiler.com/wp-content/uploads/2011/08/failsafe.cf_.tar.gz">CFEngine embedded failsafe.cf</a>. Also note that it cannot be changed since it is embedded (and this is why it is so simple), but the policy that gets pulled down is of course entirely up to you.</p>
<p>&nbsp;</p>
<h3>Bootstrapping the policy server</h3>
<p>Until now, we have assumed that the policy server is already set up for us in advance. But, as a matter of fact, bootstrapping the policy server is almost exactly as easy. It will just use its own IP address, thus all hosts will use the exact same bootstrap command. However, <code>/var/cfengine/masterfiles</code> should be populated with the desired policy before bootstrapping it (otherwise, it has no policy to grab!). But CFEngine 3.2.0 also gives you a head start with the bundled policy.</p>
<p>&nbsp;</p>
<h3>The bundled policy</h3>
<p>So what do you put in <code>/var/cfengine/masterfiles</code> on the policy server prior to doing any bootstrapping? In order to get policy updates, it should contain a promise to check for updates from the policy server, and the policy server needs to grant access to the directory with the policy updates (<code>/var/cfengine/masterfiles</code> by convention). But there are also a few other items users always want, like a <code>promises.cf</code> policy with the <code>bundlesequence</code> and <code>inputs</code>. Also, you might want to configure <code>cf-execd</code>&#8216;s email functionality. And then there&#8217;s the <code>cf-serverd</code> access configuraion..</p>
<p>CFEngine 3.2.0 is distributed with a skeleton policy that allows to change these normal parameters without needing to write your own version of everything &#8212; just plug in the data in the right place. If grab a <a title="CFEngine 3 - Sources" href="http://cfengine.com/source_code">tarball</a>, you will find the bundled policy in the masterfiles subdirectory after you unpack it. Otherwise, you can always get it from the <a title="CFEngine 3 Core - Masterfiles repository" href="http://source.cfengine.com/browse/core/trunk/masterfiles">CFEngine core subversion repository</a>.</p>
<p>Before starting using it, you can look through <code>promises.cf</code> to adjust it to your needs. In particular, have a look at the <code>bundle common def</code>. The <code>acl</code> slist there determines the access rules for <code>cf-serverd</code>.</p>
<p>&nbsp;</p>
<h3>What about trust?</h3>
<p>As we know, simplicity and security are often conflicting. In order to make our easy bootstrapping work, two kinds of trust are assumed.</p>
<ul>
<li>Bootstrapping host trusts the policy server&#8217;s public key and the policy it holds</li>
<li>Policy server trust the new client&#8217;s public key and gives access to the policy</li>
</ul>
<p>The first item is implicit from running the bootstrap command. We are essentially asking the client go to the given IP address for policy updates. If we do not want to assume this kind of trust for some reason, we have to revert to the old way of copying the policy and/or the policy-server&#8217;s public key manually. An automatic bootstrap procedure will not be useful to us in this case.</p>
<p>However, we can do something with the second item. First off, we can allow only certain time windows of client trust in the server. We can also limit the (ranges of) IP-addresses we accept. By default we allow the Class B network to access the policy server. See the <code>acl</code> slist in <code>bundle common def</code> in <code>promises.cf</code> to configure it.</p>
<p>The CFEngine 3 reference manual has some more information on <a title="CFEngine 3 Reference - Key Exchange" href="http://cfengine.com/manuals/cf3-reference.html#Key-exchange">key exchange</a> and <a title="CFEngine 3 Reference - Time Windows" href="http://cfengine.com/manuals/cf3-reference.html#Time-windows">time windows</a>.</p>
<p>&nbsp;</p>
<h3> Improvements for ifvarclass</h3>
<p>As you perhaps know, <a title="CFEngine 3 Reference - ifvarclass" href="http://cfengine.com/manuals/cf3-reference.html#ifvarclass-in-_002a">ifvarclass</a> can be used to transform a variable into a class expression. With CFEngine 3.2.0 you can also make convenient expressions and tests directly in the ifvarclass expression using the new special functions <a title="CFEngine 3 Reference - Function and()" href="http://cfengine.com/manuals/cf3-reference.html#Function-and">and()</a>, <a title="CFEngine 3 Reference - Function not()" href="http://cfengine.com/manuals/cf3-reference.html#Function-not">not()</a>, <a title="CFEngine 3 Reference - Function or()" href="http://cfengine.com/manuals/cf3-reference.html#Function-or">or()</a> and <a title="CFEngine 3 Reference - Function concat()" href="http://cfengine.com/manuals/cf3-reference.html#Function-concat">concat()</a>. This can save you class definitions that you would use only once.</p>
<p>For example, you might want to copy down some configuration only to hosts having a certain binary. This can now be done easily with one promise, as shown below.</p>
<blockquote><p>files:<br />
&#8220;/etc/testservice&#8221;,<br />
copy_from  =&gt; remote_cp(&#8220;/var/cfengine/sitefiles/etc/testservice&#8221;, &#8220;123.123.123.123&#8243;),<br />
ifvarclass =&gt; or( fileexists(&#8220;/bin/testservice&#8221;) );</p></blockquote>
<p>Also note that you can wrap any number of function calls, as shown by the dummy-example below.</p>
<blockquote><p>reports:<br />
linux::<br />
&#8220;/tmp does exist&#8221;<br />
ifvarclass =&gt; not( not(fileexists(&#8220;/tmp&#8221;)));</p></blockquote>
<p>If you would like to test the two examples on your own, you can <a href="http://www.blogcompiler.com/wp-content/uploads/2011/08/ifvarclass-demo.cf_.tar.gz">download them here</a>.</p>
<p>&nbsp;</p>
<h3>A pack of bugfixes</h3>
<p>As usual, the CFEngine developers have been working hard to check and fix bugs reported by the community. In particular, the <code>packages</code>-promises have gotten a facelift.</p>
<p>The <code>addupdate</code> <a title="CFEngine 3 Reference - Package Policy" href="http://cfengine.com/manuals/cf3-reference.html#package_005fpolicy-in-packages">package policy</a> is now fully functioning when using a repository-enabled manager such as <code>yum</code> or <code>aptitude</code>. Previously this policy was only supported when specifying <a title="CFEngine 3 Reference - Package Method" href="http://cfengine.com/manuals/cf3-reference.html#package_005fmethod-in-packages">package_file_repositories</a> combined with non-repository package commands such as <code>rpm</code> or <code>dpkg</code>. For example, the following promise will make sure Apache is installed with a version at least 2.2. If Apache 2.2 or newer is already installed, no action is taken.</p>
<blockquote><p>packages:</p>
<p>&#8220;apache2&#8243;<br />
package_method =&gt; generic,<br />
package_version =&gt; &#8220;2.2.00&#8243;,<br />
package_select =&gt; &#8220;&gt;=&#8221;,<br />
package_policy =&gt; &#8220;addupdate&#8221;;</p></blockquote>
<p>Also, for efficiency reasons, CFEngine caches the list of installed packages and their version (the output from <a title="CFEngine 3 Reference - Package Method" href="http://cfengine.com/manuals/cf3-reference.html#package_005fmethod-in-packages">package_list_command</a>) in <code>WORKDIR/state/software_packages.csv</code>. A problem encountered by some users was that CFEngine did not actually update this cache often enough, so CFEngine might actually act on stale information.  To alleviate this problem, <a title="CFEngine bug tracker - Package cache invalidation" href="https://cfengine.com/bugtracker/view.php?id=627">package cache invalidation</a> is introduced in this release. Also note that you can define the cache maximum age with the <a title="CFEngine 3 Reference - Package Method" href="http://cfengine.com/manuals/cf3-reference.html#package_005fmethod-in-packages">package_list_update_ifelapsed</a> attribute. There were also <a title="CFEngine bug tracker - Package-related fixes in 3.2.0" href="https://cfengine.com/bugtracker/search.php?project_id=0&amp;search=packages&amp;category=Promise+type%3A+packages&amp;status_id=80&amp;sticky_issues=off&amp;fixed_in_version=3.2.0&amp;sortby=last_updated&amp;dir=DESC&amp;hide_status_id=-2">a few other package-related issues</a> that were addressed in the 3.2.0 release.</p>
<p>For a complete list of the reported issues/feature requests that was resolved in CFEngine 3.2.0, have a look at the <a title="CFEngine bug tracker - Change Log" href="https://cfengine.com/bugtracker/changelog_page.php">Change Log at the bug tracker</a>.</p>
<p>Lastly, some very good news for Emacs users! Ted Zlatanov, an active member of the CFEngine Community, has <a title="CFEngine Forum - CFEngine 3 Emacs mode" href="https://cfengine.com/forum/read.php?3,22473,22695#msg-22695">created and committed cfengine3-mode to Emacs sources</a>. This has also been added to <a title="CFEngine 3 Core - Emacs Mode" href="http://source.cfengine.com/browse/core/trunk/contrib/">contrib in the CFEngine core repository</a>.</p>
<p>If you are a vim-er, don&#8217;t despair! Have a look at the <a title="Vim - CFEngine 3 syntax highlighting" href="http://www.vim.org/scripts/script.php?script_id=2904">vim syntax highlighting script</a> and the <a title="Vim - CFEngine 3 abbreviations and help files" href="http://www.vim.org/scripts/script.php?script_id=2903">abbreviations and help files</a>. Both are contributed by Neil Watson, also an important member of the CFEngine community.</p>
<p>&nbsp;</p>
<h3>Get it!</h3>
<p>As usual, CFEngine 3.2.0 is provided not only as a <a title="Cfengine 3.2.0 source code" href="http://cfengine.com/source_code/download?file=cfengine-3.2.0.tar.gz">source tarball</a>, but also prepackaged for the most popular Linux distributions by logging into the <a title="The Engine Room login" href="https://cfengine.com/pages/login">Engine Room</a> (free <a title="The Engine Room registration" href="https://cfengine.com/pages/register">registration</a> required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.</p>
<ul>
<li>Debian 5 and 6</li>
<li>Fedora 14 and 15</li>
<li>Red Hat Enterprise Linux 4, 5 and 6</li>
<li>Suse 9, 10 and 11</li>
<li>Ubuntu 8, 9, 10 and 11</li>
</ul>
<p>Note that most distributions also maintain a CFEngine 3 package, but this is usually older and may not be built in a uniform way.</p>
<p>Please do not hesitate to leave a comment if you found this useful, have suggestions for improvements, or would like to see other CFEngine-related get covered.</p>
<p>Go get those hosts CFEngined!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/08/29/cfengine-3-2-0-extended-change-log/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Windows media in Ubuntu and Firefox</title>
		<link>http://www.blogcompiler.com/2011/08/07/windows-media-in-ubuntu-and-firefox/</link>
		<comments>http://www.blogcompiler.com/2011/08/07/windows-media-in-ubuntu-and-firefox/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 14:23:26 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[Software configuration]]></category>
		<category><![CDATA[10.4]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[lags]]></category>
		<category><![CDATA[lucid]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[wma]]></category>
		<category><![CDATA[wmv]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=368</guid>
		<description><![CDATA[Streaming Windows media files (WMV and WMA) from Firefox in Ubuntu has been a known problem for a long time. At the same time, a lot of web media content is encoded in these formats, making it a real pain &#8230; <a href="http://www.blogcompiler.com/2011/08/07/windows-media-in-ubuntu-and-firefox/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Streaming Windows media files (WMV and WMA) from Firefox in Ubuntu has been a known problem for a long time. At the same time, a lot of web media content is encoded in these formats, making it a real pain that they are not working.</p>
<p>There are various plugins that claim to work, but I have had some bad experiences with some not working and others creating lags and stop working after a few minutes. Now, let&#8217;s put an end to this and install a plugin that just works flawlessly.</p>
<p>You just need to install one package: <a title="gecko-mediaplayer" href="http://sites.google.com/site/kdekorte2/gecko-mediaplayer">gecko-mediaplayer</a>. As usual, you can use the Ubuntu graphical tools, or do it on the command line:</p>
<p><code>sudo apt-get install gecko-mediaplayer</code></p>
<p>Now restart Firefox, and you should be able to play any Windows media files directly from your browser. Simple as that!</p>
<p>I have tested it in Ubuntu 10.4 (Lucid), but it should work on all recent versions of Ubuntu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/08/07/windows-media-in-ubuntu-and-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cf-execd schedule</title>
		<link>http://www.blogcompiler.com/2011/05/30/cf-execd-schedule/</link>
		<comments>http://www.blogcompiler.com/2011/05/30/cf-execd-schedule/#comments</comments>
		<pubDate>Mon, 30 May 2011 04:45:17 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[cf-agent]]></category>
		<category><![CDATA[cf-execd]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[cfengine 3]]></category>
		<category><![CDATA[executor control]]></category>
		<category><![CDATA[frequency]]></category>
		<category><![CDATA[how often]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[splaytime]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=288</guid>
		<description><![CDATA[A common question from Cfengine users is how to configure how often cf-agent is being run. Setting a simple time-based schedule is very easy, but there are a few additional steps you might want to consider to ensure optimal scalability. &#8230; <a href="http://www.blogcompiler.com/2011/05/30/cf-execd-schedule/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A common question from Cfengine users is how to configure how often cf-agent is being run. Setting a simple time-based schedule is very easy, but there are a few additional steps you might want to consider to ensure optimal scalability.</p>
<p>It is <code>cf-execd</code> that schedules the execution of <code>cf-agent</code>. In Cfengine 3, the default schedule will ensure that cf-agent is run every five minutes. To adjust this, all we need to do is add the control body for cf-execd and set the <a title="Cfengine reference - schedule" href="http://www.cfengine.org/manuals/cf3-reference.html#schedule-in-executor">schedule body-part</a> to our liking. For example, below we set <code>cf-agent</code> to run every fifteen minutes.</p>
<blockquote><p>body executor control<br />
{<br />
schedule =&gt; { &#8220;Min00&#8243;, &#8220;Min15&#8243;, &#8220;Min30&#8243;, &#8220;Min45&#8243; };<br />
}</p></blockquote>
<h2>Splaytime</h2>
<p>If you have a reasonable-sized environment, you might also want to have a look at the <code>splaytime</code> body-part. This delays the execution of <code>cf-agent</code> by a random amount of seconds within a bound. The purpose of this is to distribute the load on network resources evenly &#8212; to avoid that all your agents start pulling from the network at the exact same second. So, instead of saying that we want to run <code>cf-agent</code> the exact quarters of an hour, we can instead say we want to run it four times an hour and make our configuration more scalable as follows.</p>
<blockquote><p>body executor control<br />
{<br />
schedule =&gt; { &#8220;Min00&#8243;, &#8220;Min15&#8243;, &#8220;Min30&#8243;, &#8220;Min45&#8243; };<br />
splaytime =&gt; &#8220;15&#8243;;<br />
}</p></blockquote>
<p>There are some <a title="Cfengine 3 reference - splaytime" href="http://www.cfengine.org/manuals/cf3-reference.html#splaytime-in-executor">notes on the splaytime setting</a> in the Cfengine 3 reference manual.</p>
<h2>Advanced schedules</h2>
<p>Perhaps you have some specific time slot during the day you want your systems to spend all their resources on a specific task. Even though Cfengine 3 is the most lightweight configuration management system in existence, there might still be some shell commands or network transfers that are executed as part of your Cfengine policy. So let us adjust our schedule to run cf-agent every fifteen minutes, except from 12 PM to 6 PM.</p>
<blockquote><p>body executor control<br />
{<br />
schedule =&gt; { &#8220;Min00.(Morning|Evening|Night)&#8221;, &#8220;Min15.(Morning|Evening|Night)&#8221;,<br />
&#8220;Min30.(Morning|Evening|Night)&#8221;, &#8220;Min45.(Morning|Evening|Night)&#8221; };<br />
}</p></blockquote>
<p>As you might have noticed, each list element in schedule is actually a <em>class expression</em>, which makes it very flexible. Normally though, time-based class-expressions are used. Note the four hardclasses (automatically defined) that split the day into six-hour slots:</p>
<ul>
<li>00 AM &#8211; 06 AM : Night</li>
<li>06 AM &#8211; 12 PM : Morning</li>
<li>12 PM &#8211; 06 PM : Afternoon</li>
<li>06 PM &#8211; 12 AM : Evening</li>
</ul>
<p>We can create arbitrary complex class expressions to create any schedule that fits our needs (perhaps use one of Monday, Tuesday, etc.). Remember that you can always run <code>cf-promises -v</code> to see all the classes that are currently defined on a given host, which gives you a hint of what you have at your disposal.</p>
<h2>Internal workings</h2>
<p>We finish off with a short note on the steps <code>cf-execd</code> actually takes to do the scheduling. <code>cf-execd</code> sleeps one minute at the time. When it wakes up, it checks if any of the class-expressions in schedule evaluates to true. If so, it gets ready to run <code>cf-agent</code> (or the command in <a title="Cfengine 3 reference - exec_command" href="http://www.cfengine.org/manuals/cf3-reference.html#exec_005fcommand-in-executor">exec_command</a>). But first, it checks the <code>splaytime</code> body-part, and delays the execution an arbitrary amount of seconds (based on a hash of the host&#8217;s name) according to this setting.</p>
<p>If you want to test your new schedule, try running <code>cf-execd</code> in verbose mode (<code>cf-execd -v</code>). You would see something similar to the following once a class-expression in your schedule evaluates to true.</p>
<blockquote><p>cf3&gt; Reference time set to Sun May 29 21:10:13 2011<br />
cf3&gt; Checking schedule Min00&#8230;<br />
cf3&gt; Checking schedule Min05&#8230;<br />
cf3&gt; Checking schedule Min10&#8230;<br />
cf3&gt; Waking up the agent at Sun May 29 21:10:13 2011<br />
~ Min10<br />
cf3&gt; Sleeping for splaytime 17 seconds<br />
cf3&gt; Sleeping&#8230;<br />
cf3&gt; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
cf3&gt;   LocalExec(scheduled) at Sun May 29 21:10:30 2011<br />
cf3&gt; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
cf3&gt;  -&gt; Command =&gt; &#8220;/var/cfengine/bin/cf-twin&#8221; -f failsafe.cf &amp;&amp; &#8220;/var/cfengine/bin/cf-agent&#8221;<br />
cf3&gt;  -&gt; Command is executing&#8230;</p></blockquote>
<p>That&#8217;s it! You are now a Cfengine 3 scheduling expert!</p>
<p>Please leave a comment if you have any questions, corrections or ideas of other topics that should be covered.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/05/30/cf-execd-schedule/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cfengine 3.1.4 and 3.1.3 extended change log</title>
		<link>http://www.blogcompiler.com/2011/02/12/cfengine-3-1-3-and-3-1-4-extended-change-log/</link>
		<comments>http://www.blogcompiler.com/2011/02/12/cfengine-3-1-3-and-3-1-4-extended-change-log/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 12:59:47 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[cf-serverd]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[cfengine 3.1.3]]></category>
		<category><![CDATA[cfengine 3.1.4]]></category>
		<category><![CDATA[commands return codes]]></category>
		<category><![CDATA[extended change log]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[memory consumption]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[package return codes]]></category>
		<category><![CDATA[real segment size]]></category>
		<category><![CDATA[release notes]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[solaris zones]]></category>
		<category><![CDATA[transformer]]></category>
		<category><![CDATA[virtual size]]></category>
		<category><![CDATA[vsz]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=210</guid>
		<description><![CDATA[Highlights First of all, thanks for the good feedback from the previous extended change log! It seems like this is something the Cfengine community is interested in, so I will continue the series. This time we cover the changes in &#8230; <a href="http://www.blogcompiler.com/2011/02/12/cfengine-3-1-3-and-3-1-4-extended-change-log/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Highlights</h3>
<p>First of all, thanks for the good feedback from the previous extended change log! It seems like this is something the Cfengine community is interested in, so I will continue the series. This time we cover the changes in both Cfengine 3.1.3 and 3.1.4, since they were released quite close to each other (January 22nd and January 31st). Some rather annoying bugs were discovered by the Cfengine community in 3.1.3, so the 3.1.4 release was brought forward.</p>
<p>The new releases bring the following advancements.</p>
<ul>
<li>major memory leaks removed &#8211; daemons now show no growth</li>
<li>allowing definition of good and bad return codes for commands</li>
<li>lock database purging</li>
<li>30 second recv() timeout on Linux</li>
<li>two race conditions (causing segmentation faults) in <code>cf-serverd</code> fixed</li>
<li>Solaris global zone process list fixed</li>
<li>new function ip2host()</li>
<li>package architectures handled correctly</li>
</ul>
<p>There are some more details in the <a title="Cfengine 3.1.4 change log" href="http://source.cfengine.com/websvn/filedetails.php?repname=Cfengine+core&amp;path=%2Ftags%2F3.1.4%2FChangeLog">ChangeLog</a>-file, and at the <a title="Change Log - Cfengine Bug Tracker" href="https://cfengine.com/bugtracker/changelog_page.php">bug tracker</a>.</p>
<h3>Leak no more</h3>
<p>Memory leaks occur when a program allocates memory, but does not release it again later. This is not always a problem, because operating systems always reclaim all memory when a process terminates. Releasing memory just before termination thus only results in unnecessary resource consumption (indeed the GNU C library does not by default release memory on process termination).</p>
<p>However, in daemons and long running programs, repeated memory leaks is clearly an issue. Memory leaks usually manifest themselves in an ever-increasing size of the process&#8217; virtual memory. Unfortunately, such bugs are extremely hard to track down, because it is not always clear <em>where</em> the leak happens and <em>when</em> a certain memory segment should be released (if it is released to soon, the process will crash). In Cfengine, this is further complicated by the fact that certain policies may cause more severe leaks than others because different execution paths are followed when running them.</p>
<p>But since multiple reports of severe leaks started to come from the Cfengine community, a lot of effort was put into debugging it (see <a title="Cfengine memory leak bug" href="https://cfengine.com/bugtracker/view.php?id=427">the report</a> on the bug tracker). It took one month (!) of iteration before all the leaks were tracked down, even with much help with testing from the community &#8211; especially Jonathan. On the positive side, these leaks (or anything like them) are very unlikely to reappear. But don&#8217;t hesitate to create a report if you think you have found a leak some day.</p>
<p>The main sources of leaks turned out to be an error when releasing lists (struct Rlist). Also, when re-reading the policy, parts of the old one was never released. Since only <code>cf-monitord</code> and <code>cf-serverd</code> re-read the policy, they were the most affected components.</p>
<p>Jonathan from the Cfengine community provided a <a title="Leaky policy in Cfengine 3.1.2" href="https://cfengine.com/bugtracker/file_download.php?file_id=76&amp;type=bug">policy that caused a lot of leakage</a>, and by using this, debugging was easier. But we can also use it to illustrate the difference between Cfengine 3.1.2 and Cfengine 3.1.4. The graphs below show the segment size (RSS) of the three Cfengine daemons, measured over one day. They pretty much speak for themselves. Thanks to community members helping to fix this issue!</p>
<figure id="attachment_249" aria-labelledby="figcaption_attachment_249" class="wp-caption aligncenter" style="width: 507px"><a href="http://www.blogcompiler.com/wp-content/uploads/2011/02/multips_memory_rss-day-312.png"><img class="size-full wp-image-249 " src="http://www.blogcompiler.com/wp-content/uploads/2011/02/multips_memory_rss-day-312.png" alt="" width="497" height="299" /></a><figcaption id="figcaption_attachment_249" class="wp-caption-text">Cfengine 3.1.2 daemon leakage</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_250" aria-labelledby="figcaption_attachment_250" class="wp-caption aligncenter" style="width: 507px"><a href="http://www.blogcompiler.com/wp-content/uploads/2011/02/multips_memory_rss-day-314.png"><img class="size-full wp-image-250 " src="http://www.blogcompiler.com/wp-content/uploads/2011/02/multips_memory_rss-day-314.png" alt="Cfengine 3.1.4 daemon memory usage" width="497" height="299" /></a><figcaption id="figcaption_attachment_250" class="wp-caption-text">Cfengine 3.1.4 daemon memory usage</figcaption></figure>
<p style="text-align: right"><a href="http://www.blogcompiler.com/wp-content/uploads/2011/02/Cfengine-memory-314.tar.gz">download all graphs (including virtual sizes)</a></p>
<h3>Command return codes</h3>
<p>As of Cfengine 3.1.0, promises of type <code>commands</code> were flagged as repaired if they returned zero, not kept otherwise. This allowed to define a class in either case and run follow-up promises. In Cfengine 3.1.4, a much more flexible framework has been introduced. In addition, commands in <code>packages</code>-promises and <code>transformer</code> in <code>files</code>-promises has been incorporated. Now, Cfengine users can specify a list of return codes for which one of these promises should be kept, repaired and not kept. It&#8217;s often easier to understand by example, so let&#8217;s do just that. First let&#8217;s start with a simple shell script.</p>
<blockquote>
<pre>#!/bin/sh
# saved to /tmp/retarg
exit $1</pre>
</blockquote>
<p>So this script just exits with the code given as the first parameter, which must be from 0 to 255 on Unix. We will use this little script to demonstrate the new return code functionality in the following snippet.</p>
<blockquote>
<pre>bundle agent commands_retcode
{
commands:
  "/tmp/retarg 0",
  classes =&gt; define_retcodes;
}</pre>
<pre>###</pre>
<pre>body classes define_retcodes
{
kept_returncodes =&gt; { "5" };
repaired_returncodes =&gt; { "0" };
failed_returncodes =&gt; { "1", "2", "3", "4" };
promise_kept =&gt; { "waskept" };
promise_repaired =&gt; { "wasrepaired" };
repair_failed =&gt; { "wasfailed" };
}</pre>
</blockquote>
<p>By running <code>/tmp/retarg</code> with arguments 0, 1 and 5, we see that the classes <code>wasrepaired</code>, <code>wasfailed</code> and <code>waskept</code> gets defined, respectively. We may also use overlapping return codes in the <code>*_returncodes</code> lists, which could result in the promise getting multiple statuses (e.g. both repaired and failed). This might seem a bit strange, but gives the user total control. If the return code is not found in any of the lists, the promise does not get a status at all. When none of the lists are defined, Cfengine falls back to the default of zero being promise repaired, and anything else promise failed.</p>
<p>This flexibility is also allowed in <code>packages</code>-promises, as demonstrated in the following.</p>
<blockquote>
<pre>bundle agent packages_retcode
{
packages:
  "aatv"
  package_policy =&gt; "add",
  package_method =&gt; generic,
  classes =&gt; define_retcodes;
}</pre>
</blockquote>
<p>Lastly, in <code>files</code>-promises, the return value of the <code>transformer</code> command is considered, as shown below.</p>
<blockquote>
<pre>bundle agent transformer_retcode
{
files:
  "/tmp"
  classes =&gt; define_retcodes,
  transformer =&gt; "/tmp/retarg 0";
}</pre>
</blockquote>
<p>A complete self-containing policy demonstrating the new framework in all the three above promise types is available for <a href="http://www.blogcompiler.com/wp-content/uploads/2011/01/demo_retcodes.tar.gz">download here</a>. In the reference manual, this is documented as part of the <a title="Cfengine 3 reference - The classes body" href="http://www.cfengine.org/manuals/cf3-reference.html#classes-in-_002a">classes body</a>.</p>
<h3>Lock purging</h3>
<p>As you probably know, Cfengine has a concept of locks.  Locks ensure that promises are not checked too often, but also that repairing each promise does not take too long. These parameters are configurable through <code>ifelapsed</code> and <code>expireafter</code> policy setting, available at a <a title="Global ifelapsed setting" href="http://www.cfengine.org/manuals/cf3-reference.html#ifelapsed-in-agent">global</a> and <a title="Promise-local ifelapsed setting" href="http://www.cfengine.org/manuals/cf3-reference.html#action-in-_002a">promise</a> level. Since information about these locks needs to persist between runs of <code>cf-agent</code>, Cfengine keeps track of these locks in a database stored in /var/cfengine/state/cf_lock.* (suffix depends on the dbm used). A hash of the promise attributes is used as keys for this database.</p>
<p>The problem with this is that sometimes the attributes change even though the promise really is the same. For example, if you have a <code>commands</code>-promiser &#8220;/bin/echo $(date)&#8221;, the promiser would seem to change each time <code>cf-agent</code> runs. As another example, you may want to delete files in /tmp that are more than 3 days old. Many of these files would never reappear (but some might), so keeping an entry for all of them in the lock database just increases its size for no reason. This causes the lock database to grow indefinitely, but very slowly (if you are still not on Cfengine 3.1.4, check the size of yours). Trying to make some heuristic checks for if a given promise should be in the lock database or not would surely end in unexpected behaviour for some of the huge user base of Cfengine. A less risky approach that was introduced in Cfengine 3.1.4, is to automatically purge old locks.<code>cf-agent</code> will run a lock-purging algorithm every month, deleting locks that are more than one month old. This should take care of the (slow) growth of the lock database, while still not risking unexpected behaviour.</p>
<h3>Other improvements</h3>
<p>A 30 second timeout on the recv() system call is introduced on Linux hosts. This means that any connection that waits to receive data will time out if no data is received within 30 seconds. The reason to introduce this is to avoid a remote system to cause components of Cfengine to hang indefinitely. A remote system may become unresponsive for a number of reasons, including network unreliability, high load, deadlocks (e.g. when trying to open a database that was uncleanly shut down), kernel or driver bugs, most of which are outside of Cfengine&#8217;s control. Introducing a mechanism to back-off after a certain time has elapsed is the only way we can protect ourself from all these scenarios, but still allows for self-healing when Cfengine retries the operation later. As the details of the socket API is different amongst OSes, Linux is the first one to get this support.</p>
<p>A new function <a title="ip2host() Cfengine 3 documentation" href="http://www.cfengine.org/manuals/cf3-reference.html#Function-ip2host">ip2host()</a> that does reverse dns lookups is introduced. Note that DNS is often quite unreliable, and can thus cause <code>cf-agent</code> to hang for a while while doing the lookup.</p>
<blockquote>
<pre>bundle agent reverse_lookup
{
vars:
 "local4" string =&gt; ip2host("127.0.0.1");
 "local6" string =&gt; ip2host("::1");

reports:
cfengine_3::
  "local4 is $(local4)";
  "local6 is $(local6)";
}</pre>
</blockquote>
<p>Cfengine community members discovered that Cfengine sometimes ignored the architecture when considering packages-promises. This could cause Cfengine to believe that a given package was installed for all architectures, even though it was installed only for one. With Cfengine 3.1.4, this is handled correctly.</p>
<p>Two important issues casing segmentation faults in <code>cf-serverd</code> have been fixed. They were caused by race conditions in <code>cf-serverd</code> and were thus appearing only on busy servers. On Solaris global zones, Cfengine can now distinguish processes based on the zone they run in (previously a Nova-feature). This means that a process restart promise in the global zone will not kill processes in other zones. However, a bug was causing this not to function properly, so indeed processes in all zones were killed. This is all resolved in Cfengine 3.1.4.</p>
<h3>Get it!</h3>
<p>As usual, Cfengine 3.1.4 is provided not only as a <a title="Cfengine 3.1.4 source code" href="http://www.cfengine.org/tarballs/download.php?file=cfengine-3.1.4.tar.gz">source tarball</a>, but also prepackaged for the most popular Linux distributions by logging into the <a title="The Engine Room login" href="https://cfengine.com/pages/login">Engine Room</a> (free <a title="The Engine Room registration" href="https://cfengine.com/pages/register">registration</a> required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.</p>
<ul>
<li>CentOS 5</li>
<li>Debian 4, 5 and 6</li>
<li>Fedora 14</li>
<li>Red Hat Enterprise Linux 3, 4, 5 and 6</li>
<li>Suse 9, 10 and 11</li>
<li>Ubuntu 8, 9 and 10</li>
</ul>
<p>Note that most distributions also maintain a Cfengine 3 package, but this is usually older and may not be built in a uniform way.</p>
<p>The feedback from last post ensured that self-containing policies are available for download in companion with the snippets. Please do not hesitate to leave a comment if you found this useful, or have more suggestions for improvements.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2011/02/12/cfengine-3-1-3-and-3-1-4-extended-change-log/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Cfengine 3.1.2 extended change log</title>
		<link>http://www.blogcompiler.com/2010/12/29/cfengine-3-1-2-extended-change-log/</link>
		<comments>http://www.blogcompiler.com/2010/12/29/cfengine-3-1-2-extended-change-log/#comments</comments>
		<pubDate>Wed, 29 Dec 2010 21:49:04 +0000</pubDate>
		<dc:creator>author</dc:creator>
				<category><![CDATA[CFEngine]]></category>
		<category><![CDATA[3.1.2]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[cf-promises]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[cfengine 3.1.2]]></category>
		<category><![CDATA[change log]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[efficency]]></category>
		<category><![CDATA[extended change log]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[process list]]></category>
		<category><![CDATA[ps]]></category>
		<category><![CDATA[release notes]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.blogcompiler.com/?p=142</guid>
		<description><![CDATA[Highlights Cfengine 3.1.2 was released December 9th, 2010. The theme of the release is major efficiency improvements, but some bug fixes are also included. Looking in the ChangeLog-file in the root of the tarball, we find the following goodies. cf-promises &#8230; <a href="http://www.blogcompiler.com/2010/12/29/cfengine-3-1-2-extended-change-log/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Highlights</h3>
<p>Cfengine 3.1.2 was released December 9th, 2010. The theme of the release is major efficiency improvements, but some bug fixes are also included. Looking in the <a title="Cfengine 3.1.2 change log" href="http://source.cfengine.com/browse/core/tags/3.1.2/ChangeLog?revision=1746&amp;view=markup">ChangeLog</a>-file in the root of the tarball, we find the following goodies.</p>
<ul>
<li><code>cf-promises</code> is almost gone</li>
<li>potential for much less network load when checking for policy updates</li>
<li><code>ps</code>-command runs less frequently</li>
<li>faster access to classes</li>
</ul>
<p>We will have a look at how to take advantage of the new features in the following.</p>
<h3>Caching policy checks</h3>
<p>The biggest improvements in version 3.1.2 comes from caching the outcome of <code>cf-promises</code> runs. The main task of <code>cf-promises</code> is to verify that the syntax of the policy is correct (but it also does more advanced analysis). The other components of Cfengine reading the policy (e.g. <code>cf-agent</code>, <code>cf-execd</code>, <code>cf-serverd</code>, etc.) will require verification from <code>cf-promises</code> before even touching the policy themselves. In the default schedule of <code>cf-execd</code>, <code>cf-agent</code> runs every five minutes. This means <code>cf-promises</code> is run at least every five minutes as well.</p>
<p>The amount of time it takes to run <code>cf-promises</code> depends on a number of factors, but perhaps most importantly on the size and complexity of the checked policy. My workstation, using a fairly small policy, seems to spend a bit less than one second on running <code>cf-promises</code>.</p>
<blockquote><p>root@host:# time cf-promises<br />
real    0m0.730s</p></blockquote>
<p>Using an enterprise-size policy, this check will probably take multiple seconds to complete. Using the default schedule for <code>cf-agent</code>, this means about 30 seconds of server time per hour per server. Now, if we assume 1000 servers in the organisation, we see that a total of more than 8 hours of precious server time is getting lost just to this simple thing every hour. Even though Cfengine is the most efficient configuration management solution on the planet, there seems to be room for improvement here.</p>
<p>How often does the configuration management policy of an organisation change? Hopefully not every day. Perhaps every week, or month? Assuming once a week, it means that <code>cf-promises</code> is run against <em>the same</em> configuration 12*24*7 = 2016 times a row! How about reducing this to once?</p>
<p>This is exactly what Cfengine 3.1.2 brings, simply by touching a file <code>WORKDIR/masterfiles/cf_promises_validated</code>. This file is created by <code>cf-agent</code> or any other Cfengine component after it has successfully verified the policy with <code>cf-promises</code>. Also, before running <code>cf-promises</code>, the components check if any file either</p>
<ul>
<li>included by <a title="Cfengine 3 reference, inputs" href="http://www.cfengine.org/manuals/cf3-reference.html#inputs-in-common">body common control inputs</a></li>
<li>living <code>WORKDIR/inputs</code> (recursively)</li>
</ul>
<p>is newer than the file <code>cf_promises_validated</code> (based on modification time). If not, the run of <code>cf-promises</code> is skipped, and 8 hours of server time is reclaimed every hour!</p>
<h3>Reducing network load</h3>
<p><a href="http://www.blogcompiler.com/wp-content/uploads/2010/12/cfarch.png"><img class="alignleft size-medium wp-image-161" title="Cfengine architecture" src="http://www.blogcompiler.com/wp-content/uploads/2010/12/cfarch-300x132.png" alt="" width="300" height="132" /></a>The performance improvement by caching the outcome of runs of <code>cf-promises</code> is done automatically by Cfengine, without any need of policy change. However, in the most common architecture of Cfengine, there is still much to be gained by doing a tiny modification to the policy. We assume the hosts pull policy updates from the <code>WORKDIR/masterfiles</code> directory on distribution server(s), as seen in the picture  (shamelessly copied from the <a title="Cfengine community site" href="http://www.cfengine.org/pages/what_is_cfengine">Cfengine community site</a>).</p>
<p>The trick is to try to copy our new <code>cf_promises_validated</code> file (based on modification time) <em>before</em> trying to copy anything from the remote masterfiles directory itself. Note that it resides in masterfiles on the distribution server(s), so the access policy should need only minor modifications, if any. The end hosts check if the file got copied using if-repaired classes, and only copy the rest of masterfiles if so. The important thing to note here, is that the distribution servers must also run the policy, i.e. copy from their <code>WORKDIR/masterfiles</code> to <code>WORKDIR/inputs</code> locally and run <code>cf-agent</code> regularly in order to update <code>cf_promises_validated</code> if anything changed in <code>WORKDIR/masterfiles</code> to signal the end hosts of the change. This is however the normal way to do it. The following policy snippet demonstrates the more efficient copy.</p>
<blockquote><p># Assumptions:<br />
# *) the class &#8220;am_distribution_server&#8221; is set on distribution servers<br />
# *) the string variable &#8220;distribution_server&#8221; contains the address of the distribution server</p>
<p>files:</p>
<p>!am_distribution_server::<br />
&#8220;/var/cfengine/inputs/cf_promises_validated&#8221;<br />
comment =&gt; &#8220;Check whether a validation stamp is available for a new policy update&#8221;,<br />
copy_from =&gt; u_remote_cp(&#8220;/var/cfengine/masterfiles/cf_promises_validated&#8221;,&#8221;$(distribution_server)&#8221;),<br />
classes =&gt; u_if_repaired(&#8220;validated_updates_ready&#8221;);</p>
<p>am_distribution_server|validated_updates_ready::<br />
# distribution server should always put masterfiles in inputs in order to check new policy</p>
<p>&#8220;/var/cfengine/inputs&#8221;<br />
comment =&gt; &#8220;Copy policy updates from master source on distribution server if a new validation was acquired&#8221;,<br />
copy_from =&gt; u_remote_cp(&#8220;/var/cfengine/masterfiles&#8221;,&#8221;$(distribution_server)&#8221;),<br />
depth_search =&gt; u_recurse(&#8220;inf&#8221;);</p></blockquote>
<p style="text-align: right;"><a href="http://www.blogcompiler.com/wp-content/uploads/2010/12/update_demo.tar.gz">download above policy</a></p>
<p>The bodies used are found in the <a title="COPBL" href="http://source.cfengine.com/browse/copbl/trunk/">Cfengine Open-Promise Body Library</a>, but they are prefixed by &#8220;u_&#8221; to make the update-policy (usually part of failsafe.cf) self-containing.</p>
<p>Using this method, we reduce the (possible recursive) copy of the masterfiles directory containing tens or hundreds of files to one file. Reclaim those bytes!</p>
<h3>Internal optimisations</h3>
<p>As you might know, Cfengine relies on the <code>ps</code> command in order to acquire information about the running processes. Process information interfaces are not portable across Unices, so the <code>ps</code> command was deemed the only viable interface. Process information is required for example when making promises to start a process if it is not running, like the following.</p>
<blockquote><p>processes:<br />
&#8220;httpd&#8221;<br />
restart_class =&gt; &#8220;start_apache&#8221;;</p>
<p>&#8220;mysql&#8221;<br />
restart_class =&gt; &#8220;start_mysql&#8221;;</p>
<p>commands:<br />
start_apache::<br />
&#8220;/etc/init.d/apache2 restart&#8221;;</p>
<p>start_mysql::<br />
&#8220;/etc/init.d/mysql restart&#8221;;</p></blockquote>
<p style="text-align: right;"><a title="Process demo self-contained policy" href="http://www.blogcompiler.com/wp-content/uploads/2010/12/processes_demo.tar.gz">download above policy</a></p>
<p>Previously, these processes-promises would result in two executions of <code>ps</code>. However, running commands has significant overhead, and should thus be done only when strictly necessary. Cfengine 3.1.2 caches the output of a <code>ps</code> execution and reuses it within the same bundle, so <code>ps</code> will only run once in Cfengine 3.1.2 using the above snippet. The reason for not using a global cache for the whole run of <code>cf-agent</code> is to try to avoid staleness, as process information may change quite frequently.</p>
<p>Another internal optimisation introduced is to index class access though a simple hash table. The hash function used is simply to pick the first character of the class name (so &#8220;aix&#8221; hashes to 0, &#8220;linux&#8221; hashes to 11, etc.). Because classes seem to be distributed quite well alphabetically, this should be quite efficient. There is a trade-off between the computational burden of the hash function and the quality of the probability distribution it produces. This hash function is very fast, and should have an decent distribution on classes. As a flat list of classes was used previously, the optimisation should have significant effect on all access to classes, including class evaluation, definition, and reporting.</p>
<h3>Get it!</h3>
<p>As usual, Cfengine 3.1.2 is provided not only as a <a title="Cfengine 3.1.2 source code" href="http://www.cfengine.org/tarballs/download.php?file=cfengine-3.1.2.tar.gz">source tarball</a>, but also prepackaged for the most popular Linux distributions by logging into the <a title="The Engine Room login" href="https://cfengine.com/pages/login">Engine Room</a> (free <a title="The Engine Room registration" href="https://cfengine.com/pages/register">registration</a> required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.</p>
<ul>
<li>CentOS 5</li>
<li>Debian 5 and 6</li>
<li>Fedora 14</li>
<li>Red Hat Enterprise Linux 3, 4, 5 and 6</li>
<li>Suse 9, 10 and 11</li>
<li>Ubuntu 8, 9 and 10</li>
</ul>
<p>Note that most distributions also maintain a Cfengine 3 package, but this is usually older and may not be built in a uniform way.</p>
<p>Please leave a comment if you found this useful, or have suggestions for improvements.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogcompiler.com/2010/12/29/cfengine-3-1-2-extended-change-log/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
