nixos: convert boot.postBootCommands that load the nix DB to systemd services (#496852)
This commit is contained in:
@@ -54,19 +54,49 @@ in
|
||||
};
|
||||
|
||||
# Provide the NixOS/Nixpkgs sources in /etc/nixos. This is required
|
||||
# for nixos-install.
|
||||
boot.postBootCommands = lib.mkAfter ''
|
||||
if ! [ -e /var/lib/nixos/did-channel-init ]; then
|
||||
echo "unpacking the NixOS/Nixpkgs sources..."
|
||||
mkdir -p /nix/var/nix/profiles/per-user/root
|
||||
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/per-user/root/channels \
|
||||
-i ${channelSources} --quiet --option build-use-substitutes false \
|
||||
${lib.optionalString config.boot.initrd.systemd.enable "--option sandbox false"} # There's an issue with pivot_root
|
||||
mkdir -m 0700 -p /root/.nix-defexpr
|
||||
ln -s /nix/var/nix/profiles/per-user/root/channels /root/.nix-defexpr/channels
|
||||
mkdir -m 0755 -p /var/lib/nixos
|
||||
touch /var/lib/nixos/did-channel-init
|
||||
fi
|
||||
'';
|
||||
# for nixos-install. We use a systemd service rather than
|
||||
# boot.postBootCommands so that ordering relative to other
|
||||
# early-boot services (e.g. register-nix-paths in QEMU VMs) is
|
||||
# explicit.
|
||||
systemd.services.nix-channel-init = {
|
||||
description = "Initialize NixOS Channel";
|
||||
# Run early so the channel is available before regular services.
|
||||
# nix-env is invoked before nix-daemon.socket is up, so it
|
||||
# accesses the store directly (we are root).
|
||||
unitConfig.DefaultDependencies = false;
|
||||
wantedBy = [ "sysinit.target" ];
|
||||
before = [
|
||||
"sysinit.target"
|
||||
"shutdown.target"
|
||||
"nix-daemon.socket"
|
||||
"nix-daemon.service"
|
||||
];
|
||||
after = [
|
||||
"local-fs.target"
|
||||
# In QEMU VMs the store DB is populated by register-nix-paths.
|
||||
# On real hardware this unit does not exist and the dependency
|
||||
# is silently ignored by systemd.
|
||||
"register-nix-paths.service"
|
||||
];
|
||||
conflicts = [ "shutdown.target" ];
|
||||
restartIfChanged = false;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
if ! [ -e /var/lib/nixos/did-channel-init ]; then
|
||||
echo "unpacking the NixOS/Nixpkgs sources..."
|
||||
mkdir -p /nix/var/nix/profiles/per-user/root
|
||||
${lib.getExe' config.nix.package.out "nix-env"} -p /nix/var/nix/profiles/per-user/root/channels \
|
||||
-i ${channelSources} --quiet --option build-use-substitutes false \
|
||||
${lib.optionalString config.boot.initrd.systemd.enable "--option sandbox false"} # There's an issue with pivot_root
|
||||
mkdir -m 0700 -p /root/.nix-defexpr
|
||||
ln -s /nix/var/nix/profiles/per-user/root/channels /root/.nix-defexpr/channels
|
||||
mkdir -m 0755 -p /var/lib/nixos
|
||||
touch /var/lib/nixos/did-channel-init
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1055,16 +1055,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -377,39 +377,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
|
||||
'';
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1236,11 +1236,38 @@ in
|
||||
# allow `system.build.toplevel' to be included. (If we had a direct
|
||||
# reference to ${regInfo} here, then we would get a cyclic
|
||||
# dependency.)
|
||||
boot.postBootCommands = lib.mkIf config.nix.enable ''
|
||||
if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then
|
||||
${config.nix.package.out}/bin/nix-store --load-db < ''${BASH_REMATCH[1]}
|
||||
fi
|
||||
'';
|
||||
systemd.services.register-nix-paths = lib.mkIf config.nix.enable {
|
||||
# Run early during boot so the nix store DB is populated before any
|
||||
# service (or test backdoor) tries to use nix commands.
|
||||
# nix-store --load-db writes to the SQLite DB directly, so it does not
|
||||
# need the nix-daemon.
|
||||
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 = ''
|
||||
if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then
|
||||
${lib.getExe' config.nix.package.out "nix-store"} --load-db < "''${BASH_REMATCH[1]}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx" ++ optional (cfg.tpm.enable) "tpm_tis";
|
||||
|
||||
Reference in New Issue
Block a user