Turn scheduled commands to multi-entry

This commit is contained in:
Yan Lin 2025-10-04 22:08:37 +02:00
parent 479535c294
commit 592bc8cb45
2 changed files with 88 additions and 73 deletions

View file

@ -16,11 +16,9 @@
downloadDir = "/mnt/storage/Media/web";
};
# Scheduled YouTube downloads
services.scheduled-commands = {
services.scheduled-commands.video-downloads = {
enable = true;
serviceName = "video-downloads";
serviceDescription = "Download web videos from favorite channels";
description = "Download web videos from favorite channels";
interval = "*-*-* 08:00:00";
randomDelay = "1h";
commands = [

View file

@ -5,20 +5,25 @@ with lib;
let
cfg = config.services.scheduled-commands;
# Create wrapper script that sources user shell environment
commandScript = pkgs.writeScriptBin "${cfg.serviceName}-run" ''
# Create wrapper script for a specific instance
makeCommandScript = name: instanceCfg: pkgs.writeScriptBin "${name}-run" ''
#!${pkgs.zsh}/bin/zsh
# Source user shell to get environment and functions
source ${config.home.homeDirectory}/.zshrc
# Execute commands sequentially
${concatStringsSep "\n" cfg.commands}
${concatStringsSep "\n" instanceCfg.commands}
'';
# Filter for enabled instances
enabledInstances = filterAttrs (_: instanceCfg: instanceCfg.enable) cfg;
in
{
options.services.scheduled-commands = {
enable = mkEnableOption "scheduled command execution service";
options.services.scheduled-commands = mkOption {
type = types.attrsOf (types.submodule {
options = {
enable = mkEnableOption "this scheduled command instance";
commands = mkOption {
type = types.listOf types.str;
@ -45,53 +50,65 @@ in
description = "Random delay before execution (e.g., '30m', '1h')";
};
serviceName = mkOption {
type = types.str;
default = "scheduled-commands";
example = "video-downloads";
description = "Name for the systemd service and timer";
};
serviceDescription = mkOption {
description = mkOption {
type = types.str;
default = "Execute scheduled commands";
example = "Download YouTube videos from subscriptions";
description = "Description for the systemd service";
};
};
});
default = {};
description = "Scheduled command execution services";
};
config = mkIf cfg.enable {
# Install the wrapper script
home.packages = [ commandScript ];
config = mkMerge [
# Install wrapper scripts for all enabled instances
{
home.packages = mapAttrsToList (name: instanceCfg:
makeCommandScript name instanceCfg
) enabledInstances;
}
systemd.user.services.${cfg.serviceName} = {
# Create systemd services and timers for all enabled instances
{
systemd.user.services = mapAttrs' (name: instanceCfg:
nameValuePair name {
Unit = {
Description = cfg.serviceDescription;
Description = instanceCfg.description;
After = [ "network-online.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${commandScript}/bin/${cfg.serviceName}-run";
ExecStart = "${makeCommandScript name instanceCfg}/bin/${name}-run";
StandardOutput = "journal";
StandardError = "journal";
};
};
systemd.user.timers.${cfg.serviceName} = {
Install = {
WantedBy = mkForce [];
};
}
) enabledInstances;
systemd.user.timers = mapAttrs' (name: instanceCfg:
nameValuePair name {
Unit = {
Description = "Timer for ${cfg.serviceDescription}";
Description = "Timer for ${instanceCfg.description}";
};
Timer = {
OnCalendar = cfg.interval;
OnCalendar = instanceCfg.interval;
Persistent = true;
RandomizedDelaySec = cfg.randomDelay;
RandomizedDelaySec = instanceCfg.randomDelay;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}
) enabledInstances;
}
];
}