Unverified Commit 07c0be50 authored by WilliButz's avatar WilliButz Committed by GitHub
Browse files

Various repart image simplifications (#485954)

parents 199c3eae 5b822cf4
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ in
        Verity = "hash";
        VerityMatchKey = lib.mkDefault verityMatchKey;
        Label = lib.mkDefault "store-verity";
        Minimize = lib.mkDefault "best";
      };
      # dm-verity data partition that contains the nix store
      ${cfg.partitionIds.store} = {
@@ -106,23 +107,29 @@ in
          Format = lib.mkDefault "erofs";
          VerityMatchKey = lib.mkDefault verityMatchKey;
          Label = lib.mkDefault "store";
          Minimize = lib.mkDefault "best";
        };
      };

    };

    system.build = {
      finalImage = lib.warn "system.build.finalImage has been renamed to system.build.image" config.system.build.image;

      # intermediate system image without ESP
      intermediateImage =
        (config.system.build.image.override {
        (config.image.repart.image.override {
          # always disable compression for the intermediate image
          compression.enable = false;
        }).overrideAttrs
          (
            _: previousAttrs: {
              # make it easier to identify the intermediate image in build logs
              pname = "${previousAttrs.pname}-intermediate";
              name =
                if previousAttrs ? pname then
                  "${previousAttrs.pname}-${previousAttrs.version}-intermediate"
                else
                  "${previousAttrs.name}-intermediate";

              # do not prepare the ESP, this is done in the final image
              systemdRepartFlags = previousAttrs.systemdRepartFlags ++ [ "--defer-partitions=esp" ];
@@ -162,8 +169,8 @@ in
        );

      # final system image that is created from the intermediate image by injecting the UKI from above
      finalImage =
        (config.system.build.image.override {
      image = lib.mkOverride 99 (
        (config.image.repart.image.override {
          # continue building with existing intermediate image
          createEmpty = false;
        }).overrideAttrs
@@ -216,6 +223,7 @@ in
                rm -v repart-output_orig.json
              '';
            }
          )
      );
    };
  };
+41 −30
Original line number Diff line number Diff line
@@ -282,6 +282,15 @@ in
      '';
    };

    image = lib.mkOption {
      type = lib.types.package;
      internal = true;
      readOnly = true;
      description = ''
        The image built by this module. Used as the default for `system.build.image`.
      '';
    };

    assertions = lib.mkOption {
      type = options.assertions.type;
      default = [ ];
@@ -356,6 +365,37 @@ in

        finalPartitions = lib.mapAttrs addClosure cfg.partitions;

        image =
          let
            fileSystems = lib.filter (f: f != null) (
              lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions
            );

            format = pkgs.formats.ini { listsAsDuplicateKeys = true; };

            definitionsDirectory = utils.systemdUtils.lib.definitions "repart.d" format (
              lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) cfg.finalPartitions
            );

            mkfsEnv = mkfsOptionsToEnv cfg.mkfsOptions;
            val = pkgs.callPackage ./repart-image.nix {
              systemd = cfg.package;
              inherit (config.image) baseName;
              inherit (cfg)
                name
                version
                compression
                split
                seed
                imageSize
                sectorSize
                finalPartitions
                ;
              inherit fileSystems definitionsDirectory mkfsEnv;
            };
          in
          lib.asserts.checkAssertWarn cfg.assertions cfg.warnings val;

        assertions = lib.mapAttrsToList (
          fileName: partitionConfig:
          let
@@ -401,36 +441,7 @@ in
        );
      };

    system.build.image =
      let
        fileSystems = lib.filter (f: f != null) (
          lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions
        );

        format = pkgs.formats.ini { listsAsDuplicateKeys = true; };

        definitionsDirectory = utils.systemdUtils.lib.definitions "repart.d" format (
          lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) cfg.finalPartitions
        );

        mkfsEnv = mkfsOptionsToEnv cfg.mkfsOptions;
        val = pkgs.callPackage ./repart-image.nix {
          systemd = cfg.package;
          inherit (config.image) baseName;
          inherit (cfg)
            name
            version
            compression
            split
            seed
            imageSize
            sectorSize
            finalPartitions
            ;
          inherit fileSystems definitionsDirectory mkfsEnv;
        };
      in
      lib.asserts.checkAssertWarn cfg.assertions cfg.warnings val;
    system.build.image = cfg.image;
  };

  meta.maintainers = with lib.maintainers; [
+52 −42
Original line number Diff line number Diff line
@@ -10,13 +10,8 @@
    willibutz
  ];

  nodes.machine =
    {
      config,
      lib,
      pkgs,
      ...
    }:
  defaults =
    { config, lib, ... }:
    let
      inherit (config.image.repart.verityStore) partitionIds;
    in
