Skip to content

How Luft installs

The parts behind installing: the Install Luft app, its luft-installer service and Kestrel’s setup mode. The steps people go through are in Install from a USB stick.

Partition Size Holds
EFI system partition 1 GB Shim, SushiBoot and a signed startup image for each version of Luft. A drive that already has one, such as Windows’, shares it when it has 1 GB or more
Luft startup 2 GB, FAT The signed startup images, when the drive’s EFI system partition is smaller than 1 GB, as Windows’ usually is. Shim and SushiBoot still go on the EFI system partition, next to Windows’ boot files
Luft The rest, btrfs The system and your files

Luft starts with UEFI only.

The system is a bootc image from ghcr.io/lantharos/luft, or the -nvidia variant when the computer has an NVIDIA graphics card. It updates from there.

Install Luft notes the old system in /var/lib/luft-installer/old-system.json, which Disks and Settings use to remove it:

{
"name": "Fedora Linux 45 (Workstation Edition)",
"size": 9876543210,
"subvolume": "old-system",
"partitions": [],
"startups": ["EFI/fedora"]
}

subvolume is the kept system’s path from the top of Luft’s btrfs, or null when nothing was kept; startups are its folders on the EFI system partition, which the first sign-in removes with their start entries. Removing deletes the subvolume and anything nested in it.

The stick runs on the open-source drivers, including nouveau on NVIDIA graphics cards. Nouveau drives cards up to the GeForce RTX 50 series through NVIDIA’s own GSP firmware, which the stick carries, so setup looks the same as anywhere else. Installing picks the image with NVIDIA’s driver when there’s an NVIDIA card. A card newer than the stick’s kernel falls back to the firmware’s screen, which is slower but enough for setup; the basic graphics mode in the Esc menu does the same on purpose.

/usr/lib/luft-installer/install.toml says what to install:

# smallest-system = 34359738368 # bytes; drives or spaces below it aren't offered
[images.default]
source = "containers-storage:ghcr.io/lantharos/luft:45" # where the stick has the image
size = 5286520084 # bytes installed, for the progress bar

The image ships only the settings above the [images] tables. The stick’s build adds a table for each image it carries, with the size Podman reports for it. [images.nvidia] is used on computers with an NVIDIA graphics card. A stick with a single table installs that image on any computer. Updates come from the reference in /usr/share/luft/image-reference (ghcr.io/lantharos/luft:45, or :45-nightly in nightly images; the image build’s IMAGE_REFERENCE sets it), with -nvidia added for the NVIDIA image.

  • The stick (os/iso) keeps both images in a read-only image store on the stick, which the session there adds to Podman’s storage, so containers-storage: sources install without a network. bootc reads the image straight from the store’s layers onto the drive, so installing needs no room in memory, which is where the live session keeps its changes.
  • Its kernel command line has rd.live.image, which tells the installer it’s on the stick. greetd signs the passwordless live account in with kestrel-session --setup as its initial_session, and polkit allows that account everything, installing included. Install Luft is listed in Start only there.
  • Kernel arguments come from the image (/usr/lib/bootc/kargs.d), sealed into its startup image.
  • Started from Meet Luft’s partition, the live session saves its journal, crashes and hardware details on that partition (Logs from Try Luft).
  • When the drive’s EFI system partition is smaller than 1 GB, the installer adds a 2 GB XBOOTLDR partition (type bc13c2ff-59e6-4262-a352-b275fd6f7172, FAT) in front of Luft’s, and bootc keeps the startup images and boot entries there. Luft’s image carries a bootc with that change (os/image/patches/bootc).
  • After copying, the installer puts shim and SushiBoot on the EFI system partition with trustctl startup install, and, when Secure Boot is on, queues Luft’s key for shim and publishes the code as SecureBootCode.
  • After copying, the installer writes the locale, keyboard, time zone, host name and the account into the new system, plus /var/lib/luft-installer/first-boot with the account’s name. FinishFirstBoot removes that file, and only that account may call it.

kestrel-session --setup runs Kestrel in setup mode until Install Luft finishes, then starts the normal session. kestrel-session does the same on its own when /var/lib/luft-installer/first-boot names the person signing in. Setup mode shows the firmware logo while Sushi hands over, fades in the blurred wallpaper with the window, and ends on that same wallpaper, so the desktop takes over without a flash. It also serves the portal’s appearance settings and Luft’s palette, so apps in setup look like they do on the desktop.