diff --git a/nixos/modules/image/repart-image.nix b/nixos/modules/image/repart-image.nix new file mode 100644 index 000000000000..b4a1dfe51ff3 --- /dev/null +++ b/nixos/modules/image/repart-image.nix @@ -0,0 +1,80 @@ +# This is an expression meant to be called from `./repart.nix`, it is NOT a +# NixOS module that can be imported. + +{ lib +, runCommand +, python3 +, black +, ruff +, mypy +, systemd +, fakeroot +, util-linux +, dosfstools +, mtools +, e2fsprogs +, squashfsTools +, erofs-utils +, btrfs-progs +, xfsprogs + + # arguments +, name +, fileSystems +, partitions +, split +, seed +, definitionsDirectory +}: + +let + amendRepartDefinitions = runCommand "amend-repart-definitions.py" + { + # TODO: ruff does not splice properly in nativeBuildInputs + depsBuildBuild = [ ruff ]; + nativeBuildInputs = [ python3 black mypy ]; + } '' + install ${./amend-repart-definitions.py} $out + patchShebangs --build $out + + black --check --diff $out + ruff --line-length 88 $out + mypy --strict $out + ''; + + fileSystemToolMapping = { + "vfat" = [ dosfstools mtools ]; + "ext4" = [ e2fsprogs.bin ]; + "squashfs" = [ squashfsTools ]; + "erofs" = [ erofs-utils ]; + "btrfs" = [ btrfs-progs ]; + "xfs" = [ xfsprogs ]; + }; + + fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems; +in + +runCommand name +{ + nativeBuildInputs = [ + systemd + fakeroot + util-linux + ] ++ fileSystemTools; +} '' + amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory}) + + mkdir -p $out + cd $out + + unshare --map-root-user fakeroot systemd-repart \ + --dry-run=no \ + --empty=create \ + --size=auto \ + --seed="${seed}" \ + --definitions="$amendedRepartDefinitions" \ + --split="${lib.boolToString split}" \ + --json=pretty \ + image.raw \ + | tee repart-output.json +'' diff --git a/nixos/modules/image/repart.nix b/nixos/modules/image/repart.nix index 41e6110885b8..da4f45d9a639 100644 --- a/nixos/modules/image/repart.nix +++ b/nixos/modules/image/repart.nix @@ -90,8 +90,10 @@ in }; package = lib.mkPackageOption pkgs "systemd-repart" { - default = "systemd"; - example = "pkgs.systemdMinimal.override { withCryptsetup = true; }"; + # We use buildPackages so that repart images are built with the build + # platform's systemd, allowing for cross-compiled systems to work. + default = [ "buildPackages" "systemd" ]; + example = "pkgs.buildPackages.systemdMinimal.override { withCryptsetup = true; }"; }; partitions = lib.mkOption { @@ -131,22 +133,10 @@ in system.build.image = let - fileSystemToolMapping = with pkgs; { - "vfat" = [ dosfstools mtools ]; - "ext4" = [ e2fsprogs.bin ]; - "squashfs" = [ squashfsTools ]; - "erofs" = [ erofs-utils ]; - "btrfs" = [ btrfs-progs ]; - "xfs" = [ xfsprogs ]; - }; - fileSystems = lib.filter (f: f != null) (lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions); - fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems; - - makeClosure = paths: pkgs.closureInfo { rootPaths = paths; }; # Add the closure of the provided Nix store paths to cfg.partitions so @@ -157,23 +147,8 @@ in { closure = "${makeClosure partitionConfig.storePaths}/store-paths"; } ); - finalPartitions = lib.mapAttrs addClosure cfg.partitions; - - amendRepartDefinitions = pkgs.runCommand "amend-repart-definitions.py" - { - nativeBuildInputs = with pkgs; [ black ruff mypy ]; - buildInputs = [ pkgs.python3 ]; - } '' - install ${./amend-repart-definitions.py} $out - patchShebangs --host $out - - black --check --diff $out - ruff --line-length 88 $out - mypy --strict $out - ''; - format = pkgs.formats.ini { }; definitionsDirectory = utils.systemdUtils.lib.definitions @@ -183,30 +158,11 @@ in partitions = pkgs.writeText "partitions.json" (builtins.toJSON finalPartitions); in - pkgs.runCommand cfg.name - { - nativeBuildInputs = [ - cfg.package - pkgs.fakeroot - pkgs.util-linux - ] ++ fileSystemTools; - } '' - amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory}) - - mkdir -p $out - cd $out - - unshare --map-root-user fakeroot systemd-repart \ - --dry-run=no \ - --empty=create \ - --size=auto \ - --seed="${cfg.seed}" \ - --definitions="$amendedRepartDefinitions" \ - --split="${lib.boolToString cfg.split}" \ - --json=pretty \ - image.raw \ - | tee repart-output.json - ''; + pkgs.callPackage ./repart-image.nix { + systemd = cfg.package; + inherit (cfg) name split seed; + inherit fileSystems definitionsDirectory partitions; + }; meta.maintainers = with lib.maintainers; [ nikstur ];