clan-core/nixosModules/clanCore/state.nix

133 lines
4.7 KiB
Nix
Raw Normal View History

{
lib,
pkgs,
config,
...
}:
{
# interface
2024-06-17 10:42:28 +00:00
options.clan.core.state = lib.mkOption {
default = { };
2024-03-17 18:48:49 +00:00
type = lib.types.attrsOf (
lib.types.submodule (
{ name, config, ... }:
2024-03-17 18:48:49 +00:00
{
options = {
2024-06-05 16:37:31 +00:00
name = lib.mkOption {
type = lib.types.strMatching "^[a-zA-Z0-9_-]+$";
2024-06-05 16:37:31 +00:00
default = name;
description = ''
Name of the state
'';
};
2024-03-17 18:48:49 +00:00
folders = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Folder where state resides in
'';
};
preBackupScript = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
2024-05-31 14:36:37 +00:00
default = null;
description = ''
script to run before backing up the state dir
This is for example useful for services that require an export of their state
e.g. a database dump
'';
};
preBackupCommand = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = if config.preBackupScript == null then null else "pre-backup-${name}";
readOnly = true;
description = ''
Use this command in backup providers. It contains the content of preBackupScript.
'';
};
# TODO: implement this
#stopOnRestore = lib.mkOption {
# type = lib.types.listOf lib.types.str;
# default = [];
# description = ''
# List of services to stop before restoring the state dir from a backup
# Utilize this to stop services which currently access these folders or or other services affected by the restore
# '';
#};
preRestoreScript = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
2024-03-17 18:48:49 +00:00
description = ''
script to run before restoring the state dir from a backup
2024-01-15 09:03:47 +00:00
2024-03-17 18:48:49 +00:00
Utilize this to stop services which currently access these folders
'';
};
preRestoreCommand = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = if config.preRestoreScript == null then null else "pre-restore-${name}";
readOnly = true;
description = ''
This command can be called to restore the state dir from a backup.
It contains the content of preRestoreScript.
'';
};
postRestoreScript = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
2024-03-17 18:48:49 +00:00
description = ''
script to restore the service after the state dir was restored from a backup
2024-01-15 09:03:47 +00:00
2024-03-17 18:48:49 +00:00
Utilize this to start services which were previously stopped
'';
};
postRestoreCommand = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = if config.postRestoreScript == null then null else "post-restore-${name}";
readOnly = true;
description = ''
This command is called after a restore of the state dir from a backup.
It contains the content of postRestoreScript.
'';
};
};
2024-03-17 18:48:49 +00:00
}
)
);
};
# defaults
config.clan.core.state.HOME.folders = [ "/home" ];
config.environment.systemPackages = lib.optional (config.clan.core.state != { }) (
pkgs.runCommand "state-commands" { } ''
${builtins.concatStringsSep "\n" (
builtins.map (state: ''
writeShellScript() {
local name=$1
local content=$2
printf "#!${pkgs.runtimeShell}\nset -eu -o pipefail\n%s" "$content" > $out/bin/$name
}
mkdir -p $out/bin/
${lib.optionalString (state.preBackupCommand != null) ''
writeShellScript ${lib.escapeShellArg state.preBackupCommand} ${lib.escapeShellArg state.preBackupScript}
''}
${lib.optionalString (state.preRestoreCommand != null) ''
writeShellScript ${lib.escapeShellArg state.preRestoreCommand} ${lib.escapeShellArg state.preRestoreScript}
''}
${lib.optionalString (state.postRestoreCommand != null) ''
writeShellScript ${lib.escapeShellArg state.postRestoreCommand} ${lib.escapeShellArg state.postRestoreScript}
''}
find $out/bin/ -type f -print0 | xargs --no-run-if-empty -0 chmod 755
'') (builtins.attrValues config.clan.core.state)
)}
''
);
}