Turn scheduled commands to multi-entry
This commit is contained in:
parent
479535c294
commit
592bc8cb45
2 changed files with 88 additions and 73 deletions
|
|
@ -16,11 +16,9 @@
|
||||||
downloadDir = "/mnt/storage/Media/web";
|
downloadDir = "/mnt/storage/Media/web";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Scheduled YouTube downloads
|
services.scheduled-commands.video-downloads = {
|
||||||
services.scheduled-commands = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
serviceName = "video-downloads";
|
description = "Download web videos from favorite channels";
|
||||||
serviceDescription = "Download web videos from favorite channels";
|
|
||||||
interval = "*-*-* 08:00:00";
|
interval = "*-*-* 08:00:00";
|
||||||
randomDelay = "1h";
|
randomDelay = "1h";
|
||||||
commands = [
|
commands = [
|
||||||
|
|
|
||||||
|
|
@ -5,93 +5,110 @@ with lib;
|
||||||
let
|
let
|
||||||
cfg = config.services.scheduled-commands;
|
cfg = config.services.scheduled-commands;
|
||||||
|
|
||||||
# Create wrapper script that sources user shell environment
|
# Create wrapper script for a specific instance
|
||||||
commandScript = pkgs.writeScriptBin "${cfg.serviceName}-run" ''
|
makeCommandScript = name: instanceCfg: pkgs.writeScriptBin "${name}-run" ''
|
||||||
#!${pkgs.zsh}/bin/zsh
|
#!${pkgs.zsh}/bin/zsh
|
||||||
# Source user shell to get environment and functions
|
# Source user shell to get environment and functions
|
||||||
source ${config.home.homeDirectory}/.zshrc
|
source ${config.home.homeDirectory}/.zshrc
|
||||||
|
|
||||||
# Execute commands sequentially
|
# Execute commands sequentially
|
||||||
${concatStringsSep "\n" cfg.commands}
|
${concatStringsSep "\n" instanceCfg.commands}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Filter for enabled instances
|
||||||
|
enabledInstances = filterAttrs (_: instanceCfg: instanceCfg.enable) cfg;
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
options.services.scheduled-commands = {
|
options.services.scheduled-commands = mkOption {
|
||||||
enable = mkEnableOption "scheduled command execution service";
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption "this scheduled command instance";
|
||||||
|
|
||||||
commands = mkOption {
|
commands = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [];
|
||||||
example = [
|
example = [
|
||||||
"echo 'Starting backup...'"
|
"echo 'Starting backup...'"
|
||||||
"rsync -av /source /destination"
|
"rsync -av /source /destination"
|
||||||
"echo 'Backup completed'"
|
"echo 'Backup completed'"
|
||||||
];
|
];
|
||||||
description = "List of shell commands to execute sequentially";
|
description = "List of shell commands to execute sequentially";
|
||||||
};
|
};
|
||||||
|
|
||||||
interval = mkOption {
|
interval = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "daily";
|
default = "daily";
|
||||||
example = "*-*-* 08:00:00";
|
example = "*-*-* 08:00:00";
|
||||||
description = "Systemd timer schedule (OnCalendar format)";
|
description = "Systemd timer schedule (OnCalendar format)";
|
||||||
};
|
};
|
||||||
|
|
||||||
randomDelay = mkOption {
|
randomDelay = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "0";
|
default = "0";
|
||||||
example = "1h";
|
example = "1h";
|
||||||
description = "Random delay before execution (e.g., '30m', '1h')";
|
description = "Random delay before execution (e.g., '30m', '1h')";
|
||||||
};
|
};
|
||||||
|
|
||||||
serviceName = mkOption {
|
description = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "scheduled-commands";
|
default = "Execute scheduled commands";
|
||||||
example = "video-downloads";
|
example = "Download YouTube videos from subscriptions";
|
||||||
description = "Name for the systemd service and timer";
|
description = "Description for the systemd service";
|
||||||
};
|
};
|
||||||
|
};
|
||||||
serviceDescription = mkOption {
|
});
|
||||||
type = types.str;
|
default = {};
|
||||||
default = "Execute scheduled commands";
|
description = "Scheduled command execution services";
|
||||||
example = "Download YouTube videos from subscriptions";
|
|
||||||
description = "Description for the systemd service";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkMerge [
|
||||||
# Install the wrapper script
|
# Install wrapper scripts for all enabled instances
|
||||||
home.packages = [ commandScript ];
|
{
|
||||||
|
home.packages = mapAttrsToList (name: instanceCfg:
|
||||||
|
makeCommandScript name instanceCfg
|
||||||
|
) enabledInstances;
|
||||||
|
}
|
||||||
|
|
||||||
systemd.user.services.${cfg.serviceName} = {
|
# Create systemd services and timers for all enabled instances
|
||||||
Unit = {
|
{
|
||||||
Description = cfg.serviceDescription;
|
systemd.user.services = mapAttrs' (name: instanceCfg:
|
||||||
After = [ "network-online.target" ];
|
nameValuePair name {
|
||||||
};
|
Unit = {
|
||||||
|
Description = instanceCfg.description;
|
||||||
|
After = [ "network-online.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${commandScript}/bin/${cfg.serviceName}-run";
|
ExecStart = "${makeCommandScript name instanceCfg}/bin/${name}-run";
|
||||||
StandardOutput = "journal";
|
StandardOutput = "journal";
|
||||||
StandardError = "journal";
|
StandardError = "journal";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.timers.${cfg.serviceName} = {
|
Install = {
|
||||||
Unit = {
|
WantedBy = mkForce [];
|
||||||
Description = "Timer for ${cfg.serviceDescription}";
|
};
|
||||||
};
|
}
|
||||||
|
) enabledInstances;
|
||||||
|
|
||||||
Timer = {
|
systemd.user.timers = mapAttrs' (name: instanceCfg:
|
||||||
OnCalendar = cfg.interval;
|
nameValuePair name {
|
||||||
Persistent = true;
|
Unit = {
|
||||||
RandomizedDelaySec = cfg.randomDelay;
|
Description = "Timer for ${instanceCfg.description}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Install = {
|
Timer = {
|
||||||
WantedBy = [ "timers.target" ];
|
OnCalendar = instanceCfg.interval;
|
||||||
};
|
Persistent = true;
|
||||||
};
|
RandomizedDelaySec = instanceCfg.randomDelay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) enabledInstances;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue