rails: Add the ability to schedule services with a systemd timer

This commit is contained in:
Peter Jones 2019-01-07 14:05:12 -07:00
parent 48e5035383
commit 14d701b388
No known key found for this signature in database
GPG key ID: 9DAFAA8D01941E49
2 changed files with 34 additions and 2 deletions

View file

@ -16,6 +16,7 @@ let
# The main Rails service:
mainService = app: {
name = "main";
schedule = null;
isMain = true;
script = ''
@ -98,10 +99,11 @@ let
description = "${app.name} (Ruby on Rails) ${service.name}";
path = appPath app;
environment = appEnv app;
wantedBy = [ "multi-user.target" ];
# Only start this service if it isn't scheduled by a timer.
wantedBy = optional (service.schedule == null) "multi-user.target";
wants =
optional (!service.isMain) "rails-${app.name}-main" ++
plib.keyService app.database.passwordFile ++
plib.keyService app.sourcedFile;
@ -166,6 +168,17 @@ let
};
};
##############################################################################
# Schedule some services with a systemd timer:
appTimer = app: service: optionalAttrs (service.schedule != null) {
"rails-${app.name}-${service.name}" = {
description = "${app.name} (Ruby on Rails) ${service.name}";
wantedBy = [ "timers.target" ];
timerConfig.OnCalendar = service.schedule;
timerConfig.Unit = "rails-${app.name}-${service.name}.service";
};
};
##############################################################################
# Collect all services for a given application and turn them into
# systemd services.
@ -173,6 +186,12 @@ let
foldr (service: set: recursiveUpdate set (appService app service)) {}
( [(mainService app)] ++ attrValues app.services );
##############################################################################
# Collect all services and turn them into systemd timers:
appTimers = app:
foldr (service: set: recursiveUpdate set (appTimer app service)) {}
(attrValues app.services);
##############################################################################
# Generate a user account for a Ruby on Rails application:
appUser = app: {
@ -217,6 +236,7 @@ in
# Each application gets one or more systemd services to keep it
# running.
systemd.services = collectApps appServices;
systemd.timers = collectApps appTimers;
# Rotate all of the log files:
services.logrotate = {

View file

@ -68,6 +68,18 @@ let
description = "Shell commands executed as the service's main process.";
};
schedule = mkOption {
type = types.nullOr types.str;
default = null;
example = "*-*-* *:00/5:00";
description = ''
If null (the default), run this service in the background
continuously, restarting it if it stops. However, if this
option is set, it should be a systemd calendar string and
this service will run on a scheduled timer instead.
'';
};
isMain = mkOption {
internal = true;
type = types.bool;