feat: add upgrader
All checks were successful
/ build-host (map[host:beefcake]) (push) Successful in 55s
/ build-host (map[host:dragon]) (push) Successful in 1m18s
/ build-host (map[host:flipflop]) (push) Successful in 1m13s
/ build-host (map[host:foxtrot]) (push) Successful in 1m18s
/ build-host (map[host:router]) (push) Successful in 47s
/ build-devshell (push) Successful in 20s
/ flake-check (push) Successful in 4m27s
All checks were successful
/ build-host (map[host:beefcake]) (push) Successful in 55s
/ build-host (map[host:dragon]) (push) Successful in 1m18s
/ build-host (map[host:flipflop]) (push) Successful in 1m13s
/ build-host (map[host:foxtrot]) (push) Successful in 1m18s
/ build-host (map[host:router]) (push) Successful in 47s
/ build-devshell (push) Successful in 20s
/ flake-check (push) Successful in 4m27s
This commit is contained in:
parent
906e8a81a3
commit
f4b2a19f43
5 changed files with 175 additions and 22 deletions
|
@ -25,9 +25,6 @@
|
||||||
|
|
||||||
formatter = uGenPkgs (p: p.nixfmt-rfc-style);
|
formatter = uGenPkgs (p: p.nixfmt-rfc-style);
|
||||||
|
|
||||||
colmena = import ./lib/colmena inputs;
|
|
||||||
colmenaHive = inputs.colmena.lib.makeHive inputs.self.outputs.colmena;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: nix-on-droid for phone terminal usage? mobile-nixos?
|
TODO: nix-on-droid for phone terminal usage? mobile-nixos?
|
||||||
TODO: nix-darwin for work?
|
TODO: nix-darwin for work?
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
home-manager,
|
home-manager,
|
||||||
nixpkgs-unstable,
|
|
||||||
self,
|
self,
|
||||||
...
|
...
|
||||||
}@inputs:
|
}@inputs:
|
||||||
|
@ -13,15 +12,15 @@
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
overlays = [ self.outputs.flakeLib.forSelfOverlay ];
|
overlays = [ self.outputs.flakeLib.forSelfOverlay ];
|
||||||
});
|
});
|
||||||
nixpkgs = nixpkgsSet nixpkgs-unstable;
|
nixpkgs = nixpkgsSet inputs.nixpkgs-unstable;
|
||||||
stable = nixpkgsSet nixpkgs;
|
stable = nixpkgsSet inputs.nixpkgs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit nixpkgs;
|
inherit nixpkgs;
|
||||||
nodeNixpkgs = {
|
# nodeNixpkgs = {
|
||||||
# router = stable;
|
# # router = stable;
|
||||||
beefcake = stable;
|
# beefcake = stable;
|
||||||
};
|
# };
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit home-manager;
|
inherit home-manager;
|
||||||
hardware = inputs.hardware.outputs.nixosModules;
|
hardware = inputs.hardware.outputs.nixosModules;
|
||||||
|
@ -47,24 +46,16 @@
|
||||||
targetHost = null;
|
targetHost = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
|
||||||
inputs.self.outputs.nixosModules.default
|
|
||||||
(import ./../../packages/hosts/foxtrot.nix)
|
|
||||||
];
|
|
||||||
|
|
||||||
# boot.isContainer = true;
|
# boot.isContainer = true;
|
||||||
# time.timeZone = nodes.host-b.config.time.timeZone;
|
# time.timeZone = nodes.host-b.config.time.timeZone;
|
||||||
};
|
}
|
||||||
|
// self.outputs.nixosConfigurations.foxtrot.config;
|
||||||
beefcake =
|
beefcake =
|
||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
deployment = {
|
deployment = {
|
||||||
buildOnTarget = true;
|
buildOnTarget = true;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
imports = [
|
// self.outputs.nixosConfigurations.beefcake.config;
|
||||||
inputs.self.outputs.nixosModules.default
|
|
||||||
(import ./../../packages/hosts/beefcake.nix)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ in
|
||||||
iosevka = pkgs.callPackage ./iosevka.nix { };
|
iosevka = pkgs.callPackage ./iosevka.nix { };
|
||||||
iosevkaLyteTermSubset = pkgs.callPackage ./iosevkaLyteTermSubset.nix { };
|
iosevkaLyteTermSubset = pkgs.callPackage ./iosevkaLyteTermSubset.nix { };
|
||||||
installer = pkgs.callPackage ./installer.nix { };
|
installer = pkgs.callPackage ./installer.nix { };
|
||||||
|
upgrader = pkgs.callPackage ./upgrader { };
|
||||||
ghostty-terminfo = pkgs.callPackage ./ghostty-terminfo.nix { };
|
ghostty-terminfo = pkgs.callPackage ./ghostty-terminfo.nix { };
|
||||||
forgejo-actions-container = pkgs.callPackage ./forgejo-actions-container.nix { };
|
forgejo-actions-container = pkgs.callPackage ./forgejo-actions-container.nix { };
|
||||||
}
|
}
|
||||||
|
|
58
packages/updater.nix
Normal file
58
packages/updater.nix
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "installer";
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
fzf
|
||||||
|
jq
|
||||||
|
gawk
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
repo='https://git.lyte.dev/lytedev/nix'
|
||||||
|
if ! [[ -f flake.nix ]]; then
|
||||||
|
dir="$(mktemp -d)"
|
||||||
|
echo "No flake detected. Cloning '$repo' to '$dir/nix'"
|
||||||
|
cd "$dir"
|
||||||
|
git clone "$repo"
|
||||||
|
cd nix
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r -p 'Swap Size:' swap_size
|
||||||
|
echo
|
||||||
|
read -s -r -p 'Disk Encryption Password:' pass1
|
||||||
|
echo
|
||||||
|
read -s -r -p 'Disk Encryption Password (Again):' pass2
|
||||||
|
echo
|
||||||
|
if ! [[ $pass1 = "$pass2" ]]; then
|
||||||
|
echo "error: disk encryption passwords did not match!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
nixos_host="$(nix --extra-experimental-features 'nix-command flakes' eval --accept-flake-config --json .#nixosConfigurations --apply 'builtins.attrNames' | jq -r .[] | fzf --prompt 'Select NixOS configuration')"
|
||||||
|
partition_scheme="$(nix --extra-experimental-features 'nix-command flakes' eval --accept-flake-config --json .#diskoConfigurations --apply 'builtins.attrNames' | jq -r .[] | fzf --prompt 'Select disk partition scheme (must match NixOS configuration!)')"
|
||||||
|
disk_path="/dev/$(lsblk -d --raw | tail -n +2 | fzf --prompt 'Select local disk device' | awk '{print $1}')"
|
||||||
|
|
||||||
|
echo "$pass1" | tr -d "\n" > /tmp/secret.key
|
||||||
|
|
||||||
|
echo "This will install the host configuration for '$nixos_host' to '$disk_path' using partition scheme '$partition_scheme'. All data on the disk will be lost."
|
||||||
|
echo "Press enter to proceed. Press Ctrl-C to cancel."
|
||||||
|
read -r
|
||||||
|
echo "Starting..."
|
||||||
|
|
||||||
|
nix-shell --packages git --run "sudo nix run \
|
||||||
|
--extra-experimental-features nix-command \
|
||||||
|
--extra-experimental-features flakes \
|
||||||
|
github:nix-community/disko -- \
|
||||||
|
--flake '.#$partition_scheme' \
|
||||||
|
--mode disko \
|
||||||
|
--arg disk '\"$disk_path\"' \
|
||||||
|
--arg swapSize '\"$swap_size\"'"
|
||||||
|
|
||||||
|
nix-shell --packages git \
|
||||||
|
--run "sudo nixos-install \
|
||||||
|
--no-write-lock-file \
|
||||||
|
--flake '.#$nixos_host' \
|
||||||
|
--option trusted-substituters 'https://cache.nixos.org https://nix.h.lyte.dev' \
|
||||||
|
--option trusted-public-keys 'cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= h.lyte.dev-2:te9xK/GcWPA/5aXav8+e5RHImKYMug8hIIbhHsKPN0M='" '';
|
||||||
|
}
|
106
packages/upgrader/default.nix
Normal file
106
packages/upgrader/default.nix
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "upgrader";
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
ripgrep
|
||||||
|
fzf
|
||||||
|
jq
|
||||||
|
gawk
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
CHECK_TIMEOUT=120
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
exit_code="''${1:-0}"
|
||||||
|
echo "upgrader TARGET_HOST"
|
||||||
|
echo " -h,--help Show help"
|
||||||
|
echo " --wait-and-rollback GEN Wait CHECK_TIMEOUT seconds and rollback to the boot generation [REMOTE]"
|
||||||
|
echo " --ignore-lock Ignore locks"
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
ilog() {
|
||||||
|
echo "$1" >> .upgrader.log
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_and_rollback() {
|
||||||
|
[[ $# -lt 1 ]] && { printf "error: no GEN argument provided for --wait-and-rollback\n" >&2; usage 1; }
|
||||||
|
gen="$1"
|
||||||
|
shift
|
||||||
|
while ! pgrep nixos-rebuild &>/dev/null; do
|
||||||
|
sleep 1;
|
||||||
|
done
|
||||||
|
while ! pgrep nixos-rebuild &>/dev/null; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
for i in $(seq 0 '"$CHECK_TIMEOUT"'; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
sudo nix-env --switch-generation -p /nix/var/nix/profiles/system
|
||||||
|
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ $# -lt 1 ]] && { printf "error: no TARGET_HOST argument provided\n" >&2; usage 1; }
|
||||||
|
target_host="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
ignore_locks=0
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--wait-and-rollback)
|
||||||
|
wait_and_rollback
|
||||||
|
--ignore-locks)
|
||||||
|
ignore_locks=1
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-h | --help | help)
|
||||||
|
usage 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "error: unexpected argument '$1' (if you meant to pass this to the underlying command(s), use '-- $1')"
|
||||||
|
usage 1
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
ssh "$target_host" true
|
||||||
|
echo "SSH access to '$target_host' confirmed!"
|
||||||
|
|
||||||
|
# TODO: install upgrader on remote host and know how to call it
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo "$1"
|
||||||
|
ssh "$target_host" 'echo "$(date) $1" >> .upgrader.log'
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_bg_job() {
|
||||||
|
ssh "$target_host" 'nohup sh -c "( ( '"$1"' ) & )"'
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $ignore_locks == 0 ]] && ssh "$target_host" "stat .upgrader.lck &>/dev/null" &>/dev/null; then
|
||||||
|
log ".upgrader.lck exists on '$target_host', refusing to upgrade"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: handle boot-level failures?
|
||||||
|
|
||||||
|
boot_gen="$(ssh "$target_host" "cat /boot/loader/loader.conf | rg 'default\s*nixos-generation-(\d+)\.conf' -r '\$1'")"
|
||||||
|
log "Current Boot Generation for '$target_host': $boot_gen"
|
||||||
|
|
||||||
|
# TODO: start some kind of "waiter"
|
||||||
|
remote_bg_job 'remote_upgrader --wait-and-rollback'
|
||||||
|
|
||||||
|
log "Upgrading '$target_host' (may require sudo prompt)..."
|
||||||
|
ssh -t "$target_host" "touch .upgrader.lck; sudo nixos-rebuild test --flake git+https://git.lyte.dev/lytedev/nix"
|
||||||
|
|
||||||
|
ssh -t "$target_host" 'remote_upgrader --kill-waiter'
|
||||||
|
|
||||||
|
log 'Promoting current configuration to boot generation (may require sudo prompt)...'
|
||||||
|
ssh -t "$target_host" 'sudo /run/current-system/bin/switch-to-configuration switch'
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue