<?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>Free Software Archives &#8211; Structured Procrastination</title>
	<atom:link href="https://blog.adamspiers.org/tag/free-software/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.adamspiers.org/tag/free-software/</link>
	<description>because there&#039;s always something more interesting than what you should be doing</description>
	<lastBuildDate>Tue, 19 Jun 2018 13:18:19 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://blog.adamspiers.org/wp-content/uploads/2018/12/cropped-IMG_20160907_193859-PANO-c-7-32x32.jpg</url>
	<title>Free Software Archives &#8211; Structured Procrastination</title>
	<link>https://blog.adamspiers.org/tag/free-software/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>git branch auto-magic: git-splice, git-transplant, git-deps, and announcing git-explode!</title>
		<link>https://blog.adamspiers.org/2018/06/14/git-auto-magic/</link>
					<comments>https://blog.adamspiers.org/2018/06/14/git-auto-magic/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Thu, 14 Jun 2018 22:00:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[backporting]]></category>
		<category><![CDATA[branches]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[forward-porting]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[upstreaming]]></category>
		<category><![CDATA[version control]]></category>
		<category><![CDATA[workflow]]></category>
		<guid isPermaLink="false">https://blog.adamspiers.org/?p=1655</guid>

					<description><![CDATA[<p>For the last few years I&#8217;ve been enjoying the luxury of SUSE&#8217;s generous HackWeek policy to work on building four tools supporting higher-level workflows on top of git. I&#8217;d already (quietly) announced three of them: git-splice, git-transplant, git-deps (more details below). But I&#8217;m now excited to announce that I&#8217;ve just released the fourth: git-explode ! [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2018/06/14/git-auto-magic/">git branch auto-magic: git-splice, git-transplant, git-deps, and announcing git-explode!</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> For the last few years I&#8217;ve been enjoying the luxury of SUSE&#8217;s generous <a href="https://hackweek.suse.com/about">HackWeek</a> policy to work on building four tools supporting higher-level workflows on top of <code>git</code>.  I&#8217;d already (quietly) announced three of them: <code>git-splice</code>, <code>git-transplant</code>, <code>git-deps</code> (more details below).  But I&#8217;m now excited to announce that I&#8217;ve just released the fourth: <a href="https://github.com/aspiers/git-explode"><code>git-explode</code></a> ! </p>
<p> <code>git-explode</code> automatically explodes a large topic branch into a set of smaller, independent topic branches.  It does this by harnessing <code>git-deps</code> to automatically detect inter-dependencies between commits in the large source branch and using that dependency tree to construct the smaller topic branches. </p>
<p> I recently presented all four tools at a Meetup of the <a href="http://londongit.org/">Git London User Group</a>, and thanks to the awesome services of the host venue <a href="https://skillsmatter.com/">Skills Matter</a>, I&#8217;m delighted to announce that the <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">talk is now online</a>: </p>
<div class="figure">
<p><a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic" width="99%" align="center" alt="video of my talk on git auto-magic at the Git London User Group Meetup" title="my talk on git auto-magic at the Git London User Group Meetup"><img decoding="async" src="https://blog.adamspiers.org/wp-content/uploads/2018/06/automagic.png" alt="video of my talk on git auto-magic at the Git London User Group Meetup" width="99%" align="center" title="my talk on git auto-magic at the Git London User Group Meetup" /></a> </p>
</p></div>
<p> If you don&#8217;t have time to watch the whole thing, you can look at <a href="https://aspiers.github.io/london-git-automagic-may-2018/">the slides</a>, or just keep on reading to see which ones you might be interested in.  I&#8217;ll list them first, and then talk about the motivation for writing them. </p>
<p><span id="more-1655"></span></p>
<div id="outline-container-orge9751bc" class="outline-2">
<h2 id="orge9751bc">The tools</h2>
<div class="outline-text-2" id="text-orge9751bc">
<p> The first pair are available as patches to <code>git</code> itself: </p>
<ul class="org-ul">
<li>
<p> <a href="https://github.com/git/git/compare/master...aspiers:splice">git-splice</a> &#8211; splices commits onto/into/out of current branch </p>
<p> Jump to 08:44 in <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">the video</a> to see me introduce and demo this, or <a href="https://aspiers.github.io/london-git-automagic-may-2018/#/splice-transplant">look at the slides</a>, or <a href="https://github.com/aspiers/git/blob/splice/Documentation/git-splice.txt">read the man page</a> for example usage. </p>
</li>
<li>
<p> <a href="https://github.com/aspiers/git/compare/splice...transplant">git-transplant</a> &#8211; transplants commits from current branch onto/into another </p>
<p> Jump to 32:22 in <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">the video</a> to see me introduce and demo this, or <a href="https://aspiers.github.io/london-git-automagic-may-2018/#/transplant">look at the slides</a>, or <a href="https://github.com/aspiers/git/blob/transplant/Documentation/git-transplant.txt">read the man page</a> for example usage. </p>
</li>
</ul>
<p> The second pair are available as Python modules on PyPI, but both have a command-line interface too: </p>
<ul class="org-ul">
<li>
<p> <a href="https://github.com/aspiers/git-deps">git-deps</a> &#8211; automatically detects textual dependencies between commits </p>
<p> Jump to 41:28 in <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">the video</a> to see me introduce and demo this, or <a href="https://aspiers.github.io/london-git-automagic-may-2018/#/deps">look at the slides</a>, or <a href="https://github.com/aspiers/git-deps/blob/master/README.md">read the README</a> (which has a couple of short YouTube videos demoing the tool including the fancy web interface), or read <a href="https://blog.adamspiers.org/git-deps">my previous blog post about this</a>. </p>
</li>
<li>
<p> <a href="https://github.com/aspiers/git-explode">git-explode</a> &#8211; explodes a linear sequence of git commits into new independent topic branches </p>
<p> Jump to 51:10 in <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">the video</a> to see me introduce and demo this, or <a href="https://aspiers.github.io/london-git-automagic-may-2018/#/firework">look at the slides</a>, or <a href="https://github.com/aspiers/git-explode/blob/master/README.rst">read the README</a>. </p>
</li>
</ul>
<p> It&#8217;s taken a while to get them to a reasonable degree of polish, during which this work has been mostly under the radar, but now I&#8217;m now going to make a more concerted effort to advertise the tools, hence this blog post. </p>
</div>
</div>
<div id="outline-container-org7927f37" class="outline-2">
<h2 id="org7927f37">The Big Idea</h2>
<div class="outline-text-2" id="text-org7927f37">
<p> (Jump to 02:27 in <a href="https://skillsmatter.com/skillscasts/11825-git-auto-magic">the video</a> to see me talk about this, or <a href="https://aspiers.github.io/london-git-automagic-may-2018/#/problems">look at the slides</a>.) </p>
<p> All developers face common problems: </p>
<ul class="org-ul">
<li>It&#8217;s difficult to predict what you&#8217;ll be doing next.  One minute you might be working on a feature, the next you find a bug you need to fix, and the next you find some technical debt which requires refactoring.</li>
<li>Multi-tasking is almost unavoidable.</li>
<li>We&#8217;re human, so we sometimes screw up when trying to follow best practice workflow.</li>
</ul>
<p> What does this mean when using <code>git</code>?  Typically it means we are constantly juggling branches, and often need to manipulate the history of branches for various reasons, for example: </p>
<ul class="org-ul">
<li>Maintaining clean separation of topics between branches to facilitate code reviews: one branch for a refactoring, one for a bugfix, one for a feature, and so on.</li>
<li><a href="https://blog.adamspiers.org/easier-upstreaming-with-git/">Backporting or forward-porting series of patches between branches.</a></li>
</ul>
<p> My feeling is that while the <code>git</code> ecosystem has continued to evolve incrementally over the last few years, not much progress has been made in terms of automating this janitorial work, and that most people either do it by hand, or don&#8217;t bother doing it at all.  This leads to unclean history, and/or more work and frustration for reviewers. </p>
<p> So I wrote these tools (<a href="https://blog.adamspiers.org/easier-upstreaming-with-git/">and others</a>) in an attempt to push the boundaries of automating git workflows to higher levels, <a href="https://public-inbox.org/git/20170801011421.veyuviur3mi4hjir@pacific.linksys.moosehall/">as I explained on the <code>git</code> mailing list last year</a>.  Even if all the use cases they can cover have yet to be discovered, I hope you find them useful, or at least thought-provoking enough that you might join the effort! </p>
<p> I&#8217;d love some feedback, so do let me know what you think in the comments below. </p>
</div>
</div>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2018%2F06%2F14%2Fgit-auto-magic%2F&#038;title=git%20branch%20auto-magic%3A%20git-splice%2C%20git-transplant%2C%20git-deps%2C%20and%20announcing%20git-explode%21" data-a2a-url="https://blog.adamspiers.org/2018/06/14/git-auto-magic/" data-a2a-title="git branch auto-magic: git-splice, git-transplant, git-deps, and announcing git-explode!"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2018/06/14/git-auto-magic/">git branch auto-magic: git-splice, git-transplant, git-deps, and announcing git-explode!</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2018/06/14/git-auto-magic/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Credify &#8211; Reputation as a Service</title>
		<link>https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/</link>
					<comments>https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/#respond</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Fri, 04 May 2018 18:30:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[blockchain]]></category>
		<category><![CDATA[Credify]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[gamification]]></category>
		<category><![CDATA[karma]]></category>
		<category><![CDATA[Reddit]]></category>
		<category><![CDATA[reputation]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[StackOverflow]]></category>
		<guid isPermaLink="false">https://blog.adamspiers.org/?p=1647</guid>

					<description><![CDATA[<p>I went to a blockchain event this week out of curiosity, and heard a talk which really impressed me in that it could solve many unrelated problems with online sites in a single stroke. But before I tell you what it was, let&#8217;s set the scene with some example contexts in which I could see [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/">Credify &#8211; Reputation as a Service</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> I went to a blockchain event this week out of curiosity, and heard a talk which really impressed me in that it could solve many unrelated problems with online sites in a single stroke.  But before I tell you what it was, let&#8217;s set the scene with some example contexts in which I could see it helping in the future. </p>
<p> Some websites such as <a href="https://stackoverflow.com/">StackOverflow</a> and <a href="https://www.reddit.com/">Reddit</a> have achieved a fairly impressive and high profile degree of success by harnessing <a href="https://en.wikipedia.org/wiki/Gamification">gamification</a>, i.e. a system based on a reputation metric (sometimes labelled &#8220;karma&#8221; or &#8220;gold&#8221;), together with a set of rules and rewards engineered in a way which incentivizes the desired behaviour, namely the contribution of high quality content.  These generally work pretty well, but their systems can still be abused / manipulated in undesirable ways, and also typically there is no mechanism by which a user who has acquired a high reputation score on one site can benefit by transferring that reputation to another domain.  (Although reputation earned within one community within the Stack Exchange network does give you an initial boost when joining other communities within that network.) </p>
<p> A different problem I&#8217;ve been mulling over for years is how to create a reliable marketplace for placing bounties on <a href="https://www.gnu.org/philosophy/floss-and-foss.en.html">FLOSS</a> engineering problems.  Companies such as <a href="https://www.bountysource.com/">BountySource</a> are already having some success doing this, but it feels to me that we&#8217;re still a long way from fully realising the potential for a freelance FLOSS development industry.  One of the big problems in this space is figuring out how to measure good behaviour and reward it appropriately, whilst discouraging bad behaviour.  Sound familiar? </p>
<p> A third area I&#8217;ve been considering is that of bug/issue trackers for public FLOSS projects (and even commercial products).  Unfortunately it&#8217;s not uncommon for these systems to get <a href="https://github.com/isaacs/github/issues/967">spammed to hell and back by idiots</a>.  For instance GitHub is so scared of this problem that <a href="https://github.com/isaacs/github/issues/6">they&#8217;ve chosen not to open this particular Pandora&#8217;s box</a>.  However a karma-based approach could drastically improve the signal-to-noise ratio on these systems. </p>
<p> After spotting the common theme between these use cases, I concluded a few years ago that building a Reputation as a Service (RaaS?) platform to track reputation in a reliable manner, and allow federation of reputation between different communities, could make a lot of sense. That way each service which relies on reputation metrics doesn&#8217;t need to reinvent the wheel. </p>
<p> Fast forwarding several years, blockchain is a proven technology, and its transparency, immutability, and global decentralized nature all suggest that it&#8217;s a near perfect technology on which to build my (probably unoriginal) RaaS idea.  And the good news is that there is already an organisation apparently well on the way to solving this: Credify.  (No need to google it &#8211; the links are below!) </p>
<p> One significant hurdle to building RaaS (which needs to support thousands or even ultimately hundreds of thousands of transactions per second in order to work on a truly global scale) on a blockchain is the poor scalability of the blockchains offered by the likes of Bitcoin and Ethereum.  However Credify has neatly side-stepped this by building on top of EOS, and they&#8217;ve taken advantage of the blockchain to design a much more powerful system which rewards not only good behaviour but crucially also good recommendations and punishes bad ones. </p>
<p> One of their obvious initial targets is the online product/service review industry, since sites like Yelp, TripAdvisor, Amazon etc.  are plagued with fake reviews, and that translates to a huge financial impact within those markets.  However I&#8217;m very interested to see whether this kind of approach will extend to less commercial areas like the ones I highlighted above. </p>
<p> If you want to play around with Credify, here&#8217;s <a href="https://app.credify.one/registration?ref=5ae8ed03a0f31602f4ac13fb">a referral link</a>.  Or if you just want to learn more, check out <a href="https://credify.one/">their very nifty home page</a>. If this thing takes off like I suspect it will, I suspect there might be some advantages to becoming an early adopter. </p>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2018%2F05%2F04%2Fcredify-reputation-as-a-service%2F&#038;title=Credify%20%E2%80%93%20Reputation%20as%20a%20Service" data-a2a-url="https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/" data-a2a-title="Credify – Reputation as a Service"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/">Credify &#8211; Reputation as a Service</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2018/05/04/credify-reputation-as-a-service/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cloud rearrangement for fun and profit</title>
		<link>https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/</link>
					<comments>https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Sun, 17 May 2015 03:42:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[DPM]]></category>
		<category><![CDATA[DRS]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[placement]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[vSphere]]></category>
		<category><![CDATA[workloads]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=1070</guid>

					<description><![CDATA[<p>In a populated compute cloud, there are several scenarios in which it&#8217;s beneficial to be able to rearrange VM guest instances into a different placement across the hypervisor hosts via migration (live or otherwise). These use cases typically fall into three categories: Rebalancing &#8211; spread the VMs evenly across as many physical VM host machines [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/">Cloud rearrangement for fun and profit</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> In a populated compute cloud, there are several scenarios in which it&#8217;s beneficial to be able to rearrange VM guest instances into a different placement across the hypervisor hosts via migration (live or otherwise).  These use cases typically fall into three categories: </p>
<ol class="org-ol">
<li><b>Rebalancing</b> &#8211; spread the VMs evenly across as many physical VM host machines as possible (conceptually similar to <a href="http://www.vmware.com/products/vsphere/features-drs-dpm">vSphere DRS</a>). Example use cases:
<ul class="org-ul">
<li>Optimise workloads for performance, by reducing CPU / I/O hotspots.</li>
<li>Maximise headroom on each physical machine.</li>
<li>Reduce thermal hotspots in order to reduce power consumption; for example, back in 2003, HP showed that <a href="http://www.hpl.hp.com/techreports/2003/HPL-2003-5.pdf">intelligent workload placement can reduce energy consumption by more than 14%</a>. (Here&#8217;s an <a href="http://blog.adamspiers.org/wp-content/uploads/2015/05/heatmap.pdf">old slidedeck I made years ago when researching this use case</a>.)</li>
</ul>
</li>
<li><b>Consolidation</b> &#8211; condense VMs onto fewer physical VM host machines (conceptually similar to <a href="http://www.vmware.com/products/vsphere/features-drs-dpm">vSphere DPM</a>).  Typically involves some degree of defragmentation.  Example use cases:
<ul class="org-ul">
<li>Increase CPU / RAM / I/O utilization.  <a href="http://openstack-in-production.blogspot.co.uk/2014/07/openstack-plays-tetris-stacking-and.html">CERN blogged last summer about this Tetris-like challenge</a>, and it can be taken even further over-committing CPU/RAM and/or memory page sharing.</li>
<li>Free up physical servers to reduce power consumption.</li>
</ul>
</li>
<li><b>Evacuation</b> &#8211; free up physical servers:
<ul class="org-ul">
<li>for repurposing or decommissioning</li>
<li>for maintenance (BIOS upgrades, re-cabling etc.) or repair</li>
<li>to protect SLAs, e.g. when monitors indicate potential imminent hardware failure, or when <a href="https://en.wikipedia.org/wiki/HVAC">HVAC</a> failures are likely to cause servers to shutdown due to over-heating.  (This is different to the somewhat <a href="http://www.hastexo.com/misc/static/presentations/chosugmeetup201302/index.html#/step-18">confusingly</a> named <a href="https://wiki.openstack.org/wiki/Evacuate"><code>nova evacuate</code></a> functionality which <a href="http://docs.openstack.org/admin-guide-cloud/content/nova_cli_evacuate.html">moves VMs to a new host <i>after</i> the server has already failed</a>.)</li>
</ul>
</li>
</ol>
<p> Whilst one-shot manual or semi-automatic rearrangement can bring immediate benefits, the biggest wins often come when continual rearrangement is automated.  The approaches can also be combined, e.g. first evacuate and/or consolidate, then rebalance on the remaining physical servers. </p>
<p> Other custom rearrangements may be required according to other IT- or business-driven policies, e.g. only rearrange VM instances relating to a specific workload, in order to increase locality of reference, reduce latency, respect availability zones, or facilitate other out-of-band workflows or policies (such as data privacy or other legalities). </p>
<p> In the rest of this post I will expand this topic in the context of OpenStack, talk about the computer science behind it, propose a possible way forward, and offer a working prototype in Python. </p>
<p> If you&#8217;re in Vancouver for <a href="https://www.openstack.org/summit/vancouver-2015/">the OpenStack summit</a> which starts this Monday and you find this post interesting, ping me for a face-to-face chat! </p>
<p><span id="more-1070"></span> <!--break--></p>
<div id="outline-container-unnumbered-1" class="outline-2">
<h2 id="unnumbered-1">VM placement in OpenStack: present and future</h2>
<div class="outline-text-2" id="text-unnumbered-1">
<p> It is clear from the diversity of the use cases listed above that VM placement policies are likely to vary greatly across clouds, and sometimes even within a single cloud.  <a href="http://www.openstack.org/software/openstack-compute/">OpenStack Compute</a> (<code>nova</code>) has fairly sophisticated <a href="http://docs.openstack.org/kilo/config-reference/content/section_compute-scheduler.html">scheduling capabilities</a> which can be configured to implement some of the above policies on an incremental basis, i.e. every time a VM instance is started or migrated, the destination VM host can be automatically chosen according to filters and weighted cost functions.  However, this approach is somewhat limited for migration, because the placement policies are only considered one migration at a time.  Like in Tetris, more efficient arrangements can be achieved by thinking further ahead! </p>
<p> OpenStack clouds can already be segregated in various ways via <a href="http://docs.openstack.org/openstack-ops/content/scaling.html#segregate_cloud">cells, regions, availability zones, host aggregates</a>, and <a href="http://dev.cloudwatt.com/en/blog/affinity-and-anti-affinity-in-openstack.html">server groups</a>, and so there are various techniques available for implementing different placement policies to different areas of your cloud.  For example you could have groups of hosts dedicated to CPU-intensive or I/O-bound workloads using an anti-affinity placement policy, and other groups dedicated to light workloads using an affinity placement policy.  But these policies are static in nature (e.g. <a href="http://docs.openstack.org/kilo/config-reference/content/section_compute-scheduler.html"><code>nova</code> filters and schedulers are configured by the cloud administrator in <code>nova.conf</code></a>), which somewhat limits their flexibility. </p>
<p> OpenStack is still relatively new, however with <a href="https://wiki.openstack.org/wiki/Cinder">Cinder</a> and <a href="https://wiki.openstack.org/wiki/Neutron">Neutron</a> rapidly evolving, it is at the point where a VM&#8217;s network and storage dependencies can be live migrated along with the workload in a near seamless fashion.  So now we should be able to start developing mechanisms for implementing more sophisticated placement policies, where not only is VM rearrangement performed automatically, but the policies themselves can be varied dynamically over time as workload requirements change. </p>
</div>
</div>
<div id="outline-container-unnumbered-2" class="outline-2">
<h2 id="unnumbered-2">VMware is not the (complete) solution</h2>
<div class="outline-text-2" id="text-unnumbered-2">
<p> VMware advocates might instinctively recommend running <a href="https://wiki.openstack.org/wiki/VSphere">vSphere clusters underneath nova</a>, to harness vSphere&#8217;s pre-existing <a href="http://www.vmware.com/products/vsphere/features-drs-dpm">DRS / DPM functionality</a>.  However, there are still unresolved problems with this approach, as this <a href="http://cloudarchitectmusings.com/2013/06/26/openstack-for-vmware-admins-nova-compute-with-vsphere-part-2/">article on <code>nova-scheduler</code> and DRS</a> highlights. (Funnily enough, I encountered exactly these same problems a few years ago when I was part of a team adding vSphere integration into the orchestration component of what has since become <a href="https://www.netiq.com/products/cloud-manager/">NetIQ Cloud Manager</a> &#x2026;)  Besides, a vSphere cluster and an OpenStack cloud are very different beasts, and of course not everyone wants to build their cloud exclusively with VMware technology anyway. </p>
</div>
</div>
<div id="outline-container-unnumbered-3" class="outline-2">
<h2 id="unnumbered-3">The computer science behind cloud rearrangement</h2>
<div class="outline-text-2" id="text-unnumbered-3">
<p> Unfortunately developing algorithms to determine optimal placement is distinctly non-trivial.  For example, the consolidation scenario above is a complex variant of the <a href="https://en.wikipedia.org/wiki/Bin_packing_problem">bin packing problem</a>, which is <a href="https://en.wikipedia.org/wiki/NP-hard">NP-hard</a>. The following constraints add significant complexity to the problem: </p>
<ul class="org-ul">
<li>A useful real world solution should take into account not only the RAM footprint of the VMs, but also CPU, disk, and network.</li>
<li>The algorithm needs to ensure that <a href="https://en.wikipedia.org/wiki/Service-level_agreement">SLAs</a> are maintained whilst any rearrangement takes place.</li>
<li>If the cloud is too close to full capacity, it may not be possible to rearrange the VMs from their current placement to a more optimal placement without first shutting down some VMs, which could be prohibited by the SLAs.</li>
<li>Even if the cloud is at low utilization, live migration is not always possible, e.g.
<ul class="org-ul">
<li>the hypervisor may not support it (especially across non-identical CPU architectures)</li>
<li>shared storage may be required but unavailable</li>
<li>the network may not support it</li>
</ul>
</li>
<li>Even if the arrangement is achievable purely via a sequence of live migrations, the algorithm must also be sensitive to the performance impact to running workloads when performing multiple live migrations, since live migrations require intensive bursts of network I/O in order to synchronize the VM&#8217;s memory contents between the source and target hosts, followed by a momentary freezing of the VM as it flips from the source to the target. This trade-off between optimal resource utilization and service availability means that a sub-optimal final placement may be preferable to an optimal one.</li>
<li>In the case where the hypervisor is capable of sharing memory pages between VMs (e.g. <a href="http://www.linux-kvm.org/page/KSM">KSM on KVM</a>), the algorithm should try to place together VMs which are likely to share memory pages (e.g. VMs running the same OS platform, OS version, software libraries, or applications.  A <a href="http://lass.cs.umass.edu/papers/pdf/SPAA11-vmsharing.pdf">research paper published in 2011</a> demonstrated that VM packing which optimises placement in this fashion can be approximated in polytime, achieving 32% to 50% reduction in servers and a 25% to 57% reduction in memory footprint compared to sharing-oblivious algorithms.</li>
</ul>
<p> (There is prior art of course.  For example, several years ago, <a href="http://blog.clusterlabs.org/blog/2010/feature-spotlight-utilization/">Pacemaker implemented a <i>best effort</i> algorithm for VM host selection</a>.) </p>
</div>
</div>
<div id="outline-container-unnumbered-4" class="outline-2">
<h2 id="unnumbered-4">Divide and conquer?</h2>
<div class="outline-text-2" id="text-unnumbered-4">
<p> As noted by the 2011 research paper referenced above, this area of computer science is still evolving.  There is one constant however: any rearrangement solution must not only provide a final VM placement optimised according to the chosen constraints, but also a sequence of migrations to it from the current placement.  There will often be multiple migration sequences reaching the optimised placement from the current one, and their efficiency can vary widely.  In other words, there are two questions which need answering: </p>
<ol class="org-ol">
<li>Given a starting placement <i>A</i>, which is the best (or near-optimal) final placement <i>B</i> to head for?</li>
<li>What&#8217;s the best way to get from <i>A</i> to <i>B</i>?</li>
</ol>
<p> The above considerations strongly suggest that the first question is much harder to answer than the second, although the two are not necessarily orthogonal; for example there could be two different final placements <i>B</i> and <i>C</i> which are equally near-optimal, but it may be much harder to reach <i>C</i> from <i>A</i> than <i>B</i>. </p>
<p> I propose that it is worth examining the effectiveness of a <b>divide and conquer</b> approach: solving the second question may simplify the first, and also provide a mechanism for comparatively evaluating the effectiveness of potential answers to the first.  Another bonus of this decoupling is that it should be possible for the path-finding algorithm to also discover opportunities for parallelizing live migrations when walking the path, so that the target placement <i>B</i> can be reached more quickly. </p>
</div>
</div>
<div id="outline-container-unnumbered-5" class="outline-2">
<h2 id="unnumbered-5">A proof of concept algorithm for VM migration path-finding</h2>
<div class="outline-text-2" id="text-unnumbered-5">
<p> I&#8217;ve designed an algorithm which solves the second problem, and hacked together a proof of concept implementation in Python.  This <a href="http://youtu.be/aHK3UF3ffNg">video</a> shows it solving three randomly generated scenarios: </p>
<p><iframe width="640" height="480" src="https://www.youtube.com/embed/aHK3UF3ffNg?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p> It&#8217;s far from perfect, but as a proof of concept it seems to hold up fairly well under soak testing.  I&#8217;m pleased to announce that the code is now on github: <a href="https://github.com/aspiers/migrationpaths">https://github.com/aspiers/migrationpaths</a> and I would love to hear feedback on it. </p>
</div>
</div>
<div id="outline-container-unnumbered-6" class="outline-2">
<h2 id="unnumbered-6">Feedback</h2>
<div class="outline-text-2" id="text-unnumbered-6">
<p> If you found this blog interesting, feel free to get in touch!  I&#8217;m <code>aspiers</code> on FreeNode IRC, and <a href="https://twitter.com/adamspiers"><code>adamspiers</code> on Twitter</a>. </p>
<p> I&#8217;m also in Vancouver for <a href="https://www.openstack.org/summit/vancouver-2015/">the OpenStack summit</a> which starts this Monday, so if you are, come and say hello! </p>
</div>
</div>
<div id="outline-container-unnumbered-7" class="outline-2">
<h2 id="unnumbered-7">Acknowledgements</h2>
<div class="outline-text-2" id="text-unnumbered-7">
<p> Many thanks to <a href="http://www.hastexo.com/who/florian">Florian Haas</a>, <a href="http://hardysteven.blogspot.com/">Steven Hardy</a>, and Christoph Thiel for their input on an earlier draft version of this post, and apologies that it took me SO long to publish it! </p>
</div>
</div>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2015%2F05%2F17%2Fcloud-rearrangement%2F&#038;title=Cloud%20rearrangement%20for%20fun%20and%20profit" data-a2a-url="https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/" data-a2a-title="Cloud rearrangement for fun and profit"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/">Cloud rearrangement for fun and profit</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2015/05/17/cloud-rearrangement/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Announcing git-deps: commit dependency analysis / visualization tool</title>
		<link>https://blog.adamspiers.org/2015/01/19/git-deps/</link>
					<comments>https://blog.adamspiers.org/2015/01/19/git-deps/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Sun, 18 Jan 2015 23:15:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[version control]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=1452</guid>

					<description><![CDATA[<p>I&#8217;m happy to announce a new tool called git-deps which performs automatic analysis and visualization of dependencies between commits in a git repository. Here&#8217;s a screencast demonstration! Back in 2013 I blogged about some tools I wrote which harness the notes feature of git to help with the process of porting commits from one branch [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2015/01/19/git-deps/">Announcing git-deps: commit dependency analysis / visualization tool</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> I&#8217;m happy to announce a new tool called <a href="https://github.com/aspiers/git-deps"><code>git-deps</code></a> which performs automatic analysis and visualization of dependencies between commits in a <a href="http://git-scm.com/">git</a> repository.  Here&#8217;s <a href="http://youtu.be/irQ5gMMz-gE">a screencast demonstration</a>! </p>
<p><iframe width="640" height="360" src="//www.youtube.com/embed/irQ5gMMz-gE" frameborder="0" allowfullscreen></iframe></p>
<p> Back in 2013 I <a href="http://blog.adamspiers.org/easier-upstreaming-with-git/">blogged about some tools I wrote</a> which harness the <a href="https://www.kernel.org/pub/software/scm/git/docs/git-notes.html"><code>notes</code></a> feature of git to help with the process of porting commits from one branch to another.  These are mostly useful in the cases where porting is more complex than just cherry-picking a small number of commits. </p>
<p> However, even in the case where there are a small number of <b>desired</b> commits, sometimes those commits have hidden dependencies on other commits which you didn&#8217;t particularly want, but need to pull in anyway, e.g. in order to avoid conflicts during cherry-picking.  Of course those secondary commits may in turn require other commits, and before you know it, you&#8217;re in dependency hell, which is only supposed to happen if you&#8217;re trying to install Linux packages and it&#8217;s still 1998 &#x2026; but in fact that&#8217;s exactly what happened to me at <a href="http://www.susecon.com/">SUSEcon</a> 2013, when I attempted to help a colleague backport a bugfix in <a href="http://www.openstack.org/">OpenStack</a> <a href="http://docs.openstack.org/developer/nova/">Nova</a> from the <code>master</code> branch to a stable release branch. </p>
<p> At first sight it looked like it would only require a trivial <code>git cherry-pick</code>, but that immediately revealed conflicts due to related code having changed in <code>master</code> since the release was made.  I manually found the underlying commit which the bugfix required by using <code>git blame</code>, and tried another <code>cherry-pick</code>.  The same thing happened again.  Very soon I found myself in a quagmire of dependencies between commits, with no idea whether the end was in sight. </p>
<p> So wouldn&#8217;t it be nice if you could see the dependency tree ahead of time, rather than spending a whole bunch of time resolving unexpected conflicts due to missing dependencies, only to realise that the tree&#8217;s way deeper than you expected, and that actually a totally different approach is needed?  Well, I thought it would, and so <a href="https://github.com/aspiers/git-deps"><code>git-deps</code></a> was born! </p>
<p> In coffee breaks during the ensuing openSUSE conference at the same venue, I feverishly hacked together a prototype and it seemed to work. Then normal life intervened, and no progress was made for another year. </p>
<p> However thanks to SUSE&#8217;s generous <a href="https://hackweek.suse.com/">Hack Week</a> policy, I have had the luxury of being able to spending some of early January 2015 working to bring this tool to the next level.  I submitted a <a href="https://hackweek.suse.com/11/projects/366">Hack Week project page</a>, <a href="http://article.gmane.org/gmane.comp.version-control.git/262000">announced my intentions on the <code>git</code> mailing list</a>, started hacking, missed quite a bit of sleep, and finally recorded the above screencast. </p>
<p> The tool is available here: <a href="https://github.com/aspiers/git-deps">https://github.com/aspiers/git-deps</a> </p>
<p> Please give it a go and let me know what you think!  I&#8217;m particularly interested in hearing ideas for use cases I didn&#8217;t think of yet, and proposals for <a href="https://github.com/aspiers/git-deps/issues/23">integration with other <code>git</code> web front-ends</a>. </p>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2015%2F01%2F19%2Fgit-deps%2F&#038;title=Announcing%20git-deps%3A%20commit%20dependency%20analysis%20%2F%20visualization%20tool" data-a2a-url="https://blog.adamspiers.org/2015/01/19/git-deps/" data-a2a-title="Announcing git-deps: commit dependency analysis / visualization tool"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2015/01/19/git-deps/">Announcing git-deps: commit dependency analysis / visualization tool</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2015/01/19/git-deps/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>How to build an OpenStack cloud from SUSEcon&#8217;s free USB stick handouts</title>
		<link>https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/</link>
					<comments>https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Thu, 11 Dec 2014 14:28:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[appliance]]></category>
		<category><![CDATA[Crowbar]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[SLES]]></category>
		<category><![CDATA[suse]]></category>
		<category><![CDATA[SUSEcon]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=1182</guid>

					<description><![CDATA[<p>Once again, SUSEcon was a blast! Thanks to everyone who helped make it such a great success, especially all our customers and partners who attended. If you attended the final Thursday keynote, you should have been given a free USB stick preloaded with a bootable SUSE Cloud appliance. And if you missed out or couldn&#8217;t [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/">How to build an OpenStack cloud from SUSEcon&#8217;s free USB stick handouts</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> Once again, <a href="http://www.susecon.com/">SUSEcon</a> was a blast!  Thanks to everyone who helped make it such a great success, especially all our customers and partners who attended. </p>
<p> If you attended the final Thursday keynote, <a href="http://youtu.be/nulEm8wdPKw?t=1m45s">you should have been given a free USB stick preloaded with a bootable SUSE Cloud appliance</a>.  And if you missed out or couldn&#8217;t attend, <a href="http://cdn.novell.com/cached/video/2014/suse/cloud4-admin.x86_64-0.2.1-Build3.15.install.iso">download a copy here</a>!  This makes it possible for anyone to build an OpenStack cloud from scratch extremely quickly and easily.  (In fact, it&#8217;s almost identical to the appliance we used a few weeks ago to <a href="http://blog.adamspiers.org/2014/11/05/ruler-of-the-stack/">win the &#8220;Ruler of the Stack&#8221; competition at the OpenStack summit in Paris</a>.) </p>
<p> <a href="http://youtu.be/nulEm8wdPKw?t=1m45s">Erin explained on stage at a high-level what this appliance does</a>, but below are some more specific technical details which may help in case you haven&#8217;t yet tried it out. </p>
<p> The appliance can be booted on any physical or virtual 64-bit x86 machine &#x2026; but before we start! &#8211; if you would like try running the appliance in a VM using either KVM or VirtualBox, then there is an <b>even easier alternative which uses <a href="https://www.vagrantup.com/">Vagrant</a> to reduce the whole setup to a one-line command</b>.  If you like the sound of that, stop reading and <a href="https://github.com/SUSE-Cloud/suse-cloud-vagrant/blob/master/demos/README.md">go here instead</a>.  However if you want to try it on bare metal or with a different hypervisor such as VMware or HyperV, read on! </p>
<p><span id="more-1182"></span></p>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1">Requirements</h2>
<div class="outline-text-2" id="text-1">
<p> You&#8217;ll need the following: </p>
<ul class="org-ul">
<li>
<p> At least three physical or virtual 64-bit x86 machines, each with at least 2GB RAM and 8GB disk, and no valuable data on any of the attached disks: </p>
<ul class="org-ul">
<li>one admin node running the Crowbar deployment tool which will provision the other nodes from scratch,
</li>
<li>at least one controller node which will run OpenStack infrastructure services, and
</li>
<li>at least one compute node which will host VM instances within the cloud.  (If this compute node is a VM, then the VM instances in the cloud will have to be run either using KVM nested virtualization, or QEMU software virtualization which is slower but good enough for &#8220;kicking the tires&#8221;.)
</li>
</ul>
</li>
<li>
<p> A private IPv4 network which all the machines must be connected to. <i>Setting this up is the only potentially tricky bit of the whole exercise.</i>  By default the network in question needs to be <code>192.168.124.0/24</code> <b>with no DHCP server enabled</b>, so: </p>
<ul class="org-ul">
<li>if you are installing the appliance in a VM, you should be able to set up a NAT or host-only virtual network and configure your hypervisor so that it does not serve DHCP on that network, or
</li>
<li>if you are installing on bare metal, ensure there is no DHCP server active on that <a href="http://en.wikipedia.org/wiki/OSI_model#Layer_2:_data_link_layer">L2 segment</a>.
</li>
</ul>
</li>
<li>
<p> Another machine (physical or virtual) with a modern web browser on the same private IPv4 network. </p>
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-2" class="outline-2">
<h2 id="sec-2">Installing the appliance</h2>
<div class="outline-text-2" id="text-2">
<p> Attach the bootable USB media (physical or virtual), and boot the machine.  This will automatically install a SUSE Cloud Admin Node onto the disk.  <b>Caution: this will wipe any pre-existing OS</b>, so only use it on a spare machine or freshly-created VM, with no valuable data on any of the attached disks! </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-destroy-confirmation.png" style="width: 400px; margin: 0 auto; display: block;" alt="disk-destroying confirmation dialog box"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-destroy-confirmation.png" alt="disk-destroying confirmation dialog box" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> After confirming you are OK to wipe all existing data on the disk, the appliance will be written to disk and then booted.  Shortly after, YaST will appear, allowing you to configure: </p>
<ul class="org-ul">
<li>which keyboard layout you want,
</li>
<li>what password to use for the <code>root</code> user,
</li>
</ul>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-password.png" style="width: 300px; margin: 0 auto; display: block;" alt="root password configuration dialog box"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-password.png" alt="root password configuration dialog box" style="width: 300px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<ul class="org-ul">
<li>what hostname and domain name to use (the defaults are fine),
</li>
</ul>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-hostname.png" style="width: 300px; margin: 0 auto; display: block;" alt="hostname/DNS configuration dialog box"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-hostname.png" alt="hostname/DNS configuration dialog box" style="width: 300px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<ul class="org-ul">
<li>the network setup (the default of <code>192.168.124.10/24</code> is recommended, otherwise you will also have to configure Crowbar prior to installation),
</li>
<li>the clock and time zone, and finally
</li>
<li>the NTP configuration (supplying an upstream NTP server is recommended but not required).
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-3" class="outline-2">
<h2 id="sec-3">Logging in to the Admin Node</h2>
<div class="outline-text-2" id="text-3">
<p> Log in as <code>root</code> (with the password you specified above) either on the console or via <code>ssh root@192.168.124.10</code> if you have another machine configured to be on the same subnet. </p>
<p> Press <code>q</code> and then <code>y</code> to accept the beta EULA, which highlights that the appliance is partially based on unreleased code.  Please do not use it for production deployments! </p>
</div>
</div>
<div id="outline-container-sec-4" class="outline-2">
<h2 id="sec-4">Configuring Crowbar (optional)</h2>
<div class="outline-text-2" id="text-4">
<p> Crowbar is very powerful and flexible in terms of network configuration.  If you have other traffic on the <a href="http://en.wikipedia.org/wiki/OSI_model#Layer_2:_data_link_layer">L2 network segment</a> (e.g. if you are using bare metal hardware and a physical network rather than a dedicated virtual network) then you should check that its default networks don&#8217;t conflict with your existing traffic.  To do this, type <code>yast crowbar</code>: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-yast-crowbar.png" style="width: 400px; margin: 0 auto; display: block;" alt="how to launch the YaST Crowbar module"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-yast-crowbar.png" alt="how to launch the YaST Crowbar module" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> and select the <code>Networks</code> tab: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-crowbar-net-config.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar network configuration dialog"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-crowbar-net-config.png" alt="Crowbar network configuration dialog" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> From here you can examine and change the networks Crowbar will use. Some are only used when various options are selected later on, but at a minimum, <code>admin</code>, <code>nova_fixed</code>, and <code>nova_floating</code> will all be used.  For more information, see the <a href="https://www.suse.com/documentation/suse-cloud4/book_cloud_deploy/data/sec_depl_req_network.html">Networking section of the SUSE Cloud Deployment Guide</a>. </p>
</div>
</div>
<div id="outline-container-sec-5" class="outline-2">
<h2 id="sec-5">Installing SUSE Cloud</h2>
<div class="outline-text-2" id="text-5">
<p> From the shell prompt, type <code>screen go</code> to initiate the installation of SUSE Cloud.  This will take several minutes. </p>
</div>
</div>
<div id="outline-container-sec-6" class="outline-2">
<h2 id="sec-6">Exploring the Crowbar web interface</h2>
<div class="outline-text-2" id="text-6">
<p> On another machine on the same network as the machine running the now-installed appliance, start a browser, and navigate to <a href="http://192.168.124.10:3000/">http://192.168.124.10:3000/</a> (adjust the IP accordingly if you changed the <code>admin</code> network above). </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-crowbar-web-UI.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar web UI"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-crowbar-web-UI.png" alt="Crowbar web UI" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
</div>
</div>
<div id="outline-container-sec-7" class="outline-2">
<h2 id="sec-7">PXE-boot some other nodes</h2>
<div class="outline-text-2" id="text-7">
<p> Now simply PXE-boot your other nodes.  (Typically this requires PXE-booting to be enabled in the BIOS, and/or manually selecting it from the BIOS boot menu which is often accessible by hitting the F11 key or similar during boot.) </p>
<p> This will run a small inventory ramdisk image on each one to detect its hardware and report the discovery back to Crowbar, without touching the node&#8217;s local disk(s).  Each node will then appear in the Crowbar web UI, and sit in an idle loop whilst awaiting task allocation via Crowbar: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-node1-discovered.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar web UI with new node discovered"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-node1-discovered.png" alt="Crowbar web UI with new node discovered" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> Clicking on that node will show the results of the automatic hardware inventorying, and give us the option to allocate the node: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-view-node1.png" style="width: 400px; margin: 0 auto; display: block;" alt="viewing the newly discovered node in Crowbar's web UI"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-view-node1.png" alt="viewing the newly discovered node in Crowbar's web UI" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> When editing the node, we can give it a more human-friendly alias (e.g. <code>node1</code>), and then click Allocate to install a minimal SLES OS: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-edit-node1.png" style="width: 400px; margin: 0 auto; display: block;" alt="editing the newly discovered node in Crowbar's web UI"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-edit-node1.png" alt="editing the newly discovered node in Crowbar's web UI" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> A full OS will be automatically installed on the node via <a href="http://doc.opensuse.org/projects/autoyast/">AutoYaST</a>: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-autoyast-installation.png" style="width: 400px; margin: 0 auto; display: block;" alt="autoyast installation in progress"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-autoyast-installation.png" alt="autoyast installation in progress" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> When OS installation has finished, the console looks like this: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-autoyast-complete.png" style="width: 400px; margin: 0 auto; display: block;" alt="autoyast installation completed"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-autoyast-complete.png" alt="autoyast installation completed" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> and then the node turns green in the web UI indicating that it&#8217;s ready to have roles assigned to it: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-node1-ready.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar's web UI showing node1 as ready"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-node1-ready.png" alt="Crowbar's web UI showing node1 as ready" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> Multiple nodes can be installed via PXE/AutoYaST at the same time. </p>
</div>
</div>
<div id="outline-container-sec-8" class="outline-2">
<h2 id="sec-8">Deploying OpenStack via Crowbar barclamps</h2>
<div class="outline-text-2" id="text-8">
<p> By this point you should have at least two freshly-installed nodes managed by Crowbar (excluding the admin node itself which Crowbar runs on), in which case you are ready to deploy OpenStack via Crowbar&#8217;s barclamps, which can be found via the <code>Barclamps</code> drop-down in Crowbar&#8217;s web interface: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-show-barclamps.png" style="width: 400px; margin: 0 auto; display: block;" alt="navigating to the OpenStack barclamps in Crowbar's web UI"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-show-barclamps.png" alt="navigating to the OpenStack barclamps in Crowbar's web UI" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> This process is relatively straightforward, and a full explanation can be found in <a href="https://www.suse.com/documentation/suse-cloud4/book_cloud_deploy/data/cha_depl_ostack.html">the corresponding chapter of the SUSE Cloud 4 Deployment Guide</a>. </p>
<p> However, it is also possible to automate the whole deployment from this point on, using Crowbar&#8217;s <code>batch</code> subcommand and an appropriately crafted <code>.yaml</code> file.  There are three sample <code>.yaml</code> files in <code>/root</code> on the admin node.  The simplest configuration reflected by these three files is <code>simple-cloud.yaml</code>, which assumes a single controller node and a single compute node, with aliases <code>controller1</code> and <code>compute1</code> respectively: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-simple-cloud-dashboard.png" style="width: 400px; margin: 0 auto; display: block;" alt="simple 2-node cloud scenario shown by Crowbar's UI"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-simple-cloud-dashboard.png" alt="simple 2-node cloud scenario shown by Crowbar's UI" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> In this case, assuming your nodes are given the above aliases, you could set up the entire OpenStack cloud with this single command run as <code>root</code> on the admin node: </p>
<pre class="brush: bash; title: ; notranslate">
crowbar batch --timeout 1800 build simple-cloud.yaml
</pre>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-batch-build-database.png" style="width: 400px; margin: 0 auto; display: block;" alt="starting crowbar batch build"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-batch-build-database.png" alt="starting crowbar batch build" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> It takes a while to apply all the barclamps, as can be seen from the timestamps whilst it&#8217;s running: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-batch-build-cinder.png" style="width: 400px; margin: 0 auto; display: block;" alt="crowbar batch build on cinder"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-batch-build-cinder.png" alt="crowbar batch build on cinder" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> (The other two sample <code>.yaml</code> files are for a highly available control plane which assumes you have three nodes aliased <code>controller1</code>, <code>controller2</code>, and <code>compute1</code>.) </p>
<p> Once the barclamps are all applied, they should show as green in the Crowbar UI view: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-barclamps-green.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar UI showing barclamps successfully applied"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-barclamps-green.png" alt="Crowbar UI showing barclamps successfully applied" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
</div>
</div>
<div id="outline-container-sec-9" class="outline-2">
<h2 id="sec-9">Exploring OpenStack</h2>
<div class="outline-text-2" id="text-9">
<p> From the main Nodes dashboard in the Crowbar web UI, click the <code>controller1</code> node (or whichever one you deployed OpenStack&#8217;s Dashboard to), and you will see a couple of links to the OpenStack Dashboard (a.k.a &#8220;Horizon&#8221;): </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-link-to-horizon.png" style="width: 400px; margin: 0 auto; display: block;" alt="Crowbar UI showing barclamps successfully applied"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-link-to-horizon.png" alt="Crowbar UI showing barclamps successfully applied" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> Click on <code>OpenStack Dashboard (admin)</code> and it will take you to the OpenStack Dashboard, where you can log in as the <code>admin</code> user with a password of (by default) <code>crowbar</code>: </p>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-horizon-login.png" style="width: 400px; margin: 0 auto; display: block;" alt="OpenStack Dashboard login page"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-horizon-login.png" alt="OpenStack Dashboard login page" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<div class="figure">
<p><a href="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-horizon.png" style="width: 400px; margin: 0 auto; display: block;" alt="OpenStack Dashboard compute overview page"><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2014/12/wpid-horizon.png" alt="OpenStack Dashboard compute overview page" style="width: 400px; margin: 0 auto; display: block;" /></a> </p>
</p></div>
<p> Congratulations!  You have set up a full OpenStack cloud from scratch! Now you can start reading the SUSE Cloud <a href="https://www.suse.com/documentation/suse-cloud4/book_cloud_admin/data/book_cloud_admin.html">Admin</a> and <a href="https://www.suse.com/documentation/suse-cloud4/book_cloud_user/data/book_cloud_user.html">End User</a> guides to learn more about how to use OpenStack. </p>
</div>
</div>
<div id="outline-container-sec-10" class="outline-2">
<h2 id="sec-10">Support</h2>
<div class="outline-text-2" id="text-10">
<p> Whilst this bootable appliance is partially based on unreleased, unsupported code, we are still very interested to hear feedback from our customers and partners.  So while we (obviously!) cannot offer unlimited free support for it, if you post any questions / issues to the <a href="https://forums.suse.com/forumdisplay.php?65-SUSE-Cloud">SUSE Cloud web forum</a>, we will try to respond on a best-effort basis.  (And of course full commercial support for the <b>released</b> version of SUSE Cloud is <a href="https://www.suse.com/products/suse-cloud/">available</a> if you want it 😉 ) </p>
<p> As we say in the SUSE world, have a lot of fun! </p>
</div>
</div>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2014%2F12%2F11%2Fsusecon-usb-stick-howto%2F&#038;title=How%20to%20build%20an%20OpenStack%20cloud%20from%20SUSEcon%E2%80%99s%20free%20USB%20stick%20handouts" data-a2a-url="https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/" data-a2a-title="How to build an OpenStack cloud from SUSEcon’s free USB stick handouts"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/">How to build an OpenStack cloud from SUSEcon&#8217;s free USB stick handouts</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2014/12/11/susecon-usb-stick-howto/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>more uses for git notes, and hidden treasures in Gerrit</title>
		<link>https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/</link>
					<comments>https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Wed, 02 Oct 2013 13:05:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[version control]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=1028</guid>

					<description><![CDATA[<p>I recently blogged about some tools I wrote which harness the notes feature of git to help with the process of porting commits from one branch to another. Since then I&#8217;ve discovered a couple more consumers of this functionality which are pretty interesting: palaver, and Gerrit. palaver It seems the tireless Mark McLoughlin, one of [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/">more uses for git notes, and hidden treasures in Gerrit</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> I <a href="http://blog.adamspiers.org/easier-upstreaming-with-git/">recently blogged about some tools I wrote</a> which harness the <a href="https://www.kernel.org/pub/software/scm/git/docs/git-notes.html"><code>notes</code></a> feature of git to help with the process of porting commits from one branch to another.  Since then I&#8217;ve discovered a couple more consumers of this functionality which are pretty interesting: <code>palaver</code>, and Gerrit. </p>
<p><span id="more-1028"></span></p>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1">palaver</h2>
<div class="outline-text-2" id="text-1">
<p> It seems the tireless <a href="https://github.com/markmc">Mark McLoughlin</a>, one of the leading lights of <a href="http://openstack.org/">the OpenStack project</a>, was already thinking along similar lines, and wrote a tool called <a href="https://github.com/markmc/palaver/">palaver</a>, which also aims to streamline the porting process, and also uses <code>git notes</code> to persist state pertaining to backporting projects.  Upon first glance, the main differences between our tools seem to be as follows: </p>
<ul class="org-ul">
<li><a href="https://github.com/aspiers/git-config/blob/master/bin/git-cherry-menu"><code>git-cherry-menu</code></a> is a slightly overgrown shell-script (yuk), whereas <code>palaver</code> is Python (yay).
</li>
<li><code>palaver</code> has a nice CLI with numerous non-interactive sub-commands like <code>palaver list merged</code>, and <code>palaver review</code> which provides an interactive mode.  <code>git-cherry-menu</code> only offers an interactive mode (which is very similar in concept to <code>palaver     review</code>); for non-interactive querying of the current state, you have to use a separate command <a href="https://github.com/aspiers/git-config/blob/master/bin/git-icing"><code>git-icing</code></a>.  Personally I prefer <code>palaver</code>&#8216;s unified approach to UI design, even though it doesn&#8217;t yet have the pretty ANSI colour-coding of <code>git-icing</code> and <code>git-cherry-menu</code>.
</li>
<li>Since <code>git-icing</code> wraps around <a href="https://www.kernel.org/pub/software/scm/git/docs/git-cherry.html"><code>git cherry</code></a>, it can automatically detect some (but not all) commits which have already been ported to the target branch.  As the name suggests, <code>git-cherry-menu</code> enables cherry-picking of commits, whereas that&#8217;s still on the TODO list for <code>palaver</code>.
</li>
<li><code>palaver</code> persists state by writing notes which are JSON blobs, whereas <code>git-cherry-menu</code> uses plain text where lines beginning with <code>skip:</code> are treated specially.  Not much difference here: obviously JSON allows more sophisticated structuring of metadata, but has the disadvantage of being less readable if you view the notes branch via standard git tools such as <code>git log</code> or <code>gitk</code>.
</li>
<li><code>palaver</code> &#8220;manually&#8221; classifies commits into the following states: <code>pass</code> / <code>defer</code> / <code>pick</code> / <code>proposed</code> / <code>merged</code>, whereas my tools have fewer &#8220;manual&#8221; states &#8211; conceptually just <code>skip</code> and <code>todo</code>. <code>merged</code> is either automatically detected via <code>git cherry</code>, or manually flagged via a <code>skip</code>.  I&#8217;d say my approach is marginally uglier but the automatic detection is quite a big advantage.
</li>
<li><a href="https://github.com/aspiers/git-config/blob/master/bin/git-rnotes">git-rnotes</a> allows merging of someone else&#8217;s notes.  That&#8217;s also on     <code>palaver</code>&#8216;s TODO list.
</li>
</ul>
<p> Perhaps the best way forward might be to port the remaining functionality which <code>git-icing</code> and <code>git-cherry-menu</code> offer to <code>palaver</code>, since the latter has a nicer interface, and is pure Python. None of this is rocket science, so hopefully it wouldn&#8217;t take too long. </p>
<p> It probably makes sense to keep <code>git-rnotes</code> separate, since it is a very simple shell-script which is useful for sharing any git notes, not just those generated during a commit porting project. </p>
</div>
</div>
<div id="outline-container-sec-2" class="outline-2">
<h2 id="sec-2">Gerrit review notes</h2>
<div class="outline-text-2" id="text-2">
<p> Secondly, it turns out that <a href="http://code.google.com/p/gerrit/">Gerrit</a> also uses <code>git-notes</code>, in order to annotate each reviewed change with a bunch of very useful metadata, and <a href="http://github.com/">GitHub</a> is clever enough to expose this metadata in its web UI, e.g. </p>
<div class="figure">
<p><img decoding="async" src="http://blog.adamspiers.org/wp-content/uploads/2013/10/wpid-github-notes.png" alt="screenshot of github web UI showing git notes" /> </p>
</p></div>
<p> In Gerrit 2.6 and newer, this functionality was <a href="http://comments.gmane.org/gmane.comp.version-control.repo/5157">moved out from the core</a> into a <a href="https://gerrit-review.googlesource.com/#/admin/projects/plugins/reviewnotes"><code>reviewnotes</code> plugin</a>.  As a result, AFAICS its documentation seems to be <a href="https://gerrit.googlesource.com/plugins/reviewnotes/%2B/master/src/main/resources/Documentation/refs-notes-review.md">buried inside a separate git repository</a> rather than <a href="http://gerrit-documentation.googlecode.com/svn/Documentation/2.5.2/refs-notes-review.html">exposed as a nice web page like it used to be</a>.  However, it&#8217;s very easy to use, and <a href="http://review.openstack.org/">OpenStack&#8217;s Gerrit instance</a> certainly has the feature enabled. </p>
<p> For example, simply <code>cd</code> into any OpenStack git repository you happen to have checked out (or <a href="https://github.com/openstack/nova">clone one</a> first if not).  Then type the following: </p>
<div class="org-src-container">
<pre class="src src-text">git fetch origin refs/notes/review:refs/notes/review
export GIT_NOTES_REF=refs/notes/review
git log
</pre>
</div>
<p> You&#8217;ll see that each non-merge commit now shows annotations like the ones in the image above, explaining how the commit made its way through the review process before getting merged by Jenkins.  Perhaps the most useful piece of data in the note is the link to the relevant review on <code>http://review.openstack.org</code>, so you can quickly navigate to it in your browser and review the er, review. </p>
<p> If you don&#8217;t want <code>git log</code> to default to showing the notes, you can omit the <code>export GIT_NOTES_REF</code>, and instead do: </p>
<div class="org-src-container">
<pre class="src src-text">git log --notes=refs/notes/review
</pre>
</div>
<p> If you don&#8217;t want to have to remember the slightly cryptic method for fetching notes, my <a href="https://github.com/aspiers/git-config/blob/master/bin/git-rnotes">git-rnotes</a> wrapper offers simpler syntax: </p>
<div class="org-src-container">
<pre class="src src-text">git rnotes fetch origin
</pre>
</div>
<p> However, this currently requires <code>GIT_NOTES_REF</code> to have the right value exported. </p>
</div>
</div>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2013%2F10%2F02%2Fmore-uses-for-git-notes%2F&#038;title=more%20uses%20for%20git%20notes%2C%20and%20hidden%20treasures%20in%20Gerrit" data-a2a-url="https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/" data-a2a-title="more uses for git notes, and hidden treasures in Gerrit"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/">more uses for git notes, and hidden treasures in Gerrit</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2013/10/02/more-uses-for-git-notes/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Easier upstreaming / back-porting of patch series with git</title>
		<link>https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/</link>
					<comments>https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Thu, 19 Sep 2013 20:22:00 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[backporting]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[forward-porting]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[upstreaming]]></category>
		<category><![CDATA[version control]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=981</guid>

					<description><![CDATA[<p>Have you ever needed to port a selection of commits from one git branch to another, but without doing a full merge? This is a common challenge, e.g. forward-porting / upstreaming bugfixes from a stable release branch to a development branch, or back-porting features from a development branch to a stable release branch. Of course, [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/">Easier upstreaming / back-porting of patch series with git</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p> Have you ever needed to port a selection of commits from one <a href="http://git-scm.com/">git</a> branch to another, but without doing a full merge?  This is a common challenge, e.g. </p>
<ul class="org-ul">
<li>forward-porting / upstreaming bugfixes from a stable release branch to a development branch, or
</li>
<li>back-porting features from a development branch to a stable release branch.
</li>
</ul>
<p> Of course, git already goes quite some way to making this possible: </p>
<ul class="org-ul">
<li><a href="https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html"><code>git cherry-pick</code></a> can port individual commits, or even a range of commits (since git 1.7.2) from anywhere, into the current branch.
</li>
<li><a href="https://www.kernel.org/pub/software/scm/git/docs/git-cherry.html"><code>git cherry</code></a> can compare a branch with its upstream branch and find which commits have been upstreamed and which haven&#8217;t.  This command is particularly clever because, thanks to <a href="https://www.kernel.org/pub/software/scm/git/docs/git-patch-id.html"><code>git patch-id</code></a>, it can correctly spot when a commit has been upstreamed, even when the upstreaming process resulted in changes to the commit message, line numbers, or whitespace.
</li>
<li><a href="https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html"><code>git rebase --onto</code></a> can transplant a contiguous series of commits onto another branch.
</li>
</ul>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1">It&#8217;s not always that easy &#x2026;</h2>
<div class="outline-text-2" id="text-1">
<p> However, on the occasions when you need to sift through a larger number of commits on one branch, and port them to another branch, complications can arise: </p>
<ul class="org-ul">
<li>If cherry-picking a commit results in changes to its patch context, <code>git patch-id</code> will return a different SHA-1, and subsequent invocations of <code>git cherry</code> will incorrectly tell you that you haven&#8217;t yet ported that commit.
</li>
<li>If you mess something up in the middle of a <code>git rebase</code>, recovery can be awkward, and <code>git rebase --abort</code> will land you back at square one, undoing a lot of your hard work.
</li>
<li>If the porting process is big enough, it could take days or even weeks, so you need some way of reliably tracking which commits have already been ported and which still need porting.  In this case you may well want to adopt a divide-and-conquer approach by sharing out the porting workload between team-mates.
</li>
<li>The more the two branches have diverged, the more likely it is that conflicts will be encountered during cherry-picking.
</li>
<li>There may be commits within the range you are looking at which after reviewing, you decide should be excluded from the port, or at least porting them needs to be postponed to a later point.
</li>
</ul>
<p> It could be argued that all of these problems can be avoided with the right branch and release management workflows, and I don&#8217;t want to debate that in this post.  However, this is the real world, and sometimes it just happens that you have to deal with a porting task which is less than trivial.  Well, that happened to me and my team not so long ago, so I&#8217;m here to tell you that I have written and published some tools to solve these problems.  If that&#8217;s of interest, then read on! </p>
<p><span id="more-981"></span>
</div>
</div>
<div id="outline-container-sec-2" class="outline-2">
<h2 id="sec-2">Building tools around <code>git notes</code></h2>
<div class="outline-text-2" id="text-2">
<p> Since <code>git patch-id</code> doesn&#8217;t guarantee to return an SHA-1 which is stable enough for us to always depend on, we need some other way of reliably tracking which commits have been upstreamed, and where upstreamed commits came from.  It would also be useful to be able to mark selected commits as <i>blacklisted</i>, i.e. permanently excluded from the current porting process, or at least as <i>deferred</i>, i.e. <i>temporarily</i> excluded. </p>
<p> Of course, we could do that simply by maintaining an out-of-band text file somewhere outside the repositories in question, but that doesn&#8217;t integrate at all with existing git workflows.  Whilst pondering these challenges, I discovered a little-known and seldom-used feature of git, which is the ability to attach arbitrary text as notes on a given commit, via the <a href="https://www.kernel.org/pub/software/scm/git/docs/git-notes.html"><code>git notes</code></a> command.  &#8220;This sounds perfect!&#8221;, I thought, and actually as it turned out, it served as a pretty nice foundation for some higher-level tools which needed building: </p>
<ul class="org-ul">
<li><a href="https://github.com/aspiers/git-config/blob/master/bin/git-icing">git-icing</a> &#8211; an &#8220;interface-candy&#8221; wrapper around git cherry which adds a splash of colour, and checks for specially formatted notes attached to commits which indicate that those commits are temporarily or permanently excluded from the upstreaming backlog
</li>
<li><a href="https://github.com/aspiers/git-config/blob/master/bin/git-cherry-menu">git-cherry-menu</a> &#8211; an interactive wrapper around <code>git-icing</code> and <code>git-notes</code> which makes it easy to cherry-pick and/or blacklist non-upstreamed commits
</li>
<li><a href="https://github.com/aspiers/git-config/blob/master/bin/git-rnotes">git-rnotes</a> &#8211; a wrapper around <code>git notes</code> which makes it easier to share notes to and from remote repositories
</li>
</ul>
</div>
</div>
<div id="outline-container-sec-3" class="outline-2">
<h2 id="sec-3">A &#8220;real world&#8221; example</h2>
<div class="outline-text-2" id="text-3">
<p> Let&#8217;s see how this works in practice, by pretending we need to backport a bunch of commits from <a href="https://github.com/openstack/nova">OpenStack Nova</a>&#8216;s <code>master</code> branch to its <code>stable/grizzly</code> release branch. </p>
<div class="org-src-container">
<pre class="src src-text">$ git clone git@github.com:openstack/nova.git
Cloning into 'nova'...
remote: Counting objects: 208984, done.
remote: Compressing objects: 100% (54766/54766), done.
remote: Total 208984 (delta 167220), reused 188334 (delta 148279)
Receiving objects: 100% (208984/208984), 124.50 MiB | 4.42 MiB/s, done.
Resolving deltas: 100% (167220/167220), done.
$ cd nova
</pre>
</div>
<p> Now, <code>master</code> has changed a <b>lot</b> since <code>grizzly</code> was released, so let&#8217;s keep our pretend project to a manageable size by only attempting to backport only commits which appeared in the first few days after the stable branch was established: </p>
<div class="org-src-container">
<pre class="src src-text">$ git describe $( git merge-base origin/stable/grizzly master )
2013.1.rc1
$ git show 2013.1.rc1 | head -n3
tag 2013.1.rc1
Tagger: Thierry Carrez <a href="mailto:thierry%40CENSORED.org">&lt;thierry@CENSORED.org&gt;</a>
Date:   Wed Mar 20 17:13:32 2013 +0100
</pre>
</div>
<p> OK, so <code>grizzly</code> was branched at the point where the first release candidate was tagged.  That makes sense.  Now let&#8217;s choose a point about 5 days later: </p>
<div class="org-src-container">
<pre class="src src-text">$ git rev-list --no-merges --before='25 March 2013' origin/stable/grizzly..master | head -n1
d6a9d38a0b7488dd77d3a01ae9c4171c271d7314
$ git tag to-backport d6a9d38
</pre>
</div>
<p> &#x2026; and get ready to backport commits from <code>to-backport</code> back into our local <code>stable/grizzly</code> branch: </p>
<div class="org-src-container">
<pre class="src src-text">$ git checkout stable/grizzly
Branch stable/grizzly set up to track remote branch stable/grizzly from origin.
Switched to a new branch 'stable/grizzly'
</pre>
</div>
<p> (If you are following along at home, your <code>rev-list</code> will give a different result, since <code>origin/stable/grizzly</code> will have changed since I wrote this.  Don&#8217;t worry &#8211; just copy the <code>git tag</code> command above verbatim, and create your local grizzly branch via <code>git checkout -b stable/grizzly fc9af8f0a9</code> so that it points to the same place mind did when writing this article.) </p>
<p> At this point, two quick clarifications are needed, because things can get a bit confusing. </p>
</div>
</div>
<div id="outline-container-sec-4" class="outline-2">
<h2 id="sec-4">A quick aside: some observations on terminology</h2>
<div class="outline-text-2" id="text-4">
<p> Firstly, if you read the <a href="https://www.kernel.org/pub/software/scm/git/docs/git-cherry.html"><code>git cherry</code> man page</a> or <code>-h</code> usage text, it is described as a tool to &#8220;find commits not merged upstream&#8221;, with the expectation that you would cherry-pick the commits it finds <i>onto</i> the upstream branch.  But if you happen to be backporting, then the cherry-picking will happen in the <i>opposite</i> direction, so the &#8220;upstream&#8221; referred to by the man page is actually the real downstream, and vice-versa.  Confused yet?  If so, wherever you read the word &#8220;upstream&#8221; in the <code>git cherry</code> documentation / help text, pretend that you actually read &#8220;target&#8221;.  Then just think of &#8220;source&#8221; and &#8220;target&#8221; branches, and remember that the process is always to look for commits in the source which are not yet in the target, and then cherry-pick those into the target (or decide that you don&#8217;t want to). The same applies for the <code>git icing</code> and <code>cherry-menu</code> help text. </p>
<p> Secondly, normally we&#8217;d be porting from one branch to another, not from a tag to a branch.  But in this artificially constructed scenario, it wouldn&#8217;t make much sense to create a <code>to-backport</code> <i>branch</i> pointing to <code>d6a9d38</code>, because that branch isn&#8217;t going to move; the only branch which will be changing is our <code>stable/grizzly</code> branch, as we cherry-pick stuff into it.  In other words, the target has to be a branch, because that will change during the cherry-picking, but the source can be a branch / tag / ref / commit SHA-1 &#x2026; basically anything which <a href="https://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html"><code>git rev-parse</code></a> understands. </p>
</div>
</div>
<div id="outline-container-sec-5" class="outline-2">
<h2 id="sec-5">How far behind?</h2>
<div class="outline-text-2" id="text-5">
<p> When embarking on a porting project, the first question is usually &#8220;how much work is this going to be?&#8221;  Fortunately <code>git-icing</code> is here to help! </p>
<p> (By the way, if you want to follow along with the below by trying this yourself, simply download the three scripts either from the links above or </p>
<div class="org-src-container">
<pre class="src src-text">git clone https://github.com/aspiers/git-config
</pre>
</div>
<p> and then copy them to any directory on your <code>$PATH</code>, making sure that they are executable.) </p>
<p> <code>git-icing</code> is designed to be invoked in exactly the same way as <code>git cherry</code>, but it has some extra options, including the convenient <code>--summary</code> option, and a verbosity parameter which controls which categories of commits are displayed: </p>
<div class="org-src-container">
<pre class="src src-text">$ git icing -h
usage: git icing [options] [git cherry args]

    -v, --verbosity [N]              Set verbosity level
    -s, --summary                    Show summary

first | verbosity | description of
field |   level   | classification
------+-----------+-----------------------------------------------------
  +   |     1     | not yet upstream
  !   |     1     | still needs to be upstreamed, tracked on a TODO list
  .?  |     1     | upstream *and* blacklisted?!
  !?  |     1     | upstream *and* marked as a TODO?
  .   |     2     | blacklisted - should not be pushed to this upstream
  ?   |     2     | not yet upstream, with unparseable note
  -   |     3     | already upstream
  #   |     3     | already upstream with an annotation note
</pre>
</div>
<p> (When you run that on a colour-capable terminal, you&#8217;ll also see that the classifications are also nicely colour-coded so that commits which require attention naturally capture your eye more than those which don&#8217;t.) </p>
<p> Let&#8217;s see all commits (basically a colour-coded version of what <code>git cherry</code> would show us), plus a summary of the status quo: </p>
<div class="org-src-container">
<pre class="src src-text">$ git icing -v3 --summary stable/grizzly to-backport
+ 348cfedfcadc377fa91029b932b2a93d16475822 nova-manage: remove redundant 'dest' args
+ f16534db22d63ce9f762ee6f7a9245126e9f28ed nova-manage: remove unused import
- 775e3b02b2afbf101db22b87a1c3b189d68532e1 Pass project id in quantum driver secgroup list
+ dbbbbf4ecb2c7b03ebb30fa11e077d35b2186cbb Enable tox use of site-packages for libvirt.
- 76844433f69a7c29ed4566ad34d7e9740feaf660 Add caching for ec2 mapping ids.
+ def5fa1e0e1c0426d973e4d8e3935c6eb18698dc Set version to 2013.2
+ 3aa80834e6aab2456f0f5229a63c2dcef007cb36 Change type of ssh_port option from Str to Int
+ 26aa01094a79939320d58f2fe2d5731f169987b1 Change arguments to volume_detach()
+ b52a2157bedba693c5da7dcb783b7a151769d6b1 Add placeholder migrations to allow backports.
+ 8d5159dd6dd36d6f3d1aadc1123574c5b0aa0614 Don't actually connect to libvirtd in unit tests.
+ 8cd5f862ac071023d5a7984f07513e5aa91f7d3d Bring back sexy colorized test results.
- 45e65d8c0301da689de1afcbc9f45756e71097ab Update instance network info cache to include vif_type.
- b8f9815c5ab61466009c0447f54abc4c309e4e3f nova-manage vm list fails looking 'instance_type'
+ c199fd6fa39311305b5b5d94c2e3732b826a6414 Remove outdated try except block in ec2 code
- 03a2463be8034ee4764ac97e8020fc3d3a32f1fd Make nova.virt.fake.FakeDriver useable in integration testing
- 67628c56caf9d84588a92448880ecdb33eea08b4 Fixes passing arbitrary conductor_api argument
+ e136de1aea8d1469465272942fa3d2769cbe3a80 xenapi: fix console for rescued instance
+ 5df18f6b915cf49ac8559274a631f1366eab00fd Add a comment to placeholder migrations.
- 9075069098e32b47bd5011e2653a23b61c18d4a3 Initialize compute manager before loading driver.
- 3801a4d2f4c59dbfda49131ddde22fcb3976d651 translate cinder BadRequest exception
- 132a0c1fd1eb127e393e5794ffa6d4a3a4950567 Don't log traceback on rpc timeout.
+ 81204d4020712cf5b5b368b75d934d637b2c001b Sync rpc from oslo-incubator.
+ f665d798234c19cccc148a178e94c3717ba8bd6e Sync everything from oslo-incubator.
- 12f7d6332a731421d6e2a190ac60828c1cf98910 Reset ec2 image cache between S3 tests.
+ 7a9ce26aaf03459a7ea367fbdb91d91626a1ee93 py2.6 doesn't support TextTestRunner resultclass
- 5908b60b0420f1ad528e56b0c147a330e9a1a5d6 Make _downsize_quota_delta() use stashed instance types
+ 91b9c208f0c6e21759c7828aa42b3216853be425 disable colorizer as it swallows fails
+ df0560f0353bc0837cc62cfaa9029d21d45c529e Imported Translations from Transifex
+ d6a9d38a0b7488dd77d3a01ae9c4171c271d7314 set up FakeLogger for root logger.

Summary
=======

11 commits processed:
    11 already upstream

18 commits remaining:
    18 not yet upstream

Progress: 11 / 29 commits (37%)
</pre>
</div>
<p> OK, not bad!  We didn&#8217;t even do any real work yet, we&#8217;re already 37% of the way through.  That&#8217;s because some of the commits (the ones prefixed by <code>-</code>) have already been cherry-picked into <code>stable/grizzly</code>.  Let&#8217;s prove this for the first commit prefixed by <code>-</code> in the above output, which was <code>775e3b02</code>: </p>
<div class="org-src-container">
<pre class="src src-text">$ git log -n1 775e3b02
commit 775e3b02b2afbf101db22b87a1c3b189d68532e1
Author: Kieran Spear <a href="mailto:kispear%40CENSORED.com">&lt;kispear@CENSORED.com&gt;</a>
Date:   Mon Mar 18 17:32:26 2013 +1100

    Pass project id in quantum driver secgroup list

    The quantum driver is always returning security groups from every tenant
    a user has access to, even when the "project" filter is supplied.

    Make sure we pass along the project value when we call
    quantum.list_security_groups() so it's properly filtered.

    Fixes bug 1155381.

    Change-Id: I682c66a1f3f9db18b5f9924a37b45c759ff259f7
</pre>
</div>
<p> This commit appears to be only on <code>master</code>, not on <code>stable/grizzly</code>: </p>
<div class="org-src-container">
<pre class="src src-text">$ git branch --all --contains 775e3b02
  master
  remotes/origin/HEAD -&gt; origin/master
  remotes/origin/master
</pre>
</div>
<p> Let&#8217;s try to find the commit which cherry-picked it into <code>stable/grizzly</code>: </p>
<div class="org-src-container">
<pre class="src src-text">$ git log --format=fuller --no-merges --grep='Pass project id' stable/grizzly
commit 989435822e5841bc1355e75bbdb003b10a3baf58
Author:     Kieran Spear <a href="mailto:kispear%40CENSORED.com">&lt;kispear@CENSORED.com&gt;</a>
AuthorDate: Mon Mar 18 17:32:26 2013 +1100
Commit:     Chuck Short <a href="mailto:chuck.short%40CENSORED.com">&lt;chuck.short@CENSORED.com&gt;</a>
CommitDate: Tue Mar 26 10:09:40 2013 -0500

    Pass project id in quantum driver secgroup list

    The quantum driver is always returning security groups from every tenant
    a user has access to, even when the "project" filter is supplied.

    Make sure we pass along the project value when we call
    quantum.list_security_groups() so it's properly filtered.

    Fixes bug 1155381.

    Change-Id: I682c66a1f3f9db18b5f9924a37b45c759ff259f7
    (cherry picked from commit 775e3b02b2afbf101db22b87a1c3b189d68532e1)
$ git branch --all --contains 9894358
* stable/grizzly
  remotes/origin/stable/grizzly
</pre>
</div>
<p> There it is!  Notice that it was committed 6 days after RC1 was tagged, but it has the same <code>patch-id</code> as the original, even though the commit message/date and committer are all different: </p>
<div class="org-src-container">
<pre class="src src-text">$ git patch-id &lt; &lt;(git show 9894358)
42dd410cf36ad1c16ceb1bb7f6ed6e3f01cc28bf 989435822e5841bc1355e75bbdb003b10a3baf58
$ git patch-id &lt; &lt;(git show 775e3b02)
42dd410cf36ad1c16ceb1bb7f6ed6e3f01cc28bf 775e3b02b2afbf101db22b87a1c3b189d68532e1
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-6" class="outline-2">
<h2 id="sec-6"><code>git cherry-menu</code> &#8211; let the picking commence</h2>
<div class="outline-text-2" id="text-6">
<p> Now we can actually start porting the remaining commits. <a href="https://github.com/aspiers/git-config/blob/master/bin/git-cherry-menu"><code>git-cherry-menu</code></a> provides an interactive interface to make this process less tedious: </p>
<div class="org-src-container">
<pre class="src src-text">$ git cherry-menu -h
usage: git [options] cherry-menu &lt;command&gt; [&lt;args&gt;...]
suggested options:

[... snipped ...]

&lt;command&gt; &lt;args&gt; are typically "git icing -v3" or "git cherry", but
can be anything which gives output in the same format.  This allows
more control over which commits constitute the upstreaming backlog,
e.g.

    git icing -v2 $upstream $downstream | grep ... &gt; tmpfile
    # Could edit tmpfile here if we want
    git-cherry-menu cat tmpfile

Provides an interactive wrapper around git-icing (or git cherry).  For
each commit provided on STDIN by COMMAND which has not yet been
upstreamed, asks the user whether they want to cherry-pick the commit,
blacklist it, or skip it.  After a successful cherry-pick, the source
commit will be automatically blacklisted if the patch-id changed.

You can quit the process at any time and safely re-run it later - it
will resume from where you left off.

Invoking icing with "-v2" ensures that previously blacklisted /
upstreamed commits are also processed.
</pre>
</div>
<p> Let&#8217;s give it a go &#x2026; </p>
<div class="org-src-container">
<pre class="src src-text">$ git cherry-menu git icing -v3 stable/grizzly to-backport
commit 348cfedfcadc377fa91029b932b2a93d16475822
Author: Zhiteng Huang <a href="mailto:zhiteng.huang%40CENSORED.com">&lt;zhiteng.huang@CENSORED.com&gt;</a>
Date:   Tue Feb 26 09:23:13 2013 +0800

    nova-manage: remove redundant 'dest' args

    Includes a hack to calculate 'dest' from the argument name. This hack is
    removed in a later commit.

    Change-Id: I60567ff232ab7699f3234b3bfc1618a17a648976

diff --git a/bin/nova-manage b/bin/nova-manage
index 0fde8ba..4919d88 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -127,10 +127,10 @@ def param2id(object_id):
 class VpnCommands(object):
     """Class for managing VPNs."""

-    @args('--project', dest="project_id", metavar='&lt;Project name&gt;',
+    @args('--project', dest='project_id', metavar='&lt;Project name&gt;',

[... snipped ...]

Cherry-pick / blacklist / skip 348cfedfca, or quit ?
</pre>
</div>
<p> It&#8217;s showing us the first commit in the porting backlog, and asking us to decide whether to cherry-pick it, blacklist it (i.e. permanently exclude it from the porting process), or defer the decision by skipping it and moving onto the next commit in backlog.  (<code>q</code> quits the whole process, of course.) </p>
<p> Let&#8217;s try cherry-picking it: </p>
<div class="org-src-container">
<pre class="src src-text">Cherry-pick / blacklist / skip 348cfedfca, or quit ? c

error: could not apply 348cfed... nova-manage: remove redundant 'dest' args
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add &lt;paths&gt;' or 'git rm &lt;paths&gt;'
hint: and commit the result with 'git commit'

Spawning a shell so you can fix; exit the shell when done.
$
</pre>
</div>
<p> Oh dear, this one&#8217;s going to need some further thought.  Let&#8217;s skip it for now: </p>
<div class="org-src-container">
<pre class="src src-text">$ git reset --hard
HEAD is now at ddb676d Merge "Typo: certicates=&gt;certificates in nova.conf"
$ exit
Warning: HEAD did not change; no action taken.
Press enter to continue ... 

-----------------------------------------------------------------------

commit f16534db22d63ce9f762ee6f7a9245126e9f28ed
Author: Zhiteng Huang <a href="mailto:zhiteng.huang%40CENSORED.com">&lt;zhiteng.huang@CENSORED.com&gt;</a>
Date:   Tue Feb 26 09:23:13 2013 +0800

    nova-manage: remove unused import

    Unused since commit 9ff3121b

    Change-Id: I76bb49669d1cdfc3bf5b1c20087b4bd77420cd91

diff --git a/bin/nova-manage b/bin/nova-manage
index 4919d88..e93c3d8 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -88,7 +88,6 @@ from nova.openstack.common import timeutils
 from nova import quota
 from nova.scheduler import rpcapi as scheduler_rpcapi
 from nova import servicegroup
-from nova import utils
 from nova import version

 CONF = cfg.CONF

Cherry-pick / blacklist / skip f16534db22, or quit ?
</pre>
</div>
<p> <code>cherry-menu</code> presents the next commit in the backlog, which in this case is removing an unused import from <code>bin/nova-manage</code>.  Sounds pretty straight-forward, so let&#8217;s cherry-pick: </p>
<div class="org-src-container">
<pre class="src src-text">Cherry-pick / blacklist / skip f16534db22, or quit ? c

[stable/grizzly 3f013e4] nova-manage: remove unused import
 Author: Zhiteng Huang <a href="mailto:zhiteng.huang%40CENSORED.com">&lt;zhiteng.huang@CENSORED.com&gt;</a>
 1 file changed, 1 deletion(-)
</pre>
</div>
<p> Looks like this worked fine.  The output continues: </p>
<div class="org-src-container">
<pre class="src src-text">-----------------------------------------------------------------------

Already upstream: 775e3b02b2 - Pass project id in quantum driver secgroup list
</pre>
</div>
<p> Here <code>cherry-menu</code> is telling us it automatically skipped over a commit which is already in our target branch.  The output continues with the next commit in the backlog, which we can also successfully pick: </p>
<div class="org-src-container">
<pre class="src src-text">commit dbbbbf4ecb2c7b03ebb30fa11e077d35b2186cbb
Author: Clark Boylan <a href="mailto:clark.boylan%40CENSORED.com">&lt;clark.boylan@CENSORED.com&gt;</a>
Date:   Thu Feb 7 21:39:31 2013 -0800

    Enable tox use of site-packages for libvirt.

    Enable the use of site-packages in tox which will allow the use of the
    system install of libvirt while testing.

    Hardcode the libvirt host UUID for tests that check this UUID when
    system libvirt is being used. Without this hardcoding eight tests
    would fail when using the system libvirt install.

    Partially fixes bug #1113181

    Change-Id: I59c5fbd45639962c0963298203c39759b6ca2d11

[... snipped ...]

Cherry-pick / blacklist / skip dbbbbf4ecb, or quit ? c

[stable/grizzly b4fdf14] Enable tox use of site-packages for libvirt.
 Author: Clark Boylan <a href="mailto:clark.boylan%40CENSORED.com">&lt;clark.boylan@CENSORED.com&gt;</a>
 2 files changed, 8 insertions(+)

-----------------------------------------------------------------------

Already upstream: 76844433f6 - Add caching for ec2 mapping ids.
commit def5fa1e0e1c0426d973e4d8e3935c6eb18698dc
Author: Thierry Carrez <a href="mailto:thierry%40CENSORED.org">&lt;thierry@CENSORED.org&gt;</a>
Date:   Wed Mar 20 16:21:48 2013 +0100

    Set version to 2013.2

    Open Havana development by setting version to 2013.2.

    Change-Id: I37917d28a1f9e0adc2fe3e382412ebc4ed0f3bee

diff --git a/setup.py b/setup.py
index fd968ee..e4bc7d4 100644
--- a/setup.py
+++ b/setup.py
@@ -25,7 +25,7 @@

 setuptools.setup(
       name=project,
-      version=common_setup.get_version(project, '2013.1'),
+      version=common_setup.get_version(project, '2013.2'),
       description='cloud computing fabric controller',
       author='OpenStack',
       author_email='nova@CENSORED.launchpad.net',

Cherry-pick / blacklist / skip def5fa1e0e, or quit ?
</pre>
</div>
<p> Now, obviously we don&#8217;t want to backport this version change, so let&#8217;s blacklist it in order to permanently excluded it from the porting backlog: </p>
<div class="org-src-container">
<pre class="src src-text">Cherry-pick / blacklist / skip def5fa1e0e, or quit ? b
</pre>
</div>
<p> At this point, your favourite <code>$EDITOR</code> will be launched via an invocation of <code>git notes edit</code>, and you&#8217;ll be presented with a text buffer which looks like this: </p>
<div class="org-src-container">
<pre class="src src-text">skip: all
XXX  (you can optionally change the "all" above to the name of the
XXX  upstream branch if you want to limit blacklisting to that upstream)

XXX  Enter your justification for blacklisting here or
XXX  remove the whole note to cancel blacklisting.

#
# Write/edit the notes for the following object:

# commit def5fa1e0e1c0426d973e4d8e3935c6eb18698dc
# Author: Thierry Carrez <a href="mailto:thierry%40CENSORED.org">&lt;thierry@CENSORED.org&gt;</a>
# Date:   Wed Mar 20 16:21:48 2013 +0100
#
#     Set version to 2013.2
#     
#     Open Havana development by setting version to 2013.2.
#     
#     Change-Id: I37917d28a1f9e0adc2fe3e382412ebc4ed0f3bee
#
#  setup.py | 2 +-
#  1 file changed, 1 insertion(+), 1 deletion(-)
</pre>
</div>
<p> At this point you should remove all the lines beginning <code>XXX</code>, and decide whether you want this commit to be blacklisted from <b>any</b> future porting operation.  If so, you can leave the <code>skip: all</code> line as is and simply save the buffer and quit the editor, although it&#8217;s best practice to also give a sentence or two justifying why you&#8217;re blacklisting the commit. </p>
<p> Alternatively you can change <code>all</code> to the name of the branch to which this commit should never be ported, which in this case is <code>stable/grizzly</code>.  It is also permitted to use Ruby regular expressions here, by surrounding the regexp with forward slashes, e.g. </p>
<div class="org-src-container">
<pre class="src src-text">skip: /stable/

It never makes sense to port version number changes back to
stable releases.
</pre>
</div>
<p> Once the editor has been quit, we see: </p>
<div class="org-src-container">
<pre class="src src-text">Blacklisted def5fa1e0e
Press enter to continue ...
</pre>
</div>
<p> Behind the scenes, <code>cherry-menu</code> has attached a note to this commit within the <code>refs/notes/upstreaming</code> namespace: </p>
<div class="org-src-container">
<pre class="src src-text">$ git notes --ref=upstreaming show def5fa
skip: all
</pre>
</div>
<p> and you can even see the complete history of your note-editing: </p>
<div class="org-src-container">
<pre class="src src-text">$ git log notes/upstreaming
commit ed6cf5fa75921f23088656b7a8d8a96faa9d769d
Author: Adam Spiers <a href="mailto:aspiers%40CENSORED.com">&lt;aspiers@CENSORED.com&gt;</a>
Date:   Fri Sep 20 15:59:04 2013 +0100

    Notes added by 'git notes edit'

commit c1f6ba13e643de4da354375b479470599f92b272
Author: Adam Spiers <a href="mailto:aspiers%40CENSORED.com">&lt;aspiers@CENSORED.com&gt;</a>
Date:   Fri Sep 20 15:44:15 2013 +0100

    Notes added by 'git notes add'

[... snipped ...]
</pre>
</div>
<p> After all this hard work, maybe it&#8217;s time for lunch.  We can safely quit <code>cherry-menu</code> via <code>Control-C</code> or <code>q</code>, and resume it later. Before tucking into a tasty sandwich, let&#8217;s quickly review our progress: </p>
<div class="org-src-container">
<pre class="src src-text">$ git icing -v3 -s stable/grizzly to-backport
+ 348cfedfcadc377fa91029b932b2a93d16475822 nova-manage: remove redundant 'dest' args
- f16534db22d63ce9f762ee6f7a9245126e9f28ed nova-manage: remove unused import
- 775e3b02b2afbf101db22b87a1c3b189d68532e1 Pass project id in quantum driver secgroup list
- dbbbbf4ecb2c7b03ebb30fa11e077d35b2186cbb Enable tox use of site-packages for libvirt.
- 76844433f69a7c29ed4566ad34d7e9740feaf660 Add caching for ec2 mapping ids.
. def5fa1e0e1c0426d973e4d8e3935c6eb18698dc Set version to 2013.2
+ 3aa80834e6aab2456f0f5229a63c2dcef007cb36 Change type of ssh_port option from Str to Int
+ 26aa01094a79939320d58f2fe2d5731f169987b1 Change arguments to volume_detach()

[... snipped ...]

Summary
=======

14 commits processed:
    13 already upstream
     1 blacklisted - should not be pushed to this upstream

15 commits remaining:
    15 not yet upstream

Progress: 14 / 29 commits (48%)
</pre>
</div>
<p> Wow, almost half-way!  Notice also how the prefix by <code>def5fa1</code> has changed to a period sign to indicate that it&#8217;s now blacklisted. </p>
<p> After lunch, we can resume the process: </p>
<div class="org-src-container">
<pre class="src src-text">$ git cherry-menu git icing -v3 stable/grizzly to-backport
commit 348cfedfcadc377fa91029b932b2a93d16475822
Author: Zhiteng Huang <a href="mailto:zhiteng.huang%40CENSORED.com">&lt;zhiteng.huang@CENSORED.com&gt;</a>
Date:   Tue Feb 26 09:23:13 2013 +0800

    nova-manage: remove redundant 'dest' args

[... snipped ...]

Cherry-pick / blacklist / skip 348cfedfca, or quit ?
</pre>
</div>
<p> This is the same commit which caused conflicts last time we tried to pick it.  Let&#8217;s officially postpone resolving conflicts by adding it to a &#8220;TODO&#8221; blacklist.  Press <code>b</code>, then as before, remove the <code>XXX</code>, and also replace the <code>skip: all</code> line with: </p>
<div class="org-src-container">
<pre class="src src-text">TODO: fix conflicts next week
</pre>
</div>
<div class="org-src-container">
<pre class="src src-text">Blacklisted 348cfedfca
Press enter to continue ... 

-----------------------------------------------------------------------

Already upstream: f16534db22 - nova-manage: remove unused import
Already upstream: 775e3b02b2 - Pass project id in quantum driver secgroup list
Already upstream: dbbbbf4ecb - Enable tox use of site-packages for libvirt.
Already upstream: 76844433f6 - Add caching for ec2 mapping ids.
Blacklisted: def5fa1e0e - Set version to 2013.2
commit 3aa80834e6aab2456f0f5229a63c2dcef007cb36
Author: Devananda van der Veen <a href="mailto:devananda.vdv%40CENSORED.com">&lt;devananda.vdv@CENSORED.com&gt;</a>
Date:   Wed Mar 20 09:19:44 2013 -0700

    Change type of ssh_port option from Str to Int

    The type of CONF option virtual_power_ssh_port was incorrectly defaulted
    to Str. This can cause Paramiko to raise when casting to %d.

    Fixes bug 1157824.

    Change-Id: I30ddd1ff0da45f8392085249f1bd2a539b201a7e
</pre>
</div>
<p> Now we are taken immediately to where we left off just before lunch, because <code>git-icing</code> automatically detected the cherry-picks we did earlier, and also that we blacklisted the 2013.2 version change commit. </p>
<p> If we run <code>git-icing</code> again, we&#8217;ll see that it understands the significance of the <code>TODO</code> attached to the first commit in the backlog: </p>
<div class="org-src-container">
<pre class="src src-text">$ git icing -v3 -s stable/grizzly to-backport                                                        
! 348cfedfcadc377fa91029b932b2a93d16475822 nova-manage: remove redundant 'dest' args
- f16534db22d63ce9f762ee6f7a9245126e9f28ed nova-manage: remove unused import
- 775e3b02b2afbf101db22b87a1c3b189d68532e1 Pass project id in quantum driver secgroup list

[... snipped ...]

Summary
=======

14 commits processed:
    13 already upstream
     1 blacklisted - should not be pushed to this upstream

15 commits remaining:
    14 not yet upstream
     1 still needs to be upstreamed, tracked on a TODO list

Progress: 14 / 29 commits (48%)
</pre>
</div>
<p> On subsequent invocations of <code>git cherry-menu</code>, it will offer the option of editing existing notes.  There is also an option to automatically skip any notes including the word <code>TODO</code>: </p>
<div class="org-src-container">
<pre class="src src-text">$ git cherry-menu -h
usage: git [&lt;options&gt;] cherry-menu &lt;command&gt; [&lt;args&gt;...]
suggested options:

[... snipped ...]

-c cherry-menu.skip-todos=true
      Skip commits which have notes including 'TODO'.  This allows
      unresolved upstreaming tasks to be tracked via an external
      issue tracker without getting in the way during repeated
      runs of cherry-menu.

[... snipped ...]
</pre>
</div>
<p> So that&#8217;s the majority of <code>cherry-menu</code>&#8216;s functionality explained. It&#8217;s not rocket science, just a quick hack of a shell-script, but it gets the job done pretty well. </p>
<p> There&#8217;s one more important feature I didn&#8217;t cover: if the <code>patch-id</code> changes during cherry-picking, <code>cherry-menu</code> will notice, and automatically add the old commit to the blacklist: </p>
<div class="org-src-container">
<pre class="src src-text">Cherry-pick / blacklist / skip 81204d4020, or quit ? c

[stable/grizzly 65cd526] Sync rpc from oslo-incubator.
 Author: Russell Bryant <a href="mailto:rbryant%40CENSORED.com">&lt;rbryant@CENSORED.com&gt;</a>
 4 files changed, 47 insertions(+), 21 deletions(-)
The git patch-id changed during cherry-picking.  This is normal when
the diff context changes or merge conflicts are resolved.
Blacklisted 81204d4020 so future runs won't attempt to duplicate the upstreaming.
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-7" class="outline-2">
<h2 id="sec-7"><code>git rnotes</code> &#8211; sharing the fruits of your labours</h2>
<div class="outline-text-2" id="text-7">
<p> Maybe our project manager comes over and says &#8220;hey, we need those features backported to stable ASAP &#8211; I&#8217;ve asked Joe and Fred to help you out, OK?&#8221; </p>
<p> So far, all the work has happened in a local repository.  Of course we can push our updated <code>stable/grizzly</code> branch to a public repository somewhere, so that Joe and Fred can see what we already cherry-picked. But they&#8217;d be still missing some valuable meta-data, i.e. the git notes we created which mark which commits to exclude from porting, and why.  Unfortunately, git doesn&#8217;t yet natively provide a convenient way for pushing/pulling notes between repositories, because <a href="http://thread.gmane.org/gmane.comp.version-control.git/222644/focus%3D222812">the <code>refs/*</code> namespace hasn&#8217;t been sufficiently standardized yet</a>. To work around that, I wrote <a href="https://github.com/aspiers/git-config/blob/master/bin/git-rnotes"><code>git-rnotes</code></a> to avoid having to remember a slightly arcane sequence of git commands. </p>
<p> Usage is very simple, and mimics <code>git fetch/push/merge/pull</code>: </p>
<div class="org-src-container">
<pre class="src src-text">Usage: git-rnotes [options] SUBCOMMAND REMOTE
Options:
  -h, --help     Show this help and exit

Subcommands:

  fetch
  push
  merge
  pull
</pre>
</div>
<p> For example, if you have a remote called <code>public</code>: </p>
<div class="org-src-container">
<pre class="src src-text">export GIT_NOTES_REF=refs/notes/upstreaming
git rnotes push public
</pre>
</div>
<p> or if Joe has updated his notes and pushed them to <code>public</code> whilst you also updated yours, simply do a <code>pull</code>, which is equivalent to a <code>fetch</code> followed by a <code>merge</code>: </p>
<div class="org-src-container">
<pre class="src src-text">export GIT_NOTES_REF=refs/notes/upstreaming
git rnotes pull public
</pre>
</div>
</div>
</div>
<div id="outline-container-sec-8" class="outline-2">
<h2 id="sec-8">Wrapping up</h2>
<div class="outline-text-2" id="text-8">
<p> Sorry that was so long.  But hopefully you agree it&#8217;s relatively simple once you try it out.  I&#8217;d love to know if anyone finds this useful &#8211; if you do, please leave a comment below!  Of course pull requests against <a href="https://github.com/aspiers/git-config">my <code>git-config</code> repository</a> are always welcome. There are many other git-related hacks in that repository which you may also find useful. </p>
<p> Thanks for reading! </p>
</div>
</div>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2013%2F09%2F19%2Feasier-upstreaming-with-git%2F&#038;title=Easier%20upstreaming%20%2F%20back-porting%20of%20patch%20series%20with%20git" data-a2a-url="https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/" data-a2a-title="Easier upstreaming / back-porting of patch series with git"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/">Easier upstreaming / back-porting of patch series with git</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2013/09/19/easier-upstreaming-with-git/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
		<item>
		<title>new music video: acoustic version of Jóga by Björk, with Emma Smith</title>
		<link>https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/</link>
					<comments>https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/#respond</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Wed, 18 Sep 2013 12:20:07 +0000</pubDate>
				<category><![CDATA[front page]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[Bjork]]></category>
		<category><![CDATA[covers]]></category>
		<category><![CDATA[Emma Smith]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[Joga]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[kdenlive]]></category>
		<category><![CDATA[pop]]></category>
		<category><![CDATA[video]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=972</guid>

					<description><![CDATA[<p>I&#8217;m a long-time fan of Björk, and was recently lucky enough to snarf a spare ticket to a show here in London at the end of her Biophilia tour. It was a fairly insane show (in a good way), involving an all female Icelandic choir, a drummer, an organ, a musically aware lightning bolt generator, [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/">new music video: acoustic version of Jóga by Björk, with Emma Smith</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I&#8217;m a long-time fan of <a href="http://en.wikipedia.org/wiki/Bj%C3%B6rk">Björk</a>, and was recently lucky enough to snarf a spare ticket to a show here in London at the end of her <a href="http://en.wikipedia.org/wiki/Biophilia_Tour">Biophilia tour</a>.  It was a fairly insane show (in a good way), involving an all female Icelandic choir, a drummer, an organ, a musically aware lightning bolt generator, a pin-barrel harp, and <a href="http://en.wikipedia.org/wiki/David_Attenborough">David Attenborough</a> (obviously).  Really impressive to see how she&#8217;s still trail-blazing rather than just churning out the old favourites (although some of the latter were presented in imaginative new ways).</p>
<p>On a related note, back in February I revisited my old haunt the <a href="http://ram.ac.uk">Royal Academy of Music</a> to record/film a version of Björk&#8217;s famous tune <a href="http://en.wikipedia.org/wiki/J%C3%B3ga">Jóga</a>, arranged and sang by the amazing and consistently entertaining singer <a href="http://en.wikipedia.org/wiki/Bj%C3%B6rk">Emma Smith</a>.  Yesterday I finally finished the video editing (done with the awesome <a href="http://www.kdenlive.org/">Kdenlive</a> video editor which is <a href="http://en.wikipedia.org/wiki/Free_software">Free Software</a>), and here is the result.  Hope you enjoy it! </p>
<p><iframe width="640" height="480" src="//www.youtube.com/embed/ZlpAl-ni5KU" frameborder="0" allowfullscreen></iframe></p>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2013%2F09%2F18%2Fjoga-acoustic-cover%2F&#038;title=new%20music%20video%3A%20acoustic%20version%20of%20J%C3%B3ga%20by%20Bj%C3%B6rk%2C%20with%20Emma%20Smith" data-a2a-url="https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/" data-a2a-title="new music video: acoustic version of Jóga by Björk, with Emma Smith"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/">new music video: acoustic version of Jóga by Björk, with Emma Smith</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2013/09/18/joga-acoustic-cover/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>music industry learns nothing from the Avid / Sibelius saga?</title>
		<link>https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/</link>
					<comments>https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/#comments</comments>
		
		<dc:creator><![CDATA[Adam]]></dc:creator>
		<pubDate>Mon, 25 Feb 2013 22:46:10 +0000</pubDate>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[Avid]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[FSF]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[LilyPond]]></category>
		<category><![CDATA[MuseScore]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[Sibelius]]></category>
		<category><![CDATA[software]]></category>
		<guid isPermaLink="false">http://blog.adamspiers.org/?p=862</guid>

					<description><![CDATA[<p>UPDATE 26/02/2013: Daniel has replied to this post, and I have replied to his reply. As George Santayana famously said, &#8220;those who cannot remember the past are condemned to repeat it&#8221;. In light of recent news regarding music notation software, I would add with some disappointment and frustration that those who choose to ignore the [&#8230;]</p>
<p>The post <a href="https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/">music industry learns nothing from the Avid / Sibelius saga?</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>UPDATE 26/02/2013:</strong> Daniel has <a href="http://blog.steinberg.net/2013/02/welcome/#comment-203">replied</a> to this post, and I have <a href="http://blog.steinberg.net/2013/02/welcome/#comment-207">replied</a> to his reply.</p>
<p>As <a href="http://en.wikiquote.org/wiki/George_Santayana">George Santayana</a> famously said, &#8220;those who cannot remember the past are condemned to repeat it&#8221;. In light of recent news regarding music notation software, I would add with some disappointment and frustration that those who choose to ignore the past are also condemned to repeat it.</p>
<p>For those of you who don&#8217;t already know, <a href="http://en.wikipedia.org/wiki/Sibelius_(software)">Sibelius</a> is a proprietary software product for music notation which has for many years been one of the most popular choices for professional musicians and composers. For many of the more experienced customers in the technology industry who have already been burned in the past, a heavy reliance on a single technology is enough to trigger alarm bells &#8211; what if the company providing that technology goes bust, or decides to change direction and cease work on it, or simply does an <em>awful</em> job (*cough* Microsoft *cough*) of maintaining and supporting that technology? Then you&#8217;re up a certain creek without the proverbial paddle.</p>
<p>In the IT industry, this is a well-known phenomenon called <em><a href="http://en.wikipedia.org/wiki/Vendor_lock-in">vendor lock-in</a></em>. A powerful movement based on <a href="http://en.wikipedia.org/wiki/Free_software">Free Software</a> was born in the early eighties to free computer users from this lock-in, and is now used on billions of devices world-wide. You may have never heard of Free Software, but if you own an Android phone or a &#8220;broadband&#8221; router, or have ever used the Firefox browser or Google Chrome, you have already used it. The vast majority of the largest companies in the world all run Free Software in their datacentres around the world; for example, every time you access Google or Facebook you are (indirectly) using Free Software.</p>
<p>What does any of this have to do with Sibelius? <span id="more-862"></span>Well, in 2006, <a href="http://en.wikipedia.org/wiki/Sibelius_Software">Sibelius Software</a> was bought by <a href="http://en.wikipedia.org/wiki/Avid">Avid Technology, Inc.</a>, and despite remaining a very successful business, in July 2012 <a href="http://www.artsjournal.com/slippeddisc/2012/08/at-sibelius-software-the-last-staff-turn-out-the-lights.html">Avid laid off the entire Sibelius development team</a>, effectively condemning the product to rapid decline and a very uncertain future. This decision received widespread condemnation, and yet Avid have refused to waver from their course, potentially stranding millions of users in the medium to long term.</p>
<p>I do not wish to criticise those users for locking themselves into a proprietary solution in the first place. Many of them will have been encouraged along that route during their education (<a href="http://en.wikipedia.org/wiki/Sibelius_(software)#Users">many music colleges provide Sibelius to students</a>, for example), and will have never heard of Free Software, let alone realised that <a href="http://musescore.org/">viable alternatives</a> do <a href="http://lilypond.org/">exist</a>. These people are specialists in music, not in technology, so it&#8217;s entirely understandable that they just want music software which works well, allowing them to focus on making music rather than learning technology. (In contrast, I have no sympathy for anyone working in the IT industry who subjects themself to proprietary lock-in; full-time technologists really should know better&#8230; but I digress.)</p>
<p>However, what <em>does</em> really frustrate and disappoint me is the news that the sacked team of Sibelius developers have announced that they are repeating history by <a href="http://blog.steinberg.net/2013/02/welcome/">starting work on a new proprietary product at Steinberg</a> which has the same fatal flaw. In that blog post, Daniel Spreadbury writes:</p>
<blockquote><p>Of course there are dangers inherent in starting again from scratch, but since we don&#8217;t have any code of our own to use, we have no choice in any case.</p></blockquote>
<p>As a long-term professional <a href="http://adamspiers.org/CV/music.html">musician</a> and <a href="http://adamspiers.org/CV/IT.html">professional software developer</a> who has <a href="/tag/ly2video">recent experience of enhancing music notation software</a>, I simply cannot understand this statement, since both <a href="http://musescore.org/">MuseScore</a> and <a href="http://lilypond.org/">GNU LilyPond</a> would serve as excellent starting points for a world-class music notation product. Daniel is well aware of the existence of LilyPond, as shown by <a href="http://blog.steinberg.net/2013/02/welcome/#comment-156">one of his responses</a> to a reader who commented on his blog:</p>
<blockquote><p>Lilypond is wonderful software, and it’s great that its proponents advocate for it so strongly. I hope we will demonstrate to you that our experience and, yes, our taste in musical typography makes our new application a worthy rival, even if it is (to you) a useless, closed source white elephant.</p></blockquote>
<p>I am sure that he and his whole development team are equally aware of the existence of MuseScore. Therefore despite a clear, publically stated awareness of the risks, they are deliberately choosing to start from scratch, rather than enhance existing pieces of Free Software in a way which would <a href="http://lilypond.org/freedom.html">benefit everyone</a> (more on that in a bit).</p>
<p>I can only hazard a guess as to why Steinberg have decided to go this route, but let me first bust some very common myths about Free Software which are relevant here:</p>
<p><strong>Myth #1 &#8211; you can&#8217;t run a business or make a living off Free Software.</strong><br />
This one&#8217;s incredibly easy to address, because I can and do! &#8211; quite comfortably, thank you very much. I work (part-time) for <a href="http://suse.com/">a highly successful global software vendor</a> which has sold services related to Free Software for <a href="https://www.suse.com/company/press/2012/4/suse%2Dshowcases%2D20%2Dyears%2Dof%2Dcommercializing%2Dopen%2Dsource%2Dsoftware.html">over 20 years</a>. We are (still) profitable, and growing fast, as is the number of other companies following suit. How is that possible? By selling <em>services</em>, not licenses. In other words, selling good old-fashioned honest expertise. That can come in many forms: software maintenance (i.e. bug fixes), upgrades, technical support, documentation, consulting, training&#8230;</p>
<p>Secondly, it&#8217;s &#8220;Free&#8221; as in free speech, not as in free beer. <a href="http://en.wikipedia.org/wiki/Richard_Matthew_Stallman">The founder of the Free Software movement</a> specifically <a href="http://www.gnu.org/philosophy/selling.html">encourages the sale of Free Software</a>.</p>
<p><strong>Myth #2 &#8211; it only runs on certain systems which most people don&#8217;t use.</strong><br />
Both LilyPond and MuseScore already run on Windows, MacOS X, and Linux.</p>
<p><strong>Myth #3 &#8211; it&#8217;s written by a bunch of hobbyists / it&#8217;s lower quality / you get what you pay for</strong> etc.<br />
These statements are no more useful than any other sweeping generalisation. Are Firefox and Chrome better than Internet Explorer? The vast majority of IT professionals would say yes. But there are also plenty of counter-examples. So let&#8217;s focus specifically on music notation software.</p>
<p>I suspect that Daniel and his team would gracefully agree that LilyPond produces extremely high quality output, in many cases (admittedly not all) even slightly superior to the output from Sibelius. This is no surprise, because <a href="http://lilypond.org/doc/v2.17/Documentation/essay/the-lilypond-story">output quality is LilyPond&#8217;s primary concern</a>. They would also quite rightly point out that LilyPond is challenging to learn for less technically-minded people who tend to want to be able to do most work with the mouse. MuseScore has an interface somewhat similar to Sibelius and goes a long way towards addressing this group of users, but its output is currently nowhere near the same quality.  There are also promising front-ends for LilyPond, such as <a href="http://www.denemo.org/">Denemo</a>.</p>
<p>Since these are Free Software, any developer is free to take the existing code and enhance it in any direction they want. So the Steinberg team could have for example used LilyPond&#8217;s superb rendering engine as a starting point, optimise it for WYSIWYG rendering, and build a superb Sibelius-like graphical user interface (GUI) around it. Or they could have started with MuseScore and work on enhancing both the rendering engine and the GUI.</p>
<p>You may ask, but why should they? What are the benefits of Free Software? Here&#8217;s <a href="http://www.gnu.org/philosophy/practical.html">one rather amusing answer</a>, and <a href="http://www.edutopia.org/blog/benefits-free-software-shahzad-saeed">a slightly more helpful one</a>. I&#8217;ll add two more specific examples in this context. Firstly put yourself in the shoes of a poor music student, or a musician trying to make a living in a very poor country. Without <a href="http://www.gnu.org/education/">access to good Free Software</a>, the only choices are: obtain an illegal copy of a commercial product, or go without. Now imagine you are a high-earning film/TV composer, and whilst working on a contract you discover a bug in the proprietary software which makes your life very difficult. You report the bug to the company who develops and sells the software, and they politely decline to fix it (or more likely, ignore your request). The only choices here are: live with it, or switch your whole studio setup to another product.</p>
<p>So it&#8217;s clear how Free Software makes the world a better place. So why then have Steinberg decided to start from scratch, despite the extra risk and man-years of work this will cost? Only Daniel and his colleagues can answer that, but my guess is one or more of the following:</p>
<ul>
<li>They just don&#8217;t &#8220;get&#8221; how well Free Software projects can thrive and offer opportunities for making money.</li>
<li>They do &#8220;get&#8221; it but they believe that the profit margins in Free Software are too low for their business strategy which involves making truck-loads of money e.g. through being the sole distributor.</li>
<li>There&#8217;s a perceived technical barrier. For example, maybe they really really don&#8217;t want to use C++. (I can sympathise with this sort of stance, but it&#8217;s still not justification for working on a proprietary product.) Or maybe they have a fundamental concern with the existing architecture of LilyPond or MuseScore. For example, in <a href="http://blog.steinberg.net/2013/02/welcome/#comment-100">a response to another comment on Daniel&#8217;s blog post</a>, he writes:<br />
<blockquote><p>The difficulty with complex applications like scoring programs is that a great deal of the richness of the end result that you see visually on the screen or on paper is worked out algorithmically from the small amount of data actually contained in the file saved on disk. Even if you consider Lilypond, the Lilypond file format itself does not describe exactly how the finished score will appear, because it is up to Lilypond itself to handle positioning, spacing, etc. based on its own internal algorithms and rules.</p></blockquote>
<p>but that misses the point that it is entirely possible to get LilyPond to output positioning/spacing information which could then be fixed across LilyPond versions and embedded within a non-brittle output file format. In fact, with a few hours of help from Jan Nieuwenhuizen, one of the co-authors of LilyPond, <a href="https://github.com/aspiers/ly2video/commit/c2ab06e8142519befeafe2ab050d324095e2bc97">I implemented that recently myself</a> for the <a href="https://github.com/aspiers/ly2video/#README">ly2video</a> project without even having to modify LilyPond&#8217;s core C++ code.</li>
</ul>
<p>It further saddens me that <a href="http://www.artsjournal.com/slippeddisc/2013/02/rejoice-a-new-sibelius-is-born.html">this announcement is being considered as a reason for celebration</a>, when as far as I can see a different path could so easily have been chosen which would benefit everyone more. However I suspect these sorts of opinions are simply due to an honest ignorance of Free Software. I hope that in a very small way this post might help address that.</p>
<p><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.adamspiers.org%2F2013%2F02%2F25%2Fmusic-industry-learns-nothing-from-the-avid-sibelius-saga%2F&#038;title=music%20industry%20learns%20nothing%20from%20the%20Avid%20%2F%20Sibelius%20saga%3F" data-a2a-url="https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/" data-a2a-title="music industry learns nothing from the Avid / Sibelius saga?"><img src="https://static.addtoany.com/buttons/share_save_171_16.png" alt="Share"></a></p><p>The post <a href="https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/">music industry learns nothing from the Avid / Sibelius saga?</a> appeared first on <a href="https://blog.adamspiers.org">Structured Procrastination</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.adamspiers.org/2013/02/25/music-industry-learns-nothing-from-the-avid-sibelius-saga/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
	</channel>
</rss>
