[Nix-dev] Persistent NixOps keys

Игорь Пашев pashev.igor at gmail.com
Sun May 8 21:54:19 CEST 2016


Simple way to keep the keys on reboot.
/run/keys is mounted somewhere in initrd,
thus just a couple of services
(I was thinking about on-disk /run/keys)

{ config, lib, pkgs, ... }:
let

  inherit (builtins) attrNames;
  inherit (lib) mkIf concatMapStringsSep;
  inherit (config.deployment) keys;

  store = "/root/keys";
  runkeys = "/run/keys";

  load = pkgs.writeBashScript "nixops-load-keys" ''
    set -euo pipefail
    if [ -e '${store}/done' ] && [ ! -e '${runkeys}/done' ]; then
      cd '${store}'
      cp -pf -- ${concatMapStringsSep " " (k: "'${k}'") (attrNames keys)} \
        '${runkeys}/' || exit 0
      touch -r '${store}/done' '${runkeys}/done'
    fi
  '';

  save = pkgs.writeBashScript "nixops-save-keys" ''
    set -euo pipefail
    while true; do
      if [ -e '${runkeys}/done' ]; then
        if [ ! -e '${store}/done' ] || [ '${runkeys}/done' -nt
'${store}/done' ] ; then
          rm -rf '${store}'
          mkdir -p '${store}'
          chown --reference='${runkeys}' -- '${store}'
          chmod --reference='${runkeys}' -- '${store}'
          cd '${runkeys}'
          cp -pf -- ${concatMapStringsSep " " (k: "'${k}'") (attrNames keys)} \
            '${store}/' || continue
          touch -r '${runkeys}/done' '${store}/done'
          touch -r '${runkeys}' '${store}'
        fi
      fi
      sleep 1m
    done
  '';

in {
  config = mkIf (keys != {}) {
    systemd.services.nixops-load-keys = {
      description = "Re-load nixops keys after reboot";
      before = [ "nixops-keys.service" ];
      wantedBy = [ "keys.target" ];
      unitConfig.RequiresMountsFor = [ runkeys store ];
      serviceConfig = {
        ExecStart = load;
        Type = "oneshot";
        RemainAfterExit = false;
      };
    };

    systemd.services.nixops-save-keys = {
      description = "Save nixops keys to re-load after reboot";
      after = [ "keys.target" ];
      wantedBy = [ "keys.target" ];
      serviceConfig = {
        ExecStart = save;
        Restart = "always";
      };
    };
  };
}


P. S. writeBashScript:
{ bash, writeScript, haskellPackages, runCommand }:

name: text:
let
  f = writeScript name ''
    #!${bash}/bin/bash
    ${text}
  '';
in
runCommand name { } ''
  ${haskellPackages.ShellCheck}/bin/shellcheck ${f}
  cp -a ${f} $out
''


More information about the nix-dev mailing list