about summary refs log tree commit diff
path: root/users/sterni/machines/default.nix
blob: 4a859a337a2281ca6fd8f2bd1689b934bd00ad42 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{ depot, lib, pkgs, ... }:

let
  bins = depot.nix.getBins pkgs.nq [ "fq" "nq" ];

  machines = lib.mapAttrs
    (name: _:
      depot.ops.nixos.nixosFor (import (./. + ("/" + name)))
    )
    (lib.filterAttrs (_: type: type == "directory") (builtins.readDir ./.));

  # TODO(sterni): share code with rebuild-system
  localDeployScriptFor = { system, ... }:
    pkgs.writeShellScript "local-deploy-${system.name}" ''
      set -eu
      nix-env -p /nix/var/nix/profiles/system --set "${system}"
      "${system}/bin/switch-to-configuration" switch
    '';

  # Builds the system on the remote machine
  deployScriptFor = { system, ... }@machine:
    pkgs.writeShellScript "remote-deploy-${system.name}" ''
      set -eu

      if [ $# != 1 ]; then
        printf 'usage: %s [USER@]HOST' "$0"
        exit 100
      fi

      readonly TARGET_HOST="$1"
      readonly DEPLOY_DRV="${
        builtins.unsafeDiscardOutputDependency (
          # Wrapper script around localDeployScriptFor that merely starts the
          # local deploy script using and nq and then waits using fq. This means
          # we can't Ctrl-C the deploy and it won't be terminated by a lost
          # connection.
          pkgs.writeShellScript "queue-deploy-${system.name}" ''
            readonly STATE_DIR="''${XDG_STATE_HOME:-$HOME/.local/state}/sterni-deploy"
            mkdir -p "$STATE_DIR"

            export NQDIR="$STATE_DIR"

            "${bins.nq}" "${localDeployScriptFor machine}"
            "${bins.fq}"
          ''
        ).drvPath
      }"

      nix-copy-closure -s --gzip --to "$TARGET_HOST" "$DEPLOY_DRV"

      readonly DEPLOY_OUT="$(ssh "$TARGET_HOST" "nix-store -r '$DEPLOY_DRV'")"

      ssh "$TARGET_HOST" "$DEPLOY_OUT"
    '';

in

depot.nix.readTree.drvTargets (
  # this somehow becomes necessarily ugly with nixpkgs-fmt
  machines // { inherit deployScriptFor; } //

  lib.mapAttrs'
    (name: _: {
      name = "${name}System";
      value = machines.${name}.system;
    })
    machines

    //

  lib.mapAttrs'
    (name: _: {
      name = "${name}Deploy";
      value = deployScriptFor machines.${name};
    })
    machines
)