Building your own runtime bundle
Applications started through the hadean run command are always run in a sandboxed environment. By default, the user application is run in an environment where you have a minimal set of Ubuntu 20.04 packages. This enviornment is specified by what we call a runtime bundle, which can be found in ~/.hadean/sdk/bin/hadeanos/runtime-bundle.tar.xz. In this guide we will be looking at creating a new runtime environment, for those cases where the build environment is not compatible with the default runtime environment, or if we want to have extra packages installed by default.
You can also modify our default runtime bundles if you just need a few more packages! Just follow the "Preparing the runtime environment" section.

Downloading a base image

In this guide we will be looking at creating a CentOS 8 Stream runtime bundle. The CentOS image comes in a qcow2 format which is not supported by the Hadean Platform. Instead we need to generate a tarball that contains the root of our filesystem. We also want to modify the image to include our own packages. There are multiple ways in which this can be done, and in this guide we will be looking at one way of doing it.
In our case, CentOS8 Stream comes as a qcow2, but for other OSes (such as Ubuntu) you can download the sysroot directly, which means you can skip the "Converting a qcow2 image" section.

Converting a qcow2 image to a tarball

First, let's make a copy of the filesystem. Later on, we can use something like nsjail to install extra packages into the image.
For this step we will need:
  • wget
  • libguestfs-tools
1
# Download the image
2
wget https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20200113.0.x86_64.qcow2
3
4
# Mount the qcow2 as a RO filesystem
5
mkdir centos-image
6
guestmount --format=qcow2 -a ./CentOS-Stream-GenericCloud-8-20200113.0.x86_64.qcow2 -i --ro ./centos-image
7
8
# Make a copy, which will take some time...
9
mkdir -p centos-stream-8
10
pushd ./centos-image
11
cp -a -R * ../centos-stream-8/
12
popd
13
chmod -R u+w ./centos-stream-8/
14
15
# Unmount the `qcow2` image
16
guestunmount ./centos-image
17
18
# You can also remove this directory, but make sure the directory was unmounted properly
19
rm -r ./centos-image
20
21
# we don't need the `qcow2` image anymore
22
rm CentOS-Stream-GenericCloud-8-20200113.0.x86_64.qcow2
Copied!
You can also remove the qcow2 image if you wish to do so.

Preparing the runtime environment

For this step we will need:
  • nsjail
Now that we have the root of the system, we need to add more things into it.
1
pushd ./centos-stream-8/
2
3
# You can keep the old resolv.conf if you prefer
4
rm etc/resolv.conf
5
echo nameserver 8.8.8.8 > etc/resolv.conf
6
echo nameserver 1.1.1.1 >> etc/resolv.conf
7
8
# This is Hadean specific, and necessary for now
9
mkdir -p \
10
hadean/{metrics,sockets,workspace} \
11
var/log/hadean \
12
nix
Copied!
We created some extra Hadean-specific directories, set up some nameservers, and now we are ready to install our packages.
We are going to be using nsjail to install packages. There are other ways this can be done, for example by running the qcow2 image under QEMU, installing your dependencies, and then generating the tarball. In this guide we are going for a more scriptable approach. We ship nsjail with the Hadean SDK, and you can find it in ~/.hadean/sdk/bin/hadeanos/nsjail.
1
~/.hadean/sdk/bin/hadeanos/nsjail -Mo \
2
--rw \
3
--chroot $(pwd) \
4
--tmpfsmount /tmp --tmpfsmount /user --tmpfsmount /dev/shm \
5
--proc_rw \
6
--bindmount_ro /dev/null \
7
--user 0 --group 0 \
8
--disable_clone_newnet \
9
--keep_caps \
10
--rlimit_as 4096 \
11
--rlimit_fsize 1024 \
12
--rlimit_nofile 512 \
13
-- \
14
/usr/bin/bash \
15
-c 'dnf -y install gdb-gdbserver && dnf clean all'
Copied!
What happens here is that we run dnf -y install gdb-gdbserver && dnf clean all in our image. You can install other packages, or libraries if you wish to do so.
It is required that you install gdbserver. Without it you won't be able to debug your Hadean applications!
Now that we're done, let's create the final artefact and update the default runtime bundle.
1
tar -cJf ../centos-stream-8-bundle.tar.xz .
2
popd
3
rm -r ./centos-stream-8
4
5
# update the runtime bundle
6
cp centos-stream-8-bundle.tar.xz ~/.hadean/sdk/bin/hadeanos/runtime-bundle.tar.xz
Copied!
Now you can run your application with hadean run.
If you forgot to add things into the bundle, you can follow this section again, and modify the previously generated runtime bundle directly. Simply untar the bundle, and use nsjail to modify it.