@@ -55,12 +50,6 @@
              SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M";
            };
          };
          ${partitionIds.store-verity}.repartConfig = {
            Minimize = "best";
          };
          ${partitionIds.store}.repartConfig = {
            Minimize = "best";
          };
        };
      };

@@ -75,10 +64,7 @@
        initrd.systemd.enable = true;
      };

      system.image = {
        id = "nixos-appliance";
        version = "1";
      };
      system.image.id = "nixos-appliance";

      # don't create /usr/bin/env
      # this would require some extra work on read-only /usr
@@ -86,6 +72,12 @@
      system.activationScripts.usrbinenv = lib.mkForce "";
    };

  nodes.machine = {
    system.image.version = "1";
  };

  nodes.without-version = { };

  testScript =
    { nodes, ... }: # python
    ''
@@ -93,24 +85,22 @@
      import subprocess
      import tempfile

      tmp_disk_image = tempfile.NamedTemporaryFile()

      def create_disk_image(qemu_img, backing_file):
        tmp = tempfile.NamedTemporaryFile()
        subprocess.run([
        "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img",
          qemu_img,
          "create",
          "-f",
          "qcow2",
          "-b",
        "${nodes.machine.system.build.finalImage}/${nodes.machine.image.repart.imageFile}",
          backing_file,
          "-F",
          "raw",
        tmp_disk_image.name,
      ])

      os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name

      machine.wait_for_unit("default.target")
          tmp.name,
        ], check=True)
        return tmp

      def run_verity_tests(machine):
        with subtest("Running with volatile root"):
          machine.succeed("findmnt --kernel --type tmpfs /")

@@ -119,6 +109,26 @@
          assert "ACTIVE" in verity_info, f"unexpected verity info: {verity_info}"

          backing_device = machine.succeed("df --output=source /nix/store | tail -n1").strip()
        assert "/dev/mapper/usr" == backing_device,"unexpected backing device: {backing_device}"
          assert "/dev/mapper/usr" == backing_device, f"unexpected backing device: {backing_device}"

      tmp_disk_machine = create_disk_image(
        "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img",
        "${nodes.machine.system.build.image}/${nodes.machine.image.filePath}",
      )
      os.environ['NIX_DISK_IMAGE'] = tmp_disk_machine.name
      machine.wait_for_unit("default.target")
      run_verity_tests(machine)
      with subtest("Image version is set"):
        machine.succeed("grep IMAGE_VERSION=1 /etc/os-release")

      tmp_disk_without_version = create_disk_image(
        "${nodes."without-version".virtualisation.qemu.package}/bin/qemu-img",
        "${nodes."without-version".system.build.image}/${nodes."without-version".image.filePath}",
      )
      os.environ['NIX_DISK_IMAGE'] = tmp_disk_without_version.name
      without_version.wait_for_unit("default.target")
      run_verity_tests(without_version)
      with subtest("Image version is not set"):
        without_version.succeed('grep IMAGE_VERSION="" /etc/os-release')
    '';
}
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ in
        "-f",
        "qcow2",
        "-b",
        "${nodes.machine.system.build.image}/${nodes.machine.image.repart.imageFile}",
        "${nodes.machine.system.build.image}/${nodes.machine.image.filePath}",
        "-F",
        "raw",
        tmp_disk_image.name,