feat: custom kexec installer for headless install on read-only-root (ZimaOS)
- add nixos-images input; nixosConfigurations.kexec bakes in the ssh login key - build via config.system.build.kexecInstallerTarball - deploy: ./deploy kexec <host> streams the installer to /tmp and kexecs - works around ZimaOS RO root where nixos-anywhere ssh-copy-id fails Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Deploy the jupiter NixOS config.
|
# Deploy the jupiter NixOS config.
|
||||||
#
|
#
|
||||||
# ./deploy install <ip> first install onto a fresh box (nixos-anywhere).
|
# ./deploy kexec <host> headless-only: for a read-only-root box (ZimaOS)
|
||||||
# Wipes the OS disk. Ships the sops host key.
|
# where nixos-anywhere can't ssh-copy-id. Uploads a
|
||||||
|
# kexec installer (our SSH key baked in) to /tmp and
|
||||||
|
# boots into it. Then run `install`.
|
||||||
|
# ./deploy install <ip> first install onto a fresh box / running installer
|
||||||
|
# (nixos-anywhere). Wipes the OS disk. Ships host key.
|
||||||
# ./deploy [switch] [host] rebuild + activate on a running jupiter (default).
|
# ./deploy [switch] [host] rebuild + activate on a running jupiter (default).
|
||||||
# ./deploy boot [host] stage for next boot, don't activate now.
|
# ./deploy boot [host] stage for next boot, don't activate now.
|
||||||
# ./deploy test [host] activate without adding a boot entry.
|
# ./deploy test [host] activate without adding a boot entry.
|
||||||
@@ -18,11 +22,30 @@ HOSTKEY="$HOME/.config/homelab/jupiter/ssh_host_ed25519_key"
|
|||||||
|
|
||||||
cmd="${1:-switch}"
|
cmd="${1:-switch}"
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
switch|boot|test|install) shift || true ;;
|
switch|boot|test|install|kexec) shift || true ;;
|
||||||
*) cmd="switch" ;;
|
*) cmd="switch" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
|
kexec)
|
||||||
|
host="${1:-}"
|
||||||
|
[ -n "$host" ] || { echo "usage: ./deploy kexec <ip-or-host>" >&2; exit 1; }
|
||||||
|
|
||||||
|
echo ">> building kexec installer (SSH key baked in)"
|
||||||
|
nix build .#nixosConfigurations.kexec.config.system.build.kexecInstallerTarball \
|
||||||
|
-o result-kexec
|
||||||
|
tb="$(ls result-kexec/*.tar.gz | head -1)"
|
||||||
|
|
||||||
|
echo ">> streaming installer to root@$host and kexec-ing (enter root password)"
|
||||||
|
echo " Extracted to /tmp (tmpfs); no compressed copy stored. SSH drops as"
|
||||||
|
echo " the box jumps into the RAM installer. Disks are untouched."
|
||||||
|
# Stream the tarball straight into remote tar to avoid a second 522MB copy.
|
||||||
|
ssh "root@$host" 'mkdir -p /tmp/k && tar -C /tmp/k -xzf - && /tmp/k/kexec/run' < "$tb" || true
|
||||||
|
|
||||||
|
echo ">> box is kexec-ing. Wait ~1-2 min for the installer + network, then:"
|
||||||
|
echo " ./deploy install $host"
|
||||||
|
;;
|
||||||
|
|
||||||
install)
|
install)
|
||||||
host="${1:-}"
|
host="${1:-}"
|
||||||
[ -n "$host" ] || { echo "usage: ./deploy install <ip-or-host>" >&2; exit 1; }
|
[ -n "$host" ] || { echo "usage: ./deploy install <ip-or-host>" >&2; exit 1; }
|
||||||
|
|||||||
Generated
+54
@@ -20,6 +20,59 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixos-images": {
|
||||||
|
"inputs": {
|
||||||
|
"nixos-stable": "nixos-stable",
|
||||||
|
"nixos-unstable": "nixos-unstable"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783593136,
|
||||||
|
"narHash": "sha256-zy5an02BdZ65OgVKdRkz2TpbdBrsW+uQD7AA2wLuiTM=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixos-images",
|
||||||
|
"rev": "803f28511c7d5f39f2537c342122fd94b8e1d519",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixos-images",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783389287,
|
||||||
|
"narHash": "sha256-0xIy4dVLqq47rA+mRy0hXDfjhQd4E5PoIns/RmB7nR4=",
|
||||||
|
"ref": "nixos-26.05",
|
||||||
|
"rev": "0ad6f47ea4fe188f4bc8f0380f93ae8523337c6c",
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"ref": "nixos-26.05",
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782175435,
|
||||||
|
"narHash": "sha256-EMzXKmnOtBQ2MnvpiNOm7E+kOMvdPrIKaeg52Tip2Uk=",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"rev": "89570f24e97e614aa34aa9ab1c927b6578a43775",
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1783703440,
|
"lastModified": 1783703440,
|
||||||
@@ -39,6 +92,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"nixos-images": "nixos-images",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"sops-nix": "sops-nix"
|
"sops-nix": "sops-nix"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,13 @@
|
|||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
nixos-images = {
|
||||||
|
url = "github:nix-community/nixos-images";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, disko, sops-nix, ... }@inputs:
|
outputs = { self, nixpkgs, disko, sops-nix, nixos-images, ... }@inputs:
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
in
|
in
|
||||||
@@ -39,6 +43,23 @@
|
|||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
modules = [ ./jupiter/vm.nix ];
|
modules = [ ./jupiter/vm.nix ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Custom kexec installer with our SSH key baked in, for headless install
|
||||||
|
# onto a box with a read-only root (ZimaOS) where nixos-anywhere can't
|
||||||
|
# ssh-copy-id. Build the tarball:
|
||||||
|
# nix build .#nixosConfigurations.kexec.config.system.build.kexecInstallerTarball
|
||||||
|
# then scp it to the target's writable /tmp and run kexec/run (see README).
|
||||||
|
kexec = nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = [
|
||||||
|
nixos-images.nixosModules.kexec-installer
|
||||||
|
({ ... }: {
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGZpkPVhzi1zG5JI9hWyUgdyvNIQbp4ts4jw3idpMhhN erik@laptop"
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user