<?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>The Madstop &#187; ruby</title>
	<atom:link href="http://madstop.com/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://madstop.com</link>
	<description>Puppet development, configuration management, and less</description>
	<lastBuildDate>Mon, 02 Aug 2010 04:07:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>RailsMachine Releases Puppet Rails Tool</title>
		<link>http://madstop.com/2009/03/23/railsmachine-releases-puppet-rails-tool/</link>
		<comments>http://madstop.com/2009/03/23/railsmachine-releases-puppet-rails-tool/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 01:44:26 +0000</pubDate>
		<dc:creator>luke</dc:creator>
				<category><![CDATA[Puppet]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=67</guid>
		<description><![CDATA[RailsMachine has announced their project Moonshine, which provides a pure Ruby interface to Puppet and is essentially custom-built to simplify Rails deployment and management: One of the things that separates Moonshine from other solutions like Chef and Sprinkle is that &#8230; <a href="http://madstop.com/2009/03/23/railsmachine-releases-puppet-rails-tool/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://railsmachine.com/">RailsMachine</a> has <a href="http://blog.railsmachine.com/articles/2009/03/18/moonshine-what-burns-blue-makes-your-blues-go-away/">announced</a> their project <a href="https://github.com/railsmachine/moonshine/">Moonshine</a>, which provides a pure Ruby interface to Puppet and is essentially custom-built to simplify Rails deployment and management:</p>
<blockquote><p>One of the things that separates Moonshine from other solutions like Chef and Sprinkle is that out of the box, Moonshine comes with recipes for the same Ubuntu/Ruby Enterprise Edition/Apache/Passenger/MySQL stack that’s in production use at Rails Machine.</p></blockquote>
<p>We&#8217;re pretty excited about this, for multiple reasons.  It&#8217;s another Ruby company developing in and around Puppet, and it&#8217;s a great, simple way for Rails developers to take advantage of both Puppet and the RailsMachine stack.</p>
<p>The next step is to get the ShadowPuppet pure Ruby interface imported into Puppet.  It will complement the existing language rather than replacing it, but we haven&#8217;t really settled all of the details yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2009/03/23/railsmachine-releases-puppet-rails-tool/feed/</wfw:commentRss>
		<slash:comments>160</slash:comments>
		</item>
		<item>
		<title>Puppet wins Fukuoka Ruby Award</title>
		<link>http://madstop.com/2009/03/23/puppet-wins-fukuoka-ruby-award/</link>
		<comments>http://madstop.com/2009/03/23/puppet-wins-fukuoka-ruby-award/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 01:22:22 +0000</pubDate>
		<dc:creator>luke</dc:creator>
				<category><![CDATA[Puppet]]></category>
		<category><![CDATA[award]]></category>
		<category><![CDATA[japan]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[reductive]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=65</guid>
		<description><![CDATA[Puppet was one of the winners of the Ruby Award handed out by the Fukuoka Prefecture in Japan.  The Climate Information Toolkit won the top prize, and Puppet was one of three to win the second tier of prize. Unfortunately, &#8230; <a href="http://madstop.com/2009/03/23/puppet-wins-fukuoka-ruby-award/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Puppet was one of the <a href="http://www.flickr.com/photos/lkanies/3377826668/">winners</a> of the Ruby Award handed out by the Fukuoka Prefecture in Japan.  The <a href="http://classpath.egloos.com/4808382">Climate Information Toolkit</a> won the top prize, and Puppet was one of three to win the second tier of prize.</p>
<p>Unfortunately, we could not travel to Japan to receive the award in person, but I was able to give a talk via Skype the night of the award ceremony.  It was around 2am my time on a day I&#8217;d traveled with my wife and twins, so it was a long day, but it was worth it.  I only hope my talk was worth anything.</p>
<p>Andrew did all of the hard work around getting the submission in and organizing the talk itself, so I definitely have him to thank for that.</p>
<p>Now I just need to figure out how to get my bank to accept those postal money orders from Japan. <img src='http://madstop.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2009/03/23/puppet-wins-fukuoka-ruby-award/feed/</wfw:commentRss>
		<slash:comments>200</slash:comments>
		</item>
		<item>
		<title>Data Lifetimes and Cache Expiration</title>
		<link>http://madstop.com/2008/11/08/data-lifetimes-and-cache-expiration/</link>
		<comments>http://madstop.com/2008/11/08/data-lifetimes-and-cache-expiration/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 23:33:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programmer Therapy]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[therapy]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=34</guid>
		<description><![CDATA[This stuff drives me crazy.   (I can&#8217;t seem to say &#8220;drives me nuts&#8221; any more because of the damn joke.  That, and hanging out with too many Brits.)  I&#8217;m putting this post in &#8216;programmer therapy&#8217; because it&#8217;s written more for &#8230; <a href="http://madstop.com/2008/11/08/data-lifetimes-and-cache-expiration/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This stuff drives me crazy.   (I can&#8217;t seem to say &#8220;drives me nuts&#8221; any more because of the damn <a href="http://www.coolrunning.com/forums/Forum1/HTML/164425.shtml">joke</a>.  That, and hanging out with too many Brits.)  I&#8217;m putting this post in &#8216;programmer therapy&#8217; because it&#8217;s written more for me than for you, but maybe you&#8217;ll get something out of it.</p>
<p>Anyway, so I&#8217;m once again wrestling with data lifetime in Puppet.  This is one of those problems that always seems licked but then crops up again.</p>
<p>See, there&#8217;s plenty of data in a Puppet transaction whose lifetime should only be that transaction:  File stats, user name to gid mappings, and all kinds of information about the current state of the machine.  We need to collect this information, and we don&#8217;t want to collect it more than once a transaction (e.g., we need a file&#8217;s uid, gid, and mode, but we can get them all from a single Stat instance); but we also don&#8217;t want the data lying around for the next transaction.</p>
<p>So Puppet has support for a &#8216;flush&#8217; method throughout most of the RAL:  By default, the transaction calls &#8216;flush&#8217; on each resource, and the resource calls &#8216;flush&#8217; on its provider.  This makes it easy to get rid of data that should be cleared up after the transaction.</p>
<p>Kind of.  See, the *real* reason for the &#8216;flush&#8217; method is actually to flush changes to disk; e.g., the provider might have multiple attributes changed, and then you call &#8216;flush&#8217; on it to make all of those changes at once.  It&#8217;s just that it&#8217;s also a convenient place to clean up data because, well, it&#8217;s the only place to do so.  So some time in the last few months or years or decades, my brain decided it does both things, but it seemed to hide this conclusion from me until yesterday.</p>
<p>But yesterday I was trying to fix all of the broken tests resulting from my file serving refactoring, and I was finding that, not surprisingly, I kept having these cached stat instances lying around &#8212; but *only* if the file hadn&#8217;t changed.  E.g., consider this code:</p>
<pre><code>
assert_events([], resource)
File.unlink(file)
assert_events([:file_created], resource)
</code></pre>
<p>Ignore, please, whether this is a good idea or what; the point is that the first line runs a transaction that results in a cached stat but no changes; and because there are no changes, there&#8217;s nothing to flush to disk; and because there&#8217;s nothing to flush to disk, &#8216;flush&#8217; isn&#8217;t called; and because &#8216;flush&#8217; isn&#8217;t called, the &#8216;stat&#8217; is lying around still.  Which means the next transaction uses the cached stat, but of course, reality has changed in the meantime.</p>
<p>So, I need something that will make it easy for my data to match the lifetimes I want.  I made this <a href="http://github.com/lak/puppet/tree/master/lib/puppet/util/cacher.rb">Cacher Module</a> that purportedly solves this problem for me, but noooo, it solves a different data-lifetime problem:  I have a lot of initialization code that generally only runs once but ends up running many times during testing, so I needed a clean way to remove the initialized data after every test.  So, this module has a single, global boolean that defines whether a given chunk of data is expired or still valid.  That&#8217;s all fine and dandy for one-time configuration data, but it doesn&#8217;t work for transactions.</p>
<p>So, now I&#8217;m trying to enhance that module to support either the global expiration marker or a per-instance marker, so that I can have all of the resources use a timestamp in their catalog to determine whether their cached data is expired.</p>
<p>One of the hard problems here is that you don&#8217;t want to find yourself maintaining a global list of anything anywhere.  My first design for the Cacher module involved it keeping a reference to all the cached data, which would have made it easy to clear the cache but would have had lots of code accessing tons of global data; stupid.  Instead, everyone keeps references to their own data, and the only global data is the expiration marker.  This works great for global things.</p>
<p>But resources and catalogs aren&#8217;t global.  Even worse, I&#8217;m (reasonably) using an internal class to check expiration.  So, that internal class needs to have access to the catalog&#8217;s timestamp in order to figure out if its cached data is still valid.  This is automatically ugly &#8212; an instance you shouldn&#8217;t even need to know exists now needs access to a big collection of resources.  Yuck.  Without this, the internal class doesn&#8217;t have a reference to anything except the data it&#8217;s managing, but there&#8217;s just no escaping it needing access to that timestamp somehow, so you either give it a reference, or you pass it one every time you check for a value.</p>
<p>The *stupid* thing is that this isn&#8217;t the problem I want to solve.  I just want the old fileserving behaviour but now with gooey RESTfulness.  That, plus the fact that I&#8217;ve apparently decided that I can no longer use spackle and sheetrock mud during development means that I have to fix this even though it wouldn&#8217;t normally be on my critical path.  Yuck.</p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2008/11/08/data-lifetimes-and-cache-expiration/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A short history of Puppet, pt.1</title>
		<link>http://madstop.com/2008/11/01/a-short-history-of-puppet-pt1/</link>
		<comments>http://madstop.com/2008/11/01/a-short-history-of-puppet-pt1/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 02:37:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Puppet]]></category>
		<category><![CDATA[luke]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[isconf]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=25</guid>
		<description><![CDATA[I was asked recently for more information on Puppet&#8217;s history, and although it seems to me that I&#8217;ve talked about it plenty,  I guess I might not have written it all out, nor is it necessarily all in one place.  &#8230; <a href="http://madstop.com/2008/11/01/a-short-history-of-puppet-pt1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was asked recently for more information on Puppet&#8217;s history, and although it seems to me that I&#8217;ve talked about it plenty,  I guess I might not have written it all out, nor is it necessarily all in one place.  I&#8217;m relatively verbose, so this looks like it will be long enough to break into multiple parts.</p>
<h3>ISconf</h3>
<p>Puppet was heavily influenced by two tools, but almost more importantly, it was heavily influenced by what I couldn&#8217;t do with those tools.  I attended LISA in 2001, where I saw <a href="http://www.stevegt.com/">Steve Traugott</a> give his talk on automating infrastructures.  I was impressed enough that I convinced my then-company to bring him in for a week of consulting.  During that week, he convinced me to give a tool he&#8217;d written, <a href="http://isconf.org">ISconf</a>, a try.</p>
<p>ISconf is an insanely simple tool &#8212; it&#8217;s just a way to apply a set of make stanzas in the same order every time.  Steve&#8217;s theory was that the only way to get consistency from your computers was to do exactly the same thing on them every time.  So, he wrote up everything he did as a make stanza, and then built ISconf as a way of executing them in a consistent order.</p>
<p>Or at least, that was the theory.  When I got his code for ISconf, it was, em, not terribly usable.  It was written in shell and perl, with shell calling perl calling shell calling shell calling perl then exploding.  I had already bought into the basic theory, but I couldn&#8217;t see how to his code (which he was calling ISconf 2), so I rewrote it with some pretty significantly different functionality but following, as closely as possible, his basic theory.  Naturally, I called this ISconf 3.  On the ISconf web site, you can read more of this history, along with Steve&#8217;s relatively bitter version of how this portion of the history goes. (Incidentally, I wrote the majority of the content on that site.)</p>
<p>I won&#8217;t go into the detail of how it worked, except that all of the actual work happened with make stanzas.  This meant that, really, ISconf was a huge collection of very small shell scripts. This seems straightforward, until you start thinking about things like package installation &#8212; the command to install one package is almost the same as that to install a different package, which meant that a lot of my make stanzas had a lot of duplication.</p>
<p>To make my life easier, I started abusing the hell out of make, switching to gmake, and starting to make simple rules using &#8216;%&#8217; to avoid duplication:</p>
<pre>pkg/%:
...</pre>
<p>I can&#8217;t even remember how this worked, thankfully; I just know you can extract what the &#8216;%&#8217; matches and use it to choose the package name when installing a package.</p>
<p>This worked great for packages, since in most cases (and all the cases I was dealing with), you can easily specify a package by name.  It didn&#8217;t work so well for things like cron jobs, though &#8212; you&#8217;ve got between 1 and 6 fields, and the last field can have spaces and all manner of crap.  So, I started maintaining a separate file of all of these cron jobs, written in a perl Data::Dumper format, with each cron job having a unique name.  Then my make stanza would just refer to the arbitrary name I&#8217;d chosen.</p>
<p>This at least made ISconf more usable, but there were still a lot of problems.  You can read my writeup from around then in my <a href="http://www.usenix.org/events/lisa03/tech/full_papers/kanies/kanies.pdf">LISA paper</a>, but there were some serious problems with using ISconf.  First and foremost, it wasn&#8217;t a real solution &#8212; it was just a way to organize billions of little shell scripts, and as most anyone knows by now, I&#8217;m not so fond of shell scripts.  Also, the whole theory was bogus &#8212; there&#8217;s just no way you can guarantee consistency, not through order or any other mechanism.  Your dev servers and test servers can never be exactly the same, so stupidly replaying the same scripts in order also can&#8217;t guarantee sameness.  As a ridiculous example, I&#8217;ve seen printers that don&#8217;t work if their hostnames have an odd number of characters, and there&#8217;s just no way you can test this kind of case.</p>
<p>Beyond the theoretical problems, though, there were even worse practical issues.  You were <em>supposed</em> to never touch any code once it&#8217;d been deployed to a machine, because otherwise you couldn&#8217;t guarantee consistent behaviour, but this is just silly, because it means that you can never refactor code or change how you manage a given aspect of your system.  Imagine a solution that required immediate calcification of anything you ever did &#8212; once you deploy it, it&#8217;s deployed like that forever, even if it&#8217;s stupid.  No reason to learn; even worse, you get punished for learning, because you just add a new system to maintain every time you learn anything.</p>
<p>So, I wanted the ability to refactor my solutions, and ISconf couldn&#8217;t deliver that, so I started looking for something else that could.  Check back for part 2 to see what I did next. <img src='http://madstop.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2008/11/01/a-short-history-of-puppet-pt1/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
