Creating live isos with livemedia-creator

In this post I am going to describe how to create bootable live isos using livemedia-creator (lmc). It was created so that the same Anaconda installer logic would be used for installing systems and creating bootable media like the live iso. lmc can also be used to create disk images, but I'll cover that in the next post. Anaconda and kickstart are used to install the packages, and lmc compresses the filesystem and wraps it up in an iso. This is different from the livecd-creator tool, which is a separate project that duplicates some of Anaconda's behavior and includes its own iso creation code instead of depending on Lorax.

Installation

livemedia-creator is part of the lorax package, but you need to install a few extra things depending on how it will be used. We're going to use a boot.iso and virt-install so you need to run:

sudo dnf install lorax virt-install libvirt-daemon-config-network
sudo systemctl restart libvirtd

Note that I am running all of these examples on a freshly installed Fedora 22 TC3 Workstation system, if you use the Server product or a different spin you may need to install a different set of packages to get virtualization setup.

You will also need the netinst iso that matches the release that you want to build your iso for. I used the one from Fedora 22 Workstation TC3:

wget https://alt.fedoraproject.org/pub/alt/stage/22_TC3/Workstation/x86_64/iso/Fedora-Workstation-netinst-x86_64-22_TC3.iso

Once Fedora 22 is release you will find that in https://dl.fedoraproject.org/pub/fedora/linux/releases/22/Workstation/x86_64/iso/. I rename it to f22-boot.iso to make it a bit easier to type.

libvirtd needs to be able to access the boot.iso and the kickstart, either store them someplace like /var/tmp/ or change permissions on the build user's directory so that others can reach known paths:

cd ~
chmod a+x .

The Kickstart

lmc includes several example kickstarts in /usr/share/doc/lorax/ but we are going to start from scratch and modify the Fedora 22 Workstation kickstart. The official kickstart is written for use with livecd-creator so it needs a few changes before it will work with Anaconda and lmc.

Check out the spin-kickstart project using git:

git clone https://git.fedorahosted.org/git/spin-kickstarts.git
cd spin-kickstarts
git checkout f22

We want to use the fedora-live-workstation.ks but it includes several other kickstarts, so flatten it into a single file using:

ksflatten -c fedora-live-workstation.ks -o ~/lmc-live-workstation.ks

You can ignore the warnings that it prints, we'll fix that next. Open up the new kickstart in your favorite editor and adjust the following things:

  • Convert the fedora repo line to url --url=, point it to the primary repository you want to use for the installation. If you are using a proxy cache add it to the end as --proxy=<url>. It should look like this:

    url --url=http://dl.fedoraproject.org/pub/fedora/linux/development/22/x86_64/os/
    
  • Change other repo lines or remove them, I used a second repo to point to the updates-testing repository for F22:

    repo --name=updates-testing --baseurl=http://dl.fedoraproject.org/pub/fedora/linux/updates/testing/22/x86_64
    
  • We want to skip being prompted for empty disks so add clearpart --all --initlabel above the bootloader command.

  • Set the bootloader location to bootloader --location=mbr so that anaconda will install grub2.

  • Add the shutdown command so that the virtual machine will shut down when it is finished. Otherwise it will hang and you will need to destroy it manually.

  • Add rootpw --lock to lock the root account, and make sure that in the kickstart livesys script it either removes the root password lock or sets up the liveuser to be a member of wheel so they can sudo to root (the official kickstarts already do this).

  • Remove the duplicate part command, and increase the size to 6500

  • At the top of the %post section remove /etc/fstab so that dracut isn't confused by missing UUIDs:

    %post
    cat /dev/null > /dev/fstab
    
  • Find the line in %post that removes the initramfs to save space and delete it, we want to keep the initramfs that Anaconda created.

  • Make sure the following packages are in the %packages section

    • dracut-config-generic
    • grub2-efi
    • memtest86+
    • syslinux
    • -dracut-config-rescue

Check the kickstart using ksvalidator to make sure there aren't any typos:

ksvalidator lmc-live-workstation.ks

Your kickstart is now ready for use with Anaconda, with or without lmc, it will create a system that can be booted on any supported system (thanks to the dracut-config-generic package) and if rd.live.liveinst is passed on the cmdline it will create and login as the liveuser automatically.

Building a live iso

Once the kickstart is ready it is one short command to create the live iso:

sudo livemedia-creator --make-iso --iso=./f22-boot.iso --ks=./lmc-live-workstation.ks

lmc is using virt-install to handle running Anaconda. You can improve its performance by increasing the amount of ram used by the virtual machine by passing --ram 4096 and the number of cpus to use with the --vcpus 4 argument. lmc supports a number of other options, you can view the full list with livemedia-creator --help

You can follow the installation process by tailing the virt-install.log file, or passing --vnc vnc to lmc and using a VNC viewer to connect to the system to observe it.

While running virt-install lmc will print a '.' every 10 seconds. After Anaconda is finished there will be a large amount of debugging information printed, mostly from dracut. This helps track down problems with the initramfs creation, but can usually be ignored.

When the iso creation is finished you can copy it from its temporary directory and run it with qemu-kvm:

sudo cp /var/tmp/tmp*/images/boot.iso ./lmc-live-workstation.iso
qemu-kvm -m 1024 -smp 2 -cdrom ./lmc-live-workstation.iso

How it works

Most of the work is done by Anaconda. By using virt-install it is possible to create a live iso for other releases of Fedora by using the correct repositories in your kickstart and the matching boot.iso from the release. This should work for every release since Fedora 18, as well as Red Hat Enterprise Linux 7 and CentOS 7.

The kickstart is used by Anaconda to setup the virtual disk. When the installation is complete lmc takes the disk image and creates a compressed squashfs image of the / partition using Lorax's RuntimeBuilder module. It then uses Lorax's TreeBuilder module, with templates that have been customized for live isos. These templates are stored in /usr/share/lorax/live/, and the template location can be overridden by passing --lorax-templates with a new path.

By using Anaconda and Lorax the number of places where installation logic needs to be changed has been reduced, and code that is shared between normal system installation and boot.iso creation is used, hopefully resulting in less bugs.

Debugging

Sometimes there are problems, lmc watches the logs from Anaconda and will shut down the process when it detects an an error. If that fails it may get stuck, and you will need to force the virtual machine to shut down using virsh to destroy it. It will be named LiveOS-<UUID> so running virsh destroy LiveOS-<UUID> will shut down the VM, which lmc will detect and then cleanup any temporary files and directories.

During installation you can connect to Anaconda using vnc if you pass --vnc vnc on the livemedia-creator command line. When it fails there are several log files you can check for errors:

  • virt-install.log contains the logs from the virtual machine while running Anaconda. Things like missing packages, repo problems or not enough space on the / partition will be logged here.
  • livemedia.log has the logs from lmc.
  • program.log has the output from commands that are run by lmc. This where to look when virt-install fails, any output from it will be stored here.

Next Time

The next post will explain how you can run lmc and Anaconda inside a mock environment to create live isos without virtualization while targeting releases other than the one that the host is running.