Ubuntu 8.04 LTS Upgrade (End of Life)

Instructions for upgrading from Ubuntu 8.04 are not hard to come by. 8.04 is one of the Long Term Support versions of Ubuntu and so is a favourite amongst the professional community.

The advantage, for me, of LTS versions is that I only have to touch them once every five years. When I leave it longer though, I end up writing a post like this to help remind myself that it was a pain to do, albeit minor and interesting.

In reading Ubuntu Fridge | Ubuntu 8.04 (Hardy Heron) End of Life reached on May 9, 2013, I now see the line,

it will be archived to old-releases.ubuntu.com

. That url became a friend of mine, but I didn’t RTFM very well.

I was following the instuctions at: LucidUpgrades – Community Help Wiki under the section for 8.04 Servers – a pretty simple procedure by most accounts. Until…

Because the 8.04 files/repositories had been archived by the time I came to update, apt was well hampered in its ability to do anything useful. So, my first internet search yielded the following helpful article: Ubuntu 8.04 alternative repositories – fix the “Failed to fetch” error. I didn’t realise that ‘karmic’ was the codename for 9.04, so I upgraded via that version. Had I known what I now know, I’d have replaced that with ‘lucid’, the codename for 10.04.

In fact, I’m not sure if I ran a sudo apt-get update before I started loading on later versions. I think I should have!

Then, when running sudo apt-get upgrade or sudo apt-get dist-upgrade, I encountered another issue. This thread explains what happened quite well: [SOLVED] E: Could not perform immediate configuration on ‘util-linux’.Please see man 5 apt. Ultimately, upgrading to lucid required upstart-job, it has to be manually installed…

Well, once I upgraded once, the rest was fairly smooth. I hopped, skipped and jumped all the way to Ubuntu 14.04 LTS, and, the system still stands today, weeks later. Hurrah!

Some dayLight Relief

I’ve heard it said that developers who live in countries that are in the GMT timezone are terrible at dealing with timezones and daylight saving time correctly. Being Irish, I fall into this generalisation. While I’m sure there are a good number of developers in this stripe of the world that can do good work when it comes to time and timezones, I’d have to hold my guilty hands up and admit to not being great in this area of coding.

In my work on the AudioFile project, I decided to have the core system UTC always so that things were kept as simple as possible for me, and other developers who would integrate with the system – I think that was a good clear decision, but it was a get out for me.

Yesterday, while writing a simple CLI client for the AudioFile system, I wanted to make it more simple to use, so decided to find out how to convert a local time (GMT or IST) into a universal time (UTC). After much playing around, and references to the following material, I hacked it together:

Below is the code I came up with, but it’s worth highlighting the three standout lessons I learnt:

  1. The TZ environment variable is used by date to determine it’s output.
  2. date can accept TZ=... as the first part of a date argument to be parsed if you know that the string refers to a time in another zone.
  3. Given a date, time and a correctly configured system (in terms of local timezone), date will correctly indicate whether or not DST is active and can output the numeric offset in hours/minutes.

The following makes use of these three points – if there’s a better way to do it using simple standard tools, I’d love to know about it – get in touch!

function get_utc() {

    TZ=UTC date -d "$(date -d "$dait $time" --iso-8601=seconds)" \
        +"%Y-%m-%d %H:%M"

The following tests prove that it works as expected:

echo "2015-07-01 22:45" == "$(get_utc 2015-07-01 23:45)"
test "2015-07-01 22:45" == "$(get_utc 2015-07-01 23:45)" \
    && echo success || echo fail

echo "2015-02-01 23:45" == "$(get_utc 2015-02-01 23:45)"
test "2015-02-01 23:45" == "$(get_utc 2015-02-01 23:45)" \
    && echo success || echo fail

echo "2015-06-30 23:45" == "$(get_utc 2015-07-01 00:45)"
test "2015-06-30 23:45" == "$(get_utc 2015-07-01 00:45)" \
    && echo success || echo fail

HC-SR04 Ultrasonic Distance Measuring on Arduino

After Monday night’s success, I was hyped up about getting another package in the post. It came on Tuesday and consisted of three HC-SR04 sensors. These are the ultrasonic version of distance measuring sensors I have ordered – there is an infra-red one winging it’s way to me also.

Truth be told, I had such good success blindly following a step by step in the past that there was no thought given to my other approach – think, learn, build from scratch, encounter difficulty, repeat!

I followed one of the first guides I found, and it seemed to do the trick too. Instructables was my knight in shining armour, and with the change of a couple of pins, I had it working well and writing to the Arduino serial console.

Again, just in case our friends at Instructables take the guide offline, I have provided the code on Github.

DHT22 / AM2302 and Arduino

The first package arrived on Monday. Two neat AM2302 sensors.

First things first, grab my Nano and install the Arduino IDE on my Raspberry Pi.

I had been looking at the Arduino Build Process and was thinking that I might install the minimum possible to get builds going using vim as my main editor. I may still do that, but the IDE (slow and all as it is running on the Pi) has everything I need and was easy to get going. So:

sudo apt-get install arduino

That was about the hardest element of task 1.

I followed the good instructions at >a href=”https://learn.adafruit.com/dht”>The Adafruit Learning Centre. There it instructs you to download a zip of the DHT Sensor Library. Included therein is example code for using the library. All seems straight forward enough.

In case Adafruit decide to remove these resources, I’ve forked the library on my Github page.

I had this done in about two hours – that includes retrieving my Arduino Nano, hookup, installing the Arduino IDE and grabbing the necessary code.

Longer than a Weekend Project

My original plan was to build an Arduino based oil tank level sensor, but all my plans grow legs. Now the Arduino will also be battery powered, measure the temperature and pressure, monitor the battery level, transmit it’s measurements via 433 MHz radio to a Raspberry Pi and consume as little power as possible – so I have to change the batteries less often.

I have a tendency to get lost in projects like this. I forget about the end goal and take my time never getting there. To help avoid falling into old habbits, I’m going to speed date the components of the system giving myself a maximum of two hours with each before moving on to the next part. Hopefully we’ll see some part of the project come near to completion quite quickly.

Well, the parts are ordered:

  • Bosch BMP180 Digital Barometric Pressure Sensor Board Module
  • Generic 433 MHz Tx/Rx Pair
  • HC-SR04 Ultrasonic Sensor Distance Measuring Module

Here are some resources I’ve been reading:

Here’s the fruit of my labour so far…

System level diagram of circuit to be mounted on an exterior oil tank.

System level diagram of circuit to be mounted on an exterior oil tank.

Next instalment will be after the goods arrive.

Patching and Diff

I’ll be using git to keep track of system configuration changes in my efforts to build a concise kickstart to be redeployed again at a later stage to build another cluster.

git uses diff -u rather than plain diff. I generally like this, but the default of showing three lines of context gets in the way at times.

For example, I’ll want to incorporate the network bonding setup into the kickstart file, but, by default the installation will include the MAC address for each interface in the ifcfg-ethX files. If my patch includes a MAC addresse in the context, the patch will fail to apply. Not good.

To overcome this, when generating the patch use:

git diff -U0 <file>

This produces 0 lines of context thus eradicating the problem.

Fedora 20: Full Network Installation

I’ve got a new (old) PC from work that I want to put Fedora 20 onto. In the distant past, I would burn the full set of installation CDs / DVD. More recently, I’d burn the NetInst CD and do a network install of the rest from a mounted DVD ISO on another machine on my LAN. This time, I’m going to download the bare minimum necessary to PXE boot the target machine, and do the rest over the net. I’ll do a minimal install first, and perhaps a more full featured graphical desktop install afterwards.

Step 1: Research

From: http://en.wikipedia.org/wiki/Preboot_Execution_Environment, we learn that the process is roughly:

  • Client send DHCPDISCOVER
  • DHCP server(s) send DHCPOFFERs
  • The PXE client picks an extended DHCPOFFER
  • Something about a DHCP Proxy Server???
  • The client downloads the network bootstrap program (NBP)
  • The hard part is over… Or so he thought!

Step 2: Put it into practice

I’m going to use m0n0wall on a virtual machine within my existing Fedora installation. I have a bridge set up, so for the purposes of this article, you can imagine it’s just another machine on the LAN. m0n0wall will provide me with a DHCP server with the extended DHCPOFFER – basically a ‘next server’ attribute which tells the PXE client where to download, via TFTP, the next stage from.

I have tftpd installed as a xinetd service on my host Fedora machine. That TFTP site hosts the guts of a netinstall CD. The target machince boots SYSLINUX. I modified the boot menu to save myself typing in the path to the Fedora installation mirror.

If you, like me, are using m0n0wall, skip the DHCP specific instructions in the following documentation: Fedora Docs: PXE Boot Configuration.

My tftp directory, /var/lib/tftpboot/, looks like this:

# ls -lR
total 4
drwxr-xr-x. 3 root root 4096 Mar 15 23:24 pxelinux

total 39032
-rw-r--r--. 1 root root 34631660 Mar 15 23:24 initrd.img
-rw-r--r--. 1 root root    26460 Mar 15 22:49 pxelinux.0
drwxr-xr-x. 2 root root     4096 Mar 16 00:45 pxelinux.cfg
-rw-r--r--. 1 root root      171 Mar 15 23:13 splash.png
-rw-r--r--. 1 root root   155792 Mar 15 23:14 vesamenu.c32
-rwxr-xr-x. 1 root root  5139320 Mar 15 23:24 vmlinuz

total 4
-rw-r--r--. 1 root root 619 Mar 16 00:45 default

The default file is the only one that needed to be modified. I simply added:

repo=http://nearest.mirror.com/path/to/Fedora/20/x86_64/os/ vnc

to the append line. The vnc allows you to connect in via VNC (provided you know the IP address, which you should if you keep an eye on m0n0wall), and step through the installation remotely.

Stage 2 is just a hosted copy of the installation DVD. You can download and share this via NFS, FTP or HTTP if you’re going to do multiple installations. The exercise here is to install across the internet, so I went with my nearest HTTP mirror host.

The Fedora Docs: Configuring Installation Source page is a good reference if you are doing anything differently to me in this article.

Believe it or not, that was it! The DHCP Proxy Server never resurfaced to bite me. I think it’s only required if your DHCP server is on a different subnet to the target machine – not the case for me on this occasion.