diff --git a/nixos/modules/installer/ssh-nixos.nix b/nixos/modules/installer/ssh-nixos.nix new file mode 100644 index 00000000000..6d1b03eea0a --- /dev/null +++ b/nixos/modules/installer/ssh-nixos.nix @@ -0,0 +1,104 @@ +{ pkgs, lib, config, ... }: +let + inherit (lib) types; + inherit (config) networking; + cfg = config.installer.ssh-nixos; + nixRunDefaultCommand = "bash"; + # Wraps ssh so that nix copy or calls to ssh added to cfg.script + # use cfg.sshFlags and $SSH_FLAGS. + ssh = pkgs.writeShellScriptBin "ssh" '' + set -eu + PATH=$OLDPATH + ssh ${lib.escapeShellArgs cfg.sshFlags} ''${SSH_FLAGS:-} "$@" + ''; +in +{ +options.installer.ssh-nixos = { + PATH = lib.mkOption { + type = types.listOf types.package; + default = []; + apply = lib.makeBinPath; + description = "Packages to be appended to the PATH of the script."; + }; + script = lib.mkOption { + type = types.lines; + default = ""; + example = '' + lib.mkBefore '''''' + gpg --decrypt initrd/ssh.key.gpg | + ssh ''${config.installer.ssh-nixos.target} \ + install -D -m 400 -o root -g root /dev/stdin /root/initrd/ssh.key + ''''''; + ''; + description = '' + Install script copying through SSH the configured NixOS system + to the target + and switching to the new configuration. + This option is made available here for prepending or appending commands + with the usual mkBefore and mkAfter. + + This script is usually run with: + + $ nix run system.config.installer.ssh-nixos -f nixos.nix + + where nixos.nix can be: + + import { + system = "x86_64-linux"; + configuration = { config, lib, pkgs }: { + # Your usual configuration.nix content can go here + }; + } + + ''; + apply = script: pkgs.writeShellScriptBin nixRunDefaultCommand '' + set -eu + set -o pipefail + export OLDPATH=$PATH:${cfg.PATH} + PATH="${ssh}/bin:$OLDPATH" + set -x + ${script} + ''; + }; + target = lib.mkOption { + type = types.str; + default = "root@${networking.hostName}.${networking.domain}"; + example = "root@192.168.1.10"; + description = "SSH destination where to install NixOS."; + }; + sshFlags = lib.mkOption { + type = types.listOf types.str; + default = ["-o" "ControlMaster=auto"]; + description = '' + Extra flags passed to ssh. + Environment variable SSH_FLAGS can also be used at runtime. + ''; + }; + nixCopyFlags = lib.mkOption { + type = types.listOf types.str; + default = ["--substitute-on-destination"]; + description = '' + Extra flags passed to nix copy. + Environment variable NIX_COPY_FLAGS can also be used at runtime. + ''; + }; + profile = lib.mkOption { + type = types.str; + default = "/nix/var/nix/profiles/system"; + }; +}; +config = { + installer.ssh-nixos.PATH = with pkgs; [nix openssh]; + installer.ssh-nixos.script = + let nixos = config.system.build.toplevel; in '' + nix ''${NIX_FLAGS:-} copy \ + --to ssh://'${cfg.target}' \ + ${lib.escapeShellArgs cfg.nixCopyFlags} ''${NIX_COPY_FLAGS:-} \ + ${nixos} + ssh '${cfg.target}' \ + nix-env --profile '${cfg.profile}' --set '${nixos}' '&&' \ + '${cfg.profile}'/bin/switch-to-configuration "''${NIXOS_SWITCH:-switch}" + ''; +}; +meta.maintainers = [ lib.maintainers.julm ]; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f361163ca63..15659fde11b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -80,6 +80,7 @@ ./i18n/input-method/ibus.nix ./i18n/input-method/nabi.nix ./i18n/input-method/uim.nix + ./installer/ssh-nixos.nix ./installer/tools/tools.nix ./misc/assertions.nix ./misc/crashdump.nix