nixos/systemd-repart: enable creating root partition
This commit is contained in:
parent
a8eea70935
commit
ef80e11032
2 changed files with 117 additions and 33 deletions
|
@ -1,4 +1,4 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{ config, pkgs, lib, utils, ... }:
|
||||
|
||||
let
|
||||
cfg = config.systemd.repart;
|
||||
|
@ -26,14 +26,29 @@ let
|
|||
in
|
||||
{
|
||||
options = {
|
||||
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.
|
||||
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.
|
||||
|
||||
To run systemd-repart after the initrd, see
|
||||
`options.systemd.repart.enable`.
|
||||
'';
|
||||
To run systemd-repart after the initrd, see
|
||||
`options.systemd.repart.enable`.
|
||||
'';
|
||||
};
|
||||
|
||||
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 = {
|
||||
|
@ -84,31 +99,42 @@ in
|
|||
contents."/etc/repart.d".source = definitionsDirectory;
|
||||
|
||||
# Override defaults in upstream unit.
|
||||
services.systemd-repart = {
|
||||
# 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
|
||||
# /tmp, so we re-use it here.
|
||||
environment."TMPDIR" = "/tmp";
|
||||
serviceConfig = {
|
||||
ExecStart = [
|
||||
" " # required to unset the previous value.
|
||||
# When running in the initrd, systemd-repart by default searches
|
||||
# for definition files in /sysroot or /sysusr. We tell it to look
|
||||
# in the initrd itself.
|
||||
''${config.boot.initrd.systemd.package}/bin/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
|
||||
# /tmp, so we re-use it here.
|
||||
environment."TMPDIR" = "/tmp";
|
||||
serviceConfig = {
|
||||
ExecStart = [
|
||||
" " # required to unset the previous value.
|
||||
# When running in the initrd, systemd-repart by default searches
|
||||
# for definition files in /sysroot or /sysusr. We tell it to look
|
||||
# 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 (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 ];
|
||||
};
|
||||
# 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" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc = lib.mkIf cfg.enable {
|
||||
|
|
|
@ -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
|
||||
|
@ -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…
Reference in a new issue