Portal:MicroOS/Combustion

Jump to: navigation, search

Combustion - Configure MicroOS on the first boot

Combustion is a minimal module for dracut, which runs a user provided script on the first boot of a system.

You can use this to create additional files, install packages, set up devices or even re-partition the hard disk. The configuration can be provided as a shell script, loaded from an external storage media and is run during boot in a new system snapshot. On success, the system will directly boot into that new snapshot, so that no reboot is needed.

Ignition and Combustion scripts can be created using the Ignition & Combustion Config Generator.

Video Walk Through https://youtu.be/BHaPdJc8_zQ?t=190


What You Will Need

Setup a dedicated USB drive with a partition labeled "combustion" (which is separate from the MicroOS installation medium).

Inside that partition, you name the folder "combustion".

Finally, inside that folder, you name a file "script" which will contain your bash script. Note, the file doesn't have to be a .sh file.

The configuration files are then copied from a filesystem with the LABEL "combustion".

Note: to be compatible and co-installable with Ignition, the LABEL "ignition" is used as fallback.

MicroOS expects a directory "combustion" at the root level of the filesystem and a file "script" inside, which is executed inside a transactional-update shell.

<root directory>
├── combustion
│   ├── script
│   └── ... other files
└── ignition (optional)
    └── config.ign

You can do everything necessary for initial system configuration from this script, including addition of ssh keys, installing packages, managing users or even doing partitioning changes.

Simple example formatting USB Drive and Adding Config

Below is a sample for formatting a USB drive and adding a config, which installs the "vim-small" package and enables sshd:

mkfs.ext4 /dev/sdX
e2label /dev/sdX ignition
mount /dev/sdX /mnt
mkdir -p /mnt/combustion/
cat >/mnt/combustion/script <<EOF


Now that you have your partition and folder setup, you can use the following sample "script" file below, and add whatever else you want.

#!/bin/sh
# combustion: network
systemctl enable sshd.service
zypper --non-interactive install vim-small
EOF
echo "Hello User!" >/mnt/combustion/welcome
umount /mnt

The "# combustion: network" comment triggers networking initialization before running the script. This is equivalent to passing "rd.neednet=1" on the kernel cmdline and so the network configuration parameters (man dracut.cmdline) apply here as well. If those aren't specified, it defaults to "ip=dhcp" for each available interface.

More complex configuration example

This script additionally provides visible feedback during boot, sets a password and copies a public ssh key (which has to be in the "combustion" folder).

#!/bin/bash
# combustion: network
# Redirect output to the console
exec > >(exec tee -a /dev/tty0) 2>&1
# Set a password for root, generate the hash with "openssl passwd -6"
echo 'root:$5$.wn2BZHlEJ5R3B1C$TAHEchlU.h2tvfOpOki54NaHpGYKwdNhjaBuSpDotD7' | chpasswd -e
# Add a public ssh key and enable sshd
mkdir -pm700 /root/.ssh/
cat id_rsa_new.pub >> /root/.ssh/authorized_keys
systemctl enable sshd.service
# Install vim-small
zypper --non-interactive install vim-small
# Leave a marker
echo "Configured with combustion" > /etc/issue.d/combustion

Special Note on QEMU

If a QEMU fw_cfg blob with the name "opt/org.opensuse.combustion/script" is found, it is preferred and the content of that is used as script. Example parameter for QEMU:

-fw_cfg name=opt/org.opensuse.combustion/script,file=/var/combustion-script

Use fw_cfg qemu feature in libvirt

If you use libvirt with qemu/kvm to run your virtual machines, you can make combustion file available by editing libvirt XML for your created VM. You can use virt-manager UI or virsh edit.

Under the <domain> section, insert the following XML section:

 <sysinfo type="fwcfg">
   <entry name="opt/org.opensuse.combustion/script" file="/location/for/your/file/script"/>
 </sysinfo>

You can also using it at the creation of your VM with virt-install with the --sysinfo option:

 --sysinfo type=fwcfg,entry0.name="opt/org.opensuse.combustion/script",entry0.file="/location/for/your/file/script" \

How it works

After the first boot, the ignition-dracut-grub2 package creates a flag file at

   /boot/writable/firstboot_happened 

which tells GRUB 2 that the first boot has already happened. If this flag file is not there, GRUB adds "ignition.firstboot" to the kernel commandline.

If this option is found on the kernel cmdline, combustion.service's ConditionKernelCommandLine is fulfilled and it'll be required by initrd.target. This pulls in combustion-prepare.service, which runs after the config drive or QEMU fw_cfg blob appears (see combustion.rules for details). It is read and if the "network" flag comment is present, enables networking for later. After /sysroot is mounted and network is up (if enabled), combustion.service runs, which tries to activate all mountpoints in the system's /etc/fstab and then calls transactional-update in a chroot.

In this transactional-update session the script is started and the exit code recorded. If the script failed, transactional-update rollback is called and combustion.service marked as failed, which causes booting to fail. Note that a missing config drive or script is not considered a fatal error and only results in a warning.

/sysroot is unmounted and mounted again, so that the default subvolume gets reevaluated and directly booted into.

The ignition-firstboot-complete service in the final system runs, which adds the flag file. This means that combustion is not run on subsequent boots.

Known issues

[# combustion: network] does not work (Bug in Dracut, worked around in images)

Links

https://build.opensuse.org/package/show/devel:kubic:ignition/combustion

Example combustion scripts: https://code.opensuse.org/adathor/combustion-dotconf