Creating the Anaconda boot.iso with lorax
Fedora 22 is almost here, so I thought I'd write a couple posts on how to use lorax and livemedia-creator to create bootable Fedora images. I'll start with lorax. It is used to create the Anaconda boot.iso which is used to install systems using a network connection. You can also automate your installations by using the boot.iso with a kickstart file. Lorax is part of the current release-engineering workflow and is used to create the boot.iso/netinst Anaconda installer image. Pungi also uses the results from lorax when creating the DVD including package repositories.
Lorax documentation can be found here and is currently a work in progress. The command line arguments are best documented by lorax --help right now. Lorax source is available on github and is maintained by Will Woods and I.
Lorax Installation
Installation is easy, just run sudo dnf install lorax from a Fedora 22 system and all the needed dependencies will be installed.
It is best to use the version of lorax that matches the Fedora release you are creating the iso for. It doesn't have a complex set of dependencies, but sometimes the templates have release specific logic in them.
Create a boot.iso
To create a boot.iso you need to pass lorax a few things: Product name, version, release, and the repositories to install the rpms from. You can speed up repeated builds by using a local proxy and passing it to lorax using the --proxy argument.
Building a simple generic boot.iso is as easy as running:
sudo -i setenforce 0 lorax -p Fedora-Generic -v 22 -r 22 \ - -s http://dl.fedoraproject.org/pub/fedora/linux/development/22/x86_64/os/ \ - -s http://dl.fedoraproject.org/pub/fedora/linux/updates/testing/22/x86_64/ \ ./results/
The new boot.iso will be in ./results/images/boot.iso with the rest of the build results (things like the kernel and initramfs images) also in ./results/. You can quickly test the new iso with:
qemu-kvm -m 1024 -smp 2 -cdrom ./results/images/boot.iso
How does Lorax work?
Lorax installs rpms into a directory, configures the system, and then removes files that aren't needed. It then creates a squashfs filesystem of the directory and builds a bootable iso around it using a kernel and a generic initramfs. The kernel and initramfs are independent of the host system, the boot.iso will use whatever kernel is installed from the selected repositories.
Lorax uses templates to select which packages are installed, what to remove after the rpm installation, how to create the iso, and the directory tree containing the images.
The templates are Mako templates with some custom commands added to make it easier to install packages and remove files. You can run arbitrary python code inside the template by using the <% %> tags or control structures. Templates are stored in /usr/share/lorax/ or in a location specified by passing a custom --config file that points to a new location.
Installing packages
Lorax first uses runtime-install.tmpl to select packages to be installed. It mostly contains installpkg commands, with some arch specific tests in a few places. The end of it must be run_pkg_transaction to install the packages into the installroot.
A bit of the template looks like this:
installpkg anaconda anaconda-widgets installpkg kexec-tools-anaconda-addon ## anaconda deps that aren't in the RPM installpkg tmux installpkg iscsi-initiator-utils ## kernel and firmware installpkg kernel installpkg grubby %if basearch != "s390x": installpkg *-firmware installpkg b43-openfwwf %endif ## actually install all the requested package run_pkg_transaction
Post-installation setup
After all the packages are installed (709 of them as of this writing), the runtime-postinstall.tmpl template is run. It modifies the contents of the installroot, handling things like settings up the yum repos for Anaconda, setting up configuration files for various things, enabling anaconda at boot time using systemd and tmux, disabling systemd services that are unneeded or that will interfere with Anaconda.
eg. setting up sshd for the boot.iso:
## set up sshd install ${configdir}/sshd_config.anaconda etc/ssh install ${configdir}/pam.sshd etc/pam.d/sshd install ${configdir}/pam.sshd etc/pam.d/login install ${configdir}/pam.sshd etc/pam.d/remote ## Make logind activate anaconda-shell@.service on switch to empty VT symlink anaconda-shell@.service lib/systemd/system/autovt@.service replace "#ReserveVT=6" "ReserveVT=2" etc/systemd/logind.conf
Cleanup and file removal
At this point the installroot is complete, but it contains quite a few extras that really aren't needed at installation time. In order to reduce the size of the boot.iso lorax runs the runtime-cleanup.tmpl template on it, and removes files and packages that are unneeded. For example:
## no sound support, thanks removepkg alsa* flac gstreamer-tools libsndfile pulseaudio* sound-theme-freedesktop removepkg midisport-firmware ## remove unused themes, theme engines, icons, etc. removefrom gtk2 /usr/${libdir}/gtk-2.0/*/{engines,printbackends}/* removefrom gtk2 /usr/share/themes/*
It also removes many of the kernel modules that aren't needed during installation, things like joystick, bluetooth and sound.
Once all the extras are removed lorax creates a squashfs image containing an ext4 filesystem. In Fedora 22 this is copied to LiveOS/squashfs.img and is used as the stage2 of the boot process.
Iso creation
Lorax then creates new generic initramfs images using dracut for each of the kernels installed in the installroot. It also generates the upgrade.img that is used by fedup in the upgrade process.
The final step is for lorax to execute an architecture specific template, like x86.tmpl, to create the iso bootloader directory, install kernels and initrds. The bootloader templates from /usr/share/lorax/config_files/ are modified to show the Product and Version that was passed to lorax. Finally mkisofs is called to create the boot.iso and the .treeinfo is written to the result's directory tree.
The results directory will look like this:
results/: .discinfo EFI images isolinux LiveOS .treeinfo results/EFI: BOOT results/EFI/BOOT: BOOTX64.EFI fonts grub.cfg grubx64.efi MokManager.efi results/EFI/BOOT/fonts: unicode.pf2 results/images: boot.iso efiboot.img macboot.img pxeboot results/images/pxeboot: initrd.img upgrade.img vmlinuz results/isolinux: boot.msg initrd.img isolinux.cfg libcom32.c32 memtest upgrade.img vmlinuz grub.conf isolinux.bin ldlinux.c32 libutil.c32 splash.png vesamenu.c32 results/LiveOS: squashfs.img
Running from a git clone
If you want to run lorax from a git clone instead of using the release package you need to setup the paths correctly, and pass it a configuration file that points to the ./share/ directory inside your clone.
Create a file named lorax.conf that with this in it:
[lorax] sharedir=/home/user/lorax/share
Replace the path with the path to your git clone of the lorax source.
Now you can run lorax directly from the clone by setting the PATH and PYTHONPATH environmental variables:
PATH=./src/sbin/:$PATH PYTHONPATH=./src/ ./src/sbin/lorax lorax -p Fedora-Generic -v 22 -r 22 \ - -s http://dl.fedoraproject.org/pub/fedora/linux/development/22/x86_64/os/ \ - -s http://dl.fedoraproject.org/pub/fedora/linux/updates/testing/22/x86_64/ \ - --config=lorax.conf \ ./results/