aboutsummaryrefslogtreecommitdiff
path: root/pkgs/yo
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/yo')
-rw-r--r--pkgs/yo/README.md2
-rw-r--r--pkgs/yo/default.nix59
-rw-r--r--pkgs/yo/nixos.rb37
3 files changed, 98 insertions, 0 deletions
diff --git a/pkgs/yo/README.md b/pkgs/yo/README.md
new file mode 100644
index 0000000..a308057
--- /dev/null
+++ b/pkgs/yo/README.md
@@ -0,0 +1,2 @@
+# `nixos.rb`
+A small Ruby library for writing `nixos-rebuild` replacements.
diff --git a/pkgs/yo/default.nix b/pkgs/yo/default.nix
new file mode 100644
index 0000000..06e88d4
--- /dev/null
+++ b/pkgs/yo/default.nix
@@ -0,0 +1,59 @@
+{pkgs, ...}: let
+ yo = pkgs.writeText "yo.rb" ''
+ require '${./nixos.rb}'
+
+ FLAKE_PATH = "/home/collin/nixos"
+
+ case ARGV[0]
+ when "deploy", "dep"
+ hostname = ARGV[1] or abort "must specify hostname to build"
+ ssh_host = ARGV[2] or abort "must specify ssh host to target"
+
+ store_path = Nix.build_configuration(
+ flake_path: FLAKE_PATH,
+ hostname: hostname
+ )
+ Nix.switch_to_configuration_remote(store_path: store_path, ssh_host: ssh_host, use_magic_rollback: true)
+ when "switch", "sw"
+ store_path = Nix.build_configuration(
+ flake_path: FLAKE_PATH,
+ hostname: `hostname`.chomp
+ )
+ Nix.switch_to_configuration(
+ store_path: store_path,
+ verb: "switch",
+ sudo_cmd: "run0 --background="
+ )
+ when "boot"
+ store_path = Nix.build_configuration(
+ flake_path: FLAKE_PATH,
+ hostname: `hostname`.chomp
+ )
+ Nix.switch_to_configuration(
+ store_path: store_path,
+ verb: "boot",
+ sudo_cmd: "run0 --background="
+ )
+ when "test"
+ store_path = Nix.build_configuration(
+ flake_path: FLAKE_PATH,
+ hostname: `hostname`.chomp
+ )
+ Nix.switch_to_configuration(
+ store_path: store_path,
+ verb: "test",
+ sudo_cmd: "run0 --background="
+ )
+ when "build"
+ hostname = ARGV[1] or `hostname`.chomp
+
+ Nix.build_configuration(
+ flake_path: FLAKE_PATH,
+ hostname: hostname
+ )
+ end
+ '';
+in
+ pkgs.writeShellScriptBin "yo" ''
+ exec ${pkgs.ruby}/bin/ruby ${yo} "$@"
+ ''
diff --git a/pkgs/yo/nixos.rb b/pkgs/yo/nixos.rb
new file mode 100644
index 0000000..73a1872
--- /dev/null
+++ b/pkgs/yo/nixos.rb
@@ -0,0 +1,37 @@
+module Nix
+ def build_configuration(flake_path:, hostname:)
+ flake_target = "#{flake_path}#nixosConfigurations.'#{hostname}'.config.system.build.toplevel"
+ `nix build --no-link --print-out-paths #{flake_target}`.chomp.tap do
+ raise "Build command failed" unless $?.success?
+ end
+ end
+
+ def switch_to_configuration(store_path:, verb:, sudo_cmd: "sudo")
+ create_gen_cmd = "nix build --no-link --profile /nix/var/nix/profiles/system #{store_path}"
+ switch_cmd = "#{store_path}/bin/switch-to-configuration #{verb}"
+ system("#{sudo_cmd} bash -c '#{create_gen_cmd}; #{switch_cmd}'") or raise "Switch command failed"
+ end
+
+ def switch_to_configuration_remote(store_path:, ssh_host:, use_magic_rollback: false)
+ system("nix copy --to ssh://#{ssh_host} #{store_path}") or raise "Copy closure command failed"
+
+ create_gen_cmd = "nix build --no-link --profile /nix/var/nix/profiles/system #{store_path}"
+ switch_cmd = "#{store_path}/bin/switch-to-configuration switch"
+
+ if use_magic_rollback
+ test_cmd = "#{store_path}/bin/switch-to-configuration test"
+ system(%[ssh #{ssh_host} 'bash -c "#{test_cmd}; shutdown -r +5"']) or raise "Remote test command failed"
+
+ puts <<~MSG
+ Remote deployment complete.
+ If everything works, press ENTER to confirm and cancel rollback.
+ If SSH dies, it will restart (reversing changes) automatically in 5 minutes
+ MSG
+ $stdin.gets
+
+ system(%[ssh #{ssh_host} 'bash -c "shutdown -c; #{create_gen_cmd}; #{switch_cmd}"']) or raise "Remote switch command failed"
+ else
+ system(%[ssh #{ssh_host} 'bash -c "#{create_gen_cmd}; #{switch_cmd}"']) or raise "Remote switch command failed"
+ end
+ end
+end