Readymade Stack
Readymade

Readymade

Readymade (opens in a new tab) is the new installer for Ultramarine Linux 41 and above. It is written in Rust and libhelium (opens in a new tab) and comes with a custom backend based on systemd-repart.

Readymade is created due to frustrations (again!) with Red Hat's Anaconda installer, after we have received many complaints about the poor UX design of Anaconda, and the lack of working alternative installers for RPM-based distributions. It also adds support for other kinds of hardware, including Chromebooks, in response to the [Ultramarine Anywhere Initiative].

Building

You may view the most updated building instructions in the CI spec file (opens in a new tab) and HACKING.md (opens in a new tab).

Build dependencies:

cargo
clang-devel
cmake
gcc
gettext-devel
pkgconfig(libhelium-1)
pkgconfig(libgnome-desktop4)

Dependencies: (according to dnf rq --providers-of=requires readymade)

cairo
cairo-gobject
efibootmgr
gdk-pixbuf2
glib2
glibc
glibc
gnome-desktop4
graphene
gtk4
harfbuzz
libgcc
libhelium
pango
pkexec
vulkan-loader
xz-libs

And optionally, submarine (for Chromebook installations).

Configurations

Configurations are read from /etc/readymade.toml, or a path specified by the READYMADE_CONFIG envvar.

Some example configuration files for Ultramarine are in templates/.

The Universal Blue configurations are available here: https://github.com/ublue-os/bluefin/blob/3c75eac59184afbe89250f2a4eaaf4c748b23ec8/iso_files/configure_iso.sh#L21-L53 (opens in a new tab)

Running

There are also extra PolicyKit rules to skip password prompts for pkexec to escalate the process as root. Copy the com.fyralabs.pkexec.readymade.policy file to /usr/share/polkit-1/actions/ and restart the PolicyKit service.

In development, it may be useful to specify options to the binary, such as the configuration file path, or the log level. You can do this by setting supported environment variables.

For example, to run with tracing and the ultramarine-chromebook template, run the following command:

READYMADE_LOG=trace READYMADE_CONFIG=templates/ultramarine-chromebook.toml cargo run

You can also set READYMADE_DRY_RUN to configure if whether the install is a dry-run, this will cause an installation failure. Please note that this variable is set to 1 by default, within development builds.

Additionally, you may want to create a virtual disk to install to during development:

fallocate -l 8G test.img # Create a blank 8GB file
sudo losetup --partscan --show -f test.img # Attach the file to a free loop device, take note of the outputted device.

Note how loop devices become valid install targets within debug builds, select the one corresponding to the device noted in the prior commands.

The above commands are available as scripts in the scripts/ directory.

Debugging

Readymade currently defaults to the error log level. To set a custom log level, set READYMADE_LOG. For example READYMADE_LOG=trace will set the log level to trace, which is the most verbose level. Readymade logs to stderr and to a temporary folder /tmp/readymade-logsXXXXXX, which contains the file readymade.log. The logger is powered by tracing-appender.

It also logs to the systemd journal, so you can view the logs by running

journalctl _COMM=readymade # add -f to follow the logs

Readymade checks for Dracut's default live-base (in /dev/mapper/live-base) logical volume for the base filesystem to mount and copy from. This is usually generated with Dracut's live module. It then tries to mount the base filesystem from the logical volume and use the files from there as the source for the installer, as it assumes the running environment is a live CD environment generated by Dracut, thus it contains the original overlay filesystem in this exact location.

While you may expect it to mount a SquashFS, the default behaviour is to mount an overlay disk image generated from the SquashFS. This is to prevent the SquashFS to be extracted twice, as the live module already mounts the SquashFS and turns it into a Device Mapper device.

If that somehow fails, it may try again and check for /run/rootfsbase as the source path, this is a fallback for Dracut live environments that have the SquashFS containing the live environment directly inside the SquashFS and not as a disk image inside the SquashFS.

Readymade will mount this location if possible, and if not, it will attempt to copy files from /mnt/live-base as the source path anyway.

You can however override this by setting the environment variable REPART_COPY_SOURCE to the path of the base filesystem to copy from. This makes use of systemd 255's new relative repart source feature.

In case you have an alternate root mounted at /mnt/squash from an external source (i.e a real filesystem or a mounted SquashFS image, or even an OCI image), add the environment variable REPART_COPY_SOURCE=/mnt/squash to the command line when running Readymade.

sudo REPART_COPY_SOURCE=/mnt/rootfs readymade

Translations

You may translate Readymade to your language by visiting the Fyra Labs Weblate (opens in a new tab) instance.

Other distros can customize the install progress page (pages/installation.rs) by providing /usr/share/readymade/resources/*.gresource, and providing fluent translation files in /usr/share/readymade/bento/po/.

Postinstall modules

The following postinstall modules are available:

  • SELinux
  • Dracut
  • ReinstallKernel
  • GRUB2
  • CleanupBoot
  • PrepareFedora
  • EfiStub
  • InitialSetup
  • Language
  • CryptSetup
  • Script

To enable a module, add this to the toml configuration file:

[[postinstall]]
module = "Script" # replace Script with the module name

Readymade will execute the modules in the order specified in the configuration.