Loading nixos/modules/system/boot/systemd/repart.nix +58 −32 Original line number Diff line number Diff line { config, pkgs, lib, ... }: { config, pkgs, lib, utils, ... }: let cfg = config.systemd.repart; Loading Loading @@ -26,7 +26,8 @@ let in { options = { boot.initrd.systemd.repart.enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { boot.initrd.systemd.repart = { enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { description = lib.mdDoc '' Grow and add partitions to a partition table at boot time in the initrd. systemd-repart only works with GPT partition tables. Loading @@ -36,6 +37,20 @@ in ''; }; device = lib.mkOption { type = with lib.types; nullOr str; description = lib.mdDoc '' The device to operate on. If `device == null`, systemd-repart will operate on the device backing the root partition. So in order to dynamically *create* the root partition in the initrd you need to set a device. ''; default = null; example = "/dev/vda"; }; }; systemd.repart = { enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { description = lib.mdDoc '' Loading Loading @@ -84,7 +99,11 @@ in contents."/etc/repart.d".source = definitionsDirectory; # Override defaults in upstream unit. services.systemd-repart = { services.systemd-repart = let deviceUnit = "${utils.escapeSystemdPath initrdCfg.device}.device"; in { # systemd-repart tries to create directories in /var/tmp by default to # store large temporary files that benefit from persistence on disk. In # the initrd, however, /var/tmp does not provide more persistence than Loading @@ -98,16 +117,23 @@ in # in the initrd itself. ''${config.boot.initrd.systemd.package}/bin/systemd-repart \ --definitions=/etc/repart.d \ --dry-run=no --dry-run=no ${lib.optionalString (initrdCfg.device != null) initrdCfg.device} '' ]; }; # systemd-repart needs to run after /sysroot (or /sysuser, but we don't # have it) has been mounted because otherwise it cannot determine the # device (i.e disk) to operate on. If you want to run systemd-repart # without /sysroot, you have to explicitly tell it which device to # operate on. after = [ "sysroot.mount" ]; # systemd-repart needs to run after /sysroot (or /sysuser, but we # don't have it) has been mounted because otherwise it cannot # determine the device (i.e disk) to operate on. If you want to run # systemd-repart without /sysroot (i.e. to create the root # partition), you have to explicitly tell it which device to operate # on. The service then needs to be ordered to run after this device # is available. requires = lib.mkIf (initrdCfg.device != null) [ deviceUnit ]; after = if initrdCfg.device == null then [ "sysroot.mount" ] else [ deviceUnit ]; }; }; Loading nixos/tests/systemd-repart.nix +60 −2 Original line number Diff line number Diff line Loading @@ -56,8 +56,8 @@ let # however, creates separate filesystem images without a partition table, so # we have to create a disk image manually. # # This creates two partitions, an ESP mounted on /dev/vda1 and the root # partition mounted on /dev/vda2 # This creates two partitions, an ESP available as /dev/vda1 and the root # partition available as /dev/vda2. system.build.diskImage = import ../lib/make-disk-image.nix { inherit config pkgs lib; # Use a raw format disk so that it can be resized before starting the Loading Loading @@ -131,4 +131,62 @@ in assert "Growing existing partition 1." in systemd_repart_logs ''; }; create-root = makeTest { name = "systemd-repart-create-root"; meta.maintainers = with maintainers; [ nikstur ]; nodes.machine = { config, lib, pkgs, ... }: { virtualisation.useDefaultFilesystems = false; virtualisation.fileSystems = { "/" = { device = "/dev/disk/by-partlabel/created-root"; fsType = "ext4"; }; "/nix/store" = { device = "/dev/vda2"; fsType = "ext4"; }; }; # Create an image containing only the Nix store. This enables creating # the root partition with systemd-repart and then successfully booting # into a working system. # # This creates two partitions, an ESP available as /dev/vda1 and the Nix # store available as /dev/vda2. system.build.diskImage = import ../lib/make-disk-image.nix { inherit config pkgs lib; onlyNixStore = true; format = "raw"; bootSize = "32M"; additionalSpace = "0M"; partitionTableType = "efi"; installBootLoader = false; copyChannel = false; }; boot.initrd.systemd.enable = true; boot.initrd.systemd.repart.enable = true; boot.initrd.systemd.repart.device = "/dev/vda"; systemd.repart.partitions = { "10-root" = { Type = "root"; Label = "created-root"; Format = "ext4"; }; }; }; testScript = { nodes, ... }: '' ${useDiskImage nodes.machine} machine.start() machine.wait_for_unit("multi-user.target") systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") assert "Adding new partition 2 to partition table." in systemd_repart_logs ''; }; } Loading
nixos/modules/system/boot/systemd/repart.nix +58 −32 Original line number Diff line number Diff line { config, pkgs, lib, ... }: { config, pkgs, lib, utils, ... }: let cfg = config.systemd.repart; Loading Loading @@ -26,7 +26,8 @@ let in { options = { boot.initrd.systemd.repart.enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { boot.initrd.systemd.repart = { enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { description = lib.mdDoc '' Grow and add partitions to a partition table at boot time in the initrd. systemd-repart only works with GPT partition tables. Loading @@ -36,6 +37,20 @@ in ''; }; device = lib.mkOption { type = with lib.types; nullOr str; description = lib.mdDoc '' The device to operate on. If `device == null`, systemd-repart will operate on the device backing the root partition. So in order to dynamically *create* the root partition in the initrd you need to set a device. ''; default = null; example = "/dev/vda"; }; }; systemd.repart = { enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { description = lib.mdDoc '' Loading Loading @@ -84,7 +99,11 @@ in contents."/etc/repart.d".source = definitionsDirectory; # Override defaults in upstream unit. services.systemd-repart = { services.systemd-repart = let deviceUnit = "${utils.escapeSystemdPath initrdCfg.device}.device"; in { # systemd-repart tries to create directories in /var/tmp by default to # store large temporary files that benefit from persistence on disk. In # the initrd, however, /var/tmp does not provide more persistence than Loading @@ -98,16 +117,23 @@ in # in the initrd itself. ''${config.boot.initrd.systemd.package}/bin/systemd-repart \ --definitions=/etc/repart.d \ --dry-run=no --dry-run=no ${lib.optionalString (initrdCfg.device != null) initrdCfg.device} '' ]; }; # systemd-repart needs to run after /sysroot (or /sysuser, but we don't # have it) has been mounted because otherwise it cannot determine the # device (i.e disk) to operate on. If you want to run systemd-repart # without /sysroot, you have to explicitly tell it which device to # operate on. after = [ "sysroot.mount" ]; # systemd-repart needs to run after /sysroot (or /sysuser, but we # don't have it) has been mounted because otherwise it cannot # determine the device (i.e disk) to operate on. If you want to run # systemd-repart without /sysroot (i.e. to create the root # partition), you have to explicitly tell it which device to operate # on. The service then needs to be ordered to run after this device # is available. requires = lib.mkIf (initrdCfg.device != null) [ deviceUnit ]; after = if initrdCfg.device == null then [ "sysroot.mount" ] else [ deviceUnit ]; }; }; Loading
nixos/tests/systemd-repart.nix +60 −2 Original line number Diff line number Diff line Loading @@ -56,8 +56,8 @@ let # however, creates separate filesystem images without a partition table, so # we have to create a disk image manually. # # This creates two partitions, an ESP mounted on /dev/vda1 and the root # partition mounted on /dev/vda2 # This creates two partitions, an ESP available as /dev/vda1 and the root # partition available as /dev/vda2. system.build.diskImage = import ../lib/make-disk-image.nix { inherit config pkgs lib; # Use a raw format disk so that it can be resized before starting the Loading Loading @@ -131,4 +131,62 @@ in assert "Growing existing partition 1." in systemd_repart_logs ''; }; create-root = makeTest { name = "systemd-repart-create-root"; meta.maintainers = with maintainers; [ nikstur ]; nodes.machine = { config, lib, pkgs, ... }: { virtualisation.useDefaultFilesystems = false; virtualisation.fileSystems = { "/" = { device = "/dev/disk/by-partlabel/created-root"; fsType = "ext4"; }; "/nix/store" = { device = "/dev/vda2"; fsType = "ext4"; }; }; # Create an image containing only the Nix store. This enables creating # the root partition with systemd-repart and then successfully booting # into a working system. # # This creates two partitions, an ESP available as /dev/vda1 and the Nix # store available as /dev/vda2. system.build.diskImage = import ../lib/make-disk-image.nix { inherit config pkgs lib; onlyNixStore = true; format = "raw"; bootSize = "32M"; additionalSpace = "0M"; partitionTableType = "efi"; installBootLoader = false; copyChannel = false; }; boot.initrd.systemd.enable = true; boot.initrd.systemd.repart.enable = true; boot.initrd.systemd.repart.device = "/dev/vda"; systemd.repart.partitions = { "10-root" = { Type = "root"; Label = "created-root"; Format = "ext4"; }; }; }; testScript = { nodes, ... }: '' ${useDiskImage nodes.machine} machine.start() machine.wait_for_unit("multi-user.target") systemd_repart_logs = machine.succeed("journalctl --boot --unit systemd-repart.service") assert "Adding new partition 2 to partition table." in systemd_repart_logs ''; }; }