<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Unmaintainable &#187; tools</title>
	<atom:link href="http://unmaintainable.wordpress.com/category/tools/feed/" rel="self" type="application/rss+xml" />
	<link>http://unmaintainable.wordpress.com</link>
	<description>Scripting, Software Engineering and Stuff in Between</description>
	<lastBuildDate>Sun, 22 Nov 2009 09:05:47 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='unmaintainable.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/6f90ae5619dfc90140df401ac60575d2?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Unmaintainable &#187; tools</title>
		<link>http://unmaintainable.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://unmaintainable.wordpress.com/osd.xml" title="Unmaintainable" />
		<item>
		<title>Google Code: Migrating to Mercurial</title>
		<link>http://unmaintainable.wordpress.com/2009/07/31/migrating-to-mercurial/</link>
		<comments>http://unmaintainable.wordpress.com/2009/07/31/migrating-to-mercurial/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 08:03:49 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[rcs]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=294</guid>
		<description><![CDATA[Although one could have guessed otherwise, I&#8217;ve always been a happy Subversion user. Which former CVS user hasn&#8217;t? But now I&#8217;m ready to take the next step. For some of my personal stuff I&#8217;ve been using Mercurial for more than a year, so I thought it was time to take the plunge and switch my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=294&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Although one could have <a href="/2009/07/25/subversion-1-5-merging-massacres/">guessed otherwise</a>, I&#8217;ve always been a happy Subversion user. Which former CVS user hasn&#8217;t? But now I&#8217;m ready to take the next step. For some of my personal stuff I&#8217;ve been using Mercurial for more than a year, so I thought it was time to take the plunge and switch my <a href="http://code.google.com/p/jsystest">JSysTest project</a> to Mercurial.</p>
<p><span id="more-294"></span></p>
<p>Google Code recently added Mercurial hosting, so I didn&#8217;t have to switch the hosting provider. The conversion process is quite simple: There are <a href="http://code.google.com/p/support/wiki/ConvertingSvnToHg">good instructions</a> available that worked without any problems. From what I&#8217;ve seen so far, all functionality I care about is available (basically everything I used Subversion for).</p>
<p>One thing surprised me though: Converting a two dozen revisions took roughly 20 minutes, so for larger repositories you will have to take a long coffee break.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/294/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=294&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2009/07/31/migrating-to-mercurial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Subversion 1.5 Merging Massacres</title>
		<link>http://unmaintainable.wordpress.com/2009/07/25/subversion-1-5-merging-massacres/</link>
		<comments>http://unmaintainable.wordpress.com/2009/07/25/subversion-1-5-merging-massacres/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 08:24:09 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[rcs]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=289</guid>
		<description><![CDATA[Recently, I had the opportunity to work with Subversion 1.5 on a medium sized project. Since there were more than 20 developers working on the project with some of them in a different country, there was no other way than to use feature branches extensively. We thought Subversion&#8217;s merge tracking would reduce typical merging errors [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=289&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Recently, I had the opportunity to work with Subversion 1.5 on a medium sized project. Since there were more than 20 developers working on the project with some of them in a different country, there was no other way than to use feature branches extensively. We thought Subversion&#8217;s merge tracking would reduce typical merging errors by simplifying the process. But, well, we were wrong.</p>
<p><span id="more-289"></span></p>
<p>The sad truth is that few developers know exactly what their revision control system does behind their backs when merging branches. With Subversion prior to 1.5, things were pretty simple and there&#8217;s little magic involved. You have to be careful to state the correct revisions and if you don&#8217;t, you can still roll back your changes.</p>
<p>With 1.5, as long as everyone plays by the rules and sticks to the basic use cases, everything is fine. But if things go wrong (and they will), you&#8217;re really screwed. In a large team, there will always be someone who uses a buggy Subversion client, or someone who accidentally deletes merge properties (there&#8217;s often a high stress level before releases). And as soon as this has happened, merges may leave out revisions (or merge revisions twice) and you need in-depth knowledge to repair the damage. In some cases, even rolling back changes on trunk wasn&#8217;t enough if someone created a feature branch at the wrong time.</p>
<p>In a project consisting mostly of source files in a compiled language like Java or C#, obvious mistakes typically show up early. If you have lots of HTML, CSS, and XML configuration, or you&#8217;re working with an interpreted language, you don&#8217;t have this safety net. Your QA department (if you&#8217;re lucky enough to have one) will be the first to discover the problems.</p>
<p>So, if you&#8217;re a mostly happy Subversion 1.4 user and you&#8217;re considering migration to 1.5 or later for merge tracking, then my advice is: Don&#8217;t bother. Maybe recent versions fixed some of the problems, but I wouldn&#8217;t take chances. You don&#8217;t want to spend your nights fixing your source repository.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/289/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=289&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2009/07/25/subversion-1-5-merging-massacres/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Subversion: Externals Definitions</title>
		<link>http://unmaintainable.wordpress.com/2008/12/22/subversion-externals-definitions/</link>
		<comments>http://unmaintainable.wordpress.com/2008/12/22/subversion-externals-definitions/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 20:39:13 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[rcs]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=105</guid>
		<description><![CDATA[Externals definitions are a little known but very useful feature of subversion. Using an externals definition, you can create links to different parts of the repository (or even other repositories). Subversion clients then automatically check out the linked content into your working copy.

How this works is best explained with an example. Suppose you check out [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=105&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Externals definitions are a little known but very useful feature of subversion. Using an externals definition, you can create links to different parts of the repository (or even other repositories). Subversion clients then automatically check out the linked content into your working copy.</p>
<p><span id="more-105"></span></p>
<p>How this works is best explained with an example. Suppose you check out your code from the repository:</p>
<pre>
  svn co https://svn.your.host/project/trunk project
</pre>
<p>Inside your project, you need code from a different location in the repository or maybe even from some other repository. This could be a software module, test data, a generic part of your company&#8217;s standard build system or other things shared between projects. Many people do this manually:</p>
<pre>
  cd project
  svn co https://svn.your.host/whatever/tags/release-1.3 whatever
</pre>
<p>That&#8217;s tedious and error prone. A better approach is to use an externals definition that tells subversion to check out that project automatically for you. It works by adding some magic metadata to the <code>project</code> directory (that&#8217;s the dot on the svn command line!):</p>
<pre>
  cd project
  svn propset svn:externals \
    'whatever https://svn.your.host/whatever/tags/release-1.3' .
</pre>
<p>The <code>svn:externals</code> property accepts a set of declarations, each consisting of a directory name and a subversion URL. Because of this, the <code>propedit</code> command is more useful if you happen to need multiple declarations.</p>
<p>So, every time you check out (or update) the parent project, the <code>whatever</code> project will be checked out, too. The dependency to the other project is versioned by convention (I&#8217;ve linked to a tag in the example), but you can link to any URL and even include a revision number.</p>
<p>For more information see the <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.externals.html">Subversion book on svn:externals</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=105&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/12/22/subversion-externals-definitions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Understanding the find(1) Utility</title>
		<link>http://unmaintainable.wordpress.com/2008/09/27/understanding-find/</link>
		<comments>http://unmaintainable.wordpress.com/2008/09/27/understanding-find/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 08:10:35 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=92</guid>
		<description><![CDATA[The Unix find(1) utility is a powerful tool, yet few people really understand how it works. It may be a bit confusing at first, but a programmer who knows his boolean algebra should be able to wrap his head around the basic concepts without much trouble.

You&#8217;ve probably seen simple find constructs like this:

find . -type [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=92&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The Unix <em>find(1)</em> utility is a powerful tool, yet few people really understand how it works. It may be a bit confusing at first, but a programmer who knows his boolean algebra should be able to wrap his head around the basic concepts without much trouble.</p>
<p><span id="more-92"></span></p>
<p>You&#8217;ve probably seen simple find constructs like this:</p>
<pre>
find . -type f -name &quot;*.c&quot; -print
</pre>
<p>This prints all files (<code>-type f</code>) in the current working directory that end with <code>.c</code> (<code>-name &quot;*.c&quot;</code>). Easy. But what about this one:</p>
<pre>
find . \( -type d -name .svn -prune \) -o -print
</pre>
<p>Before you can fully understand this we&#8217;ll have to cover a few basics.</p>
<p>Find traverses a given list of directories and evaluates a user-provided expression for each file or directory it encounters. Like many programming languages, it uses short circuit evaluation for the expression. The catch is that the <em>result</em> of the expression is meaningless; no action is triggered if the result is true. Instead, operands like <code>-print</code> or <code>-ls</code> are ordinary predicates that <em>always evaluate to true</em>! Most predicates check if a file has a specified property (like if its name matches a regular expression), but <code>-print</code> is only executed for its <em>side effect</em>: It prints the file name every time it is evaluated.</p>
<p>Use the following commands to check if you understood the concepts:</p>
<pre>
find . -type f -print -print
find . -print -o -print
</pre>
<p>The first command prints the names of all files twice. That&#8217;s because the predicates are ANDed together. In the second command, the predicates are combined using the OR operator (<code>-o</code> in find syntax). Since the first <code>-print</code> already evaluates to true, there&#8217;s no point in evaluating the second one. So the file names are only printed once.</p>
<p>Let&#8217;s go back to the more advanced example:</p>
<pre>
find . \( -type d -name .svn -prune \) -o -print
</pre>
<p>Here we&#8217;ve got an expression consisting of two parts connected using the OR operator. The <code>-print</code> is only evaluated if the first part of the expression (the one in parenthesis) returns false.</p>
<p>Inside the parenthesis, there&#8217;s the <code>-prune</code> predicate we haven&#8217;t talked about yet. When <code>-prune</code> is evaluated, it has the side effect of skipping the whole directory tree. That means, after a <code>-prune</code> is evaluated, find doesn&#8217;t descend into the currently evaluated directory.</p>
<p>So, what does the command actually do? It recursively traverses a directory tree printing all files except <code>.svn</code> directories and their contents.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=92&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/09/27/understanding-find/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Reverting a Commit in Subversion</title>
		<link>http://unmaintainable.wordpress.com/2008/05/13/revert-a-commit-in-svn/</link>
		<comments>http://unmaintainable.wordpress.com/2008/05/13/revert-a-commit-in-svn/#comments</comments>
		<pubDate>Tue, 13 May 2008 16:42:19 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[rcs]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=53</guid>
		<description><![CDATA[Once in a while, someone commits a revision that has to be rolled back later for some reason. Some teams do that as a matter of policy when people check in broken code that doesn&#8217;t compile or isn&#8217;t able to run all test cases successfully. Since Subversion (and similar revision control systems) are designed to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=53&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Once in a while, someone commits a revision that has to be rolled back later for some reason. Some teams do that as a matter of policy when people check in broken code that doesn&#8217;t compile or isn&#8217;t able to run all test cases successfully. Since Subversion (and similar revision control systems) are designed to never loose changes, that isn&#8217;t easily possible.</p>
<p><span id="more-53"></span></p>
<p>If a commit really has to disappear without traces for some reason, the only way is to import your repository into a new one leaving out the offending commit. That&#8217;s a rather drastic measure causing all kinds of problems with existing working copies, so use it with great care.</p>
<p>The approach used more often is to commit a new revision that takes back earlier changes. This is like undoing all changes manually and committing them in the usual way. The offending changes are still in the history, but don&#8217;t do harm anymore.</p>
<p>This is how it works to roll back changes made in revision N:</p>
<pre>
svn merge -c -N .
</pre>
<p>Note the minus character in front of <em>N</em>. This is the same as the following command (which also works with older subversion clients):</p>
<pre>
svn merge -r N:N-1 .
</pre>
<p>Afterwards examine the changes made to the working copy and commit them.</p>
<p>To understand what&#8217;s happening here requires some background on what the merge command does conceptionally: It records which changes have to be made to revision N to turn it into revision N+1 (called a <em>delta</em>) and applies it to the working copy. That isn&#8217;t what we want in our scenario, so we reverse the usual order of revisions on the command line. Effectively, we tell the merge command to create a delta the other way round. The result is a &quot;rewinding&quot; of the code base.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/53/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/53/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/53/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=53&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/05/13/revert-a-commit-in-svn/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>SSH Public Key Authentication</title>
		<link>http://unmaintainable.wordpress.com/2008/01/01/ssh-public-key-auth/</link>
		<comments>http://unmaintainable.wordpress.com/2008/01/01/ssh-public-key-auth/#comments</comments>
		<pubDate>Tue, 01 Jan 2008 09:27:20 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2008/01/01/ssh-public-key-auth/</guid>
		<description><![CDATA[A lot of people use SSH to log into remote hosts. SSH is secure and works well, but if you have to access many hosts with long, well-chosen passwords there is a lot of typing to do just for authentication.
In this article I&#8217;ll walk you through a basic public key authentication setup. Password authentication may [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=40&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A lot of people use SSH to log into remote hosts. SSH is secure and works well, but if you have to access many hosts with long, well-chosen passwords there is a lot of typing to do just for authentication.</p>
<p>In this article I&#8217;ll walk you through a basic public key authentication setup. Password authentication may be more frequently used, but public key authentication is very convenient after the initial work is done. <a href="http://openssh.org/">OpenSSH</a> is used in the examples below, but the same process works much the same on other systems (for example <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">putty/pageant</a> on Windows).</p>
<p><span id="more-40"></span></p>
<p>In a nutshell, we&#8217;ll generate a public/private key pair on a local account and install the public key in all remote accounts we want to access. Then we can log into the accounts using the private key&#8217;s password instead of the remote account&#8217;s password. To avoid having to type the password multiple times, we&#8217;ll use a key agent which keeps the password in memory.</p>
<p>First of all, we generate a public/private key pair using <code>ssh-keygen</code>:</p>
<pre>
  $ ssh-keygen
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/matthias/.ssh/id_rsa):
  Enter passphrase (empty for no passphrase):
  Enter same passphrase again:
  Your identification has been saved in /home/matthias/.ssh/id_rsa.
  Your public key has been saved in /home/matthias/.ssh/id_rsa.pub.
  The key fingerprint is:
  6b:3c:60:9a:84:5a:06:59:62:f4:6b:25:d3:5b:0e:67 matthias@alanis
  $
</pre>
<p>Accept the default filename and then pick a strong but memorizable passphrase for your private key. If you ever forget the passphrase there is no way to recover it and the key will be useless. Don&#8217;t generate keys without a passphrase: An attacker breaking into your local account would then be able to log into all your remote accounts, too.</p>
<p>You can later change the passphrase using <code>ssh-keygen</code>&#8217;s <code>-p</code> switch. There are a lot of other command line options, but the defaults are usually just fine.</p>
<p>Now that the key pair is generated, we install the public key (from the <code>id_dsa.pub</code> file) in all remote accounts we want to log into conveniently. The private key in <code>id_dsa</code> has to be kept secret but needs to stay in your local <code>~/.ssh</code> directory. Installing the public key works by appending it to the remote <code>~/.ssh/authorized_keys</code> files. This can be done manually or using the <code>ssh-copy-id</code> tool:</p>
<pre>
  $ ssh-copy-id remoteuser@example.com
  [...]
  $
</pre>
<p>The tool prompts for the remote account&#8217;s password and then copies the public key. After this, you should be able to log in:</p>
<pre>
  $ ssh remoteuser@example.com
  Enter passphrase for key '/home/matthias/.ssh/id_dsa':
  [...]
</pre>
<p>Note that this time we&#8217;re being asked for the private key&#8217;s password, so the basic setup is done.</p>
<p>Typing the private key&#8217;s password multiple times (once per account) is tedious, so we want to enter it only once per local session. The <code>ssh-agent</code> and <code>ssh-add</code> tools shipped with OpenSSH can help here. The <code>ssh-agent</code> program runs as a per-user daemon in background. If the <code>SSH_AGENT_PID</code> environment variable is set then the agent is already running &#8211; which is pretty common on modern Linux distributions. Otherwise you can add the call to <code>ssh-agent</code> to your shell profile (eg. <code>~/.profile</code>) or an X session startup script:</p>
<pre>
  eval $(ssh-agent -s)
</pre>
<p>As soon as the agent is running, you can use it from your local interactive session to register a private key. To do this you have to execute the <code>ssh-add</code> utility:</p>
<pre>
  $ ssh-add
  Enter passphrase for /home/matthias/.ssh/id_dsa:
  Identity added: /home/matthias/.ssh/id_dsa (/home/matthias/.ssh/id_dsa)
  $
</pre>
<p>After that, you can log into your remote accounts without having to enter the password.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/40/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/40/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/40/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=40&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/01/01/ssh-public-key-auth/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>From RCS to Mercurial</title>
		<link>http://unmaintainable.wordpress.com/2007/12/08/from-rcs-to-mercurial/</link>
		<comments>http://unmaintainable.wordpress.com/2007/12/08/from-rcs-to-mercurial/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 13:25:37 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[rcs]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/12/08/from-rcs-to-mercurial/</guid>
		<description><![CDATA[I&#8217;ve been a happy user of RCS for years (in fact, my software engineering course at university was held by Walter Tichy, the original author of RCS). The good old Revision Control System may be a dinosaur, but it served me well for my configuration files and scripts.
Over the last few years, however, new and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=37&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve been a happy user of RCS <a href="http://unmaintainable.wordpress.com/2006/12/14/revision-control-using-rcs/">for years</a> (in fact, my software engineering course at university was held by Walter Tichy, the original author of RCS). The good old <em>Revision Control System</em> may be a dinosaur, but it served me well for my configuration files and scripts.</p>
<p>Over the last few years, however, new and fancy revision control systems have entered the scene. My current choice is <a href="http://www.selenic.com/mercurial">Mercurial</a>, because it&#8217;s easy to use, popular, and <a href="http://hgbook.red-bean.com">well documented</a>.</p>
<p><span id="more-37"></span></p>
<p>Since I needed some data to experiment with, I decided to switch my old RCS files over to Mercurial. Of course I wanted to keep the revision history, so a migration path was needed. For the conversion I used <a href="http://progetti.arstecnica.it/tailor">Tailor</a>, a tool for converting between various version control systems. RCS is a bit dated, so it isn&#8217;t supported directly. But since the RCS file format is used in CVS, too, the natural upgrade path lead me to CVS and from there to Mercurial. This article shows how the conversion can be done.</p>
<p>So, first of all, we create a fresh local CVS repository somewhere:</p>
<pre>
    cvs -d /var/tmp/cvsroot init
</pre>
<p>The next step is to create a module inside the repository (<code>scripts</code> in this case), to create the desired directory structure (none in the example) and copy the RCS files there. The RCS files shouldn&#8217;t be locked as this could cause trouble.</p>
<pre>
    cd /var/tmp/cvsroot
    mkdir scripts
    cd scripts
    cp /path/to/repo/servehttp,v .
    cp /path/to/repo/b,v .
</pre>
<p>If you have a large number of files, it might be a good idea to automatize this using a script. Note that usually it&#8217;s no good idea to manipulate a CVS repository manually, but this is only for conversion. To make sure everything worked, we can check out the new module:</p>
<pre>
    cvs -d :local:/var/tmp/cvsroot co scripts
</pre>
<p>If everything worked as expected, we have a fully functional CVS repository that can be converted using Tailor.</p>
<p>Unfortunately, tailor-0.9.28 doesn&#8217;t work together with Mercurial 0.9.4, which is exactly the situation you find on Ubuntu 7.10. This incompatibility has already been fixed in tailor-0.9.30 and fortunately, you don&#8217;t have to install the new version. Extracting <a href="http://darcs.arstecnica.it/">the tarball</a> and executing the script from there works fine.</p>
<pre>
    python tailor -v --source-kind cvs --target-kind hg
      --repository :local:/var/tmp/cvsroot
      --module scripts --start-revision INITIAL &gt; scripts.tailor
</pre>
<p>This creates a configuration file named <code>scripts.tailor</code> that has to be adjusted manually before the actual conversion. According to <a href="http://progetti.arstecnica.it/tailor/wiki/ConfigurationFile">the documentation</a> the purpose of the call above is to generate a template configuration file.</p>
<p>The configuration file should look like this:</p>
<pre>
    [DEFAULT]
    verbose = True

    [project]
    target = hg:target
    start-revision = INITIAL
    root-directory = /tmp/tailor-0.9.30
    state-file = tailor.state
    source = cvs:source
    subdir = scripts
    patch-name-format =

    [hg:target]

    [cvs:source]
    module = scripts
    repository = :local:/var/tmp/cvsroot
</pre>
<p>The defaults should mostly be finde, all I changed was the <code>subdir</code> setting and the <code>patch-name-format</code> to get better revision logs. More information about this can be found in <a href="http://www.selenic.com/mercurial/wiki/index.cgi/Tailor">the Mercurial wiki</a>.</p>
<p>After adjusting the configuration it&#8217;s time to actually create the new Mercurial repository (this may take a while):</p>
<pre>
    python tailor --configfile scripts.tailor
</pre>
<p>We change to the created repository and make sure all revisions have been migrated:</p>
<pre>
    cd scripts
    hg log
</pre>
<p>That&#8217;s it. You can remove the <code>CVS</code> directory as soon as you&#8217;re confident that everything worked as expected. As a last step you might want to update the <code>.hgignore</code> file.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/37/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/37/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=37&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/12/08/from-rcs-to-mercurial/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Transparent Directory Encryption</title>
		<link>http://unmaintainable.wordpress.com/2007/08/08/transparent-directory-encryption/</link>
		<comments>http://unmaintainable.wordpress.com/2007/08/08/transparent-directory-encryption/#comments</comments>
		<pubDate>Wed, 08 Aug 2007 08:46:46 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/08/08/transparent-directory-encryption/</guid>
		<description><![CDATA[In a previous article, I discussed sshfs, a user mode filesystem based on FUSE for accessing remote files. Another useful filesystem type is encfs which provides transparent encryption of directories. With encfs, files are stored encrypted in a special directory under encfs&#8217; control. The encryption algorithm and password are specified during creation of this directory.

To [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=27&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In a <a href="http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/">previous article</a>, I discussed <em>sshfs</em>, a user mode filesystem based on <a href="http://fuse.sourceforge.net">FUSE</a> for accessing remote files. Another useful filesystem type is <a href="http://arg0.net/wiki/encfs">encfs</a> which provides transparent encryption of directories. With encfs, files are stored encrypted in a special directory under encfs&#8217; control. The encryption algorithm and password are specified during creation of this directory.</p>
<p><span id="more-27"></span></p>
<p>To use encfs, you have to be a member of the <code>fuse</code> group and the fuse kernel module has to be loaded. See the <a href="http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/">sshfs article</a> for more information. If you&#8217;re using Ubuntu or some other Debian-based distribution, the encfs package itself can be installed using the following command.</p>
<pre>
  sudo apt-get install encfs
</pre>
<p>After this, you can create your first encrypted directory. A useful convention to follow is to use a mount point somewhere in your home directory (e.g. <code>~/secret</code>) and a corresponding directory for the raw encrypted files, starting with a dot (e.g. <code>~/.secret</code>).</p>
<p>Execute the following command for setting things up (no root privileges required):</p>
<pre>
  encfs ~/.secret ~/secret
</pre>
<p>Note that you have to use absolute file names. The program prompts you for various cryptographic parameters and a password. After that, the <code>~/secret</code> directory is mounted and ready for use. Try to create a few files there and see how the corresponding encrypted files appear in <code>~/.secret</code>.</p>
<p>As soon as you&#8217;re done, umount the directory:</p>
<pre>
  fusermount -u ~/secret
</pre>
<p>The next time you want to use the directory, issue the same command as above:</p>
<pre>
  encfs ~/.secret ~/secret
</pre>
<p>Encfs detects that the directory is initialized already, prompts for the password and mounts the directory.</p>
<p>In contrast to other approaches like <em>dm-crypt</em>, encfs directories grow and shrink on demand. After all, the files are encrypted individually. The downside of this approach is that attackers can draw conclusions based on the number and size of files in the encrypted directory. Filenames are encrypted, too, but depending on your use case, the amount of privacy encfs provides may or may not be enough.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/27/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/27/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=27&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/08/08/transparent-directory-encryption/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Mounting Directories via SSH</title>
		<link>http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/</link>
		<comments>http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/#comments</comments>
		<pubDate>Thu, 07 Jun 2007 15:03:30 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/</guid>
		<description><![CDATA[For mounting directories from a remote machine, usually NFS or SMB/CIFS is used which requires a running file server. On many linux servers, however, all you have is a shell account, so file transfer has to be done via scp.
Using the FUSE Linux kernel module, which provides user space filesystems and its sshfs client, you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=23&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>For mounting directories from a remote machine, usually NFS or SMB/CIFS is used which requires a running file server. On many linux servers, however, all you have is a shell account, so file transfer has to be done via <code>scp</code>.</p>
<p>Using <a href="http://fuse.sourceforge.net/">the FUSE Linux kernel module</a>, which provides user space filesystems and its <code>sshfs</code> client, you can mount remote directories from machines where all you have is an SSH account. If you can log in via SSH you can also mount the directory, there is no need to modify or configure anything on the remote machine.</p>
<p><span id="more-23"></span></p>
<p>On the client machine, you have to install FUSE and sshfs. If you&#8217;re running Ubuntu, execute the following command:</p>
<pre>
  sudo apt-get install sshfs
</pre>
<p>To get the permissions to use FUSE on your local machine, your user has to belong to the <code>fuse</code> group. This can be achieved using <code>vigr(8)</code>, for example. Don&#8217;t forget to log out and in again for the change to take effect. You can see which groups you are part of using the <code>groups</code> or <code>id</code> commands. From this point on, you can work without root privileges.</p>
<p>The next step is to create a local mount point on the client machine (using the hostname of the remote machine would be a good convention to follow):</p>
<pre>
  mkdir mountpoint
</pre>
<p>Now you can mount the remote directory:</p>
<pre>
  sshfs remote_username@remote_hostname:/home/media mountpoint
</pre>
<p>This mounts the <code>/home/media</code> directory on the remote server. If you want to mount your remote home directory and the user names on the local and remote system are the same, the command can be even shorter:</p>
<pre>
  sshfs remote_hostname: mountpoint
</pre>
<p>When you&#8217;re done, you can umount the directory:</p>
<pre>
  fusermount -u mountpoint
</pre>
<p>Check the <code>sshfs(1)</code> manpage for more information, like mapping user IDs or performance tuning.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=23&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/06/07/mounting-directories-via-ssh/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Building RPMs Without Root Access</title>
		<link>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/</link>
		<comments>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/#comments</comments>
		<pubDate>Sun, 25 Mar 2007 09:51:05 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/</guid>
		<description><![CDATA[This week at work I had the opportunity to build an RPM for some third-party software package.
My previous experiences with RPM date back to SuSE 5 almost ten years ago and I haven&#8217;t touched it ever since. Packaging for Debian or even NetBSD is mostly a painless process, so I hoped today&#8217;s RPM wouldn&#8217;t be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=16&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This week at work I had the opportunity to build an RPM for some third-party software package.</p>
<p>My previous experiences with RPM date back to SuSE 5 almost ten years ago and I haven&#8217;t touched it ever since. Packaging for Debian or even NetBSD is mostly a painless process, so I hoped today&#8217;s RPM wouldn&#8217;t be much different. Things worked out fine, except for one thing: RPM uses a well-known base directory (<code>/usr/src/packages</code> on SuSE) which only root can write to. Sure, you can pass ownership to another user, but without root access in the first place you&#8217;re out of luck.</p>
<p><span id="more-16"></span></p>
<p>Using <code>~/.rpmmacros</code>, users can define their own private staging area, but that&#8217;s no elegant solution either. Not even <a href="http://docs.fedoraproject.org/drafts/rpm-guide-en/index.html">The RPM Guide</a> came up with a usable receipe for this.</p>
<p>After some unsuccessful experiments, I decided to have a look at how python&#8217;s distutils solve this problem. With distutils, you can build RPMs from python packages (<code>python setup.py bdist_rpm</code>) without superuser privileges. That&#8217;s why I figured it had to be possible.</p>
<p>Distutils uses <code>rpmbuild</code>&#8217;s <code>--define</code> switch (undocumented in the man page) and the <code>_topdir</code> macro:</p>
<pre>
  rpmbuild -ba --define "_topdir /path/to/staging_dir"
     /path/to/staging_dir/SPECS/package.spec
</pre>
<p>Note that <code>/path/to/staging_dir</code> has to be an absolute path, leading to the directory which contains the same directory structure <code>/usr/src/packages</code> has. <code>`pwd`</code> can be used to avoid hardcoding the path. </p>
<p>From a script, I create the directory structure in my local working directory, copy source tarball and spec file to <code>SOURCES</code> and <code>SPECS</code> and execute <code>rpmbuild</code>.</p>
<p>The created RPM can then be found in the <code>RPMS</code> directory. </p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/16/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/16/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=16&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
	</channel>
</rss>