|
1 | | -# Fedora UKI Setup Script |
| 1 | +# RustyUKI |
2 | 2 |
|
3 | | -`uki-setup.sh` automates creation and lifecycle management of **Unified Kernel Images (UKIs)** on Fedora and other Linux systems that provide compatible `dracut` + `ukify` + `kernel-install` tooling. |
| 3 | +**RustyUKI** is a Rust rewrite of the original Fedora UKI setup script. It builds and installs Unified Kernel Images (UKIs) using a two-stage pipeline: |
4 | 4 |
|
5 | | -It performs a one-time setup that: |
| 5 | +1. **dracut** for initramfs generation |
| 6 | +2. **ukify** for final PE/EFI UKI assembly |
6 | 7 |
|
7 | | -- Installs required tooling (`dracut`, `ukify`, `lsinitrd`, `efibootmgr`, `binutils`). |
8 | | -- Writes a UKI rebuild helper script to `/usr/local/sbin/uki-build.sh`. |
9 | | -- Installs a `kernel-install` plugin that rebuilds/removes UKIs when kernels are added/removed. |
10 | | -- Disables default Fedora kernel-install plugins that generate GRUB/BLS entries to avoid conflicts. |
11 | | -- Builds and registers a UKI for the currently running kernel. |
| 8 | +This project is focused on Fedora-style systems with UEFI firmware and an EFI System Partition (ESP). |
12 | 9 |
|
13 | | ---- |
| 10 | +## What changed |
14 | 11 |
|
15 | | -## What this is for |
| 12 | +This repository previously centered around `uki-setup.sh`. It now includes a Rust CLI with modular code and stronger error handling. |
16 | 13 |
|
17 | | -A UKI bundles the kernel, initramfs, and kernel command line into one EFI executable. This setup now builds UKIs in two stages: dracut generates a standalone initramfs artifact first, then ukify assembles/signs the final EFI binary. |
| 14 | +- Subcommand-driven CLI (`generate`, `install`, `status`) |
| 15 | +- TOML config loading from `/etc/uki/uki.conf` |
| 16 | +- Shared command runner with dry-run support and typed command failures |
| 17 | +- Root privilege enforcement at startup |
| 18 | +- Atomic UKI output write (temp file + rename) |
18 | 19 |
|
19 | | -This project is intended for systems booting in **UEFI mode** with a mounted **EFI System Partition (ESP)** (typically `/boot/efi`). |
20 | | - |
21 | | ---- |
22 | | - |
23 | | -## Requirements |
24 | | - |
25 | | -- Linux distribution with `dracut`, `kernel-install`, and `efibootmgr` available. |
26 | | -- UEFI boot mode. |
27 | | -- Root privileges. |
28 | | -- ESP mounted at one of `/boot/efi`, `/efi`, `/boot`, `/boot/EFI`, or `/esp` (the script attempts automatic ESP discovery/mounting). |
29 | | - |
30 | | -> [!DANGER] |
31 | | -> **Make a full system backup before running this script.** A tested restore path (snapshot rollback, rescue image, or offline backup) is strongly recommended. |
32 | | -> |
33 | | -> This script is **invasive and experimental**: it modifies bootloader behavior, writes kernel-install hooks, manages EFI entries, and disables default kernel-install plugins. A misconfiguration can leave your system unbootable. |
34 | | -> |
35 | | -> Only proceed if you understand your boot stack and are prepared to recover from a failed boot. |
36 | | -
|
37 | | ---- |
38 | | - |
39 | | -## Safety and backup-first workflow (recommended) |
40 | | - |
41 | | -Before setup: |
42 | | - |
43 | | -1. Create a full backup or snapshot of your current system. |
44 | | -2. Confirm you have working rescue media. |
45 | | -3. Record current EFI entries: |
| 20 | +## CLI |
46 | 21 |
|
47 | 22 | ```bash |
48 | | -sudo efibootmgr -v |
| 23 | +rustyuki [OPTIONS] <COMMAND> |
49 | 24 | ``` |
50 | 25 |
|
51 | | -4. Confirm your root filesystem parameters (`root=UUID=...`, encryption/LVM args, etc.). |
52 | | -5. Keep at least one known-good boot entry in firmware boot order until you've validated the new UKI boots. |
| 26 | +Global options: |
53 | 27 |
|
54 | | -The setup script also creates local file backups under: |
| 28 | +- `--config <PATH>` (default `/etc/uki/uki.conf`) |
| 29 | +- `--dry-run` |
| 30 | +- `-v` (DEBUG), `-vv` (TRACE) |
55 | 31 |
|
56 | | -```bash |
57 | | -/var/backups/uki-setup/ |
58 | | -``` |
| 32 | +Subcommands: |
59 | 33 |
|
60 | | -for any existing files it overwrites. |
| 34 | +- `rustyuki generate` – generate a UKI and register EFI boot entry |
| 35 | +- `rustyuki install` – generate and run `bootctl update` |
| 36 | +- `rustyuki status` – print resolved runtime status |
61 | 37 |
|
62 | | ---- |
| 38 | +## Config file |
63 | 39 |
|
64 | | -## Quick start |
| 40 | +Default path: `/etc/uki/uki.conf` |
65 | 41 |
|
66 | | -One-line download + run from GitHub: |
| 42 | +```toml |
| 43 | +[uki] |
| 44 | +kernel_version = "" # defaults to uname -r if empty |
| 45 | +esp_path = "/boot/efi" |
| 46 | +output_dir = "/boot/efi/EFI/Linux" |
| 47 | +cmdline_file = "/etc/kernel/cmdline" |
| 48 | +splash = "" |
| 49 | +os_release = "/etc/os-release" |
67 | 50 |
|
68 | | -```bash |
69 | | -curl -fsSL https://raw.githubusercontent.com/GlitchSlayed/Fedora-UKI-Script/main/uki-setup.sh | sudo bash |
70 | | -``` |
| 51 | +[dracut] |
| 52 | +extra_args = [] |
71 | 53 |
|
72 | | -1. Clone this repository. |
73 | | -2. Optionally review configuration values at the top of `uki-setup.sh` (`AUTO_DETECT_CMDLINE` is enabled by default, while `CMDLINE` remains a manual fallback). |
74 | | -3. Run: |
75 | | - |
76 | | -```bash |
77 | | -sudo bash uki-setup.sh |
| 54 | +[ukify] |
| 55 | +extra_args = [] |
78 | 56 | ``` |
79 | 57 |
|
80 | | -After setup, future kernel install/remove operations should automatically update UKIs. |
81 | | - |
82 | | -> [!NOTE] |
83 | | -> The script auto-detects `dnf`, `apt`, `zypper`, or `pacman` and attempts to install needed dependencies with the detected package manager. |
84 | | -
|
85 | | ---- |
86 | | - |
87 | | -## Configuration options |
88 | | - |
89 | | -Configuration is in the **USER CONFIGURATION** section of `uki-setup.sh`. |
| 58 | +CLI flags override config values for `generate` and `install`. |
90 | 59 |
|
91 | | -### `EFI_DIR` |
92 | | -Directory on the ESP where UKIs are written. |
93 | | - |
94 | | -Default: |
| 60 | +## Build |
95 | 61 |
|
96 | 62 | ```bash |
97 | | -EFI_DIR="/boot/efi/EFI/Linux" |
| 63 | +cargo build --release |
98 | 64 | ``` |
99 | 65 |
|
100 | | -### `CMDLINE` |
101 | | -Kernel command line embedded into the UKI. |
102 | | - |
103 | | -Default fallback value: |
| 66 | +Binary: |
104 | 67 |
|
105 | 68 | ```bash |
106 | | -CMDLINE="root=UUID=REPLACE-ME rw quiet rhgb" |
| 69 | +target/release/rustyuki |
107 | 70 | ``` |
108 | 71 |
|
109 | | -This is only used when auto-detection is disabled or cannot find a usable bootable cmdline. Set it to your own known-good manual value as a backup. |
110 | | - |
111 | | -### `AUTO_DETECT_CMDLINE` |
112 | | -When set to `1`, command line is auto-detected in this order: |
113 | | - |
114 | | -1. `/proc/cmdline` (current running boot) |
115 | | -2. `/etc/kernel/cmdline` |
116 | | -3. `GRUB_CMDLINE_LINUX` from `/etc/default/grub` and `/etc/default/grub.d/*.cfg` |
117 | | - |
118 | | -If none of these provide a bootable command line (for example one containing `root=`), the script falls back to `CMDLINE`. |
119 | | - |
120 | | -Default: |
121 | | - |
122 | | -```bash |
123 | | -AUTO_DETECT_CMDLINE=1 |
124 | | -``` |
125 | | - |
126 | | -### `UKIFY_SB_KEY` / `UKIFY_SB_CERT` |
127 | | -Optional Secure Boot signing key/certificate paths. If both are set, ukify receives a temporary `[UKI]` config and signs as part of assembly. |
128 | | - |
129 | | -Default: |
130 | | - |
131 | | -```bash |
132 | | -UKIFY_SB_KEY="" |
133 | | -UKIFY_SB_CERT="" |
134 | | -``` |
135 | | - |
136 | | -Leave empty to build unsigned UKIs. |
137 | | - |
138 | | -### Initramfs validation controls |
139 | | -The generated `uki-build.sh` validates the standalone initramfs **before** ukify is run: |
140 | | - |
141 | | -- runs `lsinitrd` and verifies `/init` exists |
142 | | -- unpacks the initramfs (`lsinitrd --unpack`) and builds a normalized file list |
143 | | -- optionally checks required/forbidden path lists |
144 | | -- stores and compares manifests to catch regressions between builds of the same kernel |
145 | | - |
146 | | -Configuration keys in `uki-setup.sh` / generated `uki-build.sh`: |
| 72 | +## Example usage |
147 | 73 |
|
148 | 74 | ```bash |
149 | | -INITRAMFS_REQUIRED_LIST="/etc/uki/initramfs-required.txt" |
150 | | -INITRAMFS_FORBIDDEN_LIST="/etc/uki/initramfs-forbidden.txt" |
151 | | -INITRAMFS_STATE_DIR="/var/lib/uki-build" |
152 | | -INITRAMFS_STRICT_DIFF=0 |
| 75 | +sudo target/release/rustyuki status |
| 76 | +sudo target/release/rustyuki generate |
| 77 | +sudo target/release/rustyuki install --kernel-version "$(uname -r)" |
153 | 78 | ``` |
154 | 79 |
|
155 | | -If `INITRAMFS_STRICT_DIFF=1`, content changes versus the previous manifest for that kernel fail the build early. |
156 | | - |
157 | | ---- |
158 | | - |
159 | | - |
160 | | -## Continuous integration checks |
161 | | - |
162 | | -GitHub Actions now runs checks in a Fedora container (`fedora:41`) on every push and pull request. The workflow verifies: |
163 | | - |
164 | | -- Bash syntax for `uki-setup.sh` and test scripts. |
165 | | -- `shellcheck` linting. |
166 | | -- A project check script that sources `uki-setup.sh` with `UKI_SETUP_SKIP_MAIN=1` and validates the generated helper/plugin templates and initramfs validation settings. |
167 | | - |
168 | | -Run the same checks locally with: |
169 | | - |
170 | | -```bash |
171 | | -bash -n uki-setup.sh tests/test_uki_setup.sh |
172 | | -shellcheck -P . uki-setup.sh tests/test_uki_setup.sh |
173 | | -bash tests/test_uki_setup.sh |
174 | | -``` |
175 | | - |
176 | | ---- |
177 | | - |
178 | | -## Files created by setup |
179 | | - |
180 | | -Running `uki-setup.sh` creates/updates: |
181 | | - |
182 | | -- `/usr/local/sbin/uki-build.sh` — manual/automated UKI rebuild helper. |
183 | | -- `/usr/lib/kernel/install.d/90-uki-ukify.install` — kernel-install plugin. |
184 | | -- `/etc/kernel/install.d/*.install -> /dev/null` overrides for selected default plugins. |
185 | | - |
186 | | ---- |
187 | | - |
188 | | -## Manual operations |
189 | | - |
190 | | -### Rebuild UKI for current kernel |
191 | | - |
192 | | -```bash |
193 | | -sudo /usr/local/sbin/uki-build.sh "$(uname -r)" |
194 | | -``` |
195 | | - |
196 | | -### Rebuild UKI for a specific installed kernel |
197 | | - |
198 | | -```bash |
199 | | -sudo /usr/local/sbin/uki-build.sh 6.11.4-200.fc40.x86_64 |
200 | | -``` |
201 | | - |
202 | | -### Check EFI boot entries |
203 | | - |
204 | | -```bash |
205 | | -efibootmgr -v |
206 | | -``` |
207 | | - |
208 | | -### List generated UKIs |
209 | | - |
210 | | -```bash |
211 | | -ls -lh /boot/efi/EFI/Linux/*.efi |
212 | | -``` |
213 | | - |
214 | | ---- |
215 | | - |
216 | | -## Updating configuration after first run |
217 | | - |
218 | | -After initial setup, edit settings in: |
219 | | - |
220 | | -```bash |
221 | | -/usr/local/sbin/uki-build.sh |
222 | | -``` |
223 | | - |
224 | | -The setup script templates values into this file during installation. |
225 | | - |
226 | | ---- |
227 | | - |
228 | | -## Rollback / uninstall (manual) |
229 | | - |
230 | | -If you want to return to your previous boot flow, you can: |
231 | | - |
232 | | -1. Remove custom plugin and helper script: |
233 | | - |
234 | | -```bash |
235 | | -sudo rm -f /usr/lib/kernel/install.d/90-uki-ukify.install |
236 | | -sudo rm -f /usr/local/sbin/uki-build.sh |
237 | | -``` |
238 | | - |
239 | | -2. Remove override symlinks created by this setup: |
240 | | - |
241 | | -```bash |
242 | | -sudo rm -f \ |
243 | | - /etc/kernel/install.d/20-grub.install \ |
244 | | - /etc/kernel/install.d/50-depmod.install \ |
245 | | - /etc/kernel/install.d/90-loaderentry.install \ |
246 | | - /etc/kernel/install.d/92-crashkernel.install \ |
247 | | - /etc/kernel/install.d/95-kernel-install.install |
248 | | -``` |
249 | | - |
250 | | -3. Optionally delete generated UKIs from ESP and remove corresponding EFI entries with `efibootmgr`. |
251 | | - |
252 | | ---- |
253 | | - |
254 | | -## Troubleshooting |
255 | | - |
256 | | -- **UEFI not detected**: Ensure firmware boot mode is UEFI and that `efivars`/ESP are accessible. |
257 | | -- **ESP not mounted**: The script now checks `/boot/efi`, `/efi`, `/boot`, `/boot/EFI`, and `/esp`, then attempts automatic mounting (via fstab first, then ESP partition detection). If that still fails, mount it manually and rerun. |
258 | | -- **UKI fails to boot**: Re-check `CMDLINE` and storage-related boot args. |
259 | | -- **ukify missing**: Install your distro package that provides `ukify` (`systemd-ukify` on Fedora family systems). |
260 | | -- **Initramfs validation fails**: inspect `lsinitrd` output, verify your required/forbidden list files, and review manifest diffs under `INITRAMFS_STATE_DIR`. |
261 | | -- **No Secure Boot signing**: set both `UKIFY_SB_KEY` and `UKIFY_SB_CERT` in the generated build script. |
| 80 | +## Safety notes |
262 | 81 |
|
263 | | ---- |
| 82 | +- Root is required. |
| 83 | +- Ensure your ESP is mounted and writable before generating UKIs. |
| 84 | +- Keep a known-good boot entry until new UKIs are confirmed bootable. |
264 | 85 |
|
265 | | -## License |
| 86 | +## Legacy script |
266 | 87 |
|
267 | | -MIT — see [LICENSE](LICENSE). |
| 88 | +The original `uki-setup.sh` remains in the repository for reference/migration context. |
0 commit comments