modules/ascension: init
This commit is contained in:
parent
3376200e80
commit
f9daec023f
2 changed files with 127 additions and 0 deletions
125
modules/ascensions/default.nix
Normal file
125
modules/ascensions/default.nix
Normal file
|
@ -0,0 +1,125 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
ascensionsDir = "/var/lib/ascensions";
|
||||
|
||||
ascensionType = { name, ... }: {
|
||||
options = {
|
||||
incantations = mkOption {
|
||||
type = with types; functionTo (listOf package);
|
||||
default = [];
|
||||
};
|
||||
distributed = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to perform a distributed ascension using Consul KV.";
|
||||
};
|
||||
requiredBy = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ "${name}.service" ];
|
||||
description = "Services that require this ascension.";
|
||||
};
|
||||
before = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "Run the ascension before these services.";
|
||||
};
|
||||
after = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "Run the ascension after these services.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
runIncantations = f: with pkgs; f rec {
|
||||
execShellWith = extraPackages: script: writeShellScript "incantation" ''
|
||||
export PATH='${makeBinPath ([ coreutils ] ++ extraPackages)}'
|
||||
${script}
|
||||
'';
|
||||
|
||||
execShell = execShellWith [];
|
||||
|
||||
multiple = incantations: execShell (concatStringsSep " && " incantations);
|
||||
|
||||
move = from: to: execShell ''
|
||||
test -e ${escapeShellArg from} && rm -rf ${escapeShellArg to}
|
||||
mkdir -p "$(dirname ${escapeShellArg to})"
|
||||
mv ${escapeShellArgs [ from to ]}
|
||||
'';
|
||||
|
||||
chmod = mode: target: "chmod -R ${escapeShellArgs [ mode target ]}";
|
||||
};
|
||||
|
||||
consul = config.services.consul.package;
|
||||
in
|
||||
|
||||
{
|
||||
options.system.ascensions = mkOption {
|
||||
type = with types; attrsOf (submodule ascensionType);
|
||||
default = {};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd = {
|
||||
tmpfiles.rules = [
|
||||
"d ${ascensionsDir} 0755 root root - -"
|
||||
];
|
||||
|
||||
services = mapAttrs' (name: asc: {
|
||||
name = "ascend-${name}";
|
||||
value = let
|
||||
incantations = runIncantations asc.incantations;
|
||||
targetLevel = toString (length incantations);
|
||||
in {
|
||||
description = "Ascension for ${name}";
|
||||
inherit (asc) requiredBy before;
|
||||
after = asc.after ++ (lib.optional asc.distributed "consul.service");
|
||||
serviceConfig.Type = "oneshot";
|
||||
distributed.enable = asc.distributed;
|
||||
script = ''
|
||||
incantations=(${concatStringsSep " " incantations})
|
||||
${if asc.distributed then /*bash*/ ''
|
||||
getLevel() {
|
||||
${consul}/bin/consul kv get 'ascensions/${name}/currentLevel'
|
||||
}
|
||||
setLevel() {
|
||||
${consul}/bin/consul kv put 'ascensions/${name}/currentLevel' "$1" >/dev/null
|
||||
}
|
||||
isEmpty() {
|
||||
! getLevel >/dev/null 2>/dev/null
|
||||
}
|
||||
'' else /*bash*/ ''
|
||||
levelFile='${ascensionsDir}/${name}'
|
||||
getLevel() {
|
||||
echo "$(<"$levelFile")"
|
||||
}
|
||||
setLevel() {
|
||||
echo "$1" > "$levelFile"
|
||||
}
|
||||
isEmpty() {
|
||||
[[ ! -e "$levelFile" ]]
|
||||
}
|
||||
''
|
||||
}
|
||||
if isEmpty; then
|
||||
setLevel '${targetLevel}'
|
||||
echo Initializing at level ${targetLevel}
|
||||
exit 0
|
||||
fi
|
||||
cur=$(getLevel)
|
||||
echo Current level: $cur
|
||||
for lvl in $(seq $(($cur+1)) ${targetLevel}); do
|
||||
echo Running incantation for level $lvl...
|
||||
''${incantations[$((lvl-1))]}
|
||||
setLevel "$lvl"
|
||||
done
|
||||
echo All incantations complete, ascended to level $(getLevel)
|
||||
'';
|
||||
};
|
||||
}) config.system.ascensions;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -7,6 +7,7 @@ in
|
|||
{
|
||||
flake.nixosModules = with config.flake.nixosModules; {
|
||||
autopatch = ./autopatch;
|
||||
ascensions = ./ascensions;
|
||||
consul-distributed-services = ./consul-distributed-services;
|
||||
consul-service-registry = ./consul-service-registry;
|
||||
deploy-rs-receiver = ./deploy-rs-receiver;
|
||||
|
@ -45,6 +46,7 @@ in
|
|||
|
||||
serverBase = group [
|
||||
machineBase
|
||||
ascensions
|
||||
consul-distributed-services
|
||||
consul-service-registry
|
||||
deploy-rs-receiver
|
||||
|
|
Loading…
Reference in a new issue