|
| 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 | + debugEnable = config.ghaf.profiles.debug.enable; |
| 15 | +in |
| 16 | +{ |
| 17 | + options.ghaf.partitioning.verity = { |
| 18 | + enable = lib.mkEnableOption "the verity (image-based) partitioning scheme"; |
| 19 | + |
| 20 | + split = lib.mkOption { |
| 21 | + description = "Whether to split the partitions to separate files instead of a single image"; |
| 22 | + type = lib.types.bool; |
| 23 | + default = false; |
| 24 | + }; |
| 25 | + }; |
| 26 | + |
| 27 | + imports = [ |
| 28 | + "${modulesPath}/image/repart.nix" |
| 29 | + "${modulesPath}/system/boot/uki.nix" |
| 30 | + ]; |
| 31 | + |
| 32 | + config = lib.mkIf cfg.enable { |
| 33 | + |
| 34 | + system.build.ghafImage = config.system.build.image.overrideAttrs (oldAttrs: { |
| 35 | + nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ pkgs.jq ]; |
| 36 | + postInstall = '' |
| 37 | + # Extract the roothash from the JSON |
| 38 | + repartRoothash="$( |
| 39 | + ${lib.getExe pkgs.jq} -r \ |
| 40 | + '[.[] | select(.roothash != null)] | .[0].roothash' \ |
| 41 | + "$out/repart-output.json" |
| 42 | + )" |
| 43 | +
|
| 44 | + # Replace the placeholder with the real roothash in the target .raw file |
| 45 | + sed -i \ |
| 46 | + "0,/${roothashPlaceholder}/ s/${roothashPlaceholder}/$repartRoothash/" \ |
| 47 | + "$out/${oldAttrs.pname}_${oldAttrs.version}.raw" |
| 48 | +
|
| 49 | + # Compress the image |
| 50 | + ${pkgs.zstd}/bin/zstd --compress $out/*raw |
| 51 | + rm $out/*raw |
| 52 | + ''; |
| 53 | + }); |
| 54 | + |
| 55 | + image.repart.split = cfg.split; |
| 56 | + |
| 57 | + systemd.enableEmergencyMode = debugEnable; |
| 58 | + |
| 59 | + boot = { |
| 60 | + kernelParams = [ |
| 61 | + "roothash=${roothashPlaceholder}" |
| 62 | + "systemd.verity_root_options=panic-on-corruption" |
| 63 | + ] ++ lib.optional debugEnable "systemd.setenv=SYSTEMD_SULOGIN_FORCE=1"; |
| 64 | + |
| 65 | + # No bootloaders needed yet |
| 66 | + loader = { |
| 67 | + grub.enable = false; |
| 68 | + systemd-boot.enable = lib.mkForce false; |
| 69 | + }; |
| 70 | + |
| 71 | + # Enable dm-verity and compress initrd |
| 72 | + initrd = { |
| 73 | + systemd = { |
| 74 | + enable = true; |
| 75 | + dmVerity.enable = true; |
| 76 | + emergencyAccess = debugEnable; |
| 77 | + }; |
| 78 | + |
| 79 | + compressor = "zstd"; |
| 80 | + compressorArgs = [ "-6" ]; |
| 81 | + |
| 82 | + supportedFilesystems = { |
| 83 | + btrfs = true; |
| 84 | + erofs = true; |
| 85 | + }; |
| 86 | + }; |
| 87 | + }; |
| 88 | + |
| 89 | + environment.systemPackages = with pkgs; [ |
| 90 | + cryptsetup |
| 91 | + ]; |
| 92 | + |
| 93 | + # System is now immutable |
| 94 | + system.switch.enable = false; |
| 95 | + |
| 96 | + fileSystems = |
| 97 | + let |
| 98 | + tmpfsConfig = { |
| 99 | + neededForBoot = true; |
| 100 | + fsType = "tmpfs"; |
| 101 | + }; |
| 102 | + in |
| 103 | + { |
| 104 | + "/" = { |
| 105 | + fsType = "erofs"; |
| 106 | + # for systemd-remount-fs |
| 107 | + options = [ "ro" ]; |
| 108 | + device = "/dev/mapper/root"; |
| 109 | + }; |
| 110 | + |
| 111 | + "/persist" = |
| 112 | + let |
| 113 | + partConf = config.image.repart.partitions."50-persist".repartConfig; |
| 114 | + in |
| 115 | + { |
| 116 | + device = "/dev/disk/by-partuuid/${partConf.UUID}"; |
| 117 | + fsType = partConf.Format; |
| 118 | + }; |
| 119 | + } |
| 120 | + // builtins.listToAttrs ( |
| 121 | + builtins.map |
| 122 | + (path: { |
| 123 | + name = path; |
| 124 | + value = tmpfsConfig; |
| 125 | + }) |
| 126 | + [ |
| 127 | + "/bin" # /bin/sh symlink needs to be created |
| 128 | + "/etc" |
| 129 | + "/home" |
| 130 | + "/root" |
| 131 | + "/tmp" |
| 132 | + "/usr" # /usr/bin/env symlink needs to be created |
| 133 | + "/var" |
| 134 | + ] |
| 135 | + ); |
| 136 | + }; |
| 137 | +} |
0 commit comments