<?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>sixohthree.com &#187; Linux</title>
	<atom:link href="http://sixohthree.com/category/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://sixohthree.com</link>
	<description>The Weblog of Adam Backstrom</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:27:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Preware Ubuntu 11.04 Chroot Script</title>
		<link>http://sixohthree.com/1900/preware-ubuntu-11-04-chroot-script</link>
		<comments>http://sixohthree.com/1900/preware-ubuntu-11-04-chroot-script#comments</comments>
		<pubDate>Mon, 23 Jan 2012 14:16:33 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Palm]]></category>
		<category><![CDATA[touchpad]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[webOS]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1900</guid>
		<description><![CDATA[I&#8217;ll need this later.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll need this later.</p>
<pre>#!/bin/sh

# From /media/cryptofs/apps/usr/palm/applications/org.webosinternals.ubuntu-natty-chroot/bin

CHROOT=/media/ext3fs/ubuntu-natty-chroot

cp /etc/resolv.conf ${CHROOT}/etc/resolv.conf

mount --bind /dev ${CHROOT}/dev
mount --bind /dev/pts ${CHROOT}/dev/pts
mount --bind /proc ${CHROOT}/proc
mount --bind /sys ${CHROOT}/sys
mount --bind /tmp ${CHROOT}/tmp

chroot ${CHROOT} /bin/bash

umount ${CHROOT}/tmp
umount ${CHROOT}/sys
umount ${CHROOT}/proc
umount ${CHROOT}/dev/pts
umount ${CHROOT}/dev</pre>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1900/preware-ubuntu-11-04-chroot-script/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysqlhotcopy: error 24</title>
		<link>http://sixohthree.com/1698/mysqlhotcopy-error-24</link>
		<comments>http://sixohthree.com/1698/mysqlhotcopy-error-24#comments</comments>
		<pubDate>Fri, 21 Oct 2011 04:16:41 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[mysqlhotcopy]]></category>
		<category><![CDATA[ulimit]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1698</guid>
		<description><![CDATA[What does it look like when you try to mysqlhotcopy, but don't have a high enough open files ulimit?]]></description>
			<content:encoded><![CDATA[<p>What does it look like when you try to mysqlhotcopy, but your open files ulimit is too low? If you answered &#8220;error 24 (too many open files)&#8221; you&#8217;d be correct, but also:</p>
<pre>#!/bin/sh

set -u
set -e

# non-wp tables
mysqlhotcopy --addtodest 'wordpress./^(?!wp_\d)./' /backup/

# wp tables not starting with a digit
mysqlhotcopy --addtodest 'wordpress./^wp_[^\d]/' /backup/

# tables 1-99
mysqlhotcopy --addtodest 'wordpress./^wp_\d{1,2}_/' /backup/

# tables 100-999
mysqlhotcopy --addtodest 'wordpress./^wp_\d{3}_/' /backup/

# tables 1000-1499
mysqlhotcopy --addtodest 'wordpress./^wp_1[0-4]\d{2}_/' /backup/

# tables 1500-1999
mysqlhotcopy --addtodest 'wordpress./^wp_1[5-9]\d{2}_/' /backup/

# tables 2000-2499
mysqlhotcopy --addtodest 'wordpress./^wp_2[0-4]\d{2}_/' /backup/

# tables 2500-2999
mysqlhotcopy --addtodest 'wordpress./^wp_2[5-9]\d{2}_/' /backup/
</pre>
<p>Scary.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1698/mysqlhotcopy-error-24/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Locking Down rsync Over SSH</title>
		<link>http://sixohthree.com/1458/locking-down-rsync-using-ssh</link>
		<comments>http://sixohthree.com/1458/locking-down-rsync-using-ssh#comments</comments>
		<pubDate>Fri, 21 Jan 2011 12:33:09 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[openssh]]></category>
		<category><![CDATA[rsync]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1458</guid>
		<description><![CDATA[For my most recent backup scheme, I needed to lock down rsync over OpenSSH while allowing scheduled syncing. I did it using the authorized_keys command="command" option to restrict access for a specific private key.]]></description>
			<content:encoded><![CDATA[<p>For my most recent backup scheme, I needed to lock down <a href="http://samba.anu.edu.au/rsync/">rsync</a> over OpenSSH while allowing scheduled syncing. First, my requirements:</p>
<ul>
<li>Encrypted file transfer</li>
<li>Ability to work without interaction</li>
<li>Secure (i.e. locked down to specific tools/files)</li>
</ul>
<p>OpenSSH public/private keypairs and rsync over SSH was a logical starting point, but I was missing a piece to limit the rsync to specific files: the <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&amp;sektion=8"><tt>authorized_keys</tt> <tt>command="command"</tt></a> option.</p>
<h2>The Setup</h2>
<p>Hostnames have been changed to protect the innocent. For this description:</p>
<ul>
<li><strong><em>coriander</em></strong> is the server, which has some MySQL files we need to back up</li>
<li><em><strong>penny</strong></em> is the client, pulling files from <em>coriander</em> using rsync</li>
</ul>
<p>I regularly SSH to the host I wanted to backup, so this setup needed to work around a potential key conflict. Easy enough using <tt>~/.ssh/config</tt> on <em>penny</em>:</p>
<pre>Host coriander
    HostName coriander.example.com
    User adam
    IdentityFile ~/.ssh/id_dsa

Host mysql-binlog
    HostName coriander.example.com
    User adam
    IdentityFile ~/.ssh/mysql-binlog-key</pre>
<p>I run an ssh-agent, so I have to run things through <tt>env -i</tt> to prevent the <tt>rsync</tt> from using my normal key.</p>
<p>In this case, I manually copied my key into adam@<em>coriander</em>&#8216;s <tt>~/.ssh/authorized_keys</tt> file:</p>
<pre>ssh-rsa AAAAB3NzaC1yc2EAAAA…BIwAAAQEA2GNx7diU== mysql-binlog-key</pre>
<p>Next I prepended some options to this key:</p>
<pre>command="~/mysql-backup/rsync-control" ssh-rsa AAAAB3NzaC1yc2EAAAA…BIwAAAQEA2GNx7diU== mysql-binlog-key</pre>
<h2>My wish is your command=&#8221;command&#8221;</h2>
<p>At this point, let&#8217;s digress to look at the SSH command option. Try this style authorized_keys on your server to echo the environment and exit when the user logs in over SSH:</p>
<pre>command="env" ssh-rsa AAAAB3NzaC1yc2EAAAA…BIwAAAQEA2GNx7diU== mysql-binlog-key</pre>
<p>SSH to the host and see the output:</p>
<pre><strong>ambackstrom@fsck:~:0$</strong> env -i ssh mysql-binlog
SHELL=/bin/bash
SSH_CLIENT=10.0.0.2 56490 22
USER=adam
PATH=/bin:/usr/bin
PWD=/home/adam
SHLVL=1
HOME=/home/adam
SSH_CONNECTION=10.0.0.2 56490 10.0.0.1 22
_=/usr/bin/env</pre>
<p>Then once more, specifying a command to run on the server:</p>
<pre><strong>ambackstrom@fsck:~:0$</strong> env -i ssh mysql-binlog 'ls -lAF'
SHELL=/bin/bash
SSH_CLIENT=10.0.0.2 56546 22
USER=adam
PATH=/bin:/usr/bin
PWD=/home/adam
SHLVL=1
HOME=/home/adam
SSH_CONNECTION=10.0.0.2 56546 10.0.0.1 22
<span style="color: #339966;"><strong>SSH_ORIGINAL_COMMAND=ls -lAF</strong></span>
_=/usr/bin/env</pre>
<p>Our script becomes the middleman between the client and the requested command, and that command is placed in the <tt>$SSH_ORIGINAL_COMMAND</tt> environment variable. We can analyze this command and allow, deny, or modify it before execution. Given this rsync command:</p>
<pre>env -i rsync -avzP mysql-binlogs:/tmp/ /tmp/test/</pre>
<p>We get this remote command:</p>
<pre>SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtprz . /tmp/</pre>
<h2>Security via Misdirection</h2>
<p>Let&#8217;s place a new middleman script in our authorized_keys file on coriander:</p>
<pre>command="~/rsync-control" ssh-rsa AAAAB3NzaC1yc2EAAAA…BIwAAAQEA2GNx7diU== mysql-binlog-key</pre>
<p>Within <tt>~/rsync-control</tt> we&#8217;ll analyze the incoming command and take some action:</p>
<pre>#!/bin/sh

if [ "$SSH_ORIGINAL_COMMAND" = "rsync --server --sender -vlogDtprz . logs/" ] ; then
    rsync --server --sender -vlogDtprz . /var/lib/mysql/binlog/
    exit $?
fi

exit 1</pre>
<p>What we&#8217;ve actually done here is obfuscated the real binary log directory from the originating command on <em>penny</em>: the client requests the <tt>logs/</tt> directory, but we launch an rsync server for <tt>/var/lib/mysql/binlog/</tt>. If any other remote command is issued, the script exits with an error code.</p>
<p>I&#8217;m sure there are some other great uses for the command option. I know of git server like <a href="https://github.com/sitaramc/gitolite/wiki">gitolite</a> that take advantage of this feature, and I&#8217;d love to find more.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1458/locking-down-rsync-using-ssh/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Makefile for CSS and JS Minify/Compress</title>
		<link>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress</link>
		<comments>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress#comments</comments>
		<pubDate>Tue, 02 Nov 2010 10:25:19 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1380</guid>
		<description><![CDATA[I've had an ever-growing need to automate the minification and compression of CSS and JavaScript files on my web server, and while I'd written some rudimentary Makefiles in the past, I finally found time to write a kick-ass general purpose Makefile that can be applied to any project with very little modification.]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.gnu.org/software/make/">Makefiles</a>. Automation in all its forms is desirable, but Makefiles have a combination of surface simplicity and unknowable complexity that I find very endearing. I&#8217;ve had an ever-growing need to automate the minification and compression of CSS and JavaScript files on my web server, and while I&#8217;d written some rudimentary Makefiles in the past, I finally found time to write a kick-ass general purpose Makefile that can be applied to any project with very little modification.</p>
<p>You&#8217;ll want to have the <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> and <a href="http://code.google.com/closure/compiler/">Google Closure Compiler</a> installed for minification of CSS and JavaScript, respectively. I installed them to my <code>~/bin</code> directory, and referenced that directory in my Makefile.</p>
<p>Note that I&#8217;m using these two pieces of software mostly out of habit; I haven&#8217;t evaluated them or their competitors recently.</p>
<h2>The Meat</h2>
<script src='http://gist.github.com/659427.js?file=Makefile'></script><noscript><pre>#
# css/js minification/compression makefile
#

#
#   JS_TARGETS -- js files to minify/gzip
#   CSS_TARGETS -- css files to minify/gzip
#   CLEANUP -- additional files to delete during &quot;make clean&quot;
# 

JS_TARGETS =
CSS_TARGETS =
CLEANUP =

# you can use a manifest file for targets, if that's more your style:
#CSS_TARGETS = $(shell cat manifest.txt)

# you can specify that your targets are generated by rules, and should be deleted during &quot;make clean&quot;
#CLEANUP = $(CSS_TARGETS) $(JS_TARGETS)

# google closure compiler needs every input script prefixed with --js=, as in --js=file1.js
#concatenated.min.js: file1.js file2.js
#	java -jar ~/bin/compiler.jar $(addprefix --js=,$^) &gt;$@

#custom-concat.css: file1.css file2.css file3.css
#	cat $^ &gt;$@

#######################################################
# you shouldn't need to edit anything below this line #
#######################################################

.DEFAULT_GOAL := all

all: js css

YUI = java -jar ~/bin/yuicompressor-2.4.2.jar
YUI_FLAGS = --type css

CLOSURE = java -jar ~/bin/compiler.jar
CLOSURE_FLAGS = 

.PHONY: css js

%.gz: %
	gzip -9 &lt;$&lt; &gt;$@

# css
# ---

CSS_MINIFIED = $(CSS_TARGETS:.css=.min.css)
CSS_GZIP = $(CSS_TARGETS:.css=.css.gz)
CSS_MIN_GZIP = $(CSS_TARGETS:.css=.min.css.gz)

css: $(CSS_TARGETS) $(CSS_MINIFIED) $(CSS_GZIP) $(CSS_MIN_GZIP)

%.min.css: %.css
	 $(YUI) $(YUI_FLAGS) &lt;$&lt; | sed 's/ and(/ and (/g' &gt;$@

# javascript
# ----------

JS_MINIFIED = $(JS_TARGETS:.js=.min.js)
JS_GZIP = $(JS_TARGETS:.js=.js.gz)
JS_MIN_GZIP = $(JS_TARGETS:.js=.min.js.gz)

js: $(JS_TARGETS) $(JS_MINIFIED) $(JS_GZIP) $(JS_MIN_GZIP)

%.min.js: %.js
	$(CLOSURE) $(CLOSURE_FLAGS) --js=$&lt; &gt;$@

clean:
	rm -f $(CSS_MINIFIED) $(CSS_GZIP) $(CSS_MIN_GZIP) $(JS_GZIP) $(JS_MINIFIED) $(JS_MIN_GZIP) $(CLEANUP)</pre></noscript>
<h2>Customizing for Your Project</h2>
<p>To make this file useful for your own project, you&#8217;ll need to point it at your CSS and JS files.</p>
<pre>JS_TARGETS =
CSS_TARGETS =
CLEANUP =</pre>
<p>The first two variables define what scripts will be minified and compressed when you type &#8220;make js&#8221; or &#8220;make css,&#8221; respectively. Both of these commands will run when you type &#8220;make all&#8221; or simply &#8220;make.&#8221; <code>CLEANUP</code> allows you to specify additional files that will be removed when you type &#8220;make clean.&#8221;</p>
<p>Some sample customizations are mentioned in the file.</p>
<pre>CSS_TARGETS = $(shell cat manifest.txt)</pre>
<p>If you would rather organize your list of CSS or JavaScript targets into their own files, you can automatically expand that manifest file using the cat command.</p>
<pre>CLEANUP = $(CSS_TARGETS) $(JS_TARGETS)</pre>
<p>Some more advanced setups may combine several CSS files before minification, or use a custom target to concatenate JavaScript using the closure compiler. If you find that all your targets can be cleaned, you can simply reference them automatically as above.</p>
<pre>concatenated.min.js: file1.js file2.js
	java -jar ~/bin/compiler.jar $(addprefix --js=,$^) &gt;$@</pre>
<p>The closure compiler requires a prefix for all input JavaScript files. Use the make function &#8220;<code>addprefix</code>&#8221; to format the argument list.</p>
<pre>custom-concat.css: file1.css file2.css file3.css
	cat $^ &gt;$@</pre>
<p>Automatic variables greatly simplify most of the functionality within this makefile. To create a concatenated CSS file, simplify specify the target to the left of the colon, and its dependencies (the files to concatenate) to the right; the <code>cat</code> command never needs modification.</p>
<p>Of course, you can always define custom rules, ie. this one to fetch the newest development version of jQuery:</p>
<pre>jquery:
	curl -o jquery.js http://code.jquery.com/jquery-git.js</pre>
<h2>Other Magic</h2>
<p>Some other goodness happens below the &#8220;you shouldn&#8217;t need to edit past here&#8221; line. After we configure a few settings, we define how to create files based on suffixes: .min.css gets passed through YUI Compressor, .min.js through Closure, and .gz through gzip. We configure what files we care about, and make handles the rest.</p>
<pre>.DEFAULT_GOAL := all</pre>
<p>Set a default rule, rather than using the first rule in the file as the default.</p>
<pre>.PHONY: css js</pre>
<p>Prevent files named &#8220;css&#8221; or &#8220;js&#8221; from interfering with the css and js rules.</p>
<pre>%.gz: %
	gzip -9 &lt;$&lt; &gt;$@</pre>
<p>One of three pattern rules. This enables you to compress any file (not just CSS or JS) by running &#8220;make filename.gz.&#8221; I precompress my files because I&#8217;m using <a href="http://wiki.nginx.org/NginxHttpGzipStaticModule">gzip_static in nginx</a>.</p>
<pre>CSS_GZIP = $(CSS_TARGETS:.css=.css.gz)</pre>
<p>One of several variables that modifies filenames found in <code>$(CSS_TARGETS)</code>, changing the suffix from <code>.css</code> to <code>.css.gz</code>. Note that the colon/equals syntax is shorthand for <a href="http://www.gnu.org/software/make/manual/make.html#Text-Functions">patsubst</a>. Given <code>CSS_TARGETS = text.css tables.css</code>, we would get <code>CSS_GZIP = text.css.gz tables.css.gz</code>, which would be sent as targets to the more general <code>css</code> rule, and in turn would be handled by the general-purpose <code>%.gz</code> rule above.</p>
<h2>See Also</h2>
<ul>
<li><a href="http://www.cprogramming.com/tutorial/makefiles_continued.html">Advanced Makefile Tricks</a> &#8212; macros ($@ et al) and wildcard rules</li>
<li><a href="http://www.gnu.org/software/make/manual/make.html">GNU make manual</a> &#8212; <a href="http://www.gnu.org/software/make/manual/make.html#Functions">functions</a>, <a href="http://www.gnu.org/software/make/manual/make.html#Automatic-Variables">automatic variables</a>, <a href="http://www.gnu.org/software/make/manual/make.html#Pattern-Rules">pattern rules</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ubuntu 8.04 on Linode: Cloning and Upgrading to 10.04</title>
		<link>http://sixohthree.com/1329/ubuntu-8-04-on-linode-cloning-and-upgrading-to-10-04</link>
		<comments>http://sixohthree.com/1329/ubuntu-8-04-on-linode-cloning-and-upgrading-to-10-04#comments</comments>
		<pubDate>Tue, 02 Nov 2010 09:06:52 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[linode]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://sixohthree.com/?p=1329</guid>
		<description><![CDATA[Here are some jumbled notes from my Linode VPS&#8217;s upgrade from Ubuntu &#8220;Hardy Heron&#8221; 8.04 to &#8220;Lucid Lynx&#8221; 10.04. I wanted to do a test run before such a huge upgrade, and I did so by cloning my VPS to a  VMware Fusion virtual machine. Note that I also used Linode&#8217;s backup feature before the [...]]]></description>
			<content:encoded><![CDATA[<p>Here are some jumbled notes from my <a href="http://www.linode.com/?r=3b19dabb9ed30b096be4bfc83724d4e7f4c89c15">Linode</a> VPS&#8217;s upgrade from Ubuntu &#8220;Hardy Heron&#8221; 8.04 to &#8220;Lucid Lynx&#8221; 10.04. I wanted to do a test run before such a huge upgrade, and I did so by cloning my VPS to a  <a href="http://www.vmware.com/products/fusion/">VMware Fusion</a> virtual machine. Note that I also used Linode&#8217;s backup feature before the real upgrade, just to be on the safe side.</p>
<h2>Before the Storm: Finnix</h2>
<p>I had no experience with <a href="http://www.finnix.org/">Finnix</a> before this upgrade, but it was exactly what I needed throughout the process. It&#8217;s <a href="http://library.linode.com/troubleshooting/finnix-recovery">built into the Linode dashboard</a> so you can use it as a recovery console if things go wrong. I also used it as my boot disk while cloning the Linode hard disk to my VM.</p>
<h2>The Backup</h2>
<p><code>rsync</code> is my weapon of choice, since it allows for transport over SSH and incremental backups. I used <a href="http://wiki.archlinux.org/index.php/Full_System_Backup_with_rsync">this article</a> to get started with some suggested <code>rsync</code> flags. I ran this several times throughout the process:</p>
<pre>rsync -avzPH --numeric-ids --delete --delete-excluded --exclude-from=backup.lst root@server.example.com:/ /mnt/sda1/</pre>
<p>Here&#8217;s my <code>backup.lst</code> exclusion file:</p>
<pre>+ /dev/console
+ /dev/initctl
+ /dev/null
+ /dev/zero
- /dev/*
- /proc/*
- /sys/*
- /tmp/*
- *lost+found</pre>
<p>After <code>rsync</code>, <code>chroot</code> to the cloned filesystem:</p>
<pre>mount -R /proc /mnt/sda1/proc
mount -R /dev /mnt/sda1/dev
chroot /mnt/sda1 /bin/bash
vi /etc/fstab # update mountpoints. change xvda to sda1, xvdb to sda2</pre>
<p>Install a bootloader. The Linode VPS is in Xen and doesn&#8217;t normally boot its own kernel. (I know next to nothing about Xen, but this is what I&#8217;ve gleaned.)</p>
<pre>apt-get install grub
mkdir -p /boot/grub
cp -r /usr/lib/grub/i386-pc/{stage1,stage2,e2fs_stage1_5} /boot/grub
apt-get install linux
echo defoptions=vga=791 &gt;&gt;/boot/grub/menu.lst
update-grub</pre>
<p>Reboot. Make sure you kill your cron jobs while the VM is on, as many are probably inappropriate for a backup server.</p>
<pre>sudo service cron stop</pre>
<p>I recommend taking a snapshot of your backup, here. It may actually be faster to just <code>rsync</code> again, but it&#8217;s nice to have a complete backup at the ready.</p>
<p>I used a couple commands to update IP addresses on my backup so I could more accurately test services post-upgrade:</p>
<pre>sudo ~/bin/ack --follow -al '207\.192\.74\.235' /etc | sudo xargs sed -i.bak 's/207\.192\.74\.235/172.16.226.130/g'
sudo ~/bin/ack --follow -al '69\.164\.216\.5' /etc | sudo xargs sed -i.bak 's/69\.164\.216\.5/172.16.226.131/g'</pre>
<h2>The Upgrade</h2>
<p>The following notes were taking during my test upgrade, and referenced during the real upgrade. I referenced the Ubuntu Community Documentation project&#8217;s &#8220;<a href="https://help.ubuntu.com/community/LucidUpgrades">Upgrading to Ubuntu 10.04 LTS</a>&#8221; page. There is also a Linode article on <a href="http://library.linode.com/troubleshooting/upgrade-ubuntu-10.04">upgrading to Ubuntu 10.04</a>.</p>
<p>On the first pass, <code>python-setuptools</code> killed my install. This was fixed by manually reinstalling before upgrade:</p>
<pre>sudo dpkg -r python-setuptools &amp;&amp; apt-get install python-setuptools</pre>
<p>Ensure the update manager is installed, and issue the upgrade command:</p>
<pre>sudo apt-get install update-manager-core
sudo do-release-upgrade</pre>
<p>I encountered conflicts in the following packages, where I had modified local files. Also included is my resolution, which may or may not be helpful to anyone else.</p>
<ul>
<li><code>/etc/securetty</code> &#8212; keep currently installed version; package adds some unneeded ones, and removes tty0 (but does include the Xen ones added by Linode)</li>
<li><code>/etc/sysctl.conf</code> &#8212; use new; uncomment &#8220;<code>kernel.prink = 4 4 1 7</code>&#8221; and add &#8220;<code>fs.inotify.max_user_watches = 524288</code>&#8220;</li>
<li><code>/etc/mysql/my.cnf</code> &#8212; kept my version</li>
<li><code>/etc/dhcp3/dhclient.conf</code> &#8212; kept Linode version: &#8220;<code>request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, host-name, ntp-servers;</code>&#8220;</li>
<li><code>/etc/dbconfig-common/config</code> &#8212; nothing meaningful in the diff; use new</li>
<li><code>/etc/dovecot/dovecot.conf</code> &#8212; kept mine</li>
<li><code>/etc/default/openvpn</code> &#8212; was missing; installed package version</li>
<li><code>/etc/snmp/snmpd.conf</code> &#8212; kept mine</li>
<li><code>/etc/apache2/apache2.conf</code> &#8212; kept mine, as well as other apache2 files (but I did use the new <code>mime.types</code> file)</li>
<li><code>/etc/stunnel/stunnel.conf</code> &#8212; kept mine</li>
<li><code>/etc/default/stunnel4</code> &#8212; kept mine</li>
<li><code>/etc/udev/rules.d/75-persistent-net-generator.rules</code> &#8212; kept installed, looked like the <code>GOTO="persistent_net_generator_end"</code> at the start was intentional</li>
</ul>
<p>Got a warning about vulnerable SSL keys generated by older versions of Ubuntu; solution is to regenerate your keys. The dialog recommended using <code>openssl-vulnkey</code> and <code>openvpn-vulnkey</code> to test.</p>
<p>Other than having to resolve the file conflicts, the upgrade was very smooth. I found some notes about <a href="http://www.linode.com/forums/viewtopic.php?p=29330#29330">fixing the Xen serial console</a>, and <a href="http://www.linode.com/forums/viewtopic.php?p=31756#31756">syslog breaking in 10.04</a>. I also upgraded to a newer paravirt kernel in the Linode dashboard.</p>
<h3>python-setuptools error</h3>
<p>More about that error with <code>python-setuptools</code>: <a href="http://ubuntuforums.org/showthread.php?t=292830">this thread</a> was helpful. From <code>/var/log/apt/term.log</code>:</p>
<pre>Log started: 2010-10-06  08:35:15
Setting up python-setuptools (0.6c9-0ubuntu1) ...
pycentral: pycentral pkginstall: not overwriting local files
pycentral pkginstall: not overwriting local files
dpkg: error processing python-setuptools (--configure):
 subprocess post-installation script returned error exit status 1
Errors were encountered while processing:
 python-setuptools
Log ended: 2010-10-06  08:35:15</pre>
<p>Per the article, ran &#8220;apt-get remove python-setuptools&#8221; and &#8220;apt-get install python-setuptools&#8221;</p>
<h2>Post-upgrade Recompiling</h2>
<p>Something required apt-get install <code>libltdl-dev</code>. Useful info for this post, no?</p>
<p>I recompiled all my custom stuff, including <code>nginx</code>, <code>memcached</code>, <code>mod_php</code> and <code>php-fpm</code>, and <code>mysqld</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1329/ubuntu-8-04-on-linode-cloning-and-upgrading-to-10-04/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cron Output in Google Reader</title>
		<link>http://sixohthree.com/1323/cron-output-in-google-reader</link>
		<comments>http://sixohthree.com/1323/cron-output-in-google-reader#comments</comments>
		<pubDate>Thu, 30 Sep 2010 12:58:09 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://sixohthree.com/?p=1323</guid>
		<description><![CDATA[ I've created a Django app to log cron output, simultaneously reducing the amount of email I get and enabling me to make cron output more verbose.]]></description>
			<content:encoded><![CDATA[<p><a href="http://sixohthree.com/files/2010/09/google-reader-cronjobs.png"><img class="alignnone size-large wp-image-1324 post-titleimage" title="Cron Jobs in Google Reader" src="http://sixohthree.com/files/2010/09/google-reader-cronjobs-1024x670.png" alt="A screenshot of cron job output displayed in an Atom feed via Google Reader." width="1024" height="670" /></a></p>
<p>I&#8217;ve been trimming down my Inbox, filing things more aggressively and unsubscribing from the dozens of newsletters that have accumulated over the years. I&#8217;ve also created a <a href="http://www.djangoproject.com/">Django</a> app to log cron output, simultaneously reducing the amount of email I get and enabling me to make cron output more verbose. Recent log entries are exposed via an Atom feed, which I&#8217;ve plugged into Google Reader (above).</p>
<p>I spend a lot of time in Google Reader, but it&#8217;s stuff like this that makes it feel truly useful rather than just convenient.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1323/cron-output-in-google-reader/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash Completion</title>
		<link>http://sixohthree.com/867/bash-completion</link>
		<comments>http://sixohthree.com/867/bash-completion#comments</comments>
		<pubDate>Fri, 05 Jun 2009 00:54:42 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[compgen]]></category>
		<category><![CDATA[complete]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://sixohthree.com/?p=867</guid>
		<description><![CDATA[It would be difficult to <em>not</em> like bash's programmable completion. It's too bad I've had such a hard time wrapping my head around the programmable completion toolkit.]]></description>
			<content:encoded><![CDATA[<p>It would be difficult to <em>not</em> like bash&#8217;s <a href="http://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion">programmable completion</a>. Tab completion is addictive, and expanding it past files and folders into usernames, hostnames, and, well, anything you can dream up and put in a function, has incredible potential.</p>
<p>It&#8217;s too bad I&#8217;ve had such a hard time wrapping my head around the programmable completion toolkit, <code>complete</code> and <code>compgen</code>.</p>
<h3 id="867_getting-there_1">Getting There</h3>
<p>I have a function that works like <code>cd</code>, but prepends a specific directory. Our web files are stored in <code>/some/dir/webapp</code>, and I want that directory at my fingertips at all times. Here&#8217;s the function:</p>
<pre><code>wa() { cd /web/pscpages/webapp/$1 ; }</code></pre>
<p>With this function, <code>wa</code> brings me to <code>webapp</code>; <code>wa project1</code> brings me to <code>webapp/project1</code>; and so on. I just provide the full sub-path from <code>webapp</code>. Ideally, I would be able to tab-complete directories in <code>webapp</code>.</p>
<p><code>complete</code> can pull a list of possible completions from a number of sources: &#8220;actions&#8221; (like files, directories, commands, shell keywords), command output, a wordlist separated by some whitespace, or the output of a bash function, to name a few. What you&#8217;ve typed so far (the &#8220;current word&#8221;) will be used to filter all the possible completions returned by that source. Say you&#8217;ve typed &#8220;pro&#8221; and then hit tab to autocomplete. The returned completions need to match &#8220;pro&#8221; at the start of the string, meaning you can&#8217;t match against absolute paths like <code>/some/dir/webapp/project1</code>.</p>
<p><code>compgen</code> can be used to generate a list of possible completions. Matches will be output one per line, and can be piped around for transformations just like any other shell command.</p>
<p>Between these two tools, we have everything we need to autocomplete paths starting in a certain directory. Here&#8217;s a <code>compgen</code> that gives us directories matching a specified string:</p>
<pre><code>compgen -d /some/dir/webapp/</code></pre>
<p>Sample output:</p>
<pre><code>/some/dir/webapp/.svn
/some/dir/webapp/project1
/some/dir/webapp/templates
/some/dir/webapp/images</code></pre>
<p>We need to trim leading directories so &#8220;pro&#8221; matches &#8220;project1.&#8221; We should also append <code>/</code> to the pathnames, since we&#8217;re always matching directories:</p>
<pre><code>compgen -S/ -d /some/dir/webapp/ | cut -b 18-</code></pre>
<p>Playing around with <code>compgen</code>&#8216;s arguments, we can further filter the completion list by appending to our string, sort of an implied glob. Use <code>/some/dir/webapp/p</code>, and subdirectories starting with &#8220;p&#8221; will be returned. This is exactly what we want: <code>compgen</code> takes care of all the filtering for us. We have access to a couple special variables to examine the word the user is expanding. For now, it&#8217;s enough just to grab <var>${COMP_WORDS[COMP_CWORD]}</var> and append it to our path.</p>
<p>When completions are generated by a function, they&#8217;re passed back to <code>complete</code> by the <var>$COMPREPLY</var> environment variable. Pulling this all together, we can now create our completion function:</p>
<pre><code>_webapp() {
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -S/ -d /some/dir/webapp/$cur | cut -b 18- ) )
}</code></pre>
<p>All that&#8217;s left is to tell bash to use this function to complete our argument to <code>wa</code>.</p>
<pre><code>complete -o nospace -F _webapp wa</code></pre>
<h3 id="867_the-fruits_1">The Fruits</h3>
<p>So, that does it. Our original wrapper to <code>cd</code>, combined with our autocomplete functionality, looks like this:</p>
<pre><code>wa() { cd /some/dir/webapp/$1 ; }
_webapp() {
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -S/ -d /some/dir/webapp/$cur | cut -b 18- ) )
}
complete -o nospace -F _webapp wa</code></pre>
<p>Voila. Tab completion in a directory that&#8217;s not <var>$PWD</var>, and it even works with subdirectories. I hope this makes autocompletion a little clearer for others.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/867/bash-completion/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google Search Options</title>
		<link>http://sixohthree.com/827/google-search-options</link>
		<comments>http://sixohthree.com/827/google-search-options#comments</comments>
		<pubDate>Wed, 13 May 2009 16:32:12 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/?p=827</guid>
		<description><![CDATA[Google has added some search options to pages, including date-based searches, a variety of ways to find related information, and more options for displaying images with your results. Good stuff.]]></description>
			<content:encoded><![CDATA[<p><img src="///Users/adam/Desktop/search-options.png" alt="" />Google has added some search options to pages, including date-based searches, a variety of ways to find related information, and more options for displaying images with your results. Good stuff.</p>

<a href='http://sixohthree.com/827/google-search-options/search-options' title='search-options'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/search-options-150x150.png" class="attachment-thumbnail" alt="search-options" title="search-options" /></a>
<a href='http://sixohthree.com/827/google-search-options/images-from-page' title='images-from-page'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/images-from-page-150x150.png" class="attachment-thumbnail" alt="images-from-page" title="images-from-page" /></a>
<a href='http://sixohthree.com/827/google-search-options/timeline' title='timeline'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/timeline-150x150.png" class="attachment-thumbnail" alt="timeline" title="timeline" /></a>
<a href='http://sixohthree.com/827/google-search-options/wonder-wheel' title='wonder-wheel'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/wonder-wheel-150x150.png" class="attachment-thumbnail" alt="wonder-wheel" title="wonder-wheel" /></a>

]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/827/google-search-options/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Vim of a Different Color</title>
		<link>http://sixohthree.com/776/a-vim-of-a-different-color</link>
		<comments>http://sixohthree.com/776/a-vim-of-a-different-color#comments</comments>
		<pubDate>Fri, 27 Mar 2009 04:07:32 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[iterm]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/?p=776</guid>
		<description><![CDATA[After one too many compilation errors due to a missing quote/brace/bracket/etc., I finally enabled Vim syntax highlighting. The rabbit hole: :syn on. These colors suck. Look for themes. 4 bit themes suck. Let&#8217;s set up an 8 bit color terminal. Leopard&#8217;s Terminal.app fails, install iTerm 0.9.6. iTerm works, but I use GNU screen all day. [...]]]></description>
			<content:encoded><![CDATA[<p>After one too many compilation errors due to a missing quote/brace/bracket/etc., I finally enabled Vim syntax highlighting. The rabbit hole:</p>
<ol>
<li><code>:syn on</code>. These colors suck. Look for themes.</li>
<li>4 bit themes suck. Let&#8217;s set up an 8 bit color terminal.</li>
<li>Leopard&#8217;s Terminal.app <a href="http://www.vim.org/scripts/script.php?script_id=1349">fails</a>, install iTerm 0.9.6.</li>
<li>iTerm works, but I use GNU screen all day. Recompile screen with <code>--enable-colors256</code>.</li>
<li>screen wins, but doesn&#8217;t play nice with the delete key in iTerm. <a href="http://akgeeks.net/node/83">Fix it</a>.</li>
<li>Compile Vim 7.2 for 8 bit support.</li>
<li>Get an <a href="http://www.vim.org/scripts/script.php?script_id=2175">8 bit theme</a>. <code>set t_Co=256</code> in <code>.vimrc</code>.</li>
<li><code>" syntax highlight html files using the php highlighter</code><br />
<code>autocmd BufRead,BufNewFile *.html set filetype=php<br />
</code></li>
<li>Install <a href="http://www.vim.org/scripts/script.php?script_id=1984">FuzzyFinder</a> for good measure now that we&#8217;re out of Vim 6.3 territory.</li>
<li>Start saving seconds/minutes/hours of my life that before were consumed by syntax errors.</li>
</ol>
<p><a href="/~adam/wp-uploads/2009/03/vim-color.png"><img class="alignnone size-full wp-image-778" src="/~adam/wp-uploads/2009/03/vim-color.png" alt="vim-color" width="636" height="486" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/776/a-vim-of-a-different-color/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VMware Fusion 2</title>
		<link>http://sixohthree.com/525/fusion</link>
		<comments>http://sixohthree.com/525/fusion#comments</comments>
		<pubDate>Wed, 03 Sep 2008 01:35:48 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[vmwarefusion]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/?p=525</guid>
		<description><![CDATA[Digest version: it's sweet.]]></description>
			<content:encoded><![CDATA[<p>I bit the bullet and downloaded the VMware Fusion 2 release candidate today. For completeness, I also trashed my Ubuntu 7.04 Server virtual machine and installed Ubuntu 8.04 Desktop. Here&#8217;s some thoughts after a few hours of use.</p>
<h3>Installation</h3>
<p>During the machine setup, I was prompted to do a &#8220;Linux Easy Install.&#8221; The software auto-populated my full name and username, and asked me for a new password. I let it do its thing, having already pointed it to the Ubuntu installation ISO. A short while later, with no additional interaction, I was at the Gnome login screen. The username and password I had chosen during installation worked great.</p>
<h3>Interface</h3>
<p><a href="/~adam/wp-uploads/2008/09/unity.jpg"><img class="alignright size-thumbnail wp-image-528" src="/~adam/wp-uploads/2008/09/unity.jpg" alt="" width="150" height="93" /></a>The feature that finally pushed me over the 2.0 edge was Unity support in Linux. In the past I have only run server applications on my VM, but I had to see Linux Unity in action, layering my Linux applications with Mac OS X applications. It doesn&#8217;t disappoint.</p>
<p>At the other end of the spectrum is &#8220;Headless&#8221; mode. I&#8217;ve been waiting for this for a long time. When I&#8217;m using the server capabilities of my VM, I don&#8217;t want an extra application cluttering up my alt-tab. Now: &#8220;Enter Headless,&#8221; quit VMWare Fusion. Simple. I assume the VM will suspend if I shut down the computer, but I haven&#8217;t tested it yet.</p>
<p><a href="/~adam/wp-uploads/2008/09/library.jpg"><img class="alignleft size-thumbnail wp-image-527" src="/~adam/wp-uploads/2008/09/library.jpg" alt="" width="150" height="85" /></a>The new library window is a bit more attractive, and the machine settings list is more compact. The list also shows a live thumbnail of your VM&#8217;s display, be it console or graphical. Along the same lines, the console display can now be resized to zoom the terminal text in or out.</p>
<p><a href="/~adam/wp-uploads/2008/09/launcher.jpg"><img class="alignright size-thumbnail wp-image-526" src="/~adam/wp-uploads/2008/09/launcher.jpg" alt="" width="150" height="57" /></a>The Gnome application menu is also accessible from the Mac OS X Dock. Apps can be launched in Unity mode without restoring the Gnome desktop.</p>
<p>Seamless cursor movement between the Linux and Mac desktop, along with VM resolution adjusting to the size of the machine window, are also great features, though I suspect they were present in Fusion 1.0.</p>
<h3>Some Other Section</h3>
<p>Looks like the VMware Fusion team has been up to good things since the first release. I haven&#8217;t yet tried Parallels, but I can&#8217;t see a reason to try anything new from where I&#8217;m sitting.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/525/fusion/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

