<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Sankasaurus]]></title>
  <link href="http://blog.pas.net.au/atom.xml" rel="self"/>
  <link href="http://blog.pas.net.au/"/>
  <updated>2014-02-18T20:23:50-08:00</updated>
  <id>http://blog.pas.net.au/</id>
  <author>
    <name><![CDATA[Peter Sankauskas]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Getting rid of the white halo around black text on Mac OSX]]></title>
    <link href="http://blog.pas.net.au/blog/2014/02/18/getting-rid-of-the-white-halo-around-black-text-on-mac-osx/"/>
    <updated>2014-02-18T20:10:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2014/02/18/getting-rid-of-the-white-halo-around-black-text-on-mac-osx</id>
    <content type="html"><![CDATA[<p>So I just purchased an external monitor for my home office. When I plugged it in to my Macbook Pro using a Mini-displayport to Displayport, the resolution was great (2560x1080), but it looked terrible. Everything was fuzzy, and the most annoying &ndash; black text had this white halo effect around it. I could still read everything, but it wasn&rsquo;t pretty.</p>

<p>After much searching, I found this post:</p>

<p><a href="http://www.ireckon.net/2013/03/force-rgb-mode-in-mac-os-x-to-fix-the-picture-quality-of-an-external-monitor">http://www.ireckon.net/2013/03/force-rgb-mode-in-mac-os-x-to-fix-the-picture-quality-of-an-external-monitor</a></p>

<p>It talks about the OSX thinking it was plugged into a TV, and using the YCbCr color space rather than RGB. After running the script, following the instructions and restarting, the monitor is working beautifully.</p>

<p>Hopefully this helps someone else, and will serve as a reminder to me should I encounter it again.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Quick slideshow of image files on OSX]]></title>
    <link href="http://blog.pas.net.au/blog/2013/06/25/quick-slideshow-of-image-files-on-osx/"/>
    <updated>2013-06-25T15:49:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2013/06/25/quick-slideshow-of-image-files-on-osx</id>
    <content type="html"><![CDATA[<p>I only <a href="http://www.cultofmac.com/165267/view-a-folder-full-of-photos-quickly-and-easily-os-x-tips/">recently discovered</a> a quick and easy way to start a slideshow on OSX from a list of images in a folder. From Finder, select all the images you want to display (<code>Command-A</code> for all) and then:</p>

<h3><code>Option-Command-Y</code></h3>

<p>Not sure why this isn&rsquo;t more obvious as it is really handy. Enjoy.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Conversion to Octopress complete]]></title>
    <link href="http://blog.pas.net.au/blog/2013/06/08/conversion-to-octopress-complete/"/>
    <updated>2013-06-08T12:27:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2013/06/08/conversion-to-octopress-complete</id>
    <content type="html"><![CDATA[<p>Well, I was up until the wee hours of the night last night, but I finally converted my blog to <a href="http://octopress.org/">Octopress</a> and have it hosted on AWS S3. I must say, I really like Octopress and am becoming a big fan of generated static websites (such as <a href="http://pages.github.com/">Github pages</a>), where anything complicated is handled by JavaScript. The only unfortunate thing is that I couldn&rsquo;t bring the comments over from Wordpress and put them into <a href="http://disqus.com/pas256/">Disqus</a>.</p>

<p>Generating the site and pushing it to S3 is as easy as:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>rake generate
</span><span class='line'><span class="nb">cd </span>public
</span><span class='line'>s3cmd sync . s3://blog.pas.net.au/
</span></code></pre></td></tr></table></div></figure>


<p>The source in case you are interested is on Github at:</p>

<p><a href="https://github.com/pas256/blog">https://github.com/pas256/blog</a></p>

<p>Thanks to <a href="https://twitter.com/jeffbarr">Jeff Barr</a> for introducting me to Octopress on his <a href="http://awsroadtrip.com/">AWS Road Trip</a>.</p>

<p>Looking forward to getting back into this &ndash; it has been too long without a good rant. :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating large empty files quickly]]></title>
    <link href="http://blog.pas.net.au/blog/2012/10/16/creating-large-empty-files-quickly/"/>
    <updated>2012-10-16T21:46:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2012/10/16/creating-large-empty-files-quickly</id>
    <content type="html"><![CDATA[<p>I have seen many people on the interwebs using dd and <code>/dev/zero</code> to create empty files. This is great if the file is small, but for a 50Gb file, it simply takes too long, particularly on EC2. The solution? Truncate!</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>truncate -s 50G my-large-file
</span></code></pre></td></tr></table></div></figure>


<p>Boom &ndash; instant.</p>

<p>This is great for doing things like mounting /tmp on EC2 to the ephemeral storage so /tmp is not limited to 10Gb (or whatever your root image size is)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> /mnt
</span><span class='line'>truncate -s 50G big-tmp
</span><span class='line'>mkfs.xfs /mnt/big-tmp
</span><span class='line'>mount -o loop /mnt/big-tmp /tmp
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git for OSX]]></title>
    <link href="http://blog.pas.net.au/blog/2011/12/09/git-for-osx/"/>
    <updated>2011-12-09T21:52:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2011/12/09/git-for-osx</id>
    <content type="html"><![CDATA[<p>Hi have just discovered a wonderful GUI for Git on Mac OSX. It is called GitX (L) (which is different to GitX).</p>

<p>You can get it here: <a href="http://gitx.laullon.com/">http://gitx.laullon.com/</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I no longer recommend Rackspace Cloud]]></title>
    <link href="http://blog.pas.net.au/blog/2011/07/29/i-no-longer-recommend-rackspace-cloud/"/>
    <updated>2011-07-29T21:53:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2011/07/29/i-no-longer-recommend-rackspace-cloud</id>
    <content type="html"><![CDATA[<p>Regular readers of this blog (currently 6 of you madmen) will notice I removed the &ldquo;PAS Recommends&rdquo; section linking to Rackspace Cloud. That is because I can simply no longer recommend them. It is a sad day.</p>

<p>They are wasting resources by creating pointless iPhone and Android applications, and sending out survey after survey, all while the Management Console continues to get worse and worse. Right now in fact, I get a &ldquo;white screen&rdquo; after logging in.</p>

<p>Amazon&rsquo;s Web Services are kicking Rackspace Cloud&rsquo;s arse by continuously improving and upgrading their services. AWS has it all, and is only getting better while Rackspace Cloud sits dormant. I cannot believe we still cannot create an image of a machine larger than 75Gb, and that backups fail silently if the size does increase.</p>

<p>RIP Rackspace Cloud. I had much higher hopes for you.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Installing CDH3 on OS X]]></title>
    <link href="http://blog.pas.net.au/blog/2011/07/29/installing-cdh3-on-os-x/"/>
    <updated>2011-07-29T09:07:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2011/07/29/installing-cdh3-on-os-x</id>
    <content type="html"><![CDATA[<p>Installing Cloudera’s version of Hadoop on an OSX Macbook Pro is not difficult, if you get the steps right.</p>

<p>Go to: <a href="https://ccp.cloudera.com/display/SUPPORT/CDH3+Downloadable+Tarballs">https://ccp.cloudera.com/display/SUPPORT/CDH3+Downloadable+Tarballs</a>
and download the Hadoop tarball.</p>

<p>We are going to run Hadoop in pseudo-distributed mode, which is nice in a dev environment.</p>

<p>Open up a Terminal window, and run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tar xvzf ~/Downloads/hadoop-0.20.2-cdh3u1.tar.gz
</span><span class='line'><span class="nb">cd </span>hadoop-0.20.2-cdh3u1/conf
</span><span class='line'>cp ../example-confs/conf.pseudo/* .
</span></code></pre></td></tr></table></div></figure>


<p>Now we need to edit 2 files so that Hadoop knows where to write it’s data. This is when you decide where to write it. I did:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mkdir -p ~/hadoop-data/cache/hadoop/dfs/name
</span></code></pre></td></tr></table></div></figure>


<p>Edit core-site.xml</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;property&gt;</span>
</span><span class='line'>   <span class="nt">&lt;name&gt;</span>hadoop.tmp.dir<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>   <span class="nt">&lt;value&gt;</span>/Users/${user.name}/hadoop-data/cache/${user.name}<span class="nt">&lt;/value&gt;</span>
</span><span class='line'><span class="nt">&lt;/property&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, edit hdfs-site.xml</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;property&gt;</span>
</span><span class='line'>   <span class="nt">&lt;name&gt;</span>dfs.name.dir<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>   <span class="nt">&lt;value&gt;</span>/Users/${user.name}/hadoop-data/cache/hadoop/dfs/name<span class="nt">&lt;/value&gt;</span>
</span><span class='line'><span class="nt">&lt;/property&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, format HDFS, and start up the nodes:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> ../bin
</span><span class='line'>./hadoop namenode -format
</span><span class='line'>./start-all.sh
</span></code></pre></td></tr></table></div></figure>


<p>If you are typing in your password a lot, try this (assuming you have your SSH keys set up):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> ~/.ssh
</span><span class='line'>cp id_rsa.pub authorized_keys
</span></code></pre></td></tr></table></div></figure>


<p>If you have upgraded to OS X Lion (v 10.7), then you might see this every time you do something:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>2011-07-29 21:22:05.997 java<span class="o">[</span>7690:1903<span class="o">]</span> Unable to load realm info from SCDynamicStore
</span></code></pre></td></tr></table></div></figure>


<p>You can ignore it. It has something to do with Kerberos authentication (I think), but I don’t yet have a solution to getting rid of it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git and SVN working together]]></title>
    <link href="http://blog.pas.net.au/blog/2011/01/12/git-and-svn-working-together/"/>
    <updated>2011-01-12T22:07:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2011/01/12/git-and-svn-working-together</id>
    <content type="html"><![CDATA[<p>I have been using Subversion for a long time, and am relatively new to Git. This post is a little tutorial of what I have learnt getting Git and SVN to play nicely together, primarily using git-svn.</p>

<p>My goal is to maintain the code in the original SVN repository while transitioning the team to Git. This means changes to either repository get reflected into the other one.</p>

<p>First steps is to take the create an empty Git repository to import SVN into (this is your remote Git repository):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>/git-repo
</span><span class='line'>mkdir project
</span><span class='line'><span class="nb">cd </span>project
</span><span class='line'>git --bare init
</span></code></pre></td></tr></table></div></figure>


<p>Now clone the empty Git repository so you have a working directory, and the import the SVN repository into Git. The directory names need to match (in this case, they are both &ldquo;project&rdquo;):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>
</span><span class='line'>git clone file://<span class="nv">$HOME</span>/git-repo/project
</span><span class='line'>git svn clone -s file://<span class="nv">$HOME</span>/svn-repo/project
</span></code></pre></td></tr></table></div></figure>


<p>If all is going well, you should have a &ldquo;project&rdquo; directory with all of your files imported from SVN in it. This directory is also your Git clone. Now you can &ldquo;push&rdquo; these changes to your remote Git repository</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>/project
</span><span class='line'>git push origin master
</span></code></pre></td></tr></table></div></figure>


<p>Now make some changes to your working directory</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">echo</span> <span class="s2">&quot;This is a change in Git&quot;</span> &gt; git-change.txt
</span><span class='line'>git add git-change.txt
</span><span class='line'>git commit -m <span class="s2">&quot;Adding a new file&quot;</span>
</span><span class='line'>git push
</span></code></pre></td></tr></table></div></figure>


<p>We now have a change in Git that is not in SVN. To copy the change over to SVN we do a &ldquo;dcommit&rdquo;</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>git svn dcommit
</span></code></pre></td></tr></table></div></figure>


<p>Lets check out the SVN repository, and make a change in there</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>
</span><span class='line'>svn checkout file://<span class="nv">$HOME</span>/svn-repo/project/trunk svn-project
</span><span class='line'><span class="nb">cd </span>svn-project
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;Here is a change in SVN&quot;</span> &gt; svn-change.txt
</span><span class='line'>svn add svn-change.txt
</span><span class='line'>svn commit -m <span class="s2">&quot;Adding a new change in SVN&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>To get this change in Git, we need to &ldquo;rebase&rdquo;. This is not as scary as it sounds</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>/project
</span><span class='line'>git pull
</span><span class='line'>git svn rebase
</span><span class='line'>git push
</span></code></pre></td></tr></table></div></figure>


<p>Horay! We now know how to make changes go both ways between SVN and Git.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Android Market links]]></title>
    <link href="http://blog.pas.net.au/blog/2010/08/25/android-market-links/"/>
    <updated>2010-08-25T22:07:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2010/08/25/android-market-links</id>
    <content type="html"><![CDATA[<p>For those of you like me that have totally missed the <a href="http://developer.android.com/guide/publishing/publishing.html">Publishing</a> page, here is how to create a link to your Android application in the Android Market:</p>

<pre><code>market://﻿details?id=&lt;packagename&gt;
</code></pre>

<p>OR</p>

<pre><code>http://market.android.com/details?id=&lt;packagename&gt;
</code></pre>

<p>So for <a href="http://www.gbott.com/apps/remembory">Remembory</a>, I have this:</p>

<pre><code>market://﻿details?id=com.gbott.remembory
</code></pre>

<p>The &ldquo;old&rdquo; way was to link to the search page by using this:</p>

<pre><code>market://search?q=pname:&lt;package&gt;
</code></pre>

<p>&hellip;but the details page method saves the user a click, or a tough decision when there are two applications both called Remembory.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rackspace Cloud images to Cloud Files]]></title>
    <link href="http://blog.pas.net.au/blog/2010/07/26/rackspace-cloud-images-to-cloud-files/"/>
    <updated>2010-07-26T22:07:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2010/07/26/rackspace-cloud-images-to-cloud-files</id>
    <content type="html"><![CDATA[<p>For doing anything serious on Rackspace Cloud, you need to be able to use machines larger than 2Gb of RAM. Problem is, machines larger than 2Gb of RAM cannot be imaged (or backed up) &ndash; until now. About a month ago, they announced the ability to <a href="http://www.rackspacecloud.com/blog/2010/06/16/introducing-cloud-servers-snapshots-to-cloud-files/">snapshot a machine into Cloud Files</a>. Today I decided to take it for a spin and hit Snag number one: there was no way to do an image on my new 16Gb machine. After talking talking to one person at Rackspace Cloud, I was none the wiser &ndash; Snag two was the lack of training for their support staff. After asking for the supervisor, he created a ticket for the approval for the terms (letting me know I would be charged for the storage in Cloud Files) and off I went. Until I hit Snag 3 &ndash; the &ldquo;Images&rdquo; tab for the server details still showed no way of performing an image. I was told to use the &ldquo;My Server Images&rdquo; and HORAY I could make an image of my 16Gb machine.</p>

<p>Finally the feature that prevented my company from using Rackspace Cloud, and instead using AWS, was fixed! Congratulations to the Rackspace Cloud team.</p>

<p>Another thing I learnt today is that there are two data centers for Rackspace Cloud machines &ndash; DFW and ORD. The first server you provision gets assigned to one of the two data centers, and which ever one it gets put into is the data center that all of your other servers will be put into as well. So if the first server gets put into DFW, then all of the other ones you create will be. That is until you delete all of your servers. Then once again, the first server can get put into any data center.</p>

<p>I am hoping that in the future, we will have a choice about which data center a server is provisioned in, particularly since it will help for geographical distribution.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JSON SerDe for Hive]]></title>
    <link href="http://blog.pas.net.au/blog/2010/02/16/json-serde-for-hive/"/>
    <updated>2010-02-16T22:07:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2010/02/16/json-serde-for-hive</id>
    <content type="html"><![CDATA[<p>I have added another open source project to my list – a JSON SerDe for Hive. You can check it out here:</p>

<p><a href="http://code.google.com/p/hive-json-serde/">http://code.google.com/p/hive-json-serde/</a></p>

<p>This SerDe (serializer/deserializer) will let you read JSON files as input for Hive tables. In the future, it will also support writing JSON data, but that is for another day.</p>

<p>Please let me know if you have any comments or questions about it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Google Takes First Step]]></title>
    <link href="http://blog.pas.net.au/blog/2010/02/04/google-takes-first-step/"/>
    <updated>2010-02-04T22:08:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2010/02/04/google-takes-first-step</id>
    <content type="html"><![CDATA[<p>Google have taken a step in the right direction by offering people a <a href="http://blog.chromium.org/2010/01/encouraging-more-chromium-security.html">monetary reward when they find a bug in Chromium</a>. I am very excited by this news, not because I am likely to find a bug and cash in, but because it shows Google is starting to take some accountability.</p>

<p>Step 2 would be public bug trackers for ALL of their systems, particularly the online ones such as Gmail, Docs, Sites, etc.</p>

<p>Step 3 would be Googlers actually paying attention to them, maybe even hiring a customer support team.</p>

<p>Fingers crossed!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Google - Hexus One]]></title>
    <link href="http://blog.pas.net.au/blog/2010/01/08/google-hexus-one/"/>
    <updated>2010-01-08T22:08:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2010/01/08/google-hexus-one</id>
    <content type="html"><![CDATA[<p>When I first told my wife about Google releasing a phone, the very first words out of her mouth were:</p>

<blockquote><p>I would never buy a phone from Google. If something went wrong, I’m screwed! Its not like I can take it into a shop and get it fixed</p></blockquote>


<p>How right she was. According to Slashdot, <a href="http://mobile.slashdot.org/story/10/01/08/2352202/Google-Faces-Deluge-of-Nexus-One-Complaints">Google is facing a deluge of customer complaints about the Nexus One</a>. Are you having problems? Use the hash tag <a href="https://twitter.com/search?q=%23fixgoogle">#fixgoogle</a> if you are on Twitter. All tweets with that tag will appear on <a href="http://www.fixgoogle.com/">fixgoogle.com</a> when I get the site up and running.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Backups by design on AWS EC2]]></title>
    <link href="http://blog.pas.net.au/blog/2009/12/18/backups-by-design-on-aws-ec2/"/>
    <updated>2009-12-18T11:06:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/12/18/backups-by-design-on-aws-ec2</id>
    <content type="html"><![CDATA[<p>My good mate* Joel Spolsky wrote a <a href="http://www.joelonsoftware.com/items/2009/12/14.html">nice piece about backups (or rather, restoration)</a>, and I wanted to echo his remarks and how they relate to using AWS EC2.</p>

<p>If you are using EC2, you will quickly find that if an instance is terminated, any data on that instance is gone &ndash; lost forever. At first, this seems like a terrible idea, but in fact, it encourages you to get into best practices, and discover the awesome benefits of EBS.</p>

<p>We have many instances running of different types. We have built a &ldquo;custom&rdquo; Debian AMI for each of the instance types we use (web, database, management, etc). If you were to launch an instance with one of these AMIs, you would not have a fully working system. That is because these AMIs have sym-links for important and/or dynamic data. For example, on the web AMI we have created, <code>/etc/apache2</code>, <code>/etc/php5/</code> and <code>/var/www</code> are all sym-links. To where? A directory that an EBS volume is mounted to. That&rsquo;s right, all of the web configuration and website code only lives in an EBS volume. It is simple enough to write a little script that creates a nightly Snapshots of each EBS volume.</p>

<p>Now for the power of this setup. Every time you want to bring up another instance of the same type (say, for horizontally scaling), you are in fact doing a restoration from backup. Take a Snapshot (your backup), create an EBS volume, attach it to the new instance, and make it live! This doesn&rsquo;t just work for scaling, it works for bringing up staging servers that are mirrors of production or running experiments without affecting production.</p>

<p>We can even take it a step further! Those AMIs and Snapshots are all stored in S3 &ndash; data available to the whole Region. An instance and EBS volume exist in only 1 of the Availability Zones within that Region. You can use your backups to restore into a new Availability Zone which you can use to create a high-availability solution.</p>

<p>Happy scaling!</p>

<p>* I don&rsquo;t know Joel personally &ndash; we have never met &ndash; but I do follow his work, like his company and LOVE <a href="http://www.fogcreek.com/FogBugz/">Fogbugz</a>!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Motally Video and Contest]]></title>
    <link href="http://blog.pas.net.au/blog/2009/12/10/motally-video-and-contest/"/>
    <updated>2009-12-10T11:30:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/12/10/motally-video-and-contest</id>
    <content type="html"><![CDATA[<p>I am please to announce to all my fans (haha) the <a href="http://aws.amazon.com/startupchallenge/">AWS Start-up Challenge video shot at Motally</a> is finally live! This was my first ever professional video shoot &ndash; they spent 5 hours at our office to edit it down to 2 minutes. Motally was one of the 7 finalists, out of more than 1000 entries. Congratulations to <a href="http://www.gooddata.com/">GoodData</a> and <a href="http://www.bizo.com/">Bizo</a> for taking the top prizes!</p>

<p>I also want to call upon all of the mobile application developers out there. Motally is running a <a href="http://www.motally.com/contest/">mobile analytics contest called Trackappalooza</a>. Here you can win a pass to MWC in Barcelona, or up to $15,000 just for tracking your Android, iPhone or Blackberry app. <a href="http://www.motally.com/">Motally is <em>the</em> mobile analytics powerhouse</a> providing tracking capabilities for mobile websites and mobile applications.</p>

<p>Good luck!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Innovate 09]]></title>
    <link href="http://blog.pas.net.au/blog/2009/09/24/innovate-09/"/>
    <updated>2009-09-24T08:14:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/09/24/innovate-09</id>
    <content type="html"><![CDATA[<p>If anyone is interested in going to the <a href="https://www.paypal-communications.com/innovate2009/">PayPal X (Innovate 09) conference</a>, I have come across is discount. A special rate of $149 (50% off the price) if you enter promotion/coupon code: <strong>PayPalHR</strong></p>

<p>Enjoy!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dependency Nightmare for Tomcat on Debian]]></title>
    <link href="http://blog.pas.net.au/blog/2009/08/18/dependency-nightmare-for-tomcat-on-debian/"/>
    <updated>2009-08-18T09:34:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/08/18/dependency-nightmare-for-tomcat-on-debian</id>
    <content type="html"><![CDATA[<p>I would love to not have to install the real Java and Tomcat manually on Debian, but I have little choice in the matter. Take a look at this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ apt-get install tomcat5.5
</span><span class='line'>Reading package lists... Done
</span><span class='line'>Building dependency tree
</span><span class='line'>Reading state information... Done
</span><span class='line'>The following extra packages will be installed:
</span><span class='line'>ant ant-gcj ant-optional ant-optional-gcj antlr build-essential debhelper
</span><span class='line'>default-jdk default-jre default-jre-headless defoma dpkg-dev ecj ecj-gcj fastjar
</span><span class='line'>file fontconfig fontconfig-config g++ g++-4.3 gappletviewer-4.3 gcj-4.3
</span><span class='line'>gcj-4.3-base gettext gettext-base gij-4.3 gjdoc hicolor-icon-theme html2text
</span><span class='line'>intltool-debian java-common java-gcj-compat java-gcj-compat-dev
</span><span class='line'>java-gcj-compat-headless jsvc libantlr-java libantlr-java-gcj libasound2
</span><span class='line'>libatk1.0-0 libatk1.0-data libbcel-java libcairo2 libcommons-beanutils-java
</span><span class='line'>libcommons-collections-java libcommons-collections3-java libcommons-daemon-java
</span><span class='line'>libcommons-dbcp-java libcommons-digester-java libcommons-el-java
</span><span class='line'>libcommons-launcher-java libcommons-logging-java libcommons-modeler-java
</span><span class='line'>libcommons-pool-java libcompress-raw-zlib-perl libcompress-zlib-perl libcups2
</span><span class='line'>libdatrie0 libdb4.5 libdigest-hmac-perl libdigest-sha1-perl libdirectfb-1.0-0
</span><span class='line'>libecj-java libecj-java-gcj libexpat1 libfile-remove-perl libfontconfig1
</span><span class='line'>libfontenc1 libfreetype6 libgcj-bc libgcj-common libgcj9-0 libgcj9-0-awt
</span><span class='line'>libgcj9-dev libgcj9-jar libgcj9-src libglib2.0-0 libglib2.0-data libgtk2.0-0
</span><span class='line'>libgtk2.0-bin libgtk2.0-common libice6 libio-compress-base-perl
</span><span class='line'>libio-compress-zlib-perl libio-stringy-perl libjaxp1.3-java libjaxp1.3-java-gcj
</span><span class='line'>libjpeg62 liblog4j1.2-java liblog4j1.2-java-gcj libmagic1 libmail-box-perl
</span><span class='line'>libmail-sendmail-perl libmailtools-perl libmime-types-perl libmx4j-java
</span><span class='line'>libobject-realize-later-perl libpango1.0-0 libpango1.0-common libpixman-1-0
</span><span class='line'>libpng12-0 libregexp-java libservlet2.3-java libservlet2.4-java libsm6 libsqlite3-0
</span><span class='line'>libstdc++6-4.3-dev libsys-hostname-long-perl libthai-data libthai0 libtiff4
</span><span class='line'>libtimedate-perl libtomcat5.5-java libts-0.0-0 liburi-perl libuser-identity-perl
</span><span class='line'>libxcb-render-util0 libxcb-render0 libxcomposite1 libxcursor1 libxdamage1
</span><span class='line'>libxerces2-java libxerces2-java-gcj libxfixes3 libxfont1 libxft2 libxi6
</span><span class='line'>libxinerama1 libxrandr2 libxrender1 libxtst6 make mime-support patch po-debconf
</span><span class='line'>python python-central python-minimal python2.5 python2.5-minimal ttf-dejavu
</span><span class='line'>ttf-dejavu-core ttf-dejavu-extra x-ttcidfont-conf xfonts-encodings xfonts-utils
</span><span class='line'>...
</span><span class='line'>0 upgraded, 146 newly installed, 0 to remove and 0 not upgraded.
</span><span class='line'>Need to get 101MB of archives.
</span><span class='line'>After this operation, 288MB of additional disk space will be used.
</span><span class='line'>Do you want to continue [Y/n]?</span></code></pre></td></tr></table></div></figure>


<p>WTF? I understand that Tomcat needs some kind of Java, but this is ridiculous. It is installing ant, fonts, compilers and worst of all, the most evil Java ever.</p>

<p>Ubuntu has the sense to make Sun Java available, but even if you do have Sun Java installed, the above is true on Ubuntu.</p>

<p>For shame!</p>

<p>I&rsquo;ll stick to downloading from <a href="http://java.sun.com/">java.sun.com</a> and <a href="http://tomcat.apache.org/">tomcat.apache.org</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rackspace Cloud API PHP Library]]></title>
    <link href="http://blog.pas.net.au/blog/2009/08/13/rackspace-cloud-api-php-library/"/>
    <updated>2009-08-13T21:42:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/08/13/rackspace-cloud-api-php-library</id>
    <content type="html"><![CDATA[<p>I am pleased to annouce my very first open source project hosted at github. The project, called <a href="http://github.com/pas256/Rackspace-Cloud-PHP-Library">Rackspace Cloud PHP Library</a> is a simple, single PHP file to easily make <a href="http://www.rackspacecloud.com/cloud_hosting_products/servers/api">Cloud Server API</a> calls. Rackspace have not yet released any libraries for their API, possibly because it is still kind of in beta. If they do, I believe there will be of little use for my project, but right now, it has value.</p>

<p>So what was my motivation for this?</p>

<p>Well the <a href="https://manage.rackspacecloud.com/">Rackspace Cloud Management Console</a> is severely lacking in features. Things such as creating an image of a server (just like you can in AWS EC2), and sharing an IP address between servers (something you cannot do in EC2 &ndash; an IP address can only be attached to a single instance at a time). It is this second feature that I am most interested in because it means I can use a virtual IP address (floating IP) to create a HA (highly available) &ldquo;cluster&rdquo; of Tomcat servers. I plan on using <a href="http://www.keepalived.org/">keepalived</a> to do the IP switching, and Apache with <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html">mod_proxy_balancer</a> and <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html">mod_proxy_ajp</a> to talk to multiple Tomcat servers. Without reading the <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf">poorly written API documention</a> and learning that I could create a shared IP group, I would not have known this was possible.</p>

<p>This project is very much a work in progress, and what is in there now represents only about 8 hours of work. I welcome any feedback, and anyone else who wants to join.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Download Chrome OS now – it's called cl33n]]></title>
    <link href="http://blog.pas.net.au/blog/2009/07/08/download-chrome-os-now-its-called-cl33n/"/>
    <updated>2009-07-08T15:06:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/07/08/download-chrome-os-now-its-called-cl33n</id>
    <content type="html"><![CDATA[<p>For some strange reason, <a href="http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html">Chrome OS</a> is getting a lot of press. Is it a slow news day?</p>

<p><a href="http://opengardensblog.futuretext.com/archives/2009/07/google_chrome_o.html">They</a> say that it is direct competition to Microsoft, that it makes Linux less relevant&hellip; are they serious? Chrome OS is a non-announcement. There is a project that has existed for over 2 years called &ldquo;<a href="http://cl33n.com/">cl33n</a>&rdquo;. From the creator:</p>

<blockquote><p>Chrome OS is &#8220;Google Chrome running within a new windowing system on top of a Linux kernel.&#8221;<br/>cl33n is &#8220;Mozilla Firefox running in a little-used windowing system on top of a Linux kernel.&#8221;</p></blockquote>


<p>This &ldquo;OS&rdquo; is due to the released mid 2010. Is that how slowly things move inside Google? Why would it take them 12 months to create nothing more than cl33n?</p>

<p>What I am trying to say, is that Chrome OS is nothing new. Cl33n is not alone in this space either &ndash; other project like <a href="http://webconverger.com/">Webconverger</a> share my view.</p>

<p>While on the subject of Google&rsquo;s non-annoucements, did you hear that Gmail, Doc, etc are out of beta. Big news huh? So what is their excuse now for daily &ldquo;Server error&rdquo; dialogs?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fighting with SELinux and Nagios]]></title>
    <link href="http://blog.pas.net.au/blog/2009/05/02/fighting-with-selinux-and-nagios/"/>
    <updated>2009-05-02T09:25:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/05/02/fighting-with-selinux-and-nagios</id>
    <content type="html"><![CDATA[<p>I can&rsquo;t believe it, but I won! I have been trying to set up Nagios on a RHEL5 machine running SELinux and have been loosing the fight for the last 3 days. But today, I win! This is such a win, it is worth sharing.</p>

<p>Now that I have won though, I believe this is not Nagios specific at all, and if I had bothered to learn about SELinux, this may have been obvious. Anyway, the error Nagios was giving me was:</p>

<blockquote><p>Error: Could not stat() command file &#8216;/usr/local/nagios/var/rw/nagios.cmd&#8217;!<br/>The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.<br/>An error occurred while attempting to commit your command for processing.<br/>Return from whence you came</p></blockquote>


<p>As you may have already guess, the solution has nothing to do with the location or permissions of the file, the file was not missing, Nagios was running, and Nagios was checking external commands. The final line of the message is great though, and I can only hope we start to see more old English in error messages.</p>

<p>The problem of course, was that SELinux was enabled and stopping this blatant security violation. You can check to see if SELinux is on by running:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ /usr/sbin/getenforce
</span><span class='line'>Enforcing</span></code></pre></td></tr></table></div></figure>


<p>If you got &ldquo;Permissive&rdquo; or &ldquo;Disabled&rdquo;, then this post is not for you. To see SELinux&rsquo;s side of things, check out <code>/var/log/messages</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>setroubleshoot: SELinux is preventing ping (ping_t) "read write" to /usr/local/nagios/var/spool/checkresults/checkrXH96b (usr_t). For complete SELinux messages. run sealert -l 1ffc2533-42b5-4e04-b7ab-a81bb7d02040
</span><span class='line'>
</span><span class='line'>setroubleshoot: SELinux is preventing ping (ping_t) "read write" to /usr/local/nagios/var/spool/checkresults/checkrZxsA1 (usr_t). For complete SELinux messages. run sealert -l 178ba2d4-0822-47eb-9e32-bfaa19ee3c4b
</span><span class='line'>
</span><span class='line'>setroubleshoot: SELinux is preventing cmd.cgi (httpd_sys_script_t) "getattr" to /usr/local/nagios/var/rw/nagios.cmd (httpd_sys_content_t). For complete SELinux messages. run sealert -l 4df0946e-8816-4b90-a7d1-37e743697b9c</span></code></pre></td></tr></table></div></figure>


<p>As you can see, SELinux is trying to give you a hint with that sealert bit, so you should take it.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sealert -l 1ffc2533-42b5-4e04-b7ab-a81bb7d02040
</span><span class='line'>Summary:
</span><span class='line'>SELinux is preventing ping (ping_t) "read write" to
</span><span class='line'>/usr/local/nagios/var/spool/checkresults/checkrXH96b (usr_t).
</span><span class='line'>
</span><span class='line'>Detailed Description:
</span><span class='line'>
</span><span class='line'>... (removed from post)
</span><span class='line'>
</span><span class='line'>Raw Audit Messages
</span><span class='line'>
</span><span class='line'>host=myhost.myisp.host type=AVC msg=audit(1241217029.141:125305): avc: denied { read write } for pid=32379 comm="ping" path="/usr/local/nagios/var/spool/checkresults/checkrXH96b" dev=sda3 ino=52894945 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:usr_t:s0 tclass=file
</span><span class='line'>
</span><span class='line'>host=myhost.myisp.host type=SYSCALL msg=audit(1241217029.141:125305): arch=c000003e syscall=59 success=yes exit=0 a0=153952a0 a1=15395330 a2=7fff75c5eb40 a3=0 items=0 ppid=32378 pid=32379 auid=503 uid=508 gid=508 euid=0 suid=0 fsuid=0 egid=508 sgid=508 fsgid=508 tty=(none) ses=1392 comm="ping" exe="/bin/ping" subj=user_u:system_r:ping_t:s0 key=(null)</span></code></pre></td></tr></table></div></figure>


<p>That raw audit message is <strong>GOLD</strong>! There is some other information in there, but nothing about what the next step should be to create a policy and make it permanent. Using <code>chron</code> I have heard is a temporary fix. The solution is copying that raw audit message into an empty file and running <code>audit2allow</code> to create a policy:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cat &gt; /tmp/tmp-nagiosping
</span><span class='line'>host=myhost.myisp.host type=AVC msg=audit(1241217029.141:125305): avc: denied { read write } for pid=32379 comm="ping" path="/usr/local/nagios/var/spool/checkresults/checkrXH96b" dev=sda3 ino=52894945 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:usr_t:s0 tclass=file
</span><span class='line'>host=myhost.myisp.host type=SYSCALL msg=audit(1241217029.141:125305): arch=c000003e syscall=59 success=yes exit=0 a0=153952a0 a1=15395330 a2=7fff75c5eb40 a3=0 items=0 ppid=32378 pid=32379 auid=503 uid=508 gid=508 euid=0 suid=0 fsuid=0 egid=508 sgid=508 fsgid=508 tty=(none) ses=1392 comm="ping" exe="/bin/ping" subj=user_u:system_r:ping_t:s0 key=(null)
</span><span class='line'>* Ctrl-D *
</span><span class='line'>
</span><span class='line'>$ audit2allow -M NagiosPing &lt; /tmp/tmp-nagiosping
</span><span class='line'>
</span><span class='line'>******************** IMPORTANT ***********************
</span><span class='line'>To make this policy package active, execute:
</span><span class='line'>
</span><span class='line'>semodule -i NagiosPing.pp</span></code></pre></td></tr></table></div></figure>


<p>This creates a file call NagiosPing.pp which contains the SELinux policy needed to make these errors go away. The only thing left to do is to install this policy:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ semodule -i NagiosPing.pp</span></code></pre></td></tr></table></div></figure>


<p>If your setup was like mine, SELinux was actually preventing 3 different actions, needing 3 different policies. HA! That is easy now &ndash; just repeat the steps until Nagios is doing your bidding.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Skills-based Resumes]]></title>
    <link href="http://blog.pas.net.au/blog/2009/03/11/skills-based-resumes/"/>
    <updated>2009-03-11T20:00:00-07:00</updated>
    <id>http://blog.pas.net.au/blog/2009/03/11/skills-based-resumes</id>
    <content type="html"><![CDATA[<p>I have recently been updating and freshening up my resume, and thought I would do something different&hellip; something to stand out. Having interviewed many people, from software engineers to product managers and CTOs, I have had the opportunity to see many resumes. Most of the resumes I see are quite bland and boring &ndash; as if written for a machine. They have no personality, no passion and no creativity. I wanted my resume to have personality, passion and creativity.</p>

<p>Since I am a well rounded engineer, I thought I would be able to cover more of my skills in a skills-based resume, instead of a chronological list of my work experience. I went through and split my skills into areas (Coding, Data, Operations, Communication, etc) and listed a few points under each. At the end, I added my work experience, but only with a short paragraph of what I did there.</p>

<p>While I thought this style made a good resume, recruiters hate it, and so do people trying to hire.</p>

<p>After getting some advice, I wanted to share it with the rest of the world. Here are the things people want to see in software engineering/technical resume:</p>

<ul>
<li><strong>Technical Skills</strong>: After your object at the top (if you want to display passion), make a clear section describing your technical skills &ndash; languages, databases, environments.</li>
<li><strong>Summary</strong>: Recruiters give your resumes only seconds when determining its fit for a role, so help them out by having a small summary easily telling the reader how many years of experience you have, your last role, and perhaps your education. From this, they can deduce.</li>
<li><strong>Accomplishments</strong>: When you do list the companies you have worked for, make sure to include some of your notable accomplishments and things you are proud of. If possible, try and quantify them (revenue generated, queries per second, amount of data).</li>
<li><strong>Your Role</strong>: Let the reader know what your role and responsibilities were at each position you have held</li>
</ul>


<p>Resume writing is a complex task, and something a lot of people dread. I have definitely not covered everything, but I did want to make clear a skills resume is not a good idea. Also be aware that many recruiting companies load resumes through a computer before even looking at them. Try to have keywords a search engine could pick up on (like SEO for resumes).</p>

<p>Perhaps resumes written for machines is a good thing after all?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unlock your T-Mobile G1]]></title>
    <link href="http://blog.pas.net.au/blog/2009/02/23/unlock-your-t-mobile-g1/"/>
    <updated>2009-02-23T13:14:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/02/23/unlock-your-t-mobile-g1</id>
    <content type="html"><![CDATA[<p>I have successfully unlocked my T-Mobile G1 for free? How you ask? After 90-days, T-Mobile allows you to unlock almost any phone you have purchased from them with the T-Mobile branding, and all for FREE. The process can take about 2 weeks (as it did for me), but it worked. Here is how:</p>

<p>Call T-Mobile on 1-877-453-1304 from another phone (not your G1). I got that number from their Contact page
Its the standard voice prompt thing, so say English, enter your G1&rsquo;s phone number, then when they ask what you want help with, say the magic word &ldquo;Agent&rdquo;
Then they ask what you would like to talk about, and say &ldquo;SIM Unlock Request&rdquo;
My experience with T-Mobile has been pretty good, within a minute I was talking to the real person. At this point, you verify your identity, and explain to them you want to unlock you phone because you are going overseas and want to use another SIM card.
They will ask you for you phone&rsquo;s IMEI number. This is a sacred number, so be careful who you give it to, as you can report the phone stolen, give them the IMEI number, and have the phone permanently disabled. You will find the number:
on the side of the box your phone came in,
on the G1 itself under Settings &ndash;> About phone &ndash;> Status, or
by dialing *#06#
Give them your email address, and within 14-days, you will get an email from T-Mobile with your unlock code.
To unlock the phone, power it off, insert a non-t-mobile SIM card, and power it back on
At the prompt, enter the unlock code from the email and you&rsquo;re done!
The reason for writing this post is I had no idea this could be done for free with any T-Mobile phone after 90-days has past. There is no need to pay $25 to any scam site, just do it legit, for free, and without issue.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Django and Google App Engine Tutorial]]></title>
    <link href="http://blog.pas.net.au/blog/2009/02/17/django-and-google-app-engine-tutorial/"/>
    <updated>2009-02-17T11:45:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/02/17/django-and-google-app-engine-tutorial</id>
    <content type="html"><![CDATA[<p>Hi have been playing around with Google App Engine for a while now, and wanted to learn Django on a new application I am building. The two articles I started with are:</p>

<ul>
<li><a href="http://code.google.com/appengine/articles/appengine_helper_for_django.html">Using the Google App Engine Helper for Django</a></li>
<li><a href="http://code.google.com/appengine/articles/django10_zipimport.html">Using Django 1.0 on App Engine with Zipimport</a></li>
</ul>


<p>Both Django and GAE are being developed as I write this, so although these instructions are kind of recent, they are already out of date, or rely on you having knowledge of Django. Since there are a lot of others with no Python or Django experince wanting to learn, I thought I would make a tutorial that works as of today, but who knows a month from now or even tomorrow.</p>

<p>Note: This tutorial is written for Linux. Mac/Windows users will have to translate :&ndash;)</p>

<h2>Create django.zip</h2>

<p>Django comes as a .tar.gz file, but we want a zip file to take advantage of the Zipimport library, so some conversion is needed.</p>

<ol>
<li><a href="http://www.djangoproject.com/download/">Download the latest Django</a> and untar the file (in this case, it is 1.0.2)</li>
<li><code>cd Django-1.0.2-final</code></li>
<li>Create the zip file, but without the admin section since App Enging supplies it&rsquo;s own
<code>zip -r ~/django.zip django -x 'django/contrib/admin*'</code></li>
</ol>


<h2>Get the Helper</h2>

<p>The App Engine Helper or Django is an open source bootstrapper for getting Django started on App Engine. Downloading it from the website will currently give you quite an old version (r52) which will not work in this tutorial. Instead, use subversion to get the latest (r74).</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> ~
</span><span class='line'>svn <span class="nb">export </span>http://google-app-engine-django.googlecode.com/svn/trunk/ gae-django-tutorial
</span><span class='line'><span class="nb">cd </span>gae-django-tutorial
</span><span class='line'>mv ~/django.zip .
</span></code></pre></td></tr></table></div></figure>


<h2>Setup App Engine</h2>

<p>As you would with any GAE application, edit the app.yaml file to refer to your application ID. The Helper also needs to know where your Google App Engine SDK is, since it is going to change how you start the development server, so create a link to it:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd </span>gae-django-tutorial
</span><span class='line'>ln -s /path/to/google_appengine .google_appengine
</span></code></pre></td></tr></table></div></figure>


<h2>Start the development server</h2>

<p>Django has a different way of running the development server. Instead of using dev_appserver.py to start the dev server, do the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>python manage.py runserver
</span></code></pre></td></tr></table></div></figure>


<p>If everything is running correctly, you should see something like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>INFO:root:Server: appengine.google.com
</span><span class='line'>INFO:root:Checking <span class="k">for </span>updates to the SDK.
</span><span class='line'>INFO:root:The SDK is up to date.
</span><span class='line'>INFO:root:Running application google-app-engine-django on port 8000: http://localhost:8000
</span></code></pre></td></tr></table></div></figure>


<p>However, if you are like me and saw an error like the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>ImportError: No module named antlr3
</span></code></pre></td></tr></table></div></figure>


<p>Then you will need to install the antlr3 python module. Luckily this is easy.</p>

<ol>
<li>Go to <a href="http://www.antlr.org/download/Python">http://www.antlr.org/download/Python</a> and download the latest zip</li>
<li><code>unzip antlr_python_runtime-3.1.zip</code></li>
<li><code>cd antlr_python_runtime-3.1</code></li>
<li><code>sudo python setup.py install</code></li>
</ol>


<p>Lets see the site! When you go to <a href="http://localhost:8000/">http://localhost:8000/</a> you should see a page saying &ldquo;It worked! Congratulations on your first Django-powered page.&rdquo;
Pretty (un)impressive huh?</p>

<p>Ok, now lets start doing something. Kill the server by pressing Ctrl-C. The Django tutorial is the next stop, which involves creating the Polls Django app. You can read through there to get a full understanding. For simplicity, I am only what I did to get it working.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>python manage.py startapp polls
</span><span class='line'><span class="nb">cd </span>polls
</span><span class='line'>Edit models.py
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">from</span> <span class="nn">appengine_django.models</span> <span class="kn">import</span> <span class="n">BaseModel</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">google.appengine.ext</span> <span class="kn">import</span> <span class="n">db</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Poll</span><span class="p">(</span><span class="n">BaseModel</span><span class="p">):</span>
</span><span class='line'>  <span class="n">question</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span>
</span><span class='line'>  <span class="n">pub_date</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">DateTimeProperty</span><span class="p">(</span><span class="s">&#39;date published&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Choice</span><span class="p">(</span><span class="n">BaseModel</span><span class="p">):</span>
</span><span class='line'>  <span class="n">poll</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">ReferenceProperty</span><span class="p">(</span><span class="n">Poll</span><span class="p">)</span>
</span><span class='line'>  <span class="n">choice</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">StringProperty</span><span class="p">()</span>
</span><span class='line'>  <span class="n">votes</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">IntegerProperty</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>Edit views.py (notice that order_by() from the Django tutorial is just order() here)</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Context</span><span class="p">,</span> <span class="n">loader</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">polls.models</span> <span class="kn">import</span> <span class="n">Poll</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
</span><span class='line'>  <span class="n">latest_poll_list</span> <span class="o">=</span> <span class="n">Poll</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="s">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
</span><span class='line'>  <span class="n">t</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">&#39;polls/index.html&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">({</span>
</span><span class='line'>    <span class="s">&#39;latest_poll_list&#39;</span><span class="p">:</span> <span class="n">latest_poll_list</span><span class="p">,</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">c</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>cd ..</li>
<li>Edit urls.py and add to urlpatterns
<code>(r'^polls/', 'polls.views.index'),</code></li>
<li>mkdir -p templates/polls</li>
<li>cd templates/polls</li>
<li>Create index.html</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='irb'><span class='line'><span class="go"></span>
</span><span class='line'><span class="go">  &lt;p&gt;No polls are available.&lt;/p&gt;</span>
</span><span class='line'><span class="go"></span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>cd ../..</li>
<li>Edit settings.py and add to INSTALLED_APPS
&lsquo;polls&rsquo;,</li>
<li>Now you can run the dev server again:
<code>python manage.py runserver</code></li>
<li>And go to:
<a href="http://localhost:8000/polls/">http://localhost:8000/polls/</a></li>
<li>You should see the message &ldquo;No polls are available.&rdquo;</li>
</ol>


<h2>Adding some data</h2>

<p>You can go through the rest of the Django Tutorial to fill out the rest of the views. One last thing to know is the admin site. To view it, go to:</p>

<p><a href="http://localhost:8000/_ah/admin">http://localhost:8000/_ah/admin</a></p>

<p>Notice that the Datastore Viewer is empty &ndash; it doesn&rsquo;t even know about our Poll or Choice Models. Don&rsquo;t panic. Go back to your terminal, and terminate the dev server. Now run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>python manage.py shell
</span></code></pre></td></tr></table></div></figure>


<p>This brings up a special python shell with the Django environment set up for you. Now you can run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>&gt;&gt;&gt; from polls.models import Poll, Choice
</span><span class='line'>&gt;&gt;&gt; import datetime
</span><span class='line'>&gt;&gt;&gt; <span class="nv">p</span> <span class="o">=</span> Poll<span class="o">(</span><span class="nv">question</span><span class="o">=</span><span class="s2">&quot;What&#39;s up?&quot;</span>, <span class="nv">pub_date</span><span class="o">=</span>datetime.datetime.now<span class="o">())</span>
</span><span class='line'>&gt;&gt;&gt; p.save<span class="o">()</span>
</span></code></pre></td></tr></table></div></figure>


<p>You have just created a new Poll. To end the shell, press Ctrl-D.</p>

<p>If you start the dev server again (or if you never stopped it in the first place), you should be able to go to:</p>

<p><a href="http://localhost:8000/polls/">http://localhost:8000/polls/</a></p>

<p>to see you new Poll, and go to the admin site:</p>

<p><a href="http://localhost:8000/_ah/admin/datastore">http://localhost:8000/_ah/admin/datastore</a></p>

<p>to see and create new Polls</p>

<p>Easy huh? :&ndash;)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Vegemite Beer Bread]]></title>
    <link href="http://blog.pas.net.au/blog/2009/02/03/vegemite-beer-bread/"/>
    <updated>2009-02-03T15:43:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/02/03/vegemite-beer-bread</id>
    <content type="html"><![CDATA[<p>I should have posted this on Australia Day (when we made it), but I haven&rsquo;t got around to it until now.</p>

<p>Aussie Vegemite Beer Bread</p>

<h2>Ingredients:</h2>

<ul>
<li>3 cups of self-rising (raising?) flour</li>
<li>1 beer (375mL can or 12oz bottle)</li>
<li>1 big knife-load of Vegemite</li>
<li>Grated Parmesan cheese</li>
<li>Left over butter</li>
</ul>


<h2>Method:</h2>

<ol>
<li>Preheat the oven to 375°F (190°C)</li>
<li>Lightly grease a small bread tin (about 9 x 5 x 3 inches) with the butter</li>
<li>Get a big mixing bowl, tip in all the flour, add the beer and mix it up. We have found a whisk useless, but a spatula quite good</li>
<li>If you like parmesan cheese as much as us, add as much grated parmesan to the mix as you wish</li>
<li>Add the mix to the bread tin.</li>
<li>Load up a knife with vegemite and run it through the mix &ndash; the vegemite will come of the knife and marble through the dough</li>
<li>Bake for 60 minutes</li>
<li>If you didn&rsquo;t get your cheese fill, at the 40 minute mark, take the bread tin out, and sprinkle grated cheese on top of the bread</li>
<li>After 60 minutes, you should be able to put a skewer into the bread and have it come out clean. Let the bread cool a little, cut and eat as fast as possible :&ndash;)</li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[First Post – rant]]></title>
    <link href="http://blog.pas.net.au/blog/2009/01/21/first-post-rant/"/>
    <updated>2009-01-21T17:55:00-08:00</updated>
    <id>http://blog.pas.net.au/blog/2009/01/21/first-post-rant</id>
    <content type="html"><![CDATA[<p>Well, this is my first blog post, so what should I write about? Why not have a little rant about something I discovered recently (at least on Ubuntu).</p>

<p><code>sudo</code> depends on DNS</p>

<p>WTF? Why does something like local privilege escalation, which does not leave the machine I am on, have anything to do with networking. Further, why the hell should a network configuration issue stop sudo from working. And even further still, why would Ubuntu (which as part of the normal install process does not set a root password) allow something as essential and necessary as sudo to be depended on a functioning network configuration?
Amazingly though, a Google search showed this is a known issue. I really like the title of this bug: <a href="https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/185209">Manually Configuring Network Causes Massive, Unreversable, Failure</a>.
I believe this will be the first of many rants this blog will see, so readers (yes all 1 of you&hellip; thanks honey), check back soon. I&rsquo;ll try and keep it G rated, but no guarantees :&ndash;)</p>
]]></content>
  </entry>
  
</feed>
