Skip to content

Latest commit

 

History

History
152 lines (95 loc) · 7.16 KB

HACKING.md

File metadata and controls

152 lines (95 loc) · 7.16 KB

Hacking Readymade

Readymade is an OS installer written in Rust, and currently a frontend for systemd-repart.

The UI code is written in Relm, a GTK4 UI framework for Rust inspired by Elm.

Dedicated backend

The new dedicated backend for Readymade should be written in Rust, and should be able to handle the following tasks:

  • Declarative(?) disk partitioning and generation of actions to be fed to UDisks2
  • UDisks2 integration for disk partitioning and formatting (and possibly LVM and BTRFS support)
  • Smart detection for Chromebook devices and other devices that require special handling (so that we can install extra Submarine bootloader payloads when required)
  • Automatic systemd mountpoint hints using GPT partition labels/flags

If you're gonna do this in Rust, why not just use distinst?

We have considered using distinst, but we have decided to write our own installer for the following reasons:

  • distinst is being deprecated in favor of distinst2, which runs a dedicated D-Bus backend service for the installer.
  • Code from distinst is heavily tied to Debian/Ubuntu and Pop!_OS, and it is not easily portable to other distributions.
  • Regarding above point, System76's APIs are not very well documented and maintained, and requires a lot of hacking to even get working (see the old branch of this repository for an example of how we tried to get it working )
  • And because of the above points, there is only one distribution that uses distinst, and that is elementary OS. We want to make Readymade a worthy alternative to Anaconda, which means improving upon the installer experience for for RPM distributions as well.

Building

To build Readymade, you need to have the following dependencies installed:

  • GTK4
  • libhelium
  • libgnome-desktop4
  • GNU Gettext (for l10n)
  • Rust

To build Readymade, simply run:

cargo build --release # Release build, omit --release for a debug build with symbols and assertions

The build should be successful if all dependencies are installed.

Running

There are however more runtime dependencies required to actually run Readymade, which includes:

  • Submarine (place your disk image in /usr/share/submarine)
  • pkexec (For escalating the process as root)

You can simply run Readymade by executing the binary. It should be located in target/release/readymade.

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.

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

Currently Readymade only supports Chromebook installations, it is recommended you run Readymade on a Chromebook device to test the installer.

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

Localization

You can translate Readymade to your language by going to the Fyra Labs Weblate page and translating the strings there.

Contributing

Before pushing your changes, please make sure to run cargo fmt to format your code according to the Rust style guidelines provided in rustfmt.toml.

You should also run cargo clippy to check for any potential style issues or bugs in your code.

And if possible, write tests for your code, and run cargo test to ensure that your code works as expected.

Configuration file

Readymade requires a configuration file at /etc/readymade.toml. You can change it to another path using the environment variable READYMADE_CONFIG.

Some example configuration files for Ultramarine are in templates/.

Example configuration file:

[distro]
name = "Ultramarine Linux"
icon = "fedora-logo-icon" # optional

[install]
allowed_installtypes = ["chromebookinstall", "wholedisk", "dualboot", "custom"]

Tasks

Generating pot file

cargo install xtr
xtr src/main.rs -o po/readymade.pot --package-name Readymade --package-version 0.1.0

Installing po files

(Taking Japanese as an example)

msgfmt po/ja.po -o /usr/share/locale/ja/LC_MESSAGES/com.fyralabs.Readymade.mo