Just another blog

Innovate 09

Posted by PAS on 24 September 2009

If anyone is interested in going to the PayPal X (Innovate 09) conference, I have come across is discount. A special rate of $149 (50% off the price) if you enter promotion/coupon code: PayPalHR


Posted in Blog | Tagged: , , | Comments Off on Innovate 09

Dependency Nightmare for Tomcat on Debian

Posted by PAS on 18 August 2009

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:

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

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.

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

For shame!

I’ll stick to downloading from and

Posted in Blog | Tagged: , , , , , , | 2 Comments »

Rackspace Cloud API PHP Library

Posted by PAS on 13 August 2009

I am pleased to annouce my very first open source project hosted at github. The project, called Rackspace Cloud PHP Library is a simple, single PHP file to easily make Cloud Server API 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.

So what was my motivation for this?

Well the Rackspace Cloud Management Console is severly 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 – 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) “cluster” of Tomcat servers. I plan on using keepalived to do the IP switching, and Apache with mod_proxy_balancer and mod_proxy_ajp to talk to multiple Tomcat servers. Without reading the poorly written API documention and learning that I could create a shared IP group, I would not have known this was possible.

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.

Posted in Blog | Tagged: , , , , | 6 Comments »

Download Chrome OS now – it’s called cl33n

Posted by PAS on 8 July 2009

For some strange reason, Chrome OS is getting a lot of press. Is it a slow news day?

They say that it is direct competition to Microsoft, that it makes Linux less relevant… are they serious? Chrome OS is a non-announcement. There is a project that has existed for over 2 years called “cl33n“. From the creator:

Chrome OS is “Google Chrome running within a new windowing system on top of a Linux kernel.”
cl33n is “Mozilla Firefox running in a little-used windowing system on top of a Linux kernel.”

This “OS” 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?

What I am trying to say, is that Chrome OS is nothing new. Cl33n is not alone in this space either – other project like Webconverger share my view.

While on the subject of Google’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 “Server error” dialogs?

Posted in Blog | Tagged: , , , | Comments Off on Download Chrome OS now – it’s called cl33n

Fighting with SELinux and Nagios

Posted by PAS on 2 May 2009

I can’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.

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:

Error: Could not stat() command file ‘/usr/local/nagios/var/rw/nagios.cmd’!
The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.
An error occurred while attempting to commit your command for processing.
Return from whence you came

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.

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:

$ /usr/sbin/getenforce

If you got “Permissive” or “Disabled”, then this post is not for you. To see SELinux’s side of things, check out /var/log/messages:

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

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

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

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

$ sealert -l 1ffc2533-42b5-4e04-b7ab-a81bb7d02040

SELinux is preventing ping (ping_t) “read write” to
/usr/local/nagios/var/spool/checkresults/checkrXH96b (usr_t).

Detailed Description:

… (removed from post)

Raw Audit Messages 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 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)

That raw audit message is GOLD! 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 chron I have heard is a temporary fix. The solution is copying that raw audit message into an empty file and running audit2allow to create a policy:

$ cat > /tmp/tmp-nagiosping 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 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)
* Ctrl-D *

$ audit2allow -M NagiosPing < /tmp/tmp-nagiosping

******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i NagiosPing.pp

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:

$ semodule -i NagiosPing.pp

If your setup was like mine, SELinux was actually preventing 3 different actions, needing 3 different policies. HA! That is easy now – just repeat the steps until Nagios is doing your bidding.

Posted in Blog | Tagged: , , , , , | Comments Off on Fighting with SELinux and Nagios

Skills-based Resumes

Posted by PAS on 11 March 2009

I have recently been updating and freshening up my resume, and thought I would do something different… 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 – 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.

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.

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

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:

  • Technical Skills: After your object at the top (if you want to display passion), make a clear section describing your technical skills – languages, databases, environments.
  • Summary: 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.
  • Accomplishments: 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).
  • Your Role: Let the reader know what your role and responsibilities were at each position you have held

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).

Perhaps resumes written for machines is a good thing after all?

Posted in Blog | Tagged: , , , , | Comments Off on Skills-based Resumes

Unlock your T-Mobile G1

Posted by PAS on 23 February 2009

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:

  1. Call T-Mobile on 1-877-453-1304 from another phone (not your G1). I got that number from their Contact page
  2. Its the standard voice prompt thing, so say English, enter your G1’s phone number, then when they ask what you want help with, say the magic word “Agent”
  3. Then they ask what you would like to talk about, and say “SIM Unlock Request”
  4. 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.
  5. They will ask you for you phone’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:
    1. on the side of the box your phone came in,
    2. on the G1 itself under Settings -> About phone -> Status, or
    3. by dialing *#06#
  6. Give them your email address, and within 14-days, you will get an email from T-Mobile with your unlock code.
  7. To unlock the phone, power it off, insert a non-t-mobile SIM card, and power it back on
  8. At the prompt, enter the unlock code from the email and you’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.

Posted in Blog | Tagged: , , | 3 Comments »

Django and Google App Engine Tutorial

Posted by PAS on 17 February 2009

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:

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.

Note: This tutorial is written for Linux. Mac/Windows users will have to translate :-)


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.

  1. Download the latest Django and untar the file (in this case, it is 1.0.2)
  2. cd Django-1.0.2-final
  3. Create the zip file, but without the admin section since App Enging supplies it’s own
    zip -r ~/ django -x ‘django/contrib/admin*’

Get the Helper

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).

  1. cd ~
  2. svn export gae-django-tutorial
  3. cd gae-django-tutorial
  4. mv ~/ .

Setup App Engine

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:

  1. cd gae-django-tutorial
  2. ln -s /path/to/google_appengine .google_appengine

Start the development server

Django has a different way of running the development server. Instead of using to start the dev server, do the following:

  1. python runserver

If everything is running correctly, you should see something like:

INFO:root:Checking for updates to the SDK.
INFO:root:The SDK is up to date.
INFO:root:Running application google-app-engine-django on port 8000: http://localhost:8000

However, if you are like me and saw an error like the following:

ImportError: No module named antlr3

Then you will need to install the antlr3 python module. Luckily this is easy.

  1. Go to and download the latest zip
  2. unzip
  3. cd antlr_python_runtime-3.1
  4. sudo python install

Lets see the site! When you go to http://localhost:8000/ you should see a page saying “It worked! Congratulations on your first Django-powered page.”
Pretty (un)impressive huh?

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.

  1. python startapp polls
  2. cd polls
  3. Edit
    from appengine_django.models import BaseModel
    from google.appengine.ext import db
    class Poll(BaseModel):
      question = db.StringProperty()
      pub_date = db.DateTimeProperty('date published')
    class Choice(BaseModel):
      poll = db.ReferenceProperty(Poll)
      choice = db.StringProperty()
      votes = db.IntegerProperty()
  4. Edit (notice that order_by() from the Django tutorial is just order() here)
    from django.template import Context, loader
    from polls.models import Poll
    from django.http import HttpResponse
    def index(request):
      latest_poll_list = Poll.objects.all().order('-pub_date')[:5]
      t = loader.get_template('polls/index.html')
      c = Context({
        'latest_poll_list': latest_poll_list,
      return HttpResponse(t.render(c))
  5. cd ..
  6. Edit and add to urlpatterns
    (r’^polls/’, ‘polls.views.index’),
  7. mkdir -p templates/polls
  8. cd templates/polls
  9. Create index.html
    {% if latest_poll_list %}
    {% for poll in latest_poll_list %}
      <li>{{ poll.question }}</li>
    {% endfor %}
    {% else %}
      <p>No polls are available.</p>
    {% endif %}
  10. cd ../..
  11. Edit and add to INSTALLED_APPS
  12. Now you can run the dev server again:
    python runserver
  13. And go to:
  14. You should see the message “No polls are available.”

Adding some data

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:

  1. http://localhost:8000/_ah/admin

Notice that the Datastore Viewer is empty – it doesn’t even know about our Poll or Choice Models. Don’t panic. Go back to your terminal, and terminate the dev server. Now run:

  1. python shell

This brings up a special python shell with the Django environment set up for you. Now you can run:
>>> from polls.models import Poll, Choice
>>> import datetime
>>> p = Poll(question=”What’s up?”,

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

If you start the dev server again (or if you never stopped it in the first place), you should be able to go to:
to see you new Poll, and go to the admin site:
to see and create new Polls

Easy huh? :-)

Posted in Blog | Tagged: , , , , , , | 4 Comments »

Vegemite Beer Bread

Posted by PAS on 3 February 2009

I should have posted this on Australia Day (when we made it), but I haven’t got around to it until now.

Aussie Vegemite Beer Bread


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


  1. Preheat the oven to 375°F (190°C)
  2. Lightly grease a small bread tin (about 9 x 5 x 3 inches) with the butter
  3. 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
  4. If you like parmesan cheese as much as us, add as much grated parmesan to the mix as you wish
  5. Add the mix to the bread tin.
  6. Load up a knife with vegemite and run it through the mix – the vegemite will come of the knife and marble through the dough
  7. Bake for 60 minutes
  8. If you didn’t get your cheese fill, at the 40 minute mark, take the bread tin out, and sprinkle grated cheese on top of the bread
  9. 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 :-)

Posted in Blog | Tagged: , , | Comments Off on Vegemite Beer Bread

First Post – rant

Posted by PAS on 21 January 2009

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).

`sudo` depends on DNS
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: “Manually Configuring Network Causes Massive, Unreversable, Failure“.
I believe this will be the first of many rants this blog will see, so readers (yes all 1 of you… thanks honey), check back soon. I’ll try and keep it G rated, but no guarantees :-)

Posted in Blog | Tagged: , , | Comments Off on First Post – rant