Skip to main content

Custom Images

Elemental Teal images can be customized in different ways. One option is to provide additional resources within the installation media so that during installation, or eventually at boot time, additional binaries such as drivers can be included.

Another option would be to remaster the Elemental Teal by simply using a docker build. Elemental Teal is a regular container image, so it is absolutely possible to create a new image using a Dockerfile based on Elemental Teal image.

Customize installation ISO and installation process

In order to adapt the installation ISO a simple approach is to append extra configuration files into the ISO root in the same way a registration yaml configuration file is added.

Additional configuration files

Elemental Teal installation can be customized in three different, non-exclusive ways. First, including some custom Elemental client configuration file, second, by including additional cloud-init files to execute at boot time, and finally, by including installation hooks.

Custom Elemental client configuration file

Elemental client install, upgrade and reset commands can be configured with a custom configuration file.

In order to set a custom configuration file in the installation media the MachineRegistration resource associated with this ISO should also include the Elemental client configuration directory. For that purpose, the install field supports the config-dir field. See MachineRegistration reference and the example below:

apiVersion: elemental.cattle.io/v1beta1kind: MachineRegistrationmetadata:  name: my-nodes  namespace: fleet-defaultspec:  ...  config:    ...    elemental:      ...      install:        ...        config-dir: "/run/initramfs/live/elemental.conf.d"

Elemental Teal live ISOs, when booted, have the ISO root mounted at /run/initramfs/live. So in that case, the ISO will contain the custom Elemental client configuration file as /elemental.conf.d/config.yaml.

Adding additional cloud-init files at boot

In order to include additional cloud-init files during the installation they need to be added to the installation data into the MachineRegistration resource. More specific the config-urls field is used for this exact purpose. See MachineRegistration reference page.

config-urls is a list of string literals where each item is an http url pointing to a cloud-init file or a local path of a cloud init file. Note the local path is evaluated at the time of execution by the installation media, hence the local path must exist within the installation media, commonly an ISO image.

Since in Elemental Teal live systems the ISO root is mounted at /run/initramfs/live, the local paths for config-url in MachineRegistrations are likely to point there. See the example below:

apiVersion: elemental.cattle.io/v1beta1kind: MachineRegistrationmetadata:  name: my-nodes  namespace: fleet-defaultspec:  ...  config:    ...    elemental:      ...      install:        ...        config-urls:        - "/run/initramfs/live/oem/10_install_extra_drivers.yaml"

In that case the ISO root is expected to include the /oem/10_install_extra_drivers.yaml file.

Installation hooks

Elemental client install, upgrade and reset procedures include three different hooks:

  • before-install: executed after all partition mountpoints are set.
  • after-install-chroot: executed after deploying the OS image and before unmounting the associated loop filesystem image. Runs chrooted to the OS image.
  • after-install: executed before unmounting partitions but after all OS images are set and unmounted.

Hooks are provided as cloud-init stages. Equivalent hooks exist for reset and upgrade procedures.

Hooks are evaluated at install,reset and upgrade processes from /oem, /system/oem and /usr/local/cloud-config, however additional paths can be provided with the cloud-init-paths flag in Elemental client configuration.

Adding extra driver binaries into the ISO example

This example is covering the case in which extra driver binaries are included into the ISO and during the installation they are installed over the OS image.

For that use case the following files are required:

  • additional binaries to install (they could be in the form of RPMs)
  • additional hooks file to copy binaries into the persistent storage and to install them
  • additional Elemental client configuration file to point hooks file location

Lets create an overlay directory to include the overlay root-tree that needs to be applied over the ISO root. In that case the overlay directory could contain:

overlay/  data/    extra_drivers/      some_driver.rpm  hooks/    install_hooks.yaml  elemental/    config.yaml

The Elemental client config file in overlay/elemental could be as:

cloud-init-paths:  - "/run/initramfs/live/hooks"

This is just to let Elemental client know where to find installation hooks.

Finally, the overlay/hooks/install_hooks.yaml could be as:

name: "Install extra drivers"stages:  before-install:    # Preload data to the persistent storage    # During installation persistent partition is mounted at /run/cos/persistent    - commands:        - rsync -a /run/initramfs/live/data/ /run/cos/persistent  after-install-chroot:    # extra_drivers folder is at `/usr/local/extra_drivers` from the OS image chroot    - commands:      - rpm -iv /usr/local/extra_drivers/some_driver.rpm

Note the installation hooks only cover installation procedures, for upgrades equivalent before-upgrade and/or after-upgrade-chroot should be defined.

Repacking the ISO image with extra files

Assuming an overlay folder was created in the current directory containing all additional files to be appended, the following xorriso command adds the extra files:

xorriso -indev elemental-teal.x86_64.iso -outdev elemental-teal.custom.x86_64.iso -map overlay / -boot_image any replay

For that a xorriso equal or higher than version 1.5 is required.

Remastering a custom docker image

Since Elemental Teal image is a Docker image it can also be used as a base image in a Dockerfile in order to create a new container image.

Imagine some additional package from an extra repository is required, the following example show case how this could be added:

# The version of Elemental to modifyFROM registry.opensuse.org/isv/rancher/elemental/teal52/15.3/rancher/elemental-node-image/5.2:VERSION# Custom commandsRUN rpm --import <repo-signing-key-url> && \    zypper addrepo --refresh <repo_url> extra_repo && \    zypper install -y <extra_package># IMPORTANT: /etc/os-release is used for versioning/upgrade. The# values here should reflect the tag of the image currently being builtARG IMAGE_REPO=norepoARG IMAGE_TAG=latestRUN echo "IMAGE_REPO=${IMAGE_REPO}"          > /etc/os-release && \    echo "IMAGE_TAG=${IMAGE_TAG}"           >> /etc/os-release && \    echo "IMAGE=${IMAGE_REPO}:${IMAGE_TAG}" >> /etc/os-release

Where VERSION is the base version we want to customize.

And then the following commands

docker build --build-arg IMAGE_REPO=myrepo/custom-build \             --build-arg IMAGE_TAG=v1.1.1 \             -t myrepo/custom-build:v1.1.1 .docker push myrepo/custom-build:v1.1.1

The new customized OS is available as the Docker image myrepo/custom-build:v1.1.1 and it can be run and verified using docker with

docker run -it myrepo/custom-build:v1.1.1 bash