Skip to content

Commit b9e288f

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

File tree

13 files changed

+425
-100
lines changed

13 files changed

+425
-100
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: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
22
# SPDX-License-Identifier: Apache-2.0
33
{
4-
config,
54
pkgs,
6-
lib,
75
...
86
}:
97
let
10-
cfg = config.ghaf.partitioning.disko;
11-
128
postBootCmds = pkgs.writeShellApplication {
139
name = "postBootScript";
1410
runtimeInputs = with pkgs; [
@@ -49,7 +45,7 @@ let
4945
};
5046
in
5147
{
52-
config = lib.mkIf cfg.enable {
48+
config = {
5349
# To debug postBootCommands, one may run
5450
# journalctl -u initrd-nixos-activation.service
5551
# inside the running Ghaf host.

modules/partitioning/disko-debug-partition.nix

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ let
2323
in
2424
{
2525
options.ghaf.partitioning.disko = {
26-
enable = lib.mkEnableOption "Enable the disko partitioning scheme";
27-
2826
imageBuilder.compression = lib.mkOption {
2927
type = lib.types.enum [
3028
"none"
@@ -35,7 +33,8 @@ in
3533
};
3634
};
3735

38-
config = lib.mkIf cfg.enable {
36+
config = {
37+
system.build.ghafImage = config.system.build.diskoImages;
3938
disko = {
4039
imageBuilder = {
4140
extraPostVM = lib.mkIf (cfg.imageBuilder.compression == "zstd") ''
@@ -44,71 +43,73 @@ in
4443
'';
4544
};
4645
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-
];
46+
disk = {
47+
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
7158
};
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;
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+
];
71+
};
72+
priority = 2;
8173
};
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-
];
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;
81+
};
82+
priority = 3;
9483
};
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-
];
84+
root = {
85+
size = "40G";
86+
content = {
87+
type = "filesystem";
88+
format = "ext4";
89+
mountpoint = "/";
90+
mountOptions = [
91+
"noatime"
92+
"nodiratime"
93+
];
94+
};
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+
];
107+
};
107108
};
108109
};
109110
};
110111
};
111-
};
112+
} // (if (builtins.hasAttr "disks" cfg) then cfg.disks else { });
112113
};
113114
};
114115
};

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: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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+
split = lib.mkOption {
18+
description = "Whether to split the partitions to separate files instead of a single image";
19+
type = lib.types.bool;
20+
default = false;
21+
};
22+
};
23+
24+
config = {
25+
imports = [
26+
"${modulesPath}/image/repart.nix"
27+
"${modulesPath}/system/boot/uki.nix"
28+
];
29+
30+
system.build.ghafImage = config.system.build.image.overrideAttrs (oldAttrs: {
31+
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ pkgs.jq ];
32+
postInstall = ''
33+
# Extract the roothash from the JSON
34+
repartRoothash="$(
35+
${lib.getExe pkgs.jq} -r \
36+
'[.[] | select(.roothash != null)] | .[0].roothash' \
37+
"$out/repart-output.json"
38+
)"
39+
40+
# Replace the placeholder with the real roothash in the target .raw file
41+
sed -i \
42+
"0,/${roothashPlaceholder}/ s/${roothashPlaceholder}/$repartRoothash/" \
43+
"$out/${oldAttrs.pname}_${oldAttrs.version}.raw"
44+
'';
45+
});
46+
47+
boot.kernelParams = [
48+
"roothash=${roothashPlaceholder}"
49+
];
50+
51+
# TODO remove these
52+
boot.initrd.systemd.initrdBin = [
53+
pkgs.less
54+
pkgs.util-linux
55+
];
56+
ghaf.systemd.withDebug = true;
57+
nixpkgs.config.allowUnfree = true;
58+
# TODO end
59+
60+
image.repart.split = cfg.split;
61+
62+
boot.loader.grub.enable = false;
63+
boot.loader.systemd-boot.enable = lib.mkForce false;
64+
boot.initrd.systemd = {
65+
enable = true;
66+
dmVerity.enable = true;
67+
};
68+
69+
boot.initrd.compressor = "zstd";
70+
boot.initrd.compressorArgs = [ "-6" ];
71+
environment.systemPackages = with pkgs; [
72+
cryptsetup
73+
];
74+
75+
# System is now immutable
76+
system.switch.enable = false;
77+
78+
# For some reason this needs to be true
79+
users.mutableUsers = lib.mkForce true;
80+
81+
services.getty.autologinUser = "root";
82+
83+
boot.initrd.supportedFilesystems = {
84+
btrfs = true;
85+
erofs = true;
86+
};
87+
88+
fileSystems =
89+
let
90+
tmpfsConfig = {
91+
neededForBoot = true;
92+
fsType = "tmpfs";
93+
};
94+
in
95+
{
96+
"/" = {
97+
fsType = "erofs";
98+
# for systemd-remount-fs
99+
options = [ "ro" ];
100+
device = "/dev/mapper/root";
101+
};
102+
103+
"/persist" =
104+
let
105+
partConf = config.image.repart.partitions."50-persist".repartConfig;
106+
in
107+
{
108+
device = "/dev/disk/by-partuuid/${partConf.UUID}";
109+
fsType = partConf.Format;
110+
};
111+
}
112+
// builtins.listToAttrs (
113+
builtins.map
114+
(path: {
115+
name = path;
116+
value = tmpfsConfig;
117+
})
118+
[
119+
"/bin" # /bin/sh symlink needs to be created
120+
"/etc"
121+
"/home"
122+
"/root"
123+
"/tmp"
124+
"/usr" # /usr/bin/env symlink needs to be created
125+
"/var"
126+
]
127+
);
128+
};
129+
}

0 commit comments

Comments
 (0)