<?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; Development</title>
	<atom:link href="http://madstop.com/tag/development/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>Using &#8216;git rebase&#8217; to clean development histories</title>
		<link>http://madstop.com/2009/04/13/using-git-rebase-to-clean-development-histories/</link>
		<comments>http://madstop.com/2009/04/13/using-git-rebase-to-clean-development-histories/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 06:54:11 +0000</pubDate>
		<dc:creator>luke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Puppet]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=71</guid>
		<description><![CDATA[In general, development in the Puppet world is a series of essentially disconnected batches of commits.  We do a pretty good job of applying related commits all at once, so it&#8217;s obvious when a set of commits is related, but &#8230; <a href="http://madstop.com/2009/04/13/using-git-rebase-to-clean-development-histories/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In general, development in the Puppet world is a series of essentially disconnected batches of commits.  We do a pretty good job of applying related commits all at once, so it&#8217;s obvious when a set of commits is related, but otherwise, we don&#8217;t have to worry.</p>
<p>Sometimes, though, multiple series of commits are related to each other, which can easily get lost.  Even worse, multiple series of commits developed in tandem can cause downright painful development histories.</p>
<p>For example, we&#8217;re currently working on <a href="http://groups.google.com/group/puppet-dev/browse_thread/thread/0de4dd8094416469#">refactoring Puppet&#8217;s ActiveRecord integration</a> while at the same time we&#8217;re adding the ability to <a href="http://groups.google.com/group/puppet-dev/browse_thread/thread/12875331120b13c0/811da1ae485628e4">queue the database store operations</a>.  We&#8217;ve had two development teams (of 1 to 3 people each) working on each feature, constantly publishing and rebasing against each others&#8217; work.  You could certainly argue that this isn&#8217;t the right model (we should have worked in serial rather than parallel, probably), time constraints didn&#8217;t allow this.</p>
<p>On Friday, we got to the point where we&#8217;re nearly done, and I started sending my code to the -dev list for review.  That was straightforward enough, because I&#8217;d done my development in a separate branch and I still had those branches.  The other team, though, had been pushing code around like made, tuning and modifying their code over time, so sending their commits out for review was harder.  To top it off, our final branch was already a mixture of the different efforts.</p>
<p>So, I decided to see if I could clean up the development history. We had 80 commits spread all around, and I needed to reorder and squash them so they made easy sense during code review.  (This is a pseudo-process without actual code, because the reality was too messy to reproduce here.)  First I needed a list of the commits in the branch; git rebase is our tool through this process, and using it interactively (with &#8216;-i&#8217;) is the key.  So, I made a new branch and started my rebasing:</p>
<blockquote><p>git checkout dev</p>
<p>git checkout -b clean_dev</p>
<p>git rebase -i 0.24.8</p></blockquote>
<p>This opens up my editor with an ordered list of all of the commits in my branch that aren&#8217;t in 0.24.8.  There are three things you can do with commits in this list:  Leave them alone, combine them with another commit, and delete them (which deletes them from the branch).  Because I knew this would be a long complicated process, I saved the whole list to a separate file to start.</p>
<p>Some of the commits in our branch were backports of fixes we needed from the &#8216;master&#8217; branch, so these were the only commits I left in the commit list in my first rebase.  This added about six commits, and was pretty easy to merge.  All of the other commits were just deleted from my clean branch.</p>
<p>The next step was to add my indirected ActiveRecord code.  This was only four or five commits, but should have been collapsed into fewer than that (e.g.,  one of the commits fixed a misspelling in a test).  There are multiple ways you could do this, including cherry-picking, but rebasing is definitely the most powerful.  I created a new temporary branch in which to do my rebase:</p>
<blockquote><p>git checkout -b clean_indirected_activerecord</p>
<p>git rebase -i clean_dev</p></blockquote>
<p>This actually results in a noop, because I&#8217;m rebasing against a branch that&#8217;s a complete duplicate of my current branch.  However, because I&#8217;m in interactive mode, I can do whatever I want from here, so I pasted in my four or five commits, and s/pick/squash/ where appropriate.  Once I dealt with any merge conflicts, I then merged back into my clean branch:</p>
<blockquote><p>git checkout clean_dev</p>
<p>git merge &#8211;no-ff clean_indirected_activerecord</p></blockquote>
<p>I decided to force the merge commit to exist because, um, actually I don&#8217;t have a good reason.  It seemed like a good idea to have a clear milepost saying that a given branch is merged, like that first email in a code review describing a patch series.</p>
<p>So now I&#8217;ve got a branch that has a series of patches that prepare the branch for us (with backported fixes, mostly), then a series of patches providing the first set of development.  Now I just need to repeat this process for the other three development stages, one done by me and two done by others.</p>
<p>I had no problem with my other code; it was 8 or so patches, but I wrote them all, so I could easily handle merge conflicts.  I also had no problem with one of the other chunks of code, because it was only three commits, so simple cherry-picking would have sufficed.</p>
<p>The last bit is where rebasing eventually broke down.  In the end, I had 35 commits that I thought contributed something  to the code (we had some duplicate commits in there, somehow, and some other commits that got cancelled out by later commits), but it looked like they should have been reduced to as little as four or five commits, because that&#8217;s about how many components were added in the code.  However, I don&#8217;t know this code as well as the people who wrote it, so I decided to punt here and told them they needed to clean up their development path and send me some patches that had no duplication and no code that gets deleted in a later patch.  My expectation is that they&#8217;ll create entirely new commits from the current state of the files, because the current commit history reflects a process rather than the desired state.</p>
<p>This whole process made me think of a discussion <a href="http://groups.google.com/group/puppet-dev/browse_thread/thread/27d4285e732f0e39/a65b086a6693da31?lnk=gst&amp;q=git+rebase#a65b086a6693da31">we had a while back</a> on the -dev list (and a <a href="http://groups.google.com/group/puppet-dev/browse_thread/thread/d920706cf9154100/0f71a89ec54c3226?lnk=gst&amp;q=git+rebase#0f71a89ec54c3226">related thread</a> started by Brice Figureau).  Apparently Linux development maintains every commit series separately, and only merges them when it&#8217;s time for release.  Or rather, the release involves a final merge.  They maintain multiple ongoing development branches; one of them has all of the proposed patch series, but it&#8217;s never merged directly into the release branch.  Instead, when a given patch series is accepted, it&#8217;s merged separately into the main branch.</p>
<p>This rebasing I did above made me realize the benefit of that approach &#8211; if the four development chunks had each remained separate branches, rather than merging early and merging often, it would have been *much* easier to keep them clean, and the developer responsible for a given chunk could always easily rebase just his or her own commits without affecting anyone else.  Then, when it was time for release, I could just merge them all in the appropriate order and release.</p>
<p>This is pretty easy for four patch series, but obviously gets more complicated as we have tens of sets.  I think for now, it&#8217;s too much work to maintain the patch sets in appropriate merge order without actually merging, but I think at some point, it really will make sense.  At the very least, this process has taught me the value of rebasing early and rebasing often.</p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2009/04/13/using-git-rebase-to-clean-development-histories/feed/</wfw:commentRss>
		<slash:comments>164</slash:comments>
		</item>
		<item>
		<title>Summary of February 2009 Puppet Developer call</title>
		<link>http://madstop.com/2009/02/05/summary-of-february-2009-puppet-developer-call/</link>
		<comments>http://madstop.com/2009/02/05/summary-of-february-2009-puppet-developer-call/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 18:13:16 +0000</pubDate>
		<dc:creator>luke</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Puppet]]></category>
		<category><![CDATA[facter]]></category>
		<category><![CDATA[reductive]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=58</guid>
		<description><![CDATA[We had another developer call last night, and until I can get the audio posted, here&#8217;s a basic summary. Development Workflow We led the discussion with a conversation about how the development workflow will change now that we&#8217;re finally releasing &#8230; <a href="http://madstop.com/2009/02/05/summary-of-february-2009-puppet-developer-call/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We had another developer call last night, and until I can get the <a href="http://reductivelabs.com/podcast">audio posted</a>, here&#8217;s a basic summary.</p>
<h2>Development Workflow</h2>
<p>We led the discussion with a conversation about how the development workflow will change now that we&#8217;re finally releasing the code in master as 0.25.  After much discussion, we largely concluded that the least-surprise solution was to use the &#8216;master&#8217; branch for stable development, and have something like a &#8216;next&#8217; branch for new features and major refactorings.</p>
<p>The main goal is for new developers to be able to clone our repository and get to developing code immediately without having to worry about switching branches or any such thing.  More experienced developers will know where their development should be done, so it&#8217;s mostly a question of least-surprise for newcomers.</p>
<p>There was also discussion of fly-by-night developers, people who show up, produce a patch or two, and wander off.  James Turnbull (who handles 99% of the merging and release management) said he was fine accepting patches over email, rather than forcing people to publish everything via git.</p>
<p>Other than those two changes, our development workflow has worked pretty well.  However, the fly-by-night patches led into discussion of&#8230;</p>
<h2>Core vs. Modules</h2>
<p>Puppet&#8217;s core is starting to get many non-core features, like Nagios and Zenöss integration.  It&#8217;s essentially impossible for the core team to maintain all of these extentions, but many of them were written as a one-off solution and won&#8217;t be maintained by their authors.  Because of this, we  as a project need to develop a means of splitting Puppet&#8217;s core away from all of these modules.</p>
<p>Discussion was had of using a Nagios-style &#8216;plugins&#8217; repository, but I don&#8217;t like that idea because it leaves basically the same problem &#8211; a centralized repository that no one wants to maintain.</p>
<p>Instead, we all basically agreed that we want to focus on modules as the means of adding functionality to Puppet, but the big problem there is that the only way to do so is to add package-like behaviours to modules, and none of us wants to make our own package manager.  Nonetheless, it was agreed that this was the only real option, so it just remains to do it.</p>
<h2>Roadmap and Release Status</h2>
<p>Against all odds, it looks like we&#8217;ll get 0.25 out in February &#8211; I&#8217;ll be merging in the last major refactor this week, and then it&#8217;s just a question of getting as many bug-fixes in as we can and dropping the release.</p>
<p>In addition, there are (annoyingly) a few important bugs in 0.24.7, so we&#8217;re unfortunately going to have to be put out a 0.24.8 release.  One thing that&#8217;s become clear in the last couple of releases is that we need to get more community testing of release candidates &#8211; many of the bugs would have been caught by basic testing in the community.</p>
<h2>Facter Design and Shadow{Facter,Puppet}</h2>
<p>RailsMachine released <a href="http://github.com/railsmachine/shadow_puppet/tree/master">ShadowPuppet</a> and <a href="http://github.com/railsmachine/shadow_facter/tree/master">ShadowFacter</a> in the last few weeks, and it&#8217;s led to a flurry of design conversations.  We didn&#8217;t cover too much of it in the dev call, other than my reiteration that I&#8217;m excited by them and would like to merge them into Puppet and Facter.</p>
<h2>Conclusion</h2>
<p>And that was it.  Please join us on the next call if you can.</p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2009/02/05/summary-of-february-2009-puppet-developer-call/feed/</wfw:commentRss>
		<slash:comments>111</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>
		<item>
		<title>Building a Puppet Roadmap</title>
		<link>http://madstop.com/2008/10/29/building-a-puppet-roadmap/</link>
		<comments>http://madstop.com/2008/10/29/building-a-puppet-roadmap/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 23:05:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Puppet]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[roadmap]]></category>

		<guid isPermaLink="false">http://madstop.com/?p=23</guid>
		<description><![CDATA[We've had a Roadmap for a while, but it's pretty simplistic, and I haven't had enough of a plan to be able to reasonably maintain it.  In our call today, though, we came up with a pretty clear plan for what we're going to do next, when we're going to do it, and what version numbers it will have.  Here's a summary of what we decided (which I'll then be importing into the roadmap document, where it will actually be maintained). <a href="http://madstop.com/2008/10/29/building-a-puppet-roadmap/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just got off a Puppet developer call (for which we have a <a href="http://reductivelabs.com/podcast/dircaster.php">podcast</a>), and we&#8217;ve finally developed a slightly-less-rudimentary Roadmap.</p>
<p>We&#8217;ve had a <a href="http://reductivelabs.com/trac/puppet/wiki/RoadMap">Roadmap</a> for a while, but it&#8217;s pretty simplistic, and I haven&#8217;t had enough of a plan to be able to reasonably maintain it.  In our call today, though, we came up with a pretty clear plan for what we&#8217;re going to do next, when we&#8217;re going to do it, and what version numbers it will have.  Here&#8217;s a summary of what we decided (which I&#8217;ll then be importing into the roadmap document, where it will actually be maintained).</p>
<ul>
<li>0.24.7: We&#8217;re going to get this release out as soon as possible (most likely around the middle of November), with any critical fixes resulting from the 0.24.6 release.  <strong>This will be the last stable release in the 0.24.x line.</strong></li>
<li>0.25: This release will be the first release from the master branch, and is planned for the end of the year.  Its primary changes will be all of the plumbing to support REST, plus converting, at a minimum, file serving and catalog retrieval to using REST.</li>
<li>0.26: This release will convert any remaining XMLRPC network APIs to REST, and will be the last release before 1.0. It should be out in the second quarter of 2009.</li>
<li>1.0: This release stabilizes the network API:  According to the plan, projects developed against its API should work going forward.</li>
</ul>
<p>We&#8217;ve got less detail on the 2.0 and 3.0 releases, but we&#8217;ve got main targets for them.  The 2.0 release will focus on refactoring the transactional system, and the 3.0 release will focus on refactoring the RAL extension interfaces.</p>
<p>Now that we&#8217;ve got a version roadmap, we can begin doing realistic ticket assignments to those different versions.</p>
<p>Of course, we&#8217;ll still need a lot of help from the community to get all of the tickets done that we want to complete.  The versions will have a key deliverable, and that&#8217;s what I&#8217;ll be focusing on, but we&#8217;ll want a lot more in each release, and that&#8217;s where we&#8217;ll need help.</p>
]]></content:encoded>
			<wfw:commentRss>http://madstop.com/2008/10/29/building-a-puppet-roadmap/feed/</wfw:commentRss>
		<slash:comments>81</slash:comments>
		</item>
	</channel>
</rss>
