<?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>Anchor Web Hosting Blog &#187; automation</title>
	<atom:link href="http://www.anchor.com.au/blog/tag/automation/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.anchor.com.au/blog</link>
	<description>A view into the Anchor Engineroom</description>
	<lastBuildDate>Wed, 08 Feb 2012 00:51:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Anchor Presenting at DevOps Meetup &#8211; Thursday September 15th</title>
		<link>http://www.anchor.com.au/blog/2011/09/anchor-presenting-at-devops-meetup-thursday-september-15th/</link>
		<comments>http://www.anchor.com.au/blog/2011/09/anchor-presenting-at-devops-meetup-thursday-september-15th/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 06:13:22 +0000</pubDate>
		<dc:creator>Keiran Holloway</dc:creator>
				<category><![CDATA[FTW]]></category>
		<category><![CDATA[Newsletter]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[beer]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[server builds]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.anchor.com.au/blog/?p=1933</guid>
		<description><![CDATA[Just a short post to let you all know that Anchor&#8217;s David Basden and Chris Collins will be presenting their software which is being used in our on-going projects to automate everything relating to Anchor dedicated server builds. The software, which has been released as open source on github as was discussed in brief in [...]]]></description>
			<content:encoded><![CDATA[<p>Just a short post to let you all know that Anchor&#8217;s David Basden and Chris Collins will be presenting their software which is being used in our on-going projects to automate everything relating to Anchor <a href="http://www.anchor.com.au/servers/dedicated-servers/" title="Dedicated servers">dedicated server</a> builds.</p>
<p>The software, which has been released as <a href="https://github.com/anchor">open source on github</a> as was discussed in brief in the previously two blog posts <a href="http://www.anchor.com.au/blog/2011/08/the-automation-waltz/" title="The automation waltz">The automation waltz</a> and <a href="http://www.anchor.com.au/blog/2011/08/automate-all-the-things/" title="Automate all the things">Automate all the things</a>. </p>
<p>The event will be held at 7pm, next Thursday, 15th September at the Orient in Sydney and will give you the fantastic opportunity to have a beer and chat with the authors of the software as well as like minded people with both developer and systemadmin backgrounds. </p>
<p>Comprehensive details as well as registration for the meetup can be found at <a href="http://www.meetup.com/devops-sydney/events/29079101/" title="September DevOps Meetup">September DevOps Meetup</a>  </p>
<p>Look forward to seeing you then! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.anchor.com.au/blog/2011/09/anchor-presenting-at-devops-meetup-thursday-september-15th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AUTOMATE ALL THE THINGS!</title>
		<link>http://www.anchor.com.au/blog/2011/08/automate-all-the-things/</link>
		<comments>http://www.anchor.com.au/blog/2011/08/automate-all-the-things/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 01:06:20 +0000</pubDate>
		<dc:creator>David Basden</dc:creator>
				<category><![CDATA[FTW]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[make-magic]]></category>
		<category><![CDATA[mudpuppy]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[orchestra]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[server builds]]></category>
		<category><![CDATA[sys-admin toys]]></category>
		<category><![CDATA[system configuration]]></category>

		<guid isPermaLink="false">http://www.anchor.com.au/blog/?p=1913</guid>
		<description><![CDATA[You can’t walk two metres down the street without someone going on about how cool and hip &#8220;The Cloud&#8221; is these days, being able to spin up hundreds of identical Linux VMs easily. Tools to build and configure lots of identical systems or VMs are plentiful. But what if there is no “standard build” or [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1919" class="wp-caption alignright" style="width: 330px"><a href="http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html"><img class="size-full wp-image-1919" src="http://www.anchor.com.au/blog/wp-content/uploads/2011/08/automate-all-the-things1.png" alt="" width="320" height="240" /></a><p class="wp-caption-text">Illustration © Allie Brosh of Hyperbole and a Half</p></div>
<p>You can’t walk two metres down the street without someone going on about how cool and hip &#8220;The Cloud&#8221; is these days, being able to spin up hundreds of identical Linux VMs easily. Tools to build and configure lots of identical systems or VMs are plentiful.</p>
<p>But what if there is no “standard build” or even anything close, with different hardware, networking, software, distro, services, firewalls etc. every time, but you don’t want to spend all your time doing custom server builds and configuration?</p>
<p>Being a provider that specialises in customised hosting solutions, not only do most of our server builds have custom requirements, but we also have to configure lots of our own internal systems to deal with the eccentricities of each new server that we bring up. We have systems for monitoring, notifications, backups, fire-walling, accounting, scheduling of system updates, and that&#8217;s only a sampling of them.</p>
<p>We heavily use tools like puppet to automate things, but with almost every server being different, even configuring the tools designed to automate configuration starts taking serious time. For us, building a custom system and customising the systems that support it can take one of our sysadmins the best part of a day.</p>
<p>To solve this problem we’ve written some software that will take vague hand-waving from sales people[0] and turn it into a deterministic set of build steps that can be automated, without a sysadmin being involved at all. We now have heterogeneous server builds that are fully automated, and spun up in minutes rather than days. Rather than yet another bland VM copy, you get a beautiful and unique snowflake of awesome.</p>
<p>Even more fun, we&#8217;ve released them all as free software under the modified BSD license.</p>
<p>The first tool is called make-magic. Its job is to turn the high level requirements (I want a webserver and I want it blue) in to a detailed set of steps that can be automated (Find an online-paint shop. Buy some blue paint. Get it shipped to the data centre. etc.).</p>
<p>The core of make-magic can be guaranteed to always output a valid, correct list of steps for any set of input requirements. It even keeps track of which ones are done, which steps require others to be done first, and can let you know which ones can be done all at the same time.</p>
<p>There are some really interesting underlying problems that come up when you have to automatically generate a really specific, and provably correct set of steps from hundreds of thousands of permutations based on some high level requirements. We&#8217;ve beaten our heads against those brick walls, put it in a box, and posted it on github. You can find it at <a title="https://github.com/anchor/make-magic" href="https://github.com/anchor/make-magic">https://github.com/anchor/make-magic</a></p>
<p>Fun as it is, we still don&#8217;t want to have to go through and do those steps ourselves. This is where the second tool, mudpuppy, comes in.</p>
<p>mudpuppy is a Python based automation agent/client for make-magic. It allows you to write independent &#8216;modules&#8217; in Python code, to automate items in a make-magic task. When run, mudpuppy will poll the make-magic server for tasks that need to be done, and will automate any items which it has a module for. Once the module has run successfully, mudpuppy will tell make-magic that the item has been completed, and will look for more work to do.</p>
<p>You can find mudpuppy on github at <a title="https://github.com/anchor/mudpuppy" href="https://github.com/anchor/mudpuppy">https://github.com/anchor/mudpuppy</a></p>
<p>mudpuppy isn&#8217;t the only tool that can be controlled by make-magic. make-magic has a simple, well defined JSON based HTTP API that mudpuppy uses, and which should be easy to talk to with most languages.</p>
<p>Earlier this month, Chris wrote about Orchestra, a set of tools for fast, reliable remote job execution on remote servers. mudpuppy is able to talk directly to Orchestra and get it to spin off jobs, get back the results, and use it to update information in make-magic. No extra parts required: They talk to each other out of the box.</p>
<p>As mentioned in Chris&#8217;s post, you can find Orchestra on github at <a title="https://github.com/anchor/orchestra" href="https://github.com/anchor/orchestra">https://github.com/anchor/orchestra</a></p>
<p>The combination of make-magic, mudpuppy and Orchestra (plus puppet, whatever else you might have lying around, or anything you&#8217;ve always wanted to try) give us the ability at the end of the day for us to build custom servers faster, reliably, and with ludicrously more flexibility than with any other systems that automate server builds that we&#8217;ve come across. Hopefully you&#8217;ll find them useful too.</p>
<p>If you&#8217;re interested in learning some more, Chris and I will be talking at the Sydney DevOps meetup on the 15th of September. There&#8217;s more details at <a title="http://devops.meetup.com/cities/au/sydney/" href="http://devops.meetup.com/cities/au/sydney/">http://devops.meetup.com/cities/au/sydney/</a></p>
<p>[0] Actually our &#8220;sales&#8221; people are pretty technical themselves, so they tend to wave their hands in the right direction.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.anchor.com.au/blog/2011/08/automate-all-the-things/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Automation Waltz</title>
		<link>http://www.anchor.com.au/blog/2011/08/the-automation-waltz/</link>
		<comments>http://www.anchor.com.au/blog/2011/08/the-automation-waltz/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 08:36:47 +0000</pubDate>
		<dc:creator>Chris Collins</dc:creator>
				<category><![CDATA[FTW]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[go]]></category>
		<category><![CDATA[golang]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[orchestra]]></category>

		<guid isPermaLink="false">http://www.anchor.com.au/blog/?p=1763</guid>
		<description><![CDATA[When you have a bunch of machines involved in a process, you need to ensure that various stages in this process have executed. If the target host is unavailable, you want a guarantee that the job will execute when the host becomes available again.  This is well beyond the capabilities of ssh in a for-loop. [...]]]></description>
			<content:encoded><![CDATA[<p>When you have a bunch of machines involved in a process, you need to ensure that various stages in this process have executed. If the target host is unavailable, you want a guarantee that the job will execute when the host becomes available again.  This is well beyond the capabilities of ssh in a for-loop.</p>
<p>In trying to solve this problem, we had assessed tools like <a href="http://www.puppetlabs.com/mcollective/introduction/">mcollective</a>, but came to the conclusion that they were inappropriate for our environment.  mcollective in particular was removed from consideration as it was designed for a more homogeneous environment than the one here at Anchor.</p>
<p>When we realised we needed a different solution, a few of us gathered around a whiteboard and started enumerating our requirements.  The result was <a href="http://github.com/anchor/Orchestra">Orchestra</a>, which we&#8217;re releasing today under the BSD License.</p>
<p>Orchestra is a suite for managing the reliable execution of tasks over a number of hosts. It is intended to be simple and secure, leaving more complicated coordination and tasks to tools better suited for those jobs.</p>
<p>Because everybody loves this web development stuff, it was developed to provide an interface that operates asynchronously in relation to the<br />
execution of the work being done, allowing for cheap and easy polling of job state.</p>
<p>And last, but not least, because having critical system services depend on potentially fragile language interpreters or their libraries is generally a really bad idea for reliability, it was completely implemented in <a href="http://www.golang.org/">Go</a> - a type-safe static language that compiles to native code and includes many features derived from dynamic languages. Despite this, the work units it executes for you can be written in any language you like.</p>
<p>Orchestra itself is far from finished, but it&#8217;s working reliably enough that we&#8217;re already using it in production in a very limited capacity, and have been slowly extending it&#8217;s reach into new areas as appropriate.</p>
<p>We&#8217;d love you to take a look and see if it works for you, we&#8217;re open to suggestions and contributions for improvement. If you&#8217;re after a quick overview, doc/orchestra.tex is a good place to start, and the samples/ directory contains commented config files for the various daemons.</p>
<p>We don&#8217;t believe in duplicating functionality, so it&#8217;s assumed that your config, SSL certificates and scores are distributed by another automation tool &#8211; we use puppet. Utilities like <a href="http://cr.yp.to/daemontools.html">daemontools</a> or <a href="http://god.rubyforge.org/">god</a> do a great job of keeping your daemons running.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.anchor.com.au/blog/2011/08/the-automation-waltz/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bringing the Mountain to Mohamed</title>
		<link>http://www.anchor.com.au/blog/2009/11/bringing-the-mountain-to-mohamed/</link>
		<comments>http://www.anchor.com.au/blog/2009/11/bringing-the-mountain-to-mohamed/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 15:12:59 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[FTW]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[project starbug]]></category>
		<category><![CDATA[rsync]]></category>

		<guid isPermaLink="false">http://www.anchor.com.au/blog/?p=1341</guid>
		<description><![CDATA[I have never in my life been asked, &#8220;How do porcupines make love?&#8221;. However, I know the answer very well: &#8220;very carefully&#8221;. In the same vein, when migrating the mass of data that makes up Github, you take your time and you work very, very carefully. Since this sort of migration doesn&#8217;t happen every day, [...]]]></description>
			<content:encoded><![CDATA[<p>I have never in my life been asked, &#8220;How do porcupines make love?&#8221;. However, I know the answer very well: &#8220;very carefully&#8221;.  In the same vein, when migrating the mass of data that makes up Github, you take your time and you work very, <em>very</em> carefully.  Since this sort of migration doesn&#8217;t happen every day, and it&#8217;s not something you <em>want</em> to be learning on the job, I thought I&#8217;d write down my experiences for posterity.</p>
<h3>SCRIPT IT!</h3>
<p>As a big fan of automation, there wasn&#8217;t much chance that this whole thing wasn&#8217;t going to be scripted up the wazoo.  We just need to copy the filesystem data across, dump the database and load it into the new site&#8230; and we&#8217;re done.  Right?</p>
<p>HA!  Not likely.  To give you an idea of the scale of this thing, it took close to 24 hours just to do an rsync scan of the repository filesystems, <em>without</em> actually copying any data.  Then there&#8217;s the database &#8212; the events table alone contained approximately 81.5 million records, which took a great many hours to dump from the live database during pre-migration work.  It doesn&#8217;t take a great mathematician to realise that copying all this data over the Internet while the site was down for business wasn&#8217;t going to fly.</p>
<p>Initially, we were going to rely on the bandwidth of a station wagon full of tapes (or a couple of USB drives in a FedEx jet, anyway) to do the initial copying of data.  However, due to some technical problems at the old facility, the &#8220;average transfer rate&#8221; wasn&#8217;t very high (the copy to disk took several <em>weeks</em> to complete), and we ended up kicking off a network-based initial sync of the repository data that finished less than half an hour after the drives were plugged into the machines at the new data centre.  While I&#8217;m still a fan of shipping disks around for large-scale transfers, I won&#8217;t discount using the Internet to transfer such a large data set around so quickly next time.</p>
<h4>Incrementalism</h4>
<p>Since a single real-time copy wasn&#8217;t practical, we&#8217;d have to look to incremental copying, where we pre-sync as much data as possible before the Big Cutover Day, and then only copy the latest changes while the site is down.</p>
<p>Thankfully, Github&#8217;s software design has pretty much all the hooks we needed to make this a straightforward task.  For example, we didn&#8217;t have to dump the entire events table, because once a row is written it&#8217;s never changed &#8212; so we only need to dump events that were created since the last dump.</p>
<p>The system also keeps track of the last time a repository was changed, which means that we can ask the database for a list of repositories that have changed since the last sync, which makes for a very simple (and quick!) incremental sync.  For a smaller data set we would just use rsync directly, but due to the performance limitations of the previous hosting environment, this took far, <em>far</em> too long to do with just rsync.</p>
<p>So, we can script everything, and there&#8217;s the ability to do repeated incremental syncs.  What do these scripts look like?</p>
<p>Well, first up, there&#8217;s a lot of them.  It was best to write separate scripts to synchronise each data set &#8212; one for the repositories, one for the events table, one for the rest of the database, one for gists, and so on.  This meant that it was fairly trivial to develop these scripts in parallel, and they could be tested and run independently of each other.  </p>
<p>Also, each task that had to be performed for a given data set was in its own script, so each step could be tested independently.  For example, the repo sync job consisted of one script to collect the list of repos that needed resyncing and write that list to disk, another script to sync a single repository, and a third script to loop over all the repos listed by the first script and invoke the second script for each of them.</p>
<p>The other important properties of these scripts were:</p>
<ul>
<li>We relied heavily on multitasking to overcome bandwidth limitations from a single TCP stream.  When you&#8217;re copying data over high capacity links, your available transfer rate is constrained more by the round-trip time between the endpoints than the available bandwidth &#8212; the longer it takes for an ACK to get back to the sender, the slower your data will flow.  So, since we had eight filesystems to copy data from, we fired off eight parallel rsync processes as child processes of the individual scripts.</li>
<li>Each script kept track of what it was doing and what it had done, and tried to avoid doing the same work again.  The repository syncs kept track of the repositories that had already been copied by means of a timestamp file &#8212; when we did a sync, we touched a file and then used the mtime of that file (<tt>stat -c %Y</tt> ftw!) to determine the start time of the next sync. The events table was straightforward &#8212; before each dump, we just ask the destination table where it&#8217;s up to, and dump from there.  Even the &#8220;main&#8221; database, which we dumped in it&#8217;s entireity each time, was dumped to a file compressed with `gzip &#8211;rsyncable` before being rsync&#8217;d across, saving a good few minutes of network transfer time on each cycle.</li>
<li>If something went wrong during the sync, we knew about it immediately. We wired up a small SMS sending script to send us alerts if the script terminated improperly.  This saved us a lot of waiting and watching, because we knew that we&#8217;d be told when we had to take notice of what&#8217;s going on.</li>
<li>Everything was logged.  The stdout and stderr of all processes was captured, and the scripts wrote their own log entries to that stream as well as to a &#8220;summary&#8221; log, like this: <tt>echo $(date) processing repo $repo |tee -a $LOGFILE</tt>.  Any errors were tagged with a unique string and written in a machine-parseable format, so we could re-run any failed components of the sync to ensure that nobody was missed.</li>
<li>While there were typically several scripts that had to be run in an appropriate order to make a sync happen, there was always a single script that did everything that needed doing &#8212; we never had to run more than one command to get a given sync done.</li>
</ul>
<p>Once all of these individual scripts had been written, tested, debugged, tested a few more times, and generally fretted over until our nails were chewed to the quick, it was time to assemble the master script.  I&#8217;m not about to run a dozen scripts to migrate a site when one will suffice.  This was particularly important in Github&#8217;s case because to minimise downtime we wanted to run several things in parallel, then wait until they&#8217;d all finished, then run the syncs that depended on the data we&#8217;d synced in the last lot, and so on.  Our scripts looked a lot like this:</p>
<pre>
task1 &gt;logs/task1.log 2&gt;&amp;1 &amp;
task1_pid=${!}

task2 &gt;logs/task2.log 2&gt;&amp;1 &amp;
task2_pid=${!}

wait $task1_pid
wait $task2_pid

task3 &gt;logs/task3.log 2&gt;&amp;1 &amp;
task3_pid=${!}

task4 &gt;logs/task4.log 2&gt;&amp;1 &amp;
task4_pid=${!}

task5 &gt;logs/task5.log 2&gt;&amp;1 &amp;
task5_pid=${!}

wait $task3_pid
wait $task4_pid
wait $task5_pid
</pre>
<p>There was also a pile of &#8220;doing this, now doing this, now doing this&#8221; logging (with timestamps) that helped us to get a feel for how long the different parts would take, and where everything was up to.</p>
<p>When we actually performed the cutover, the &#8220;main&#8221; sync script was running for a total of 27 minutes. Given that we&#8217;d given ourselves an hour to get everything across, we were all quite pleased with this outcome.</p>
<h4>Putting on the brakes</h4>
<p>Whilst all these scripts ran really well, and the background processes made everything run really fast, I must say it was a right pain in the butt to stop things mid-flight when it was necessary.  Hitting Ctrl-C only stopped the foreground (controller) script, and all of the children that had been started in the background kept flying along.</p>
<p>Doing this again, I&#8217;d make sure all my scripts had traps on SIGINT that killed off all the child processes that they had spawned.  In retrospect, this is just a variant of &#8220;one script to start everything&#8221; &#8212; you should only need to do one thing (Ctrl-C) to stop it all, as well.</p>
<p>Also, the timestamp files weren&#8217;t handled real well.  If you did kill things off mid-run (or, heaven forbid, a script crashed out) then the timestamp files would be wrong, because we just did a straight touch at the beginning of the script.  What would have been better would be something like this:</p>
<pre>
touch stamp.new
do_all_the_work
mv stamp stamp.prev
mv stamp.new stamp
</pre>
<p>This would make sure that premature death would leave the stamp as-is, while still capturing the true start time of the job (which a simple touch at the end would fail to do).</p>
<h3>When Databases Attack</h3>
<p>Testing the new site before we let users at it, we found that creating gists wasn&#8217;t working right.  It turned out that the database dumping script didn&#8217;t have the right set of options, and the schemas of the tables weren&#8217;t quite right (no autoincrements), and that was giving gist creation conniptions.  Thankfully, the bug in the script was quickly spotted and the database dump was re-run.  We even managed to get the second dump and load completed before our scheduled maintenance window was finished.  If our scripts hadn&#8217;t<br />
been broken down by data set, this resyncing process would have been made a whole lot harder because we wouldn&#8217;t have been able to easily run <em>just</em> the parts that needed to be redone.</p>
<p>Once we opened the floodgates of the new site, everything ran happily for a minute or two, and then ground to a halt.  The whaaaaa?  Poke, prod&#8230; hmm, the database is running a bit hotter than I&#8217;d expect&#8230; whoa!  1500 queries active, all against the events table, with the disks working so hard the heads nearly came out the sides of the cases.  What&#8217;s going on here?</p>
<p>As it turns out, schema insanity had struck again &#8212; this time, <em>some</em> of the indexes on the events table had failed to come across.  While we know what happened with the main database dump, this one is still a mystery.  How did <em>some</em> of the indexes fail to materialise?  We&#8217;ve gone over the dumps and can&#8217;t find how they got lost.  We&#8217;re putting it down to yet another case of MySQL doing dumb things without telling anyone.</p>
<h3>Limiting the impact</h3>
<p>As a final small improvement to the migration process, the site was able to into a &#8220;read only&#8221; mode, so that users could still browse code and pull from repositories while we were migrating.  This made the migration a lot less intrusive for users, because a lot of site functions still worked, especially those made by casual users (who would be less likely to know all about the time of the migration).</p>
<h3>Lessons Learnt</h3>
<p>Here are a few things I&#8217;ll definitely do differently next time:</p>
<ul>
<li>Anywhere you&#8217;re depending on a third party to execute part of your migration, have a backup plan in case they can&#8217;t deliver &#8212; and know when you&#8217;ll have to execute your backup plan.  In our case, knowing exactly how long it would have taken to copy all the data over the Internet and then calculating back, we would have known to start copying over the network a few days earlier than we did. </li>
<li>Make sure that synchronisation scripts are as easy to stop as they are to start.</li>
<li>Verify the database schemas completely on the destination DB server by manual inspection, as well as dumping them and comparing to what&#8217;s on the source DB server.</li>
</ul>
<p>I wonder when we&#8217;ll get our next Github-scale migration&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.anchor.com.au/blog/2009/11/bringing-the-mountain-to-mohamed/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SaaS (Socks as a Service)</title>
		<link>http://www.anchor.com.au/blog/2008/12/saas-socks-as-a-service/</link>
		<comments>http://www.anchor.com.au/blog/2008/12/saas-socks-as-a-service/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 02:47:29 +0000</pubDate>
		<dc:creator>Barney Desmond</dc:creator>
				<category><![CDATA[FTW]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[black]]></category>
		<category><![CDATA[socks]]></category>
		<category><![CDATA[sockscription]]></category>
		<category><![CDATA[subscription]]></category>

		<guid isPermaLink="false">http://www.anchor.com.au/blog/?p=158</guid>
		<description><![CDATA[http://www.blacksocks.com/ I came across this rather amusing company a little while ago. They&#8217;ve been around since before the turn of the millennium but I somehow hadn&#8217;t stumbled upon them until now. What with everything turning web2.0-ey nowadays, I&#8217;d say they&#8217;ve got themselves a nice little niche. In case you&#8217;re too busy to visit (or too [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.blacksocks.com/">http://www.blacksocks.com/</a></p>
<p>I came across this rather amusing company a little while ago. They&#8217;ve been around since before the turn of the <span class="query">millennium but I somehow hadn&#8217;t stumbled upon them until now. What with everything turning web2.0-ey nowadays, I&#8217;d say they&#8217;ve got themselves a nice little niche.</span></p>
<p>In case you&#8217;re too busy to visit (or too much of a slacker, <a href="http://www.urbandictionary.com/define.php?term=tldr">TL;DR!</a>), the concept is simple: you pay a yearly subscription fee (they call it a &#8220;sockscription&#8221;), and they keep sending you pairs of nice new black socks. It&#8217;s a very cute idea that has wide-ranging appeal and applicability. It also abides by one of the general rules for sysadmins, which is to automate whatever you can; the less time you waste thinking about repeatable tasks, the more time you have for fun things.</p>
<p>Right now I&#8217;m lamenting the state of the Aussie dollar, as the billing amounts will be in USD. However, this is far too compelling a concept to ignore, and the current state of my sock drawer is positively unacceptable with only two pairs of plain blacks socks (both with holes, no less!). One does not wear white sports socks with black patent leather lace-ups, it&#8217;s just not done (hey, I like to <em>dress</em> up). I&#8217;ll have to put in an order as soon as possible, those kneesocks look like just the ticket.</p>
<p><em><span style="normal;"><span class="t_nihongo_kanji" lang="ja">かえして！ニーソックス</span></span></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.anchor.com.au/blog/2008/12/saas-socks-as-a-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

