config

NixOS config
Log | Files | Refs | README | LICENSE

default.nix (5099B) - Raw


      1 {
      2   config,
      3   lib,
      4   pkgs,
      5   ...
      6 }:
      7 {
      8   options.mj.services.deployerbot.main = with lib.types; {
      9     enable = lib.mkEnableOption "Enable system updater orchestrator";
     10     deployDerivations = lib.mkOption { type = listOf str; };
     11     deployIfPresent = lib.mkOption {
     12       type = listOf (submodule {
     13         options = {
     14           derivationTarget = lib.mkOption { type = str; };
     15           pingTarget = lib.mkOption { type = str; };
     16         };
     17       });
     18       default = [ ];
     19     };
     20     uidgid = lib.mkOption { type = int; };
     21     repo = lib.mkOption { type = str; };
     22   };
     23 
     24   options.mj.services.deployerbot.follower = with lib.types; {
     25     enable = lib.mkEnableOption "Allow system to be deployed with deployerbot";
     26     sshAllowSubnets = lib.mkOption { type = listOf str; };
     27     publicKeys = lib.mkOption { type = listOf str; };
     28     uidgid = lib.mkOption { type = int; };
     29   };
     30 
     31   config = lib.mkMerge [
     32     (
     33       let
     34         cfg = config.mj.services.deployerbot.main;
     35       in
     36       lib.mkIf cfg.enable {
     37         # TODO: git config --global user.email bot@jakstys.lt
     38         users.users.deployerbot-main = {
     39           description = "Deployerbot Main";
     40           home = "/var/lib/deployerbot-main";
     41           shell = "/bin/sh";
     42           group = "deployerbot-main";
     43           isSystemUser = true;
     44           createHome = true;
     45           uid = cfg.uidgid;
     46         };
     47         users.groups.deployerbot-main.gid = cfg.uidgid;
     48 
     49         systemd.services.deployerbot = {
     50           description = "Update all known systems";
     51           environment = {
     52             TZ = "UTC";
     53           };
     54           path = [
     55             pkgs.git
     56             pkgs.openssh
     57             pkgs.nix
     58           ];
     59           restartIfChanged = false;
     60           serviceConfig = {
     61             Type = "oneshot";
     62             User = "deployerbot-main";
     63             WorkingDirectory = config.users.users.deployerbot-main.home;
     64             LoadCredential = [ "ssh-key:/etc/ssh/ssh_host_ed25519_key" ];
     65           };
     66           script =
     67             let
     68               deployDerivationsStr = builtins.concatStringsSep " " cfg.deployDerivations;
     69             in
     70             ''
     71               set -xeuo pipefail
     72 
     73               export GIT_SSH_COMMAND="ssh -i ''${CREDENTIALS_DIRECTORY}/ssh-key"
     74               if [[ ! -d config ]]; then
     75                 git clone ${cfg.repo} config
     76                 cd config
     77               else
     78                 cd config
     79                 git fetch origin
     80                 git reset --hard origin/main
     81               fi
     82 
     83               nix flake update --accept-flake-config --commit-lock-file
     84               nix flake check --all-systems --accept-flake-config
     85 
     86               EXITCODE=0
     87               ${pkgs.deploy-rs.deploy-rs}/bin/deploy \
     88                 --ssh-opts="-i ''${CREDENTIALS_DIRECTORY}/ssh-key" \
     89                 --ssh-user=deployerbot-follower \
     90                 --confirm-timeout 60 \
     91                 --skip-checks \
     92                 --targets ${deployDerivationsStr} -- \
     93                   --accept-flake-config || EXITCODE=1
     94 
     95               if [[ $EXITCODE != 0 ]]; then
     96                 exit $EXITCODE
     97               else
     98                 git push origin main
     99               fi
    100 
    101               # Optional deployments
    102               ${lib.concatMapStringsSep "\n" (t: ''
    103                 if ${pkgs.inetutils}/bin/ping -c 1 ${t.pingTarget}; then
    104                   ${pkgs.deploy-rs.deploy-rs}/bin/deploy \
    105                     --ssh-opts="-i ''${CREDENTIALS_DIRECTORY}/ssh-key" \
    106                     --ssh-user=deployerbot-follower \
    107                     --confirm-timeout 60 \
    108                     --skip-checks \
    109                     --targets ${t.derivationTarget} -- \
    110                       --accept-flake-config || EXITCODE=1
    111                 fi
    112               '') cfg.deployIfPresent}
    113 
    114               exit $EXITCODE
    115             '';
    116         };
    117 
    118         systemd.timers.deployerbot = {
    119           description = "deployerbot-main timer";
    120           wantedBy = [ "timers.target" ];
    121           timerConfig.OnCalendar = "*-*-* 09:00:00 Europe/Vilnius";
    122         };
    123 
    124         mj.base.unitstatus.units = [ "deployerbot" ];
    125 
    126         nix.settings.trusted-users = [ "deployerbot-main" ];
    127       }
    128     )
    129 
    130     (
    131       let
    132         cfg = config.mj.services.deployerbot.follower;
    133       in
    134       lib.mkIf cfg.enable {
    135         users.users.deployerbot-follower = {
    136           description = "Deployerbot Follower";
    137           home = "/var/lib/deployerbot-follower";
    138           shell = "/bin/sh";
    139           group = "deployerbot-follower";
    140           extraGroups = [ "wheel" ];
    141           isSystemUser = true;
    142           createHome = true;
    143           uid = cfg.uidgid;
    144           openssh.authorizedKeys.keys = map (
    145             k:
    146             ''from="${
    147               builtins.concatStringsSep "," (
    148                 cfg.sshAllowSubnets
    149                 ++ [
    150                   "::1"
    151                   "127.0.0.1"
    152                 ]
    153               )
    154             }" ''
    155             + k
    156           ) cfg.publicKeys;
    157         };
    158         users.groups.deployerbot-follower.gid = cfg.uidgid;
    159         nix.settings.trusted-users = [ "deployerbot-follower" ];
    160       }
    161     )
    162   ];
    163 }