nixos: convert remaining postBootCommands that load the nix DB to systemd services

Convert all remaining boot.postBootCommands that call
nix-store --load-db into register-nix-paths systemd services for
consistency with qemu-vm.nix and to make the ordering dependency
with nix-channel-init explicit.

All services use the same unit name (register-nix-paths) and the
same sysinit.target ordering, so nix-channel-init's
after=register-nix-paths.service dependency works uniformly across
all platforms.

Platform-specific logic (netboot password setup, sd-image partition
expansion) is kept in the service script or in boot.postBootCommands
as appropriate.
This commit is contained in:
r-vdp
2026-03-23 10:01:50 +01:00
parent d292d47526
commit 6ab12a513a
6 changed files with 202 additions and 77 deletions
+26 -9
View File
@@ -1054,16 +1054,33 @@ in
}
);
boot.postBootCommands = ''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
${config.nix.package.out}/bin/nix-store --load-db < /nix/store/nix-path-registration
systemd.services.register-nix-paths = {
description = "Register Nix Store Paths";
unitConfig.DefaultDependencies = false;
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
${lib.getExe' config.nix.package.out "nix-store"} --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
touch /etc/NIXOS
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
# Add vfat support to the initrd to enable people to copy the
# contents of the CD to a bootable USB stick.
+30 -11
View File
@@ -166,27 +166,46 @@ with lib;
boot.loader.timeout = 10;
systemd.services.register-nix-paths = {
description = "Register Nix Store Paths";
unitConfig.DefaultDependencies = false;
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
# After booting, register the contents of the Nix store
# in the Nix database in the tmpfs.
${lib.getExe' config.nix.package "nix-store"} --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
touch /etc/NIXOS
${lib.getExe' config.nix.package "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
boot.postBootCommands = ''
# After booting, register the contents of the Nix store
# in the Nix database in the tmpfs.
${config.nix.package}/bin/nix-store --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
# Set password for user nixos if specified on cmdline
# Allows using nixos-anywhere in headless environments
for o in $(</proc/cmdline); do
case "$o" in
live.nixos.passwordHash=*)
set -- $(IFS==; echo $o)
${pkgs.gnugrep}/bin/grep -q "root::" /etc/shadow && ${pkgs.shadow}/bin/usermod -p "$2" root
${lib.getExe pkgs.gnugrep} -q "root::" /etc/shadow && ${lib.getExe' pkgs.shadow "usermod"} -p "$2" root
;;
live.nixos.password=*)
set -- $(IFS==; echo $o)
${pkgs.gnugrep}/bin/grep -q "root::" /etc/shadow && echo "root:$2" | ${pkgs.shadow}/bin/chpasswd
${lib.getExe pkgs.gnugrep} -q "root::" /etc/shadow && echo "root:$2" | ${lib.getExe' pkgs.shadow "chpasswd"}
;;
esac
done
+59 -26
View File
@@ -343,39 +343,72 @@ in
}
) { };
boot.postBootCommands =
systemd.services.expand-root-partition = lib.mkIf config.sdImage.expandOnBoot {
description = "Grow the root partition and filesystem to fill the SD card";
unitConfig = {
DefaultDependencies = false;
ConditionPathExists = config.sdImage.nixPathRegistrationFile;
};
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"register-nix-paths.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
# Figure out device names for the boot device and root filesystem.
rootPart=$(${lib.getExe' pkgs.util-linux "findmnt"} -n -o SOURCE /)
bootDevice=$(${lib.getExe' pkgs.util-linux "lsblk"} -npo PKNAME $rootPart)
partNum=$(${lib.getExe' pkgs.util-linux "lsblk"} -npo MAJ:MIN $rootPart | ${lib.getExe pkgs.gawk} -F: '{print $2}')
# Resize the root partition and the filesystem to fit the disk
echo ",+," | ${lib.getExe' pkgs.util-linux "sfdisk"} -N$partNum --no-reread $bootDevice
${lib.getExe' pkgs.parted "partprobe"}
${lib.getExe' pkgs.e2fsprogs "resize2fs"} $rootPart
'';
};
systemd.services.register-nix-paths =
let
expandOnBoot = lib.optionalString config.sdImage.expandOnBoot ''
# Figure out device names for the boot device and root filesystem.
rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
bootDevice=$(lsblk -npo PKNAME $rootPart)
partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}')
# Resize the root partition and the filesystem to fit the disk
echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
${pkgs.parted}/bin/partprobe
${pkgs.e2fsprogs}/bin/resize2fs $rootPart
'';
nixPathRegistrationFile = config.sdImage.nixPathRegistrationFile;
inherit (config.sdImage) nixPathRegistrationFile;
in
''
# On the first boot do some maintenance tasks
if [ -f ${nixPathRegistrationFile} ]; then
set -euo pipefail
set -x
${expandOnBoot}
# Register the contents of the initial Nix store
${config.nix.package.out}/bin/nix-store --load-db < ${nixPathRegistrationFile}
{
description = "Register Nix Store Paths";
unitConfig = {
DefaultDependencies = false;
ConditionPathExists = nixPathRegistrationFile;
};
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
${lib.getExe' config.nix.package.out "nix-store"} --load-db < ${nixPathRegistrationFile}
# nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
# Prevents this from running on later boots.
rm -f ${nixPathRegistrationFile}
fi
'';
'';
};
};
}
+32 -10
View File
@@ -1,4 +1,9 @@
{ config, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (pkgs) writeScript;
@@ -45,17 +50,34 @@ in
};
boot.isContainer = true;
boot.postBootCommands = ''
# After booting, register the contents of the Nix store in the Nix
# database.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
systemd.services.register-nix-paths = {
description = "Register Nix Store Paths";
unitConfig = {
DefaultDependencies = false;
ConditionPathExists = "/nix-path-registration";
};
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
${lib.getExe' config.nix.package.out "nix-store"} --load-db < /nix-path-registration
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# nixos-rebuild also requires a "system" profile
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
# Install new init script
system.activationScripts.installInitScript = ''
+26 -9
View File
@@ -31,17 +31,34 @@
{
boot.isContainer = true;
boot.postBootCommands = ''
# After booting, register the contents of the Nix store in the Nix
# database.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
systemd.services.register-nix-paths = {
description = "Register Nix Store Paths";
unitConfig = {
DefaultDependencies = false;
ConditionPathExists = "/nix-path-registration";
};
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
${lib.getExe' config.nix.package.out "nix-store"} --load-db < /nix-path-registration
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# nixos-rebuild also requires a "system" profile
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
# supplement 99-ethernet-default-dhcp which excludes veth
systemd.network = lib.mkIf config.networking.useDHCP {
+29 -12
View File
@@ -76,18 +76,6 @@ with lib;
extraCommands = "mkdir -p root etc/systemd/network";
};
boot.postBootCommands = ''
# After booting, register the contents of the Nix store in the Nix
# database.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
boot = {
isContainer = true;
loader.initScript.enable = true;
@@ -117,6 +105,35 @@ with lib;
};
systemd = {
services.register-nix-paths = {
description = "Register Nix Store Paths";
unitConfig = {
DefaultDependencies = false;
ConditionPathExists = "/nix-path-registration";
};
wantedBy = [ "sysinit.target" ];
before = [
"sysinit.target"
"shutdown.target"
"nix-daemon.socket"
"nix-daemon.service"
];
after = [ "local-fs.target" ];
conflicts = [ "shutdown.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
${lib.getExe' config.nix.package.out "nix-store"} --load-db < /nix-path-registration
rm /nix-path-registration
# nixos-rebuild also requires a "system" profile
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
mounts = mkIf (!cfg.privileged) [
{
enable = false;