Logiciel Libre

January 29, 2007

Bootstrapping with Bash

Filed under: Default — Tags: — adam @ 6:58 am CST

I created a Xen guest (virtual machine) containing a minimal Fedora Core 6 install. The install was so minimal, in fact, that I didn’t have many of my usual tools and toys. This presented a problem when I tried to use yum to upgrade the system: yum wasn’t there.

I thought of a few ways to install missing pieces:

  1. mount virtual disk while guest is powered down, copy in files
  2. boot the VM to a rescue disk containing needed files
  3. use sockets to transfer in some files

Favoring programming over sysadmin stuff, I opted to use sockets to manually transfer a tarball of some RPMs into the guest. Bash, Python, and Gawk were all available. I found solutions for the first two, but I just can’t bring myself to learn/use Gawk.

The Bash version is interesting; Bash supports some arbitrary TCP and UDP socket operations, but it appears it can’t set up listeners. I was able to use netcat to listen on the host, the write the data as soon as the guest connected. If netcat were available on the guest, I wouldn’t have to do this funky Bash socket stuff, but it was still fun to learn.

Host:

nc -vnl 3000 < /tmp/pkgs.tar

Guest:

# open read/write socket connection to host using file descriptor 5
exec 5<>/dev/tcp/192.168.1.50/3000

# receive tarball
cat <&5 > /tmp/pkgs.tar

# inform host we're done receiving
echo -e "I'm done, thanks!\n" >&5

# close file descriptor
exec 5>&-
exec 5<&-

A minimal version of the above only really needs the first ‘exec’ and ‘cat’ lines. Handy in case you can’t cut and paste it, say if your access to the guest is a VNC client rather than a serial console.

With Python it’s possible to set up a true listener, and just netcat over files. Here’s the host code:

nc -vn 192.168.1.51 3000 < /tmp/pkgs.tar

And the guest:

#!/usr/bin/python
import socket
HOST = ''
PORT = 3000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
fh = open('/tmp/pkgs.tar', 'w')
while True:
    data = conn.recv(1024)
    if not data: break
    fh.write(data)
conn.close()

No Comments »

No comments yet.

RSS feed for comments on this post.

Leave a comment

Powered by WordPress