<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
  <title>ananelson.com</title>
  <subtitle>she who scrivens</subtitle>
  <link href="http://ananelson.com/feeds/blog.xml" rel="self" />
  <link href="http://ananelson.com/" />
  <updated>2009-11-24T16:59:47+00:00</updated>
  <author>
    <name>Ana Nelson</name>
  </author>
  <id>http://ananelson.com/</id>
  
  <entry>
    <title>Short URLs With Webby and htaccess</title>
    <link href="/blog/2009/11/short-urls-with-webby-and-htaccess/" />
    <id>tag:ananelson.com,2009-11-24:1259073629</id>
    <updated>2009-11-24T14:40:29+00:00</updated>
    <content type="html">
        &lt;p&gt;Please visit the website for source code downloads and syntax highlighting.&lt;/p&gt;&lt;p&gt;Here&amp;#8217;s a quick way to create short URLs for any page on your Webby-created website. You can even use this to create short URLs to external websites, so you can have your own personal shortening service.&lt;/p&gt;
&lt;p&gt;We are going to create a dynamic .htaccess file using Webby. If you already have a &lt;code&gt;content/.htaccess&lt;/code&gt; file, rename it to &lt;code&gt;content/htaccess.txt&lt;/code&gt; or similar. We need to add some Webby metadata to the top of the page.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;---
layout: nil
dirty: true
filter:
  - erb
---
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;layout:nil&lt;/code&gt; tells Webby not to use a HTML template for this file. &lt;code&gt;dirty: true&lt;/code&gt; means the file will be regenerated with every build. Finally &lt;code&gt;filter: erb&lt;/code&gt; tells Webby to process any &lt;code&gt;erb&lt;/code&gt; statements and put the output into our document.&lt;/p&gt;
&lt;p&gt;Now, we are going to manually add a &lt;code&gt;shortcut: x&lt;/code&gt; item to the metadata of any page we&amp;#8217;d like to create a shortcut to, and then create a redirect line for each shortcut in the htaccess file.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&amp;lt;% codes_used = [] %&amp;gt;

&amp;lt;%  @pages.find(
    :all, 
    :in_directory =&amp;gt; @page.dir, 
    :recursive =&amp;gt; true, 
    :sort_by =&amp;gt; :shortcut, 
    :reverse =&amp;gt; true
  ).each do |p| -%&amp;gt;
&amp;lt;% break if p.shortcut.nil? -%&amp;gt;
&amp;lt;% codes_used &amp;lt;&amp;lt; p.shortcut -%&amp;gt;
&amp;lt;%= &amp;quot;Redirect 301 /s/#{p.shortcut} http://ananelson.com#{p.url}&amp;quot; %&amp;gt;
&amp;lt;% end -%&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;This will create lines in the htaccess file like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Redirect 301 /s/1 http://ananelson.com/blog/2009/11/simulations-in-the-cloud/&lt;/pre&gt;&lt;p&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ananelson.com/s/1&quot;&gt;http://ananelson.com/s/1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You could omit the /s/ if you wanted, and have links like &lt;a href=&quot;http://ananelson.com/1&quot;&gt;http://ananelson.com/1&lt;/a&gt;. This would be shorter, but it would clutter up the namespace at the root of your URLs. Decide which is more important to you.&lt;/p&gt;
&lt;p&gt;To link to external pages, I have just created an array of 2-element arrays called SHORTCUTS in my Sitefile, and then create links like so:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&amp;lt;% SHORTCUTS.each do |s, u| -%&amp;gt;
&amp;lt;%= &amp;quot;Redirect 301 /s/#{s} #{u}&amp;quot; %&amp;gt;
&amp;lt;% codes_used &amp;lt;&amp;lt; s -%&amp;gt;
&amp;lt;% end -%&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;You may have noticed that I&amp;#8217;ve been adding the shortcuts to an array called &lt;code&gt;codes_used&lt;/code&gt;, I use this for some very crude duplicate detection to make sure I haven&amp;#8217;t defined the same shortcut twice.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&amp;lt;% raise &amp;quot;duplicate codes in &amp;quot; + codes_used.sort.join(&amp;quot;, &amp;quot;) unless codes_used.uniq.length == codes_used.length -%&amp;gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s all the dynamic content, but you can use the rest of the file for any other htaccess config.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;# Put other htaccess config below.

Options -Indexes 
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;You can download the &lt;a href=&quot;ht.txt&quot;&gt;full script&lt;/a&gt;. (You should remove the ### comments from this file if you use it.)&lt;/p&gt;
&lt;p&gt;If you have followed my naming convention then you&amp;#8217;ll end up with a file called &lt;code&gt;htaccess.txt&lt;/code&gt; in the output directory. We need this to be called &lt;code&gt;.htaccess&lt;/code&gt; instead. Because of the way Webby automatically creates filenames, it&amp;#8217;s easiest to just rename this file ourselves in a Rake task. In my Sitefile I define a task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;desc &quot;rename htaccess.txt to .htaccess&quot;
task :htaccess do
  `mv output/htaccess.txt output/.htaccess`
end&lt;/pre&gt;&lt;p&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and I have my deploy task call this task, so it happens automatically.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;desc 'deploy the site to the webserver'
task :deploy =&amp;gt; [:build, :htaccess, 'deploy:rsync']&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re interested in the analytics of your shortcuts, you&amp;#8217;ll be able to parse your access logs (try &lt;a href=&quot;http://splunk.com&quot;&gt;splunk&lt;/a&gt;). You might want to have some easy way to distinguish internal from external links, you could do this by having external shortcuts use a different path such as http://ananelson.com/e/1. I don&amp;#8217;t think that Javascript-based analytics (like Google Analytics) will detect that this redirect has taken place.&lt;/p&gt;
    </content>
  </entry>
  
  <entry>
    <title>Configuring a VM for SSHing Out</title>
    <link href="/blog/2009/11/configuring-a-vm-for-sshing-out/" />
    <id>tag:ananelson.com,2009-11-21:1258805322</id>
    <updated>2009-11-21T12:08:42+00:00</updated>
    <content type="html">
        &lt;p&gt;Please visit the website for source code downloads and syntax highlighting.&lt;/p&gt;&lt;p&gt;In my previous post on running simulations in a VM, &lt;a href=&quot;/blog/2009/11/simulations-in-the-cloud/&quot;&gt;Simulations in the Cloud&lt;/a&gt;, I suggested using this syntax for fetching a secure remote bzr repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; bzr branch sftp://sshuser:sshpassword@example.com/path
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;I wasn&amp;#8217;t all that happy with this, but it did work, at least at first. However, now something has been tightened up and this method does not read the ssh password from the command. In any event, it wasn&amp;#8217;t a great way to handle this.&lt;/p&gt;
&lt;p&gt;Here is a better way. More robust, more general. It uses SSH keys rather than your SSH password. I&amp;#8217;m assuming you have a private WebDAV location. Note that unless you use https to connect to the WebDAV, your information won&amp;#8217;t be encrypted so this is not a highly secure method. You need to do your own risk analysis and decide for yourself whether this is appropriate for you. I&amp;#8217;d suggest having a dedicated user account just containing the code and data needed for this technique, so that if your account were to be compromised it wouldn&amp;#8217;t mean someone having access to everything.&lt;/p&gt;
&lt;p&gt;Here is a diagram showing the steps we need to take.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Create a key pair, install the public key in authorized_keys. Move or copy the private key to your private WebDAV storage.&lt;/li&gt;
	&lt;li&gt;When you create your VM, copy the private key to the .ssh directory.&lt;/li&gt;
	&lt;li&gt;Now that you have SSH credentials, you can fetch your private code or data from the SSH storage. You could do this directly via scp, or by using an ssh-based protocol built in to your version control system.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;keys.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As in the previous post, you can store your WebDAV username and password in a &lt;code&gt;.netrc&lt;/code&gt; file:&lt;br /&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.netrc&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;machine dav.ananelson.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;login temp&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;password passw0rd&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Then, assuming your private key is stored in this WebDAV, you can fetch it using &lt;code&gt;cadaver&lt;/code&gt;:&lt;br /&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;get id_rsa&amp;quot;&lt;/span&gt; | cadaver http://dav.ananelson.com/webdav
chmod 0400 id_rsa
mkdir ~/.ssh/
mv id_rsa ~/.ssh/
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;So, you have now installed your SSH credentials on your Virtual Machine. However, if you try to connect via SSH in a script now, it&amp;#8217;ll probably fail because your server won&amp;#8217;t be listed in the known hosts file. The simplest way to fix this is to disable strict host key checking.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.ssh/config&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;StrictHostKeyChecking no&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Now, a call like this should work:&lt;br /&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;bzr branch sftp://sshuser@example.com/path/to/bzr-repos/simcode
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here is the whole script. You may notice that I&amp;#8217;ve added a &lt;code&gt;run-models.sh&lt;/code&gt; script, this is to make it easier to run models interactively if you wish to after the config script has run.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;cat &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;==================================================&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;\nOutput from running above script:\n\n\n&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Upgrade the system and install developer tools.&lt;/span&gt;
pacman --noconfirm -Sy pacman
pacman --noconfirm -Syu
pacman --noconfirm -Sy base-devel 

&lt;span class=&quot;c&quot;&gt;# Install cadaver for WebDAV.&lt;/span&gt;
pacman --noconfirm -Sy cadaver

&lt;span class=&quot;c&quot;&gt;### @export &amp;quot;netrc&amp;quot;&lt;/span&gt;
cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.netrc&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;machine dav.ananelson.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;login temp&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;password passw0rd&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;### @end&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Install language and language packaging system.&lt;/span&gt;
pacman --noconfirm -Sy python

curl -O http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg
bash setuptools-0.6c11-py2.6.egg

&lt;span class=&quot;c&quot;&gt;# Install bazaar.&lt;/span&gt;
easy_install pyrex
easy_install bzr
easy_install paramiko

&lt;span class=&quot;c&quot;&gt;### @export &amp;quot;fetch-private-key&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;get id_rsa&amp;quot;&lt;/span&gt; | cadaver http://dav.ananelson.com/webdav
chmod 0400 id_rsa
mkdir ~/.ssh/
mv id_rsa ~/.ssh/

&lt;span class=&quot;c&quot;&gt;### @export &amp;quot;disable-strict&amp;quot;&lt;/span&gt;
cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.ssh/config&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;StrictHostKeyChecking no&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;### @export &amp;quot;fetch-repo&amp;quot;&lt;/span&gt;
bzr branch sftp://sshuser@example.com/path/to/bzr-repos/simcode
&lt;span class=&quot;c&quot;&gt;### @end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;get run_models.sh&amp;quot;&lt;/span&gt; | cadaver http://dav.ananelson.com/webdav
bash &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;dirname &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/run-models.sh
&lt;/pre&gt;&lt;/div&gt;
    </content>
  </entry>
  
  <entry>
    <title>Simulations in the Cloud</title>
    <link href="/blog/2009/11/simulations-in-the-cloud/" />
    <id>tag:ananelson.com,2009-11-11:1257976222</id>
    <updated>2009-11-11T21:50:22+00:00</updated>
    <content type="html">
        &lt;p&gt;Please visit the website for source code downloads and syntax highlighting.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;background-color:yellow;&quot;&gt;Update: Here&amp;#8217;s another post with an alternate way of configuring SSH on your VM &lt;a href=&quot;/blog/2009/11/configuring-a-vm-for-sshing-out/&quot;&gt;Configuring a VM for SSHing Out&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;background-color:yellow;&quot;&gt;Updated at the end to add an alternative script including password-protection of your script and transcript logging.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;How I would have loved &lt;a href=&quot;http://aws.amazon.com/ec2/&quot;&gt;Amazon EC2&lt;/a&gt; back when I was working on my Ph.D. thesis! My simulations frequently ran for hours, and would take over my laptop&amp;#8217;s CPU and memory while they were running. I eventually invested in a Mac Mini and was able to do other work on my laptop while they were running, but simulations are one of those classic cloud use cases where you have a short-term unpredictable need for rather a lot of computing power.&lt;/p&gt;
&lt;p&gt;So, today I want to describe a workflow for getting a simulation, or any other batch job, up and running on an Amazon EC2 instance in an automated and repeatable fashion. I am going to use &lt;a href=&quot;http://www.archlinux.org/&quot;&gt;Arch Linux&lt;/a&gt; since that&amp;#8217;s the Linux flavour I&amp;#8217;m most familiar with. Arch has a very nice packaging system called &lt;a href=&quot;http://www.archlinux.org/pacman/&quot;&gt;pacman&lt;/a&gt; which makes this task very smooth. I&amp;#8217;m sure you could make this work with other flavours of Linux, and in fact they might have the advantage of a more mature selection of ready-made machine images.&lt;/p&gt;
&lt;p&gt;The basic premise is to have a script which configures a bare virtual machine with all the software you need, and either stops there for you to step in and run your simulation, or carries on and runs your simulation for you. We are going to use Parallels to create our own Virtual Machine locally (from scratch!) and then once we have our script developed, we are going to run it on an Amazon EC2 instance in the cloud.&lt;/p&gt;
&lt;p&gt;To start with, you&amp;#8217;ll need to activate your Amazon account (the same one you order books with) to work with EC2. Click on the &lt;a href=&quot;http://aws.amazon.com/console/&quot;&gt;Sign in to the AWS Console&lt;/a&gt; link and enter your Amazon username and password (or create a new account if you want to keep things separate). If you&amp;#8217;ve never done this before, you&amp;#8217;ll be asked to verify your account by telephone. An Amazon robot will phone the number you give them, and you&amp;#8217;ll have to input a PIN number. I had to try this twice, the first time my phone never rang, but the second time it worked perfectly. This just takes a few minutes, and then you&amp;#8217;re ready to start spending money by renting chunks of cloud. Hooray!&lt;/p&gt;
&lt;p&gt;The instructions you&amp;#8217;ll see after you log in to the AWS console are geared towards the command line tools. You actually don&amp;#8217;t need to worry about creating certificates or anything like that just yet. We&amp;#8217;re just going to use the web interface and this will guide you step by step. If you want to, this would be a good time to download the Getting Started Guide and read through it. It&amp;#8217;s available from the &lt;a href=&quot;http://aws.amazon.com/documentation/&quot;&gt;Documentation Centre&lt;/a&gt;  along with lots of other goodies. Also, make yourself aware of the &lt;a href=&quot;http://aws.amazon.com/ec2/#pricing&quot;&gt;fees&lt;/a&gt; for Amazon EC2. There&amp;#8217;s no charge for signing up, only when you actually launch and use an instance.&lt;/p&gt;
&lt;p&gt;Now, we are actually going to move away from Amazon for a little while and create a Virtual Machine locally using &lt;a href=&quot;http://parallels.com&quot;&gt;Parallels&lt;/a&gt;. We will use this VM to develop our setup script. If you don&amp;#8217;t have access to Parallels (or a 14 day free trial thereof) or any alternative, you can use an EC2 instance to develop your install script, but you&amp;#8217;ll be paying by the hour and it won&amp;#8217;t be as easy to reset the VM and start over. Of course if you just want to try this out, you&amp;#8217;re welcome to just run my script in an EC2 instance. Just change or delete the WebDAV credentials or else the script will fail.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s quite straightforward to create a Virtual Machine from scratch using Parallels. You&amp;#8217;ll need to download an ISO image of the operating system you want to install. In this case, the Arch Linux core i686 ISO. (I&amp;#8217;m on my little laptop which is only 32 bit. If you have a 64 bit machine then you can download the x86_64 ISO instead.) These are large files, over 300 MB, so be patient and use Bit/Torrent if possible. The download page for Arch Linux is &lt;a href=&quot;http://www.archlinux.org/download/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once the ISO is downloaded, then in Parallels choose &amp;#8220;New&amp;#8230;&amp;#8221; from the File menu. This will bring up the New Virtual Machine Assistant. Click on the Skip Detection button, and in the next dialog choose More Linux &amp;#8594; Other Linux.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;vm1.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;vm2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finish navigating the assistant, defaults are fine or tweak as you see fit. When you finish, you should have a blank machine which look something like this (for Parallels 5):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;vm3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When you start this machine up, it will tell you that it&amp;#8217;s about to install the operating system. In the CD/DVD drive selection, choose the downloaded ISO image. The Arch Linux install should begin now. If you haven&amp;#8217;t used Arch before, then check out the &lt;a href=&quot;http://wiki.archlinux.org/index.php/Beginners%27_Guide&quot;&gt;Beginner&amp;#8217;s Guide&lt;/a&gt; and &lt;a href=&quot;http://wiki.archlinux.org/index.php/Official_Arch_Linux_Install_Guide&quot;&gt;Install Guide&lt;/a&gt; for help. Parallels should take care of network connectivity for you. We don&amp;#8217;t have a &amp;#8220;Parallels Tools&amp;#8221; for this VM though, so things like copying and pasting from the parent OS won&amp;#8217;t be possible. Also, resizing the VM window won&amp;#8217;t actually make the screen any bigger, it will just give you black space around your console. I assume these are solvable issues, but it hasn&amp;#8217;t been worth my while to do so yet. I didn&amp;#8217;t time the install (sorry!) but it shouldn&amp;#8217;t take more than 10 or 15 minutes. You should be prompted to reboot when the install is finished, and then you should have a shiny new system which looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;vm4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now, before we do anything further, we want to switch everything off. Type &lt;code&gt;shutdown -h now&lt;/code&gt; to power down the virtual machine. When it&amp;#8217;s off, choose &amp;#8220;Take Snapshot&amp;#8230;&amp;#8221; from the Virtual Machine menu in Parallels. Name the snapshot &amp;#8220;Clean Install&amp;#8221;. Now, we have a fresh install snapshot which we can revert to at any time. This is what will make it easy for us to develop and &lt;strong&gt;test&lt;/strong&gt; our setup script which we will eventually be putting to good use on our EC2 instance. Of course, you might also find it useful to simply run simulations in this local virtual machine in case all you want is a repeatable clean environment. Having a standard clean image like this is great if you are writing a tutorial and want to be sure you have captured all the prerequisites people need to install. It&amp;#8217;s very easy to forget that there&amp;#8217;s a hidden dependency on tool X or Y when you installed it 2 years ago and don&amp;#8217;t even remember it&amp;#8217;s there! If you test your install script on a clean VM, that sort of error is much less likely, and at least someone having difficulty can recreate the conditions you used by constructing a similar VM.&lt;/p&gt;
&lt;p&gt;Go to &amp;#8220;Manage Snapshots&amp;#8230;&amp;#8221; to double check and you should see a nice little graphic like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;vm5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Right. The boring stuff is done and now we can get to work on our setup script. Actually, we are going to need to do 1 step manually. We need to install curl on our shiny new VM so that we can fetch our setup script. Type &lt;code&gt;pacman -Sy curl&lt;/code&gt;. If you get an error message, you might need to uncomment your local mirror in &lt;code&gt;/etc/pacman.d/mirrorlist&lt;/code&gt;. You might be told that you need to upgrade &lt;code&gt;pacman&lt;/code&gt; first. If so, go ahead, then run &lt;code&gt;pacman -Sy curl&lt;/code&gt; again when that&amp;#8217;s finished. Now, if you want, take another Snapshot at this point so you don&amp;#8217;t have to do this part again.&lt;/p&gt;
&lt;p&gt;Here is a sample script which illustrates some of the considerations needed to run simulations automatically. I am using the &lt;a href=&quot;http://simpy.sourceforge.net/&quot;&gt;SimPy&lt;/a&gt; framework, and running all the examples in the SimPyModels directory as a demonstration. When finished, we are using WebDAV to export the simulation results for later analysis.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Upgrade the system and install developer tools.&lt;/span&gt;
pacman --noconfirm -Sy pacman
pacman --noconfirm -Syu
pacman --noconfirm -Sy base-devel 

&lt;span class=&quot;c&quot;&gt;# Install language and language packaging system&lt;/span&gt;
pacman --noconfirm -Sy python

curl -O http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg
bash setuptools-0.6c11-py2.6.egg

&lt;span class=&quot;c&quot;&gt;# Install simulation framework&lt;/span&gt;
easy_install simpy

&lt;span class=&quot;c&quot;&gt;# Install subversion to export examples more easily&lt;/span&gt;
pacman --noconfirm -Sy subversion

&lt;span class=&quot;c&quot;&gt;# Download code to run&lt;/span&gt;
svn &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;https://simpy.svn.sourceforge.net/svnroot/simpy/SimPy/SimPy/trunk/SimPyModels/

&lt;span class=&quot;c&quot;&gt;# Create a directory to store results&lt;/span&gt;
mkdir results

&lt;span class=&quot;c&quot;&gt;# Execute the code&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MODELS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;SimPyModels/*.py
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;m in &lt;span class=&quot;nv&quot;&gt;$MODELS&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OUTFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;basename &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  python &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;gt; results/&lt;span class=&quot;nv&quot;&gt;$OUTFILE&lt;/span&gt;.out
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Bundle files we want to save for export&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FILENAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;results-&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;uuidgen&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;.tgz
tar -czvf &lt;span class=&quot;nv&quot;&gt;$FILENAME&lt;/span&gt; results

&lt;span class=&quot;c&quot;&gt;# Install cadaver for WebDAV&lt;/span&gt;
pacman --noconfirm -Sy cadaver

&lt;span class=&quot;c&quot;&gt;# Create a config file for cadaver&lt;/span&gt;
cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.netrc&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;machine dav.ananelson.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;login temp&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;password temp&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Upload the tgz of results to remote webdav store&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;put $FILENAME&amp;quot;&lt;/span&gt; | cadaver http://dav.ananelson.com/webdav
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;I developed this script by trial and error, and a lot of iteration on a fresh VM to validate it. I stored the script on a remote server and ran it via:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
curl -O http://ananelson.com/blog/2009/11/simulations-in-the-cloud/configure-arch.sh
bash configure-arch.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;This way the script wouldn&amp;#8217;t get erased when I reset the VM, and I am mimicking the procedure I will eventually use on EC2. All I need to do to test the script is to revert the VM to the post-install-curl state, then type these 2 lines of code and watch the results scroll by.&lt;/p&gt;
&lt;p&gt;The goal should be to install as little as possible to get the desired software to run. Pacman and easy_install do a lot of the work, helped out by curl when you need to fetch a binary from somewhere and subversion to export examples from the SimPy repository.&lt;/p&gt;
&lt;p&gt;The most difficult part of developing this script was deciding how to export the data out of the VM when finished. I eventually settled on WebDAV since I think it&amp;#8217;s the simplest option, and pretty widely available. It also has the nice feature that your results can be automatically published to the web if you want to do so. I&amp;#8217;ll discuss this further below after we&amp;#8217;ve looked at Amazon. Incidentally, I used UUID rather than timestamps to differentiate the results files because VMs can lose the correct time if they are stopped and reset a lot.&lt;/p&gt;
&lt;p&gt;Right. Now to run this on EC2! Log in to your EC2 management console and click on AMIs. Set the select boxes to &amp;#8220;All Images&amp;#8221; and &amp;#8220;All Platforms&amp;#8221; and search for &amp;#8220;arch&amp;#8221;. Make sure the region is US-East (it doesn&amp;#8217;t matter where in the world YOU are, this is where your EC2 instance will run, US-East is less expensive and has more public images to choose from). I use ami-092ac960, as described in &lt;a href=&quot;http://blog.mudy.info/2009/04/archlinux-ec2-public-ami/&quot;&gt;this article&lt;/a&gt; This is a 64-bit AMI which means that we will need to run a large instance, which is a few times more expensive than running a small instance (see &lt;a href=&quot;http://aws.amazon.com/ec2/#pricing&quot;&gt;price list&lt;/a&gt;). (I haven&amp;#8217;t been able to get the 32-bit version of this to work, which would work on a small instance. I&amp;#8217;ll post an update if/when I do.)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There are various other Arch images up there, some of them might be better options, I haven&amp;#8217;t researched them all but please leave a comment if you have any suggestions. Remember when you launch an image that you are running someone else&amp;#8217;s code. It&amp;#8217;s possible, however unlikely, that someone could have uploaded a nasty image which you will be paying to let loose on the internets! Use at your own risk etc., and here are &lt;a href=&quot;http://docs.amazonwebservices.com/AWSEC2/latest/DeveloperGuide/index.html?AESDG-chapter-usingsharedamis.html#usingsharedamis-security&quot;&gt;some tips from Amazon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Okay, if you want to go through with this step, then right-click on the image and choose Launch Instance. This will bring up a Launch wizard. The first step is to create a Key Pair. Just stick in your name and click &amp;#8220;Create &amp;amp; Download Your Key Pair&amp;#8221;. You will end up with a file called &amp;#8220;something.pem&amp;#8221; in your Downloads directory. Just leave it there for now.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, you&amp;#8217;ll be asked to set up a security group. This means you&amp;#8217;re setting access permissions for the virtual machine. In order to SSH into this machine from outside, which you&amp;#8217;ll probably want to do, you have to enable this explicitly. There is already a &amp;#8220;default&amp;#8221; security group which DOESN&amp;#8217;T have SSH access. So, let&amp;#8217;s create another one called &lt;code&gt;ssh&lt;/code&gt;. Make sure the SSH box is checked and click Continue.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we get to the final screen (and your last chance to Cancel and not pay Amazon any money!). Enter &amp;#8220;1&amp;#8221; in the number of instances. Make sure the Key Pair Name and Security Groups are set to the ones you just created (they will be by default). Now, you know our nice setup script? The one we just got ready? Well, click on &amp;#8220;Advanced Options&amp;#8221; and you&amp;#8217;ll see a User Data field. Paste your script right in here and as soon as your instance is launched, your script will start to run. Because we&amp;#8217;ve tested it on a generic Arch linux install, it will hopefully work straight away when we run it on an EC2 Arch install. That&amp;#8217;s the idea, anyway. You can either paste your actual script, or the 2 line curl -O &amp;#8230; script as above. Curl is already installed on this image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you wish, go ahead and launch this instance. It can take a few minutes to launch, but pretty soon you should see a green dot in your instances list.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you right click on this green instance, you&amp;#8217;ll see a few useful things. If you right click and choose Connect, you&amp;#8217;ll get instructions on how to SSH in to your virtual machine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To make life easy, &lt;code&gt;cd&lt;/code&gt; into your downloads directory (so you&amp;#8217;re in the same directory as the pem file you downloaded a few minutes ago). As per the instructions, &lt;code&gt;chmod 400&lt;/code&gt; the pem file. Then copy and paste the ssh instructions onto your command line. You&amp;#8217;ll get a known hosts warning message since you&amp;#8217;ve never connected to this host before. If all has gone well, you&amp;#8217;ll now be &lt;strong&gt;in&lt;/strong&gt; the cloud. How cool is that!!&lt;/p&gt;
&lt;p&gt;The management console also has a built-in system log viewer, so you can see if something has gone wrong or follow the progress of your startup script.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;aws7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finally, when you&amp;#8217;re finished with everything, don&amp;#8217;t forget to right click and terminate this instance. You&amp;#8217;re billed in whole-hour increments.&lt;/p&gt;
&lt;p&gt;So, hopefully you&amp;#8217;ll actually have very little to do &lt;strong&gt;in&lt;/strong&gt; the cloud since we&amp;#8217;ve gotten all the prep work done in our local Virtual Machine and the script will be launched automatically and will WebDAV out the data when it&amp;#8217;s finished.&lt;/p&gt;
&lt;p&gt;You can experiment with using larger images, there&amp;#8217;s Quadruple Extra Large or High-CPU Extra Large, and see if they improve your simulation run times. If you are going to make a habit of this, then you&amp;#8217;ll want to be systematic and build a little minimal benchmarking into your scripts so you can assess what the benefits are of using a larger image. Remember, even though it&amp;#8217;s &amp;#8220;the cloud&amp;#8221;, there is still energy being used to power your CPU units, so don&amp;#8217;t be wasteful. The good news is that this is much more efficient and cost effective than buying a machine just for the occasional simulation run. It&amp;#8217;s also accessible from anywhere in the world, any time.&lt;/p&gt;
&lt;p&gt;We have run all this via the web interface for EC2, so we were clicking on buttons and doing other interactive things. However, this process could be fully automated if you used Amazon&amp;#8217;s command line interface for EC2. For now, I don&amp;#8217;t need that level of automation, but it is something I plan to develop and it would be very nice to have that built in to a simulation framework. The command line tools are a little finicky to set up, but they would be a good long-term investment if you&amp;#8217;re likely to do a lot of this. Also, you might find that developing a custom AMI would be a useful investment.&lt;/p&gt;
&lt;p&gt;I mentioned the issue of how to get your data out of EC2 when the simulation has finished. I settled on WebDAV since I wasn&amp;#8217;t too concerned about having WebDAV credentials exposed in a public script temporarily. The obvious alternative of using scp would mean I&amp;#8217;d need to get a private SSH key into the virtual machine somehow, perhaps by pasting it into the user data field and writing it to some location on the new machine which a script could access. Here are some other alternatives I considered:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Email yourself the file. Drawbacks: (a) having to install some mail-sending capability and (b) Amazon image IP addresses have been abused by spammers, so you might never get your email.&lt;/li&gt;
	&lt;li&gt;FTP yourself the file. Similar enough to WebDAV.&lt;/li&gt;
	&lt;li&gt;scp from outside, using the pem file you downloaded. scp has the same -i option as ssh, as described above. Fine, and very secure, but it&amp;#8217;s a manual job unless you have a cron which checks every 5 minutes for you.&lt;/li&gt;
	&lt;li&gt;Amazon Elastic Block Store (EBS) This is a promising option for future development. EBS is persistent storage designed for EC2. However, in order to get data OUT of an EBS volume you need to store it to S3 (or extract it by some other means in a running EC2 instance). So, it&amp;#8217;s a little involved. But, once you had this set up, it might be the most convenient option long-term. There are fees for using EBS and S3.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Okay, so there are a lot of options here, and you can even get more creative and perhaps run a web server on the remote machine so you can download or interact with your data there. Or, maybe someone can come up with a nice tool accessible via curl which generates a temporary SSH key to let you scp a file somewhere secure, which you can access later. My goal was to just find 1 way of doing this, and the WebDAV works quite nicely for me.&lt;/p&gt;
&lt;p&gt;I think the idea of having a clean, reproducible environment based on VMs and AMIs gives you a lot of flexibility in terms of getting access to extra computing power when you need it, and sharing scripts without necessarily needing to have access to the same exact image. My script should work with any recent build of Arch Linux, not my particular VM, as demonstrated by the fact that I developed it on one VM and then ran it on another one. Of course, you may find differences between various environments, but the fact that you are using a standardized process will make it easier to identify and compensate for such differences. I will now consider developing standard install scripts for some of my software projects, especially with regard to producing automated documentation, so that it&amp;#8217;s easy for people to reproduce my results and to help themselves to troubleshoot installation issues they may be having on their own machines.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;background-color:yellow;&quot;&gt;Update: Here is another version of this script with some more ideas.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This script installs python and ruby, along with some ruby gems, and installs the bazaar version control system with paramiko (needed for ssh/sftp). It uses bazaar&amp;#8217;s sftp facility to access a private bazaar repo via ssh. You are expected to redirect the output from this script into a file script.out, and script.out is included with the results bundle so you have a record of what happened to produce your data. The first few lines ensure that a copy of the script is included in the script.out transcript.&lt;/p&gt;
&lt;p&gt;This script is intended to be stored in a password-protected web directory, possibly the same as the WebDAV directory which results will be pushed to at the end of the script. You would call this script via:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
curl -O http://webdavuser:webdavpassword@example.com/webdav/script.sh
bash script.sh &amp;amp;&amp;gt; script.out
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;In interactive use, i.e. when developing and validating your script, you would probably want to do something like this:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
curl -O http://webdavuser:webdavpassword@example.com/webdav/script.sh
cat script.sh # Double check you got what you expected
bash script.sh &amp;amp;&amp;gt; script.out &amp;amp;
tail -f script.out # Follow what's happening
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href=&quot;configure-arch-2.sh&quot;&gt;script&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;cat &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;==================================================&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;\nOutput from running above script:\n\n\n&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Upgrade the system and install developer tools.&lt;/span&gt;
pacman --noconfirm -Sy pacman
pacman --noconfirm -Syu
pacman --noconfirm -Sy base-devel 

&lt;span class=&quot;c&quot;&gt;# Install language and language packaging system.&lt;/span&gt;
pacman --noconfirm -Sy python

curl -O http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg
bash setuptools-0.6c11-py2.6.egg

pacman --noconfirm -Sy ruby

&lt;span class=&quot;c&quot;&gt;# Install gems.&lt;/span&gt;
gem install do_sqlite3
gem install datamapper


&lt;span class=&quot;c&quot;&gt;# Install bazaar.&lt;/span&gt;
easy_install bzr
easy_install paramiko

&lt;span class=&quot;c&quot;&gt;# Download code to run.&lt;/span&gt;
bzr branch sftp://sshuser:sshpassword@example.com/path/to/bzr-repos/simcode

&lt;span class=&quot;c&quot;&gt;# Create a directory to store results.&lt;/span&gt;
mkdir results

&lt;span class=&quot;c&quot;&gt;# Execute the code.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;simcode
&lt;span class=&quot;nv&quot;&gt;MODELS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;models/*.rb
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;m in &lt;span class=&quot;nv&quot;&gt;$MODELS&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OUTFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;basename &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;\nRunning file: $m\n\n&amp;quot;&lt;/span&gt;
  ruby &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;gt; ../results/&lt;span class=&quot;nv&quot;&gt;$OUTFILE&lt;/span&gt;.out
  mkdir ../results/&lt;span class=&quot;nv&quot;&gt;$OUTFILE&lt;/span&gt;.dir
  mv results/* ../results/&lt;span class=&quot;nv&quot;&gt;$OUTFILE&lt;/span&gt;.dir/
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ..

&lt;span class=&quot;c&quot;&gt;# Copy results of script.out into results.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Assuming you run this script with:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# bash conf.sh &amp;amp;&amp;gt; script.out &amp;amp;; tail -f script.out&lt;/span&gt;
cp script.out results/

&lt;span class=&quot;c&quot;&gt;# Bundle files we want to save for export.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FILENAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;results-&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;uuidgen&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;.tgz
tar -czvf &lt;span class=&quot;nv&quot;&gt;$FILENAME&lt;/span&gt; results

&lt;span class=&quot;c&quot;&gt;# Install cadaver for WebDAV.&lt;/span&gt;
pacman --noconfirm -Sy cadaver

&lt;span class=&quot;c&quot;&gt;# Create a config file for cadaver.&lt;/span&gt;
cat &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;EOF &amp;gt; ~/.netrc&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;machine www.example.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;login webdabuser&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;password webdavpassword&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;EOF&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Upload the tgz of results to remote webdav store.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;put $FILENAME&amp;quot;&lt;/span&gt; | cadaver http://www.example.com/webdav/
&lt;/pre&gt;&lt;/div&gt;
    </content>
  </entry>
  
  <entry>
    <title>North Pole Tenderfoot by Doug Hall</title>
    <link href="/blog/2009/10/north-pole-tenderfoot-by-doug-hall/" />
    <id>tag:ananelson.com,2009-10-12:1255382528</id>
    <updated>2009-10-12T22:22:08+01:00</updated>
    <content type="html">
        &lt;p&gt;Please visit the website for source code downloads and syntax highlighting.&lt;/p&gt;&lt;p&gt;I came to this book with a very strong desire to like it. I have a deep respect for &lt;a href=&quot;http://doughall.com&quot;&gt;the author&lt;/a&gt;. I have listened to his &lt;a href=&quot;http://brainbrewradio.com&quot;&gt;radio show&lt;/a&gt; for several years. I admire his attitude and his accomplishments. I have taken &amp;#8220;inspiration and encouragement&amp;#8221; from his ideas and his words. So, I probably would have enjoyed this book even if it had been mediocre, because I would have been learning about a formative event in the life of someone in whom I had a lot of interest. I was also a little worried that, while I would find the book inspiring, I might not be able to share that feeling with others who weren&amp;#8217;t in on the back story.&lt;/p&gt;
&lt;p&gt;I needn&amp;#8217;t have worried. This book is not mediocre, nor even close to it. It is well conceived, well organized and well written. It is honest, intimate and entertaining. It is about the mundane chores of life, which in the Arctic are revealed as feats of endurance and creativity, and it is about the most profound questions and challenges we face in our lives.&lt;/p&gt;
&lt;p&gt;In the introduction, the author tells how he first performed this story as a play, since of his 4 previous books, the 2 most successful had been adapted from content delivered as lectures. I think this technique shows through in the balance and discipline of the writing. The story never drags, and I always wanted to know what happened next. As an author, you are safely far away from your audience, not so as a playwright-cum-actor on opening night.&lt;/p&gt;
&lt;p&gt;This is a well-balanced book. It&amp;#8217;s an adventure story. The author has a talent for getting himself into and then out of trouble, and to learn from and laugh at that experience. This makes him a very likeable protagonist, and it&amp;#8217;s a great example of how the right sort of humility sets you up for success in life. It&amp;#8217;s a book about entrepreneurship, a successful businessman launching a new charitable venture with a colossal publicity stunt. It&amp;#8217;s a book about the relevance of history. How we walk in the footsteps of those pioneers who came before us, sharing the essence of their personal struggle, but with new and different challenges appropriate to our own time, and how the benefit of hindsight can give us new knowledge about the past. This is a book about making your own luck, finding your own meaning and acting on your dreams. It&amp;#8217;s a wonderful antidote to cynicism and malaise, and it&amp;#8217;s also a jolly good read. I highly recommend it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.amazon.co.uk/gp/product/1578603285?ie=UTF8&amp;tag=flightwise-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1578603285&quot;&gt;Amazon UK&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.powells.com/biblio/62-9781578603282-0&quot;&gt;Powells&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.amazon.com/North-Pole-Tenderfoot-Expedition-Following/dp/1578603285/&quot;&gt;Amazon&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  
  <entry>
    <title>Introducing roux</title>
    <link href="/blog/2009/09/introducing-roux/" />
    <id>tag:ananelson.com,2009-09-24:1253821867</id>
    <updated>2009-09-24T20:51:07+01:00</updated>
    <content type="html">
        &lt;p&gt;Please visit the website for source code downloads and syntax highlighting.&lt;/p&gt;&lt;p&gt;roux is a tool for running R scripts and creating pretty and practical output from the results. Roux is an R package which helps roux to work. For the moment, roux is a bash script which is hard-coded to use Pygments and to output HTML, but in time I&amp;#8217;ll work to adapt this to use other highlighters and output formats, and to be platform-independent if possible.&lt;/p&gt;
&lt;p&gt;I wrote recently about why you would want a &lt;a href=&quot;http://ananelson.com/blog/2009/09/a-diy-html-r-transcript-viewer/&quot;&gt;tool for running R scripts and viewing the output in a browser&lt;/a&gt; and I explained a little about how it was implemented. This is basically the same tool only a little more refined, slightly easier to install and use.&lt;/p&gt;
&lt;p&gt;The main advance is that this script now redefines the &lt;code&gt;plot()&lt;/code&gt; function itself. This means it will create separate png images for each plot you draw, regardless of whether you make an explicit call to a graphics device. In fact if you do call &lt;code&gt;quartz()&lt;/code&gt; or any other graphics device, it gets ignored. More testing is needed to be sure this is the sensible behaviour in every case. I don&amp;#8217;t yet have support for the &lt;code&gt;add=TRUE&lt;/code&gt; plot parameter for example. However this and other exceptions should be able to be dealt with.&lt;/p&gt;
&lt;p&gt;This is nowhere near perfect, it won&amp;#8217;t work if you trigger a graph other than via &lt;code&gt;plot()&lt;/code&gt;, for example, but I think the core idea is extensible enough to be able to eventually accommodate at least the majority of situations. One option I may consider is to start a new image for each graphics device but just ignore it if the file size is 0, so that if a call to &lt;code&gt;quartz()&lt;/code&gt; is followed by a call to &lt;code&gt;plot()&lt;/code&gt;, the image triggered by &lt;code&gt;quartz()&lt;/code&gt; just gets ignored. Suggestions and scripts which don&amp;#8217;t work will be happily received.&lt;/p&gt;
&lt;p&gt;The roux script is now shorter and simpler. Instead of storing functions in a .RData file, now a line is prepended to your script which loads the Roux package. This has the advantage of being more explicit, and the corresponding disadvantage of showing up in your output. Also, you can now run roux from anywhere, and it will create image and html output files from whereever you run the script. So, you no longer have to be in the directory where your R script is, although of course you can run it there if you wish to. This should make it easier to clobber temporary files. Also, once the Roux package is installed in the normal way, it will be available to your R, so there is no longer any need to have a .R helper file.&lt;/p&gt;
&lt;p&gt;So, to run this, you now need to install:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A &lt;a href=&quot;r-console-lexer.diff&quot;&gt;patched&lt;/a&gt; version of &lt;a href=&quot;http://pygments.org&quot;&gt;Pygments&lt;/a&gt;. (apply patch and setup.py install)&lt;/li&gt;
	&lt;li&gt;The &lt;a href=&quot;Roux_0.0-1.tar.gz&quot;&gt;Roux R package&lt;/a&gt; (install in R)&lt;/li&gt;
	&lt;li&gt;The &lt;a href=&quot;roux&quot;&gt;roux script&lt;/a&gt; (make executable, put on your PATH)&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, because I love showing off what this can do, here&amp;#8217;s a really nice self-contained &lt;a href=&quot;http://mayin.org/ajayshah/KB/R/tutorial.R&quot;&gt;R tutorial&lt;/a&gt; and here is what the &lt;a href=&quot;tutorial.R-with-images.html&quot;&gt;output from running this R script&lt;/a&gt; looks like. (By the way, there are lots more R resources by Ajay Shah &lt;a href=&quot;http://mayin.org/ajayshah/KB/R/index.html&quot;&gt;here&lt;/a&gt;.)&lt;/p&gt;
&lt;p style=&quot;background-color:yellow;&quot;&gt;Update: I have written an install script. It assumes you have Python and Mercurial installed. USE AT YOUR OWN RISK. &lt;a href=&quot;install.sh&quot;&gt;install.sh&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  
</feed>
