Dear visitor,

it seems your are using Internet Explorer in version 11 or lower as your web browser. Due to a lack of supported modern web standards I do not support this browser anymore.

Please use an alternative web browser such as:

Fedora CoreOS - Embed Ignition Configuration into VM Image

Fedora CoreOS (FCOS), and the used configuration system Ignition, does currently not support injecting the needed configuration file via so called config-drives. It is required to host this file on a separate web server or to use a custom data injection mechanism of one of the supported cloud providers (like user-data from Amazon AWS EC2). As this can be difficult for users with simpler use cases and with no access to external web servers, I want to provide a short overview how to embed the configuration file into the FCOS image itself.

How does Ignition load the configuration?

If you set up a virtual machine running FCOS according to my previous blog post and take a closer look at the initial boot log outputs, at some point you can find something like this:

ignition[684]: INFO  : reading system config file "/usr/lib/ignition/base.ign"
ignition[684]: DEBUG : parsing config with SHA512: ff6a5153be363997e4d5d3ea8cc4048373a457....
...
ignition[495]: reading system config file "/usr/lib/ignition/user.ign"
ignition[495]: no config at "/usr/lib/ignition/user.ign"

This is a hint that Ignition actually tries to read two configuration files from the disk image itself, with only base.ign actually available. Where does this file come from?

The Fedora CoreOS image build process is managed via the FCOS build pipeline, which is build around CoreOS Assembler. The assembler is a tool collection which operates on a FCOS configuration manifest to produce FCOS disk images.

Fedora CoreOS is using dracut to create an initial ramdisk file system (referred to as initramfs) used during the boot process before the actual root file system is mounted. Dracut allows using modules to customize the initramfs. Part of the FCOS configuration manifest repository are different dracut modules, with one of them providing the basic Ignition configuration file.

This module contains the previous mentioned base.ign file, which holds the configuration of the initial core user:

{
  "ignition": {
    "version": "3.0.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "gecos": "CoreOS Admin",
        "groups": [
          "adm",
          "sudo",
          "systemd-journal",
          "wheel"
        ]
      }
    ]
  }
}

For the purposes of this post this is still not really helpful as rebuilding the initramfs is out of scope. But, with a bit of further research, another repository with additional dracut modules can be found. One module includes a setup script to provide the user.ign file:

...
# We will support a user embedded config in the boot partition
# under $bootmnt/ignition/config.ign. Note that we mount /boot
# but we don't unmount boot because we are run in a systemd unit
# with MountFlags=slave so it is unmounted for us.
bootmnt=/mnt/boot_partition
mkdir -p $bootmnt
# mount as read-only since we don't strictly need write access and we may be
# running alongside other code that also has it mounted ro
mount -o ro /dev/disk/by-label/boot $bootmnt
copy_file_if_exists "${bootmnt}/ignition/config.ign" "${destination}/user.ign"
...

The documentation reveals, embedding a custom configuration on the boot partition of the FCOS system image is in fact possible.

Modifying the FCOS Image

Since there is now a possibility to inject an Ignition configuration into the system image without tempering with the initramfs, the further steps are rather easy:

To automate these tasks, I make use of tooling provided by the libguestfs-tools package (on a Fedora system) which allows for operations on virtual machine file systems.

Finding the device containing the file system with the boot label in the image can be done with virt-filesystems in the following manner:

# This command reveals the device path containing the file system with 
# the 'boot' label, e.g. '/dev/sda1'.
virt-filesystems -a fcos.qcow2 -l | grep boot | awk -F ' ' '{print $1}'

To copy a file into the image, guestfish can be used. This is a powerful tool for examining and modifying virtual machine file systems and can be used interactively via a shell or with its command-line interface.

Using guestfish with a provided config.ign looks like this:

fs_boot_path=$(virt-filesystems -a fcos.qcow2 -l | grep boot | awk -F ' ' '{print $1}')
config_file_path=./config.ign

guestfish add fcos.qcow2 : \
          run : \
          mount "$fs_boot_path" / : \
          mkdir /ignition : \
          copy-in "$config_file_path" /ignition/ : \
          unmount-all : \
          exit

For a short introduction on how to generate the config.ign file please take a look at my introductory post about Fedora CoreOS. A full example bash script for all tasks mentioned is provided here.

The image of Fedora CoreOS has now the Ignition configuration embedded. Running this image with e.g. QEMU results in a FCOS instance with the correct settings automatically applied. The so modified image can be used with e.g. a hosting provider which allows server setups using virtual machine images.

References