Files
pvv-nixos-config/modules/drumknotty/worblehat.nix
h7x4 e64b75f5c5 modules/drumknotty: split into several parts
This also fixes a few issues, such as enabling `createLocalDatabase` for
multiple programs, and wraps all the screen logic within a screenrc
file. Some assertions were also added to avoid some easy-to-make
mistakes.
2026-03-26 17:27:05 +09:00

210 lines
6.4 KiB
Nix

{
config,
pkgs,
lib,
...
}:
let
mainCfg = config.services.drumknotty;
cfg = config.services.drumknotty.worblehat;
format = pkgs.formats.toml { };
in
{
options.services.drumknotty.worblehat = {
enable = lib.mkEnableOption "";
package = lib.mkPackageOption pkgs "worblehat" { };
settings = lib.mkOption {
description = "Configuration for worblehat";
default = { };
type = lib.types.submodule {
freeformType = format.type;
};
};
createLocalDatabase = lib.mkEnableOption "" // {
description = ''
Whether to set up a local postgres database automatically.
::: {.note}
You must set up postgres manually before enabling this option.
:::
'';
};
deadline-daemon = {
enable = lib.mkEnableOption "" // {
description = ''
Whether to enable the worblehat deadline-daemon service,
which periodically checks for upcoming deadlines and notifies users.
Note that this service is independent of the main worblehat service,
and must be enabled separately.
'';
};
onCalendar = lib.mkOption {
type = lib.types.str;
description = ''
How often to trigger rendering the map,
in the format of a systemd timer onCalendar configuration.
See {manpage}`systemd.timer(5)`.
'';
default = "*-*-* 10:15:00";
};
};
};
config = lib.mkMerge [
{
assertions = [
{
assertion = cfg.createLocalDatabase -> config.services.postgresql.enable;
message = "PostgreSQL must be enabled for worblehat to create a local database";
}
];
# TODO: Retrieve defaults from the example config file in the project code.
services.drumknotty.worblehat.settings = {
logging = {
debug = lib.mkDefault true;
debug_sql = lib.mkDefault false;
};
database = {
type = lib.mkDefault "sqlite";
sqlite.path = lib.mkDefault "./worblehat.sqlite";
postgresql = {
host = lib.mkDefault "localhost";
port = lib.mkDefault 5432;
username = lib.mkDefault "worblehat";
password = lib.mkDefault "/var/lib/worblehat/db-password";
database = lib.mkDefault "worblehat";
};
};
flask = {
TESTING = lib.mkDefault true;
DEBUG = lib.mkDefault true;
FLASK_ENV = lib.mkDefault "development";
SECRET_KEY = lib.mkDefault "change-me";
};
smtp = {
enabled = lib.mkDefault false;
host = lib.mkDefault "smtp.pvv.ntnu.no";
port = lib.mkDefault 587;
username = lib.mkDefault "worblehat";
password = lib.mkDefault "/var/lib/worblehat/smtp-password";
from = lib.mkDefault "worblehat@pvv.ntnu.no";
subject_prefix = lib.mkDefault "[Worblehat]";
};
deadline_daemon = {
enabled = lib.mkDefault true;
dryrun = lib.mkDefault false;
warn_days_before_borrowing_deadline = lib.mkDefault [
5
1
];
days_before_queue_position_expires = lib.mkDefault 14;
warn_days_before_expiring_queue_position_deadline = lib.mkDefault [
3
1
];
};
};
}
(lib.mkIf ((mainCfg.enable && cfg.enable) || cfg.deadline-daemon.enable) {
environment.systemPackages = [ cfg.package ];
environment.etc."worblehat/config.toml".source = format.generate "worblehat-config.toml" cfg.settings;
})
(lib.mkIf (mainCfg.enable && cfg.enable) {
services.drumknotty.worblehat.settings.general = lib.mkIf mainCfg.kioskMode {
quit_allowed = false;
stop_allowed = false;
};
services.drumknotty.worblehat.settings.database = lib.mkIf cfg.createLocalDatabase {
type = "postgresql";
postgresql.host = "/run/postgresql";
};
services.postgresql = lib.mkIf cfg.createLocalDatabase {
authentication = ''
local ${cfg.settings.database.postgresql.database} ${cfg.settings.database.postgresql.username} peer map=${cfg.settings.database.postgresql.username}
'';
identMap = ''
${cfg.settings.database.postgresql.username} drumknotty ${cfg.settings.database.postgresql.username}
'';
ensureDatabases = [ cfg.settings.database.postgresql.database ];
ensureUsers = [{
name = cfg.settings.database.postgresql.username;
ensureDBOwnership = true;
ensureClauses.login = true;
}];
};
systemd.services.worblehat-setup-database = lib.mkIf cfg.createLocalDatabase {
description = "Worblehat database setup";
wantedBy = [ "default.target" ];
requiredBy = [ "drumknotty-screen-session.service" ];
before = [ "drumknotty-screen-session.service" ];
after = [ "postgresql.service" ];
unitConfig = {
ConditionPathExists = "!/var/lib/worblehat/.db-setup-done";
};
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe cfg.package} --config /etc/worblehat/config.toml create-db";
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/worblehat/.db-setup-done";
StateDirectory = "worblehat";
User = "drumknotty";
Group = "drumknotty";
};
};
})
(lib.mkIf cfg.deadline-daemon.enable {
systemd.timers.worblehat-deadline-daemon = lib.mkIf cfg.deadline-daemon.enable {
description = "Worblehat Deadline Daemon";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.deadline-daemon.onCalendar;
Persistent = true;
};
};
systemd.services.worblehat-deadline-daemon = lib.mkIf cfg.deadline-daemon.enable {
description = "Worblehat Deadline Daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart =
let
worblehatArgs = lib.cli.toCommandLineShellGNU { } {
config = "/etc/worblehat/config.toml";
};
in
"${lib.getExe cfg.package} ${worblehatArgs} deadline-daemon";
User = "drumknotty";
Group = "drumknotty";
};
};
})
];
}