gocron: init at 0.9.14 (#519182)

This commit is contained in:
Oleksii Filonenko
2026-06-30 15:45:49 +00:00
committed by GitHub
6 changed files with 344 additions and 0 deletions
@@ -28,6 +28,8 @@
- [FlapAlerted](https://github.com/Kioubit/FlapAlerted), detects BGP flapping events and provides statistics based on BGP update messages. Available as [services.flap-alerted](#opt-services.flap-alerted.enable).
- [gocron](https://github.com/flohoss/gocron), a task scheduler with web interface. Available as [services.gocron](#opt-services.gocron.enable).
- [Unpackerr](https://unpackerr.zip), extracts downloads for Radarr, Sonarr, Lidarr, Readarr, and/or a Watch folder. Available as [services.unpackerr](#opt-services.unpackerr.enable).
- [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service) is an OAuth2.0 and OpenID Connect provider for Matrix homeservers (such as Synapse). It replaces standard password authentication with modern OpenID Connect flows, and can delegate authentication to upstream OIDC providers. Available as [services.matrix-authentication-service](#opt-services.matrix-authentication-service.enable).
+1
View File
@@ -1491,6 +1491,7 @@
./services/scheduling/atd.nix
./services/scheduling/cron.nix
./services/scheduling/fcron.nix
./services/scheduling/gocron.nix
./services/scheduling/prefect.nix
./services/scheduling/scx-loader.nix
./services/scheduling/scx.nix
@@ -0,0 +1,173 @@
{
options,
config,
lib,
pkgs,
...
}:
let
cfg = config.services.gocron;
settingsFormat = pkgs.formats.yaml { };
gocronConf = settingsFormat.generate "gocron.yaml" cfg.settings;
defaultUser = "gocron";
defaultGroup = "gocron";
timeZone = config.time.timeZone;
hardeningOptions = lib.mkOption {
description = "Configuration for hardening the systemd service.";
type = lib.types.submodule {
options = {
ProtectHome = lib.mkOption {
description = ''
Whether to make the home directories inaccessible to the service.
See <link xlink:href="https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#ProtectHome="/> for more details.
'';
type = lib.types.either lib.types.str lib.types.bool;
default = true;
example = "read-only";
};
ProtectSystem = lib.mkOption {
description = ''
Whether to make several system directories inaccessible to the service.
See <link xlink:href="https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#ProtectSystem="/> for more details.
'';
type = lib.types.either lib.types.str lib.types.bool;
default = true;
example = "full";
};
};
};
};
in
{
options.services.gocron = {
enable = lib.mkEnableOption "gocron, a task scheduler";
package = lib.mkOption {
default = pkgs.gocron;
defaultText = lib.literalExpression "pkgs.gocron";
type = lib.types.package;
description = ''
gocron package to use.
'';
};
openFirewall = lib.mkOption {
description = "Whether to open the firewall port to access the web ui.";
type = lib.types.bool;
default = false;
};
user = lib.mkOption {
description = "Unix User to run the server under";
type = lib.types.str;
default = defaultUser;
};
group = lib.mkOption {
description = "Unix Group to run the server under";
type = lib.types.str;
default = defaultGroup;
};
extraGroups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "backup" ];
description = ''
Additional groups for the systemd service.
'';
};
hardening = hardeningOptions;
settings = lib.mkOption {
# Setting this type allows for correct merging behavior
type = settingsFormat.type;
default = { };
description = ''
Configuration for gocron, see
<link xlink:href="https://github.com/flohoss/gocron/blob/main/config/config.yaml"/>
for supported settings.
'';
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = !lib.hasAttr "software" cfg.settings;
message = "Software installation configuration is only supported for traditional distros by upstream.";
}
];
services.gocron.settings = {
time_zone = if timeZone != null then timeZone else lib.mkDefault "Etc/UTC";
server = {
address = lib.mkDefault "127.0.0.1";
port = lib.mkDefault 8156;
};
db.location = lib.mkDefault "/var/lib/gocron";
};
systemd.services.gocron = {
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.gocron} --config '${gocronConf}'";
User = cfg.user;
Group = cfg.group;
DeviceAllow = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
MountAPIVFS = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateNetwork = lib.mkDefault false;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = cfg.hardening.ProtectHome;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = cfg.hardening.ProtectSystem;
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
UMask = "0077";
StateDirectory = lib.mkIf (cfg.settings.db.location == "/var/lib/gocron") "gocron";
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [
"@system-service"
];
};
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.settings.server.port ];
users.users.${cfg.user} = {
isSystemUser = true;
inherit (cfg) group;
};
users.groups.${cfg.group} = { };
meta = {
buildDocsInSandbox = true;
maintainers = with lib.maintainers; [ juliusfreudenberger ];
};
};
}
+1
View File
@@ -702,6 +702,7 @@ in
gobgpd = runTest ./gobgpd.nix;
gocd-agent = runTest ./gocd-agent.nix;
gocd-server = runTest ./gocd-server.nix;
gocron = runTest ./gocron.nix;
gocryptfs = runTest ./gocryptfs.nix;
gokapi = runTest ./gokapi.nix;
gollum = runTest ./gollum.nix;
+58
View File
@@ -0,0 +1,58 @@
{ pkgs, ... }:
{
name = "gocron";
meta.maintainers = with pkgs.lib.maintainers; [ juliusfreudenberger ];
nodes.machine =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
services.gocron = {
enable = true;
settings = {
jobs = [
{
name = "Test job";
disabled_cron = true;
commands = [
"echo 'Job runs successfully'"
];
}
];
};
};
};
testScript = ''
def gocron_is_up(_) -> bool:
status, _ = machine.execute("curl --fail http://localhost:8156")
return status == 0
def job_is_available() -> bool:
status, output = machine.execute("curl http://localhost:8156/api/jobs | jq '. | length'")
return status == 0 and int(output) == 1
def start_job():
machine.succeed("curl -X POST http://localhost:8156/api/jobs/Test%20job")
def job_ran_successfully() -> bool:
output = machine.succeed("curl http://localhost:8156/api/runs/Test%20job | jq '.[0].status_id, .[0].logs.[2].message'")
split_output = output.split('\n')
ran_successfully = int(split_output[0]) == 3
log_message_as_expected = "Job runs not successfully" in split_output[1]
return ran_successfully and log_message_as_expected
machine.wait_for_unit("gocron.service")
machine.wait_for_open_port(8156)
with machine.nested("Waiting for UI to work"):
retry(gocron_is_up)
with machine.nested("Test job"):
if not job_is_available():
exit(1)
start_job()
if not job_ran_successfully():
exit(1)
'';
}
+109
View File
@@ -0,0 +1,109 @@
{
lib,
fetchFromGitHub,
nodejs,
fetchYarnDeps,
yarnConfigHook,
yarnBuildHook,
yarnInstallHook,
stdenv,
buildGoModule,
makeWrapper,
bash,
versionCheckHook,
nix-update-script,
nixosTests,
}:
buildGoModule (finalAttrs: {
pname = "gocron";
version = "0.9.14";
__structuredAttrs = true;
src = fetchFromGitHub {
owner = "flohoss";
repo = "gocron";
tag = "v${finalAttrs.version}";
hash = "sha256-LKjK5V+WrzTJlWPytafy8Ypva41RW4/12aSGaJj572I=";
};
gocron-web = stdenv.mkDerivation (finalAttrsWebassets: {
pname = "${finalAttrs.pname}-web";
src = "${finalAttrs.src}/web";
inherit (finalAttrs) version;
yarnOfflineCache = fetchYarnDeps {
yarnLock = finalAttrsWebassets.src + "/yarn.lock";
hash = "sha256-f0xnF9gd3c0KPrORPVkApyWPy+DazyzHeQu32wWybiw=";
};
nativeBuildInputs = [
yarnConfigHook
yarnBuildHook
yarnInstallHook
nodejs
];
preBuild = ''
yarn types
'';
postBuild = ''
mv dist/ $out
'';
});
vendorHash = "sha256-VbmS9Fh0pr/dUB+pZBqKbi4bu6Do/3TRr9uI3TmGsOM=";
postPatch = ''
substituteInPlace handlers/web.go \
--replace-fail "web/assets" "${finalAttrs.gocron-web}/assets" \
--replace-fail "web/static" "${finalAttrs.gocron-web}/static" \
--replace-fail "web/index.html" "${finalAttrs.gocron-web}/index.html"
substituteInPlace main.go \
--replace-fail '"github.com/flohoss/gocron/internal/software"' "" \
--replace-fail "software.Install()" ""
'';
ldflags = [
"-s"
"-w"
"-X github.com/flohoss/gocron/internal/buildinfo.Version=${finalAttrs.version}"
];
nativeBuildInputs = [
makeWrapper
];
postInstall = ''
wrapProgram $out/bin/gocron --prefix PATH : ${
lib.makeBinPath [
bash
]
}
'';
nativeInstallCheckInputs = [ versionCheckHook ];
doInstallCheck = true;
passthru.updateScript = nix-update-script {
extraArgs = [
"--subpackage"
"gocron-web"
];
};
passthru.tests = nixosTests.gocron;
meta = {
description = "Task scheduler built with Go and Vue.js.";
homepage = "https://github.com/flohoss/gocron";
license = lib.licenses.mit;
mainProgram = "gocron";
maintainers = with lib.maintainers; [
juliusfreudenberger
];
};
})