151 lines
4.7 KiB
Nix
151 lines
4.7 KiB
Nix
{ lib, pkgs, config, systems, ... }:
|
|
let
|
|
inherit (builtins) head attrNames;
|
|
inherit (lib) mkMerge mkIf mkDefault optionalAttrs mapAttrs' optionalString;
|
|
inherit (lib.my) mkOpt' mkBoolOpt';
|
|
|
|
cfg = config.my.deploy;
|
|
|
|
keepGensOpt = with lib.types; mkOpt' ints.unsigned 10
|
|
"Number of generations to keep when cleaning up old deployments (0 to disable deletion on deployment).";
|
|
keepGensSnippet = p: n: optionalString (n > 0) ''
|
|
${config.nix.package}/bin/nix-env -p "${p}" --delete-generations +${toString n}
|
|
'';
|
|
|
|
# Based on https://github.com/serokell/deploy-rs/blob/master/flake.nix
|
|
nixosActivate = cfg': base: (pkgs.deploy-rs.lib.activate.custom // {
|
|
dryActivate = "$PROFILE/bin/switch-to-configuration dry-activate";
|
|
boot = ''
|
|
$PROFILE/bin/switch-to-configuration boot
|
|
|
|
${keepGensSnippet "$PROFILE" cfg'.keepGenerations}
|
|
'';
|
|
}) base.config.system.build.toplevel ''
|
|
# work around https://github.com/NixOS/nixpkgs/issues/73404
|
|
cd /tmp
|
|
|
|
"$PROFILE"/bin/switch-to-configuration switch
|
|
|
|
# https://github.com/serokell/deploy-rs/issues/31
|
|
${with base.config.boot.loader;
|
|
optionalString systemd-boot.enable
|
|
"sed -i '/^default /d' ${efi.efiSysMountPoint}/loader/loader.conf"}
|
|
|
|
${keepGensSnippet "$PROFILE" cfg'.keepGenerations}
|
|
'';
|
|
|
|
systemdUtil = pkgs.writeShellApplication {
|
|
name = "systemd-util.sh";
|
|
text = ''
|
|
svcActionWatch() {
|
|
action="$1"
|
|
shift
|
|
unit="$1"
|
|
shift
|
|
|
|
journalctl -o cat --no-pager -n 0 -f -u "$unit" &
|
|
jPid=$!
|
|
cleanup() {
|
|
# shellcheck disable=SC2317
|
|
kill "$jPid"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
systemctl "$@" "$action" "$unit"
|
|
}
|
|
'';
|
|
};
|
|
|
|
ctrProfiles = optionalAttrs cfg.generate.containers.enable (mapAttrs' (n: c:
|
|
let
|
|
ctrConfig = systems."${n}".configuration.config;
|
|
in
|
|
{
|
|
name = "container-${n}";
|
|
value = {
|
|
path = (pkgs.deploy-rs.lib.activate.custom // {
|
|
boot = ''
|
|
echo "Next systemd-nspawn@${n}.service restart / reload will load config"
|
|
'';
|
|
}) ctrConfig.my.buildAs.container ''
|
|
source ${systemdUtil}/bin/systemd-util.sh
|
|
${if c.hotReload then ''
|
|
if (! systemctl show -p ActiveState systemd-nspawn@${n} | grep -q "ActiveState=active") || \
|
|
systemctl show -p StatusText systemd-nspawn@${n} | grep -q "Dummy container"; then
|
|
action=restart
|
|
else
|
|
action=reload
|
|
fi
|
|
|
|
svcActionWatch "$action" systemd-nspawn@${n}
|
|
'' else ''
|
|
svcActionWatch restart systemd-nspawn@${n}
|
|
''}
|
|
|
|
${keepGensSnippet "$PROFILE" cfg.generate.containers.keepGenerations}
|
|
'';
|
|
profilePath = "/nix/var/nix/profiles/per-container/${n}/system";
|
|
|
|
user = "root";
|
|
};
|
|
}) config.my.containers.instances);
|
|
in
|
|
{
|
|
options.my.deploy = with lib.types; {
|
|
authorizedKeys = {
|
|
keys = mkOpt' (listOf singleLineStr) [ ] "SSH public keys to add to the default deployment user.";
|
|
keyFiles = mkOpt' (listOf path) [ lib.my.c.sshKeyFiles.deploy ] "SSH public key files to add to the default deployment user.";
|
|
};
|
|
|
|
enable = mkBoolOpt' true "Whether to expose deploy-rs configuration for this system.";
|
|
inherit (lib.my.deploy-rs) node;
|
|
|
|
generate = {
|
|
system = {
|
|
enable = mkBoolOpt' true "Whether to generate a deploy-rs profile for this system's config.";
|
|
mode = mkOpt' str "switch" "switch-to-configuration mode.";
|
|
keepGenerations = keepGensOpt;
|
|
};
|
|
containers = {
|
|
enable = mkBoolOpt' true "Whether to generate deploy-rs profiles for this system's containers.";
|
|
keepGenerations = keepGensOpt;
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkMerge [
|
|
{
|
|
my.deploy.enable = mkIf (config.my.build.isDevVM || config.boot.isContainer) false;
|
|
}
|
|
(mkIf cfg.enable {
|
|
my.deploy.node = {
|
|
hostname = mkDefault config.networking.fqdn;
|
|
profilesOrder = [ "system" ] ++ (attrNames ctrProfiles);
|
|
profiles = {
|
|
system = mkIf cfg.generate.system.enable {
|
|
path = nixosActivate cfg.generate.system { inherit config; };
|
|
|
|
user = "root";
|
|
};
|
|
} // ctrProfiles;
|
|
|
|
sshUser = "deploy";
|
|
user = mkDefault "root";
|
|
sudo = mkDefault (if config.security.doas.enable then "doas -u" else "sudo -u");
|
|
sshOpts = mkDefault [ "-p" (toString (head config.services.openssh.ports)) ];
|
|
};
|
|
|
|
users = {
|
|
users."${cfg.node.sshUser}" = {
|
|
isSystemUser = true;
|
|
group = cfg.node.sshUser;
|
|
extraGroups = mkDefault [ "wheel" ];
|
|
shell = pkgs.bash;
|
|
openssh.authorizedKeys = cfg.authorizedKeys;
|
|
};
|
|
groups."${cfg.node.sshUser}" = {};
|
|
};
|
|
})
|
|
];
|
|
}
|