Build process

In the getting started section it was shown that the following command will perform the image build:

make image-build

In this section we will review this build process in-depth.

Overview

From a high level view the build process is simple: A kickstart is passed to livemedia-creator which is in turn building the appliance image.

Let's start with the specifics about the kickstart file.

Kickstart

The kickstart file defines what packages go into the appliance image. In addition, a few additional configuration steps can be performed as part of the installation.

A kickstart file is used because anaconda is used for installation, and kickstart can be used for deep, repeatable customization with anaconda, or for simple automated installs.

See the official kickstart documentation for more informations.

The specific kickstart which defines the oVirt Node appliance is defined in the ovirt-node-ng-image.ks file, which hosted in theovirt-node-ng repository. See the getting started section for how to clone that repository.

Unattended installation

The first important note about the Node kickstart is that it needs to contain enough directives to perform an unattended installation.

There are "enough directives" if the kickstart provides answers to all spokes (anaconda's terminology for a configuration section). You will know whether there is enough information by watching the installer. If there are spokes which are not completed, directives which fill those spokes will need to be added. If the text directive is used in the kickstart, spokes which are complete will helpfully have [x] next to them. Those which do not will show [ ].

Security

To provide a baseline level of security, the image comes with:

  • SELinux in permissive mode (during development)
  • A locked root account
  • A locked node account, which should get unlocked during installation

The following directives are used to achieve this:

selinux --permissive
rootpw --lock
user --name=node --lock

Filesystem

It is important to note that the kickstart will only create a disk with a single partition, because this partition will be extracted and be wrapped in the squashfs.

Another important point is the choide of a filesystem which supports discard or trim. This feature enables alter - after deployment - an efficient use of the available space, and is a crucial point in the upgrade and rollback implementation. See the upgrade section for more details on the storage requirements.

The following directives are used to ensure that only a single ext4 partition with discard support is used:

clearpart --all --initlabel
part / --size=3072 --fstype=ext4 --fsoptions=discard

Packages

The %packages section defines what packages get installed inside the appliance image. The primary goal should be to keep this list small.

If you find yourself adding packages to this kickstart section, you should ask yourself why the package you are adding isn't a already a dependency of an included package. If it isn't, is it necessary for inclusion? If you believe that it is, submit a patch which includes it as a dependency of ovirt-node-node-host or some upstream package which is already included.

Let's take a look at the important packages:

%packages
# config -generic == not -hostonly, this is needed
# to support make a generic initrd (which does not keep lvm information)
dracut-config-generic

# EFI support
grub2-efi
shim
efibootmgr

lvm2
imgbased
%end

The packages are used to achieve the following:

  • Add EFI support
  • Add generic initramfs support
  • Add lvm2 and imgbased support

On normal installs of Fedora or CentOS, these packages don't need to be added explicitly, because anaconda will install them automatically if they are needed. lvm2 will be installed if LVM is used for storage, grub2-efi will be installed if the OS is installed on EFI hardware, etc.

We need to install these packages explicitly, because it is expected that the appliance image contains everything that is needed for every use-case, and we want to include support for configurations which differ from the install environment, which, as noted above, only has one partition, and livemedia-creator does not install in EFI mode.

FIXME The package requirements should go to some package dependencies, i.e. ovirt-release-node-host, see this bug.

%post scriptlets for additional software

You might have noticed that vdsm is missing in the package list above.

vdsm can not be installed directly, because it needs the ovirt-release package to be installed to add to the necessary repositories.

That is why vdsm is getting installed in a %post scriptlet.

Installation

Now that the kickstart is ready, it is passed to anaconda inside the VM to install the required packages onto disk.

Let's see how this step looks in-depth.

Before we continue: both of the methods described below are using the same basic mechanism to perform the installation. They only differ in additional logic around pre- and post-processing of the kickstart and the final image.

Current build process: livemedia-creator

The image is built using livemedia-creator. livemedia-creator uses Anaconda, kickstart, and Lorax to create a wide range of outputs, with a focus on flexibility. livemedia-creator is used extensively by many other projects, and it is used here to provide a stable, maintained way to perform the necessary build and install steps rather than using the installer tools directly.

The ovirt-node-ng repository includes a wrapper around livemedia-creator to simplify usage, and only two arguments need to be provided, with an optional flag which may be used for development.

scripts/ovirt-node-ng-build-tool.py is used to build, and takes the following arguments:

--kickstart KICKSTART
                      the kickstart describing the image to create
--base BASE           The path to a netinstall ISO, or one of
                      [fedora23|centos7] and the image will be retrieved
                      automatically
--qcow-debug          creates a qcow2 image instead of fs for debugging
                      purposes

To use it, simply pass --kickstart data/ovirt-node-ng-image.ks (for a manual, step-by-step install), and your choice of --base fedora23 or --base centos7, depending on what you'd like your Node image based upon.

Recent versions of Fedora should work, as should other distros (as long as they're RPM-based, and derived from EL7/F21 or later. Please don't try this with CentOS 6!), but they probably won't be supported. We'd love to know if you get it working with another distro, though.

FIXME koji support should be added

Image Format: Liveimg

Node is installed (and updated) using a single operating system image. Contrary to many other distributions, packages are not used to install the operating system. Packages are primarily used to build the image, and eventually to customize the image.

The liveimg image format is a Fedora-andCentOS-ish format used to deliver LiveCDs. A liveimg is a file-system image wrapped into a squashfs image. The reasoning behind this matroska mechanism is that the file-system image can be mounted easily, and the squashfs image -- as it can compress -- helps reduce the size of the image. Because it has been around for a long time, this format has mature support in both dracut and anaconda. This effectively enables two use-cases with a single image:

  • anaconda can use this image as a source instead of individual rpms
  • dracut can boot into a liveimg

Delivery Format

The appliance image is delivered in the squashfs liveimg format.

This format is understood by anaconda (for installation) and dracut (for stateful and diskless boots).

The format is described in man dracut.cmdline:

The filesystem structure is expected to be:

   squashfs.img          |  Squashfs downloaded via network
      !(mount)
      /LiveOS
          |- ext3fs.img  |  Filesystem image to mount read-only
               !(mount)
               /bin      |  Live filesystem
               /boot     |
               /dev      |
               ...       |

Note: the ext3fs.img is a file-system image, not a disk image.

The ext3fs.img can be created using a variety of tools, the primary one used by Node is livemedia-creator (part of lorax).

Eventually livemedia-creator will be capable of creating squashfs images directly.