diff --git a/nixos/modules/installer/cd-dvd/channel.nix b/nixos/modules/installer/cd-dvd/channel.nix index e5fa5db420be..ef8606bfc977 100644 --- a/nixos/modules/installer/cd-dvd/channel.nix +++ b/nixos/modules/installer/cd-dvd/channel.nix @@ -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 + ''; + }; }; } diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index e1c9941c6c1d..c42fd64824aa 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -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. diff --git a/nixos/modules/installer/netboot/netboot.nix b/nixos/modules/installer/netboot/netboot.nix index a4d9664a5531..4b5593d37d88 100644 --- a/nixos/modules/installer/netboot/netboot.nix +++ b/nixos/modules/installer/netboot/netboot.nix @@ -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 $(