Browse Source

Make installer image more independent

main
Dustin Frisch 4 weeks ago
parent
commit
dcf2a3b484
No known key found for this signature in database GPG Key ID: B4C3BF012D9B26BE
  1. 81
      installer.nix
  2. 86
      installer/default.nix
  3. 19
      installer/installer.nix
  4. 22
      machines/nfs/dhcp.nix
  5. 38
      machines/nfs/netinstaller.nix

81
installer.nix

@ -0,0 +1,81 @@
{ pkgs, lib, modulesPath, config, ... }:
with lib;
let
auto-installer = pkgs.writers.writeBash "auto-installer" ''
set -o errexit
set -o nounset
set -o pipefail
set -x
if [[ "$(cat /proc/cmdline)" =~ nixos\.install=([^ ]+) ]]; then
INSTALL="''${BASH_REMATCH[1]}"
else
echo "No install derivation found" >&2
exit 1
fi
${pkgs.retry}/bin/retry \
--times 10 \
--delay 15 \
-- ${pkgs.nix}/bin/nix-store \
--realize \
--add-root /tmp/installer \
"$INSTALL"
exec /tmp/installer
'';
in
{
imports = [
"${modulesPath}/installer/netboot/netboot-minimal.nix"
./shared/network.nix
./shared/cache.nix
./shared/users.nix
];
_module.args = {
name = "installer";
};
networking.useDHCP = mkForce true;
services.getty.autologinUser = lib.mkForce "root";
systemd.services."auto-install" = {
description = "Automated NixOS installer";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
conflicts = [ "getty@tty1.service" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ bash nix ];
unitConfig = {
AssertKernelCommandLine = "nixos.install";
FailureAction = "force-reboot";
};
serviceConfig = {
Type = "oneshot";
ExecStart = auto-installer;
StandardInput = "none";
StandardOutput = "journal+console";
StandardError = "journal+console";
};
};
# Expose the installer script
system.build.installer = installer;
}

86
installer/default.nix

@ -1,86 +0,0 @@
{ pkgs, lib, modulesPath, config, target, ... }:
with lib;
let
installer = pkgs.callPackage ./installer.nix { inherit target; };
auto-installer =
let
# This removes the direct dependency from the installer to the target image.
# The install script is realized later during runtime using the cache.
# To make this work, the cache must provide the real installer script.
installer-path = builtins.unsafeDiscardStringContext (toString installer);
in
pkgs.writers.writeBash "auto-installer" ''
set -o errexit
set -o nounset
set -o pipefail
set -x
${pkgs.retry}/bin/retry \
--times 10 \
--delay 15 \
-- ${pkgs.nix}/bin/nix-store \
--realize \
--add-root /tmp/installer \
"${installer-path}"
/tmp/installer
reboot
'';
in
{
imports = [
"${modulesPath}/installer/netboot/netboot-minimal.nix"
../shared/users.nix
../shared/network.nix
../shared/cache.nix
];
_module.args = {
name = "installer";
};
networking.useDHCP = mkForce true;
services.getty.autologinUser = lib.mkForce "root";
systemd.services."auto-install" = {
description = "Automated NixOS installer";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
conflicts = [ "getty@tty1.service" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ bash nix ];
unitConfig = {
FailureAction = "force-reboot";
};
serviceConfig = {
Type = "oneshot";
ExecStart = auto-installer;
StandardInput = "none";
StandardOutput = "journal+console";
StandardError = "journal+console";
};
};
# Expose the installer script
system.build.installer = installer;
system.stateVersion = config.system.nixos.release;
}

19
installer/installer.nix

@ -1,19 +0,0 @@
{ writers, target, ... }:
writers.writeBash "installer" ''
set -o errexit
set -o nounset
set -o pipefail
set -x
"${target.config.system.build.diskoScript}"
"${target.config.system.build.nixos-install}/bin/nixos-install" \
--root /mnt \
--system "${target.config.system.build.toplevel}" \
--no-channel-copy \
--no-root-password \
--verbose
''

22
machines/nfs/dhcp.nix

@ -63,28 +63,6 @@
pool = "10.32.44.100 - 10.32.44.200";
}
];
option-data = [
{
name = "routers";
data = "10.32.44.1";
}
{
name = "domain-name-servers";
data = "10.0.0.53";
}
{
name = "domain-name";
data = config.networking.domain;
}
{
name = "domain-search";
data = config.networking.domain;
}
];
}
];

38
machines/nfs/netinstaller.nix

@ -4,15 +4,31 @@ with lib;
let
installer = pkgs.nixos [
../../installer
{
_module.args = {
target = nodes."client";
};
}
../../installer.nix
];
installer-script =
let
target = nodes."client".config.system.build;
in
pkgs.writers.writeBash "installer" ''
set -o errexit
set -o nounset
set -o pipefail
set -x
"${target.diskoScript}"
"${target.nixos-install}/bin/nixos-install" \
--root /mnt \
--system "${target.toplevel}" \
--no-channel-copy \
--no-root-password \
--verbose
'';
ipxe-script = pkgs.writeText "boot-local.ipxe" ''
#!ipxe
@ -26,7 +42,7 @@ let
kernel --name kernel http://''${next-server:ipv4}/bzImage || goto err
initrd --name initrd http://''${next-server:ipv4}/initrd || goto err
boot kernel initrd=initrd init=${installer.config.system.build.toplevel}/init loglevel=4 || goto err
boot kernel initrd=initrd init=${installer.config.system.build.toplevel}/init nixos.install=${installer-script} loglevel=4 || goto err
:err
shell
@ -68,12 +84,6 @@ in
openFirewall = true;
};
# Ensure the intaller script and therefore the client system is part of the
# store so it can be fetched by the installer.
boot.postBootCommands = ''
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/installer --set "${installer.installer}"
'';
networking.extraHosts = ''
127.0.0.1 boot.${config.networking.domain}
'';

Loading…
Cancel
Save