Fix fcron service to properly load the crontab on first startup, make it multi-instance aware, add tests

This commit is contained in:
Sander van der Burg 2021-04-03 15:45:12 +02:00 committed by Sander van der Burg
parent c130294a0a
commit 89dba90892
7 changed files with 96 additions and 9 deletions

View File

@ -127,7 +127,7 @@ rec {
pkg = constructors.declarativeFcron {
fcrontabPerUser = {
systab = ''
@ 1 echo hello >> /tmp/hello
*/1 * * * * echo hello >> /tmp/hello
'';
};
};

View File

@ -74,7 +74,7 @@ in
declarativeFcron = import ./fcron/declarative.nix {
inherit createManagedProcess stateDir spoolDir runtimeDir tmpDir forceDisableUserChange;
inherit (pkgs) lib writeTextFile fcron;
inherit (pkgs) lib writeTextFile fcron utillinux;
};
hydra-evaluator = import ./hydra/hydra-evaluator.nix {

View File

@ -1,4 +1,4 @@
{createManagedProcess, writeTextFile, lib, fcron, stateDir, runtimeDir, tmpDir, spoolDir, forceDisableUserChange}:
{createManagedProcess, writeTextFile, lib, fcron, utillinux, stateDir, runtimeDir, tmpDir, spoolDir, forceDisableUserChange}:
{ instanceSuffix ? ""
, instanceName ? "fcron${instanceSuffix}"
@ -8,14 +8,15 @@
let
fcronSpoolDir = "${spoolDir}/${instanceName}";
fcronEtcDir = "${stateDir}/etc/${instanceName}";
in
import ./default.nix {
inherit createManagedProcess writeTextFile lib fcron stateDir runtimeDir tmpDir spoolDir forceDisableUserChange;
} {
inherit instanceSuffix instanceName;
initialize = ''
${lib.concatMapStrings (user:
initialize =
lib.concatMapStrings (user:
let
fcrontab = builtins.getAttr user fcrontabPerUser;
fcrontabFile = writeTextFile {
@ -26,7 +27,9 @@ import ./default.nix {
''
cp ${fcrontabFile} ${fcronSpoolDir}/${user}.orig
''
) (builtins.attrNames fcrontabPerUser)}
${initialize}
'';
+ ''
${lib.optionalString (!forceDisableUserChange) "${utillinux}/bin/runuser -u root -g ${instanceName} --"} fcrontab -c ${fcronEtcDir}/fcron.conf -u systab -z
''
) (builtins.attrNames fcrontabPerUser)
+ initialize;
}

View File

@ -20,6 +20,21 @@ let
user = instanceName;
group = instanceName;
# We must override the package configuration settings to compile it with different configuration settings,
# if we want to use a different group or run fcron as unprivileged user
fcronPkg =
if forceDisableUserChange then fcron.overrideAttrs (originalAttrs:
originalAttrs // {
configureFlags = originalAttrs.configureFlags ++ [ "--with-run-non-privileged" "--with-rootname=unprivileged" "--with-rootgroup=users" "--with-username=unprivileged" "--with-groupname=users" ];
}
)
else if user != "fcron" || group != "fcron" then fcron.overrideAttrs (originalAttrs:
originalAttrs // {
configureFlags = originalAttrs.configureFlags ++ [ "--with-rootgroup=${group}" "--with-username=${user}" "--with-groupname=${group}" ];
}
)
else fcron;
in
createManagedProcess {
inherit instanceName;
@ -34,7 +49,8 @@ createManagedProcess {
${initialize}
'';
process = "${fcron}/bin/fcron";
path = [ fcronPkg ];
process = "${fcronPkg}/bin/fcron";
args = [ "--configfile" "${fcronEtcDir}/fcron.conf" ];
foregroundProcessExtraArgs = [ "--foreground" "--nosyslog" ];
daemonExtraArgs = [ "--background" ];

View File

@ -27,6 +27,10 @@ in
inherit pkgs processManagers profiles testService;
};
fcron = import ./fcron {
inherit pkgs processManagers profiles testService;
};
influxdb = import ./influxdb {
inherit pkgs processManagers profiles testService;
};

24
tests/fcron/default.nix Normal file
View File

@ -0,0 +1,24 @@
{ pkgs, testService, processManagers, profiles }:
testService {
exprFile = ./processes.nix;
readiness = {instanceName, instance, ...}:
''
'';
tests = {instanceName, instance, ...}:
''
machine.succeed("sleep 70")
''
+
(if instanceName == "fcron" then ''
machine.succeed("grep 'hello' /tmp/hello")
''
else if instanceName == "fcron-secondary" then ''
machine.succeed("grep 'bye' /tmp/bye")
''
else "");
inherit processManagers profiles;
}

40
tests/fcron/processes.nix Normal file
View File

@ -0,0 +1,40 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, spoolDir ? "${stateDir}/spool"
, cacheDir ? "${stateDir}/cache"
, libDir ? "${stateDir}/lib"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
, processManager
}:
let
constructors = import ../../services-agnostic/constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir cacheDir libDir spoolDir forceDisableUserChange processManager;
};
in
rec {
fcron = {
pkg = constructors.declarativeFcron {
fcrontabPerUser = {
systab = ''
*/1 * * * * echo hello >> /tmp/hello
'';
};
};
};
fcron-secondary = {
pkg = constructors.declarativeFcron {
instanceSuffix = "-secondary";
fcrontabPerUser = {
systab = ''
*/1 * * * * echo bye >> /tmp/bye
'';
};
};
};
}