Skip to content

Commit 0a8563e

Browse files
committed
lenovo-x1-extras: build image with dm-verity
Signed-off-by: Humaid Alqasimi <humaid.alqassimi@tii.ae>
1 parent bccae76 commit 0a8563e

File tree

13 files changed

+426
-81
lines changed

13 files changed

+426
-81
lines changed

modules/common/systemd/base.nix

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ let
5959
inherit (cfg) withUkify;
6060
withUserDb = cfg.withHomed;
6161
withUtmp = cfg.withJournal || cfg.withAudit;
62+
withSysupdate = true;
6263
}
6364
// lib.optionalAttrs (lib.strings.versionAtLeast pkgs.systemdMinimal.version "255.0") {
6465
withVmspawn = cfg.withMachines;
@@ -230,7 +231,7 @@ in
230231
withRepart = mkOption {
231232
description = "Enable systemd repart functionality.";
232233
type = types.bool;
233-
default = false;
234+
default = true;
234235
};
235236

236237
withHomed = mkOption {
@@ -290,13 +291,13 @@ in
290291
withCryptsetup = mkOption {
291292
description = "Enable systemd LUKS2 functionality.";
292293
type = types.bool;
293-
default = false;
294+
default = true;
294295
};
295296

296297
withFido2 = mkOption {
297298
description = "Enable systemd Fido2 token functionality.";
298299
type = types.bool;
299-
default = false;
300+
default = true;
300301
};
301302

302303
withTpm2Tss = mkOption {

modules/hardware/common/input.nix

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ let
2626
in
2727
{
2828
config = {
29-
# Disk configuration
30-
# TODO Remove or move this
31-
disko.devices.disk = cfg.disks;
32-
3329
# Host udev rules for input devices
3430
services.udev.extraRules = ''
3531
# Keyboard
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
22
# SPDX-License-Identifier: Apache-2.0
33
{
4-
config,
54
pkgs,
5+
config,
66
lib,
77
...
88
}:
99
let
10-
cfg = config.ghaf.partitioning.disko;
11-
1210
postBootCmds = pkgs.writeShellApplication {
1311
name = "postBootScript";
1412
runtimeInputs = with pkgs; [
@@ -47,9 +45,13 @@ let
4745
parted -s -a opt "$PARENT_DISK" "resizepart $PARTNUM 100%"
4846
'';
4947
};
48+
49+
enable =
50+
((builtins.hasAttr "verity" config.ghaf.partitioning) && config.ghaf.partitioning.verity.enable)
51+
|| ((builtins.hasAttr "disko" config.ghaf.partitioning) && config.ghaf.partitioning.disko.enable);
5052
in
5153
{
52-
config = lib.mkIf cfg.enable {
54+
config = lib.mkIf enable {
5355
# To debug postBootCommands, one may run
5456
# journalctl -u initrd-nixos-activation.service
5557
# inside the running Ghaf host.

modules/partitioning/disko-debug-partition.nix

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let
2323
in
2424
{
2525
options.ghaf.partitioning.disko = {
26-
enable = lib.mkEnableOption "Enable the disko partitioning scheme";
26+
enable = lib.mkEnableOption "the disko partitioning scheme";
2727

2828
imageBuilder.compression = lib.mkOption {
2929
type = lib.types.enum [
@@ -36,6 +36,7 @@ in
3636
};
3737

3838
config = lib.mkIf cfg.enable {
39+
system.build.ghafImage = config.system.build.diskoImages;
3940
disko = {
4041
imageBuilder = {
4142
extraPostVM = lib.mkIf (cfg.imageBuilder.compression == "zstd") ''
@@ -44,71 +45,73 @@ in
4445
'';
4546
};
4647
devices = {
47-
disk.disk1 = {
48-
type = "disk";
49-
imageSize = "60G";
50-
content = {
51-
type = "gpt";
52-
partitions = {
53-
boot = {
54-
name = "boot";
55-
size = "1M";
56-
type = "EF02";
57-
priority = 1; # Needs to be first partition
58-
};
59-
esp = {
60-
name = "ESP";
61-
size = "500M";
62-
type = "EF00";
63-
content = {
64-
type = "filesystem";
65-
format = "vfat";
66-
mountpoint = "/boot";
67-
mountOptions = [
68-
"umask=0077"
69-
"nofail"
70-
];
48+
disk = {
49+
disk1 = {
50+
type = "disk";
51+
imageSize = "60G";
52+
content = {
53+
type = "gpt";
54+
partitions = {
55+
boot = {
56+
name = "boot";
57+
size = "1M";
58+
type = "EF02";
59+
priority = 1; # Needs to be first partition
7160
};
72-
priority = 2;
73-
};
74-
swap = {
75-
size = "12G";
76-
type = "8200";
77-
content = {
78-
type = "swap";
79-
resumeDevice = true; # resume from hiberation from this device
80-
randomEncryption = true;
61+
esp = {
62+
name = "ESP";
63+
size = "500M";
64+
type = "EF00";
65+
content = {
66+
type = "filesystem";
67+
format = "vfat";
68+
mountpoint = "/boot";
69+
mountOptions = [
70+
"umask=0077"
71+
"nofail"
72+
];
73+
};
74+
priority = 2;
8175
};
82-
priority = 3;
83-
};
84-
root = {
85-
size = "40G";
86-
content = {
87-
type = "filesystem";
88-
format = "ext4";
89-
mountpoint = "/";
90-
mountOptions = [
91-
"noatime"
92-
"nodiratime"
93-
];
76+
swap = {
77+
size = "12G";
78+
type = "8200";
79+
content = {
80+
type = "swap";
81+
resumeDevice = true; # resume from hiberation from this device
82+
randomEncryption = true;
83+
};
84+
priority = 3;
9485
};
95-
priority = 4;
96-
};
97-
persist = {
98-
size = "100%";
99-
content = {
100-
type = "filesystem";
101-
format = "btrfs";
102-
mountpoint = "/persist";
103-
mountOptions = [
104-
"noatime"
105-
"nodiratime"
106-
];
86+
root = {
87+
size = "40G";
88+
content = {
89+
type = "filesystem";
90+
format = "ext4";
91+
mountpoint = "/";
92+
mountOptions = [
93+
"noatime"
94+
"nodiratime"
95+
];
96+
};
97+
priority = 4;
98+
};
99+
persist = {
100+
size = "100%";
101+
content = {
102+
type = "filesystem";
103+
format = "btrfs";
104+
mountpoint = "/persist";
105+
mountOptions = [
106+
"noatime"
107+
"nodiratime"
108+
];
109+
};
107110
};
108111
};
109112
};
110113
};
111-
};
114+
} // (if (builtins.hasAttr "disks" cfg) then cfg.disks else { });
112115
};
113116
};
114117
};

modules/partitioning/flake-module.nix

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
disko-debug-partition.imports = [
77
inputs.disko.nixosModules.disko
88
./disko-debug-partition.nix
9-
./disko-postboot.nix
9+
./btrfs-postboot.nix
10+
];
11+
verity-release-partition.imports = [
12+
./verity-partition.nix
13+
./verity-repart.nix
14+
./verity-sysupdate.nix
15+
./btrfs-postboot.nix
1016
];
1117
};
1218
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Copyright 2025 TII (SSRC) and the Ghaf contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
{
4+
config,
5+
lib,
6+
pkgs,
7+
modulesPath,
8+
...
9+
}:
10+
11+
let
12+
roothashPlaceholder = "61fe0f0c98eff2a595dd2f63a5e481a0a25387261fa9e34c37e3a4910edf32b8";
13+
cfg = config.ghaf.partitioning.verity;
14+
in
15+
{
16+
options.ghaf.partitioning.verity = {
17+
enable = lib.mkEnableOption "the verity (image-based) partitioning scheme";
18+
19+
split = lib.mkOption {
20+
description = "Whether to split the partitions to separate files instead of a single image";
21+
type = lib.types.bool;
22+
default = false;
23+
};
24+
};
25+
26+
imports = [
27+
"${modulesPath}/image/repart.nix"
28+
"${modulesPath}/system/boot/uki.nix"
29+
];
30+
31+
config = lib.mkIf cfg.enable {
32+
33+
system.build.ghafImage = config.system.build.image.overrideAttrs (oldAttrs: {
34+
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ pkgs.jq ];
35+
postInstall = ''
36+
# Extract the roothash from the JSON
37+
repartRoothash="$(
38+
${lib.getExe pkgs.jq} -r \
39+
'[.[] | select(.roothash != null)] | .[0].roothash' \
40+
"$out/repart-output.json"
41+
)"
42+
43+
# Replace the placeholder with the real roothash in the target .raw file
44+
sed -i \
45+
"0,/${roothashPlaceholder}/ s/${roothashPlaceholder}/$repartRoothash/" \
46+
"$out/${oldAttrs.pname}_${oldAttrs.version}.raw"
47+
'';
48+
});
49+
50+
image.repart.split = cfg.split;
51+
52+
boot = {
53+
kernelParams = [
54+
"roothash=${roothashPlaceholder}"
55+
];
56+
57+
# No bootloaders needed yet
58+
loader = {
59+
grub.enable = false;
60+
systemd-boot.enable = lib.mkForce false;
61+
};
62+
63+
# Enable dm-verity and compress initrd
64+
initrd = {
65+
systemd = {
66+
enable = true;
67+
dmVerity.enable = true;
68+
};
69+
70+
compressor = "zstd";
71+
compressorArgs = [ "-6" ];
72+
73+
supportedFilesystems = {
74+
btrfs = true;
75+
erofs = true;
76+
};
77+
};
78+
};
79+
80+
environment.systemPackages = with pkgs; [
81+
cryptsetup
82+
];
83+
84+
# System is now immutable
85+
system.switch.enable = false;
86+
87+
services.getty.autologinUser = "root";
88+
89+
fileSystems =
90+
let
91+
tmpfsConfig = {
92+
neededForBoot = true;
93+
fsType = "tmpfs";
94+
};
95+
in
96+
{
97+
"/" = {
98+
fsType = "erofs";
99+
# for systemd-remount-fs
100+
options = [ "ro" ];
101+
device = "/dev/mapper/root";
102+
};
103+
104+
"/persist" =
105+
let
106+
partConf = config.image.repart.partitions."50-persist".repartConfig;
107+
in
108+
{
109+
device = "/dev/disk/by-partuuid/${partConf.UUID}";
110+
fsType = partConf.Format;
111+
};
112+
}
113+
// builtins.listToAttrs (
114+
builtins.map
115+
(path: {
116+
name = path;
117+
value = tmpfsConfig;
118+
})
119+
[
120+
"/bin" # /bin/sh symlink needs to be created
121+
"/etc"
122+
"/home"
123+
"/root"
124+
"/tmp"
125+
"/usr" # /usr/bin/env symlink needs to be created
126+
"/var"
127+
]
128+
);
129+
};
130+
}

0 commit comments

Comments
 (0)