SkyForge: Creating Debian root filesystems in a Dockerfile-style

For a handful of projects work and hobby alike I use Debian. However, when you deal with embedded systems (e.g. ARM SoC) you normally don’t have the installer CD or even the disk drive. You end up creating a filesystem, compiling the kernel. Well, pretty much the usual way it goes.

The process can be somehow lengthy if done by hand using debootstrap and multistrap and especially mind-blowing if you are a total newbie. (Alas, I’m already no n00b here. Getting older, heh)
The worst part of it is that you not only need to create a root filesystem for debian, but set it up in a more or less sane way, e.g. set the default password, ssh keys… The usual thing.

In the Big Enterprise ™ we can see tools like vagrant creating us a base box in the VM and chef or puppet actually setting the system up. While we can use, say chef or chef-solo on an armhf board (why not?) we still have to make sure we have some base image it will set things up on, right?

While actually using chef for an arm board is somewhat a task for future work (And I still have to better master chef. Really), creating a base root filesystem is something I’d like to focus on in this note. After experimenting a lot with multistrap, debootstrap and scripts that make use of both; After several failed iterations (nothing comes easy in this life, deal with it) I came up with a tool to aid debian base rootfs creation using a simple Dockerfile-inspired syntax.

Basically, it works like this:

  • You create your multistrap.conf, perhaps in a nested way
  • You create a small file called Skyfile
  • You use the skyforge tool to actually build the root filesystem

A typical SkyFile may look like this:

#The basic multistrap stuff
MULTISTRAP armel debian-devel.conf
RUN DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C /var/lib/dpkg/info/dash.preinst install
RUN DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C dpkg --configure -a
 
#Install a proper resolv.conf from host
INSTALL /etc/resolv.conf
 
#Install my GPG Key
APT_KEY http://acme.inc/repo/repository.gpg
 
#Basic system setup
PASSWD 12345678
HOSTNAME shade
LOCALE en_US.UTF8 UTF8
IFACE_STATIC eth0 192.168.20.9 255.255.255.0 192.168.20.1 8.8.8.8
#IFACE_DHCP eth0
 
#Enable root access over ssh
RUN sed 's/PermitRootLogin without-password/PermitRootLogin yes/' -i etc/ssh/sshd_config
 
REMOVE /etc/resolv.conf
 
STORE rootfs.tgz

Next you run

skyforge build

And end up with a nice tarball of your filesystem. For a list of available commands you can dive into docs here.

So, another shell script, you say. What’s the catch? And the catch is that the skyforge script keeps snapshots of each and every command you run. When you edit something in your Skyfile and trigger the build Skyforge will not rerun everything from the very scratch. It will revert to the very place where the previous skyfile version and the current version diverted and execute only the new steps. Pretty much the same way docker works.

This is cool because:

  • You avoid overcaffeinating yourself waiting while apt downloads all the packages for the thousandth time via the slow corporate proxy.
  • You avoid raping debian’s mirror servers with useless load each time you rebuild
  • Can develop a complex Skyfile very fast

Under the hood SkyForge uses either OverlayFS for snapshots or plain tarballs (if explicitly enabled before the actual build). And with OverlayFS it’s really fast.

You can grab SkyForge and use it for your fun and profit right here:

https://github.com/nekromant/skyforge

Leave a Reply