summaryrefslogtreecommitdiff
path: root/system-profiles/rebuild-machines/default.nix
blob: e2a15aae6d7ef53450fc81a774426175ae7dee69 (plain)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
{ config, pkgs, hostName, lib, ... }:

with lib;

let
  cfg = config.system.rebuild-machine;

  sshConfig = pkgs.writeText "config" ''
    UserKnownHostsFile ${knownHostsFile}

    Host ${cfg.repoHost}
      User ${cfg.repoUser}
      IdentityFile ${if isNull cfg.sopsConfig then cfg.repoPrivkey else config.sops.secrets."${cfg.sopsName}".path}
      IdentitiesOnly yes
  '';

  knownHostsFile = pkgs.writeText "known_hosts" (concatMapStringsSep "\n" (kPath: cfg.repoHost + " " + readFile kPath) (attrValues cfg.repoPubkeys));
  
  rebuildScript = pkgs.stdenv.mkDerivation {
    name = "rebuild-${hostName}";

    src = ./rebuild-machine.zsh;

    buildInputs = with pkgs; [ makeWrapper ];

    phases = [ "buildPhase" "installPhase" ];

    inherit (pkgs) zsh coreutils openssh;
    inherit (cfg) flake scriptName;
    nixosRebuild = config.system.build.nixos-rebuild;
    inherit (config.security) wrapperDir;
    inherit sshConfig;

    buildPhase = ''
      substituteAll $src rebuild-machine.zsh
    '';

    installPhase = ''
      mkdir -p $out/bin
      install -m 0755 rebuild-machine.zsh $out/bin/${cfg.scriptName}
    '';
  };
in {
  options = {
    system.rebuild-machine = {
      scriptName = mkOption {
        type = types.str;
        default = "rebuild-${hostName}";
        description = ''
          Name of the script wrapping <literal>nixos-rebuild</literal>
        '';
      };
      
      flake = mkOption {
        type = types.nullOr types.str;
        default = "git+ssh://${cfg.repoHost}/nixos?ref=flakes#${hostName}";
        description = ''
          The Flake URI of the NixOS configuration to build.
        '';
      };

      repoHost = mkOption {
        type = types.str;
        default = "git.yggdrasil.li";
      };
      
      repoUser = mkOption {
        type = types.str;
        default = "gitolite";
      };

      repoPubkeys = mkOption {
        type = types.attrsOf types.path;
        default = genAttrs ["rsa" "ed25519"] (kType: ./ssh-pub + "/${cfg.repoHost}-${kType}.pub");
      };

      repoPrivkey = mkOption {
        type = types.path;
        default = ./ssh + "/${hostName}/private";
      };

      sopsName = mkOption {
        type = types.nullOr types.str;
        default = "rebuild-machines";
      };

      sopsConfig = mkOption {
        type = types.nullOr types.attrs;
        default = {
          format = "binary";
        };
      };
    };
  };
  
  config = {
    assertions = [
      { assertion = isNull cfg.sopsConfig || (!(isNull cfg.sopsName));
        message = "If option sopsConfig is not null option sopsName may not be null";
      }
    ];
    
    sops.secrets = lib.mkIf (!(isNull cfg.sopsConfig)) {
      "${cfg.sopsName}" = {
        sopsFile = cfg.repoPrivkey;
      } // cfg.sopsConfig;
    };

    environment.systemPackages = [ rebuildScript ];
  };
}