Revisiting Foster

Foster’s main purpose is to be a proving ground for the components I’m building that will ultimately generate the SURRO Linux installer ISO.

I’ve been busy with work so it’s not been very active. I’m slowly revisiting my work with it. As most of you who do work with software can probably relate to, when you look at older code, even your own, sometimes it’s a little different than you remember it and a little more involved.

I’ve made this way harder than it needs to be.

So, I’ll go over some of the high level about what this is, how it works, and start a little cleaner as I wrap my head around how this should work.

Environment Preparation

It starts with a makefile.

The makefile in the Foster project is basically a wrapper for a set of shell scripts: one for make, and one for clean. As you might guess, make builds the Foster project. clean removes all the artifacts.


In the build script, you’ll see it’s mostly docker commands: I wrap a docker container around the whole build process.

The build script is just a kickoff point for docker pulling an image and spinning it up as a container. That container has a shared volume, which is the directory where the examplar project files are, as well as other files necessary to bootstrap into the environment I’m creating in the container.


Examplar is, in this context, a build tool that is driving the whole build process.  It is also developed by me.

The docker image will then download the source code for Examplar, install any C++ compilation tools needed, such as the gcc compiler, and then build Examplar.

The image will then execute that freshly compiled Examplar instance against the Examplar project files from the shared volume mentioned earlier. The mechanism for this execution is the script which the docker container is told to run when it spins up. This script is located on the bootstrap shared volume as well. By the time this script is executed it means the instructions in the docker file have completed and the build is out of the environment preparation phase.

The script will execute the the examplar instance and pass on the return code from that examplar instance to its calling process to indicate success or failure of the build process.

The Examplar Project (Cycle 0)

Now that we’re in the part controlled by the Examplar project, examplar will execute units defined in its project files on the bootstrap shared volume. The order of execution of those units are defined in the plan file.

Environment Checks

It starts with environment checks and some primitive rectification attempts when it finds issues. When I say “environment” in this context I’m referring to the operating system of the running container. This includes present packages, their features and configuration, shell variables, and more.

Source Downloads

The source for the components to be compiled to create the new operating system are downloaded into a source directory.


Examplar will then create a directory at the root of the container OS filesystem. That directory will be the SYSROOT of the new operating system it is compiling, and will eventually be a CHROOT used to compile the rest of the pieces needed for a fully bootable system.


Once this directory exists, examplar will begin compiling a cross-compiler from raw source to avoid sanitation issues created by upstream patches. That cross-compiler will be configured to output to the chroot. This step is problematic and is a work in progress.

The SYSROOT / Chroot Population

Examplar then begins compiling the bare, core parts of the system, such as the kernel and its dependencies, again dumping output into the CHROOT/SYSROOT directory. Once enough packages are present to compile librpm and rpm package management pieces, examplar will chroot into the newly populated sysroot and begin compiling pieces from the inside out. From there RPM packages are used.