vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / image / repart-image.nix
blobcc4c2211e3d3034c1921cae64c42a0b19ba96066
1 # This is an expression meant to be called from `./repart.nix`, it is NOT a
2 # NixOS module that can be imported.
4 { lib
5 , stdenvNoCC
6 , runCommand
7 , python3
8 , black
9 , ruff
10 , mypy
11 , systemd
12 , fakeroot
14   # filesystem tools
15 , dosfstools
16 , mtools
17 , e2fsprogs
18 , squashfsTools
19 , erofs-utils
20 , btrfs-progs
21 , xfsprogs
23   # compression tools
24 , zstd
25 , xz
27   # arguments
28 , name
29 , version
30 , imageFileBasename
31 , compression
32 , fileSystems
33 , finalPartitions
34 , split
35 , seed
36 , definitionsDirectory
37 , sectorSize
38 , mkfsEnv ? {}
39 , createEmpty ? true
42 let
43   systemdArch = let
44     inherit (stdenvNoCC) hostPlatform;
45   in
46     if hostPlatform.isAarch32 then "arm"
47     else if hostPlatform.isAarch64 then "arm64"
48     else if hostPlatform.isx86_32 then "x86"
49     else if hostPlatform.isx86_64 then "x86-64"
50     else if hostPlatform.isMips32 then "mips-le"
51     else if hostPlatform.isMips64 then "mips64-le"
52     else if hostPlatform.isPower then "ppc"
53     else if hostPlatform.isPower64 then "ppc64"
54     else if hostPlatform.isRiscV32 then "riscv32"
55     else if hostPlatform.isRiscV64 then "riscv64"
56     else if hostPlatform.isS390 then "s390"
57     else if hostPlatform.isS390x then "s390x"
58     else if hostPlatform.isLoongArch64 then "loongarch64"
59     else if hostPlatform.isAlpha then "alpha"
60     else hostPlatform.parsed.cpu.name;
62   amendRepartDefinitions = runCommand "amend-repart-definitions.py"
63     {
64       # TODO: ruff does not splice properly in nativeBuildInputs
65       depsBuildBuild = [ ruff ];
66       nativeBuildInputs = [ python3 black mypy ];
67     } ''
68     install ${./amend-repart-definitions.py} $out
69     patchShebangs --build $out
71     black --check --diff $out
72     ruff check --line-length 88 $out
73     mypy --strict $out
74   '';
76   fileSystemToolMapping = {
77     "vfat" = [ dosfstools mtools ];
78     "ext4" = [ e2fsprogs.bin ];
79     "squashfs" = [ squashfsTools ];
80     "erofs" = [ erofs-utils ];
81     "btrfs" = [ btrfs-progs ];
82     "xfs" = [ xfsprogs ];
83   };
85   fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems;
87   compressionPkg = {
88     "zstd" = zstd;
89     "xz" = xz;
90   }."${compression.algorithm}";
92   compressionCommand = {
93     "zstd" = "zstd --no-progress --threads=$NIX_BUILD_CORES -${toString compression.level}";
94     "xz" = "xz --keep --verbose --threads=$NIX_BUILD_CORES -${toString compression.level}";
95   }."${compression.algorithm}";
97   stdenvNoCC.mkDerivation (finalAttrs:
98   (if (version != null)
99   then { pname = name; inherit version; }
100   else { inherit name;  }
101   ) // {
102   __structuredAttrs = true;
104   nativeBuildInputs = [
105     systemd
106     fakeroot
107   ] ++ lib.optionals (compression.enable) [
108     compressionPkg
109   ] ++ fileSystemTools;
111   env = mkfsEnv;
113   inherit finalPartitions definitionsDirectory;
115   partitionsJSON = builtins.toJSON finalAttrs.finalPartitions;
117   # relative path to the repart definitions that are read by systemd-repart
118   finalRepartDefinitions = "repart.d";
120   systemdRepartFlags = [
121     "--architecture=${systemdArch}"
122     "--dry-run=no"
123     "--size=auto"
124     "--seed=${seed}"
125     "--definitions=${finalAttrs.finalRepartDefinitions}"
126     "--split=${lib.boolToString split}"
127     "--json=pretty"
128   ] ++ lib.optionals createEmpty [
129     "--empty=create"
130   ] ++ lib.optionals (sectorSize != null) [
131     "--sector-size=${toString sectorSize}"
132   ];
134   dontUnpack = true;
135   dontConfigure = true;
136   doCheck = false;
138   patchPhase = ''
139     runHook prePatch
141     amendedRepartDefinitionsDir=$(${amendRepartDefinitions} <(echo "$partitionsJSON") $definitionsDirectory)
142     ln -vs $amendedRepartDefinitionsDir $finalRepartDefinitions
144     runHook postPatch
145   '';
147   buildPhase = ''
148     runHook preBuild
150     echo "Building image with systemd-repart..."
151     fakeroot systemd-repart \
152       ''${systemdRepartFlags[@]} \
153       ${imageFileBasename}.raw \
154       | tee repart-output.json
156     runHook postBuild
157   '';
159   installPhase = ''
160     runHook preInstall
162     mkdir -p $out
163   ''
164   # Compression is implemented in the same derivation as opposed to in a
165   # separate derivation to allow users to save disk space. Disk images are
166   # already very space intensive so we want to allow users to mitigate this.
167   + lib.optionalString compression.enable
168   ''
169     for f in ${imageFileBasename}*; do
170       echo "Compressing $f with ${compression.algorithm}..."
171       # Keep the original file when compressing and only delete it afterwards
172       ${compressionCommand} $f && rm $f
173     done
174   '' + ''
175     mv -v repart-output.json ${imageFileBasename}* $out
177     runHook postInstall
178   '';
180   passthru = {
181     inherit amendRepartDefinitions;
182   };