Project: Automated offsite backups for an NSLU2 – part 8

12 November 2006

Previously in this series: Part 1, Part 2, Part 3, Part 4, Part 5, Part 6, Part 7.

I’ve discovered that in order to get automated offsite backups from my NSLU2 to Amazon S3, I have to get it to run Ruby so that it can run s3sync. Installing Ruby required the slug’s firmware to be upgraded to a new version of Linux, called Unslung, so I did that – and I also installed s3sync on a Ubuntu machine as a dry run. Both of these worked out OK, so the next step was to get the Ruby language itself running under the Unslung firmware – and importantly, to make sure that Ruby had the OpenSSL package installed; the latter had proven non-obvious under regular Linux, so I was expecting problems on Unslung, which is, after all, a cut-down version of the operating system.

The first thing was to work out how to install new packages on an Unslung system in the first place. The last section of the installation README gives a link to this page, which is a good starting point. Going from the instructions there, I made sure that the gateway and DNS server were correctly set up on the slug’s web admin pages, then ran ipkg update from a telnet window logged into the unslung slug. This seemed to work just fine – appropriate messages about downloading, inflating and updating things went by. The next recommended steps were to run ipkg install unslung-feeds, and then ipkg update again. I’m sure there is a very good reason for this, but I’ve no idea what it is – for now, I just followed the instructions, bleating occasionally. Nothing obviously bad happened, and it looked like it managed to install some further lists of software.

The next step was to run ipkg list to see what I could now install. And wow, there were a lot of packages. Most importantly for this project, there was the ruby one, so…

# ipkg install ruby
Installing ruby (1.8.5-1) to root...
Downloading http://ipkg.nslu2-linux.org/feeds/unslung/cross/ruby_1.8.5-1_armeb.ipk
Configuring ruby
# 

That looked promising – but…

# ruby --version
ruby: No such file or directory

Hmmm. So, how to find out where it’s been installed? Well, ipkg --help is apparently an unrecognised option, but when I tried it, it forced a printout of the options for ipkg anyway. This made it clear that I should run ipkg files ruby to find out where everything was, and from there I found out that it had installed the binary in /opt/bin/ – which is not unreasonable.

# /opt/bin/ruby --version
ruby 1.8.5 (2006-08-25) [armv5b-linux]

Looking good! Come to thing of it, that’s a more recent version of Ruby than the default for Ubuntu Linux :-)

Now, as I said earlier in this post, one worry I had was the difficulty of installing the Ruby OpenSSL libraries, which are a requirement for s3sync. I had noticed something relevant-looking as the list of files for the package went past earlier, so decided to double-check:

# ls /opt/lib/ruby/1.8/openssl/
bn.rb           buffering.rb    cipher.rb       digest.rb       ssl.rb
x509.rb

This was pretty promising – not a sure thing, but it looked good. So how to be sure – or, at least reasonably sure – that nothing was missing? Well, going back to the error message I got when s3sync failed on my Ubuntu machine (which, at the time, lacked an OpenSSL library for Ruby) I noted that I’d had the error

./S3.rb:25:in `require': no such file to load -- openssl (LoadError)

So, it sounded to me like the “require” command in Ruby loads libraries – perhaps somewhat like import in Python or Java, or using in C#. A quick grep through the s3sync source seemed to confirm this – the first few non-comment lines of S3.rb ran:

require 'base64'
require 'cgi'

…and then, shortly after, there was:

require 'openssl'

So, I could reasonably comfortably posit that if a Ruby script containing just that last line would run happily on the slug, s3sync should be able to run. On that basis, I created such a file and ran it:

# cd /tmp
# ls
# cat > test.rb
require 'openssl'
# /opt/bin/ruby test.rb
/opt/lib/ruby/1.8/armv5b-linux/openssl.so: libssl.so.0.9.7: cannot open shared object file: No such file or directory - /opt/lib/ruby/1.8/armv5b-linux/openssl.so (LoadError)
        from /opt/lib/ruby/1.8/openssl.rb:17
        from test.rb:1:in `require'
        from test.rb:1
#

Now, from this I suspected that the Ruby system had its own SSL stuff installed, and it was just the operating system’s shared library that was missing. In retrospect, this was not obvious – after all, the file that was missing was in /opt/lib/ruby. But, without noticing that, I decided to try installing any non-Ruby OpenSSL package that was out there:

# ipkg list | grep ssl
alac-decoder - 0.1.0-2 - A decoder for the apple lossless file format
flac - 1.1.2-4 - FLAC is a free lossless audio codec.  This package contains the codec libraries and the command-line tools flac and metaflac.
openssl - 0.9.7d-5 - Openssl provides the ssl implementation in libraries libcrypto and libssl, and is needed by many other applications and librari
perl-io-socket-ssl - 0.999-1 - IO-Socket-SSL - Nearly transparent SSL encapsulation for IO::Socket::INET
perl-net-ssleay - 1.30-1 - Net_SSLeay - Perl extension for using OpenSSL
wget-ssl - 1.10.2-3 - A network utility to retrieve files from the Web
# ipkg install openssl
Installing openssl (0.9.7d-5) to root...
Downloading http://ipkg.nslu2-linux.org/feeds/unslung/cross/openssl_0.9.7d-5_armeb.ipk
Configuring openssl
#

…and then tried running the script again:

# /opt/bin/ruby test.rb
#

Which looked perfect. Perhaps someone can tell me how that all worked… or perhaps I’ll work it out myself later. But for now, onward! The next step was clearly to copy over s3sync, and to try it out on a simple directory. And that’s one for tomorrow.

Next: Running s3sync on an Unslung NSLU2.