Compare commits

..

28 Commits

Author SHA1 Message Date
Vegard Bieker Matthey
309f55bdfd flake.lock: bump dibbler and worblehat 2026-03-19 17:20:46 +01:00
Vegard Bieker Matthey
ed5cb0273f use main branch for worblehat after merge 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
3b6ed118fe use correct setting for password 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
a762cfe599 set some defaults for dibblerSettings 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
7decdd3319 only use a-Z and 0-9 for worblehat password 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
2c09046ff0 set defaults for worblehat settings 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
90064a34b0 actually use dibbler and worblehat settings 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
cd2671f530 stub: worblehat settings 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
9a52d2bae9 start worblehat correctly 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
a8661c4290 use variable for screen session 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
da7dc422ca add worblehat daemons 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
6fc6954531 add database password for worblehat 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
a15dfb95a0 fix type stuff for cli args 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
dc75e523e7 fix module in overlays 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
5a9a780a34 add drumknotty.nix module 2026-03-19 16:53:30 +01:00
Vegard Bieker Matthey
38e54112a0 drumknotty: init 2026-03-19 16:53:18 +01:00
Vegard Bieker Matthey
6b1fb4c065 only cross-compile when necessary
This fixes issues with rebuilding georg and brzeczyszczykiewicz.

Reviewed-on: https://git.pvv.ntnu.no/Drift/pvv-nixos-config/pulls/128
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
Co-authored-by: Vegard Bieker Matthey <VegardMatthey@protonmail.com>
Co-committed-by: Vegard Bieker Matthey <VegardMatthey@protonmail.com>
2026-02-21 21:14:04 +01:00
Vegard Bieker Matthey
18167dca0a update README to reflect added host 2026-02-14 19:12:41 +01:00
Vegard Bieker Matthey
b5fecc94a7 hosts: add skrot
Co-authored-by: System administrator <root@skrot.pvv.ntnu.no>
Reviewed-on: https://git.pvv.ntnu.no/Drift/pvv-nixos-config/pulls/124
Co-authored-by: Vegard Bieker Matthey <VegardMatthey@protonmail.com>
Co-committed-by: Vegard Bieker Matthey <VegardMatthey@protonmail.com>
2026-02-14 18:53:54 +01:00
h7x4
0d40c7d7a7 base/acme: use different email alias for account 2026-02-13 19:45:45 +09:00
h7x4
b327582236 kommode/gitea: use redis for sessions and queue 2026-02-13 18:55:42 +09:00
h7x4
7e39bf3ba2 bicep/matrix/ooye: add rsync pull target for principal backups 2026-02-13 18:26:55 +09:00
h7x4
5bb0cd0465 kommode/gitea: set default theme 2026-02-13 14:32:36 +09:00
h7x4
9efda802cb kommode/gitea: move ui configuration to customization 2026-02-13 14:23:48 +09:00
h7x4
3c08be3d73 kommode/gitea: configure redis cache 2026-02-13 03:50:21 +09:00
Øystein Tveit
b1a2836b5d kommode/gitea: custom emoji 2026-02-13 03:38:45 +09:00
h7x4
ba1f30f737 kommode/gitea: configure more meta fields 2026-02-13 03:13:49 +09:00
Daniel Olsen
c455c5a7e3 bicep/matrix/livekit: fix matrix domain in livekit, allow dan's server as well 2026-02-11 22:58:19 +01:00
15 changed files with 586 additions and 55 deletions

View File

@@ -43,7 +43,7 @@ revert the changes on the next nightly rebuild (tends to happen when everybody i
| [kommode][kom] | Virtual | Gitea + Gitea pages | | [kommode][kom] | Virtual | Gitea + Gitea pages |
| [lupine][lup] | Physical | Gitea CI/CD runners | | [lupine][lup] | Physical | Gitea CI/CD runners |
| shark | Virtual | Test host for authentication, absolutely horrendous | | shark | Virtual | Test host for authentication, absolutely horrendous |
| [skrott/skrot][skr] | Physical | Kiosk, snacks and soda | | [skrot/skrott][skr] | Physical | Kiosk, snacks and soda |
| [wenche][wen] | Virtual | Nix-builders, general purpose compute | | [wenche][wen] | Virtual | Nix-builders, general purpose compute |
## Documentation ## Documentation

View File

@@ -2,7 +2,7 @@
{ {
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
defaults.email = "drift@pvv.ntnu.no"; defaults.email = "acme-drift@pvv.ntnu.no";
}; };
# Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode: # Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode:

62
flake.lock generated
View File

@@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1770133120, "lastModified": 1771267058,
"narHash": "sha256-RuAWONXb+U3omSsuIPCrPcgj0XYqv+2djG0cnPGEyKg=", "narHash": "sha256-EEL4SmD1b3BPJPsSJJ4wDTXWMumJqbR+BLzhJJG0skE=",
"ref": "main", "ref": "main",
"rev": "3123b8b474319bc75ee780e0357dcdea69dc85e6", "rev": "e3962d02c78b9c7b4d18148d931a9a4bf22e7902",
"revCount": 244, "revCount": 254,
"type": "git", "type": "git",
"url": "https://git.pvv.ntnu.no/Projects/dibbler.git" "url": "https://git.pvv.ntnu.no/Projects/dibbler.git"
}, },
@@ -124,6 +124,27 @@
"url": "https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients.git" "url": "https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients.git"
} }
}, },
"libdib": {
"inputs": {
"nixpkgs": [
"worblehat",
"nixpkgs"
]
},
"locked": {
"lastModified": 1769338528,
"narHash": "sha256-t18ZoSt9kaI1yde26ok5s7aFLkap1Q9+/2icVh2zuaE=",
"ref": "refs/heads/main",
"rev": "7218348163fd8d84df4a6f682c634793e67a3fed",
"revCount": 13,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/libdib.git"
},
"original": {
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/libdib.git"
}
},
"matrix-next": { "matrix-next": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -195,11 +216,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1767906352, "lastModified": 1770960722,
"narHash": "sha256-wYsH9MMAPFG3XTL+3DwI39XMG0F2fTmn/5lt265a3Es=", "narHash": "sha256-IdhPsWFZUKSJh/nLjGLJvGM5d5Uta+k1FlVYPxTZi0E=",
"ref": "main", "ref": "main",
"rev": "d054c5d064b8ed6d53a0adb0cf6c0a72febe212e", "rev": "c2e4aca7e1ba27cd09eeaeab47010d32a11841b2",
"revCount": 13, "revCount": 15,
"type": "git", "type": "git",
"url": "https://git.pvv.ntnu.no/Drift/nix-gitea-themes.git" "url": "https://git.pvv.ntnu.no/Drift/nix-gitea-themes.git"
}, },
@@ -353,7 +374,8 @@
"pvv-nettsiden": "pvv-nettsiden", "pvv-nettsiden": "pvv-nettsiden",
"qotd": "qotd", "qotd": "qotd",
"roowho2": "roowho2", "roowho2": "roowho2",
"sops-nix": "sops-nix" "sops-nix": "sops-nix",
"worblehat": "worblehat"
} }
}, },
"roowho2": { "roowho2": {
@@ -461,6 +483,28 @@
"repo": "sops-nix", "repo": "sops-nix",
"type": "github" "type": "github"
} }
},
"worblehat": {
"inputs": {
"libdib": "libdib",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1773932847,
"narHash": "sha256-IklIAdlonrmO8/lkDxNIVz9+ORL4pcVotMTxeyvxzoc=",
"ref": "main",
"rev": "0871a319f51d3cb0d1abb5b11edb768b39906d3f",
"revCount": 104,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/worblehat.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/worblehat.git"
}
} }
}, },
"root": "root", "root": "root",

View File

@@ -23,6 +23,9 @@
dibbler.url = "git+https://git.pvv.ntnu.no/Projects/dibbler.git?ref=main"; dibbler.url = "git+https://git.pvv.ntnu.no/Projects/dibbler.git?ref=main";
dibbler.inputs.nixpkgs.follows = "nixpkgs"; dibbler.inputs.nixpkgs.follows = "nixpkgs";
worblehat.url = "git+https://git.pvv.ntnu.no/Projects/worblehat.git?ref=main";
worblehat.inputs.nixpkgs.follows = "nixpkgs";
matrix-next.url = "github:dali99/nixos-matrix-modules/v0.8.0"; matrix-next.url = "github:dali99/nixos-matrix-modules/v0.8.0";
matrix-next.inputs.nixpkgs.follows = "nixpkgs"; matrix-next.inputs.nixpkgs.follows = "nixpkgs";
@@ -94,7 +97,6 @@
}: }:
let let
commonPkgsConfig = { commonPkgsConfig = {
inherit localSystem crossSystem;
config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg)
[ [
"nvidia-x11" "nvidia-x11"
@@ -104,8 +106,11 @@
# Global overlays go here # Global overlays go here
inputs.roowho2.overlays.default inputs.roowho2.overlays.default
]) ++ overlays; ]) ++ overlays;
}; } // (if localSystem != crossSystem then {
inherit localSystem crossSystem;
} else {
system = crossSystem;
});
pkgs = import nixpkgs commonPkgsConfig; pkgs = import nixpkgs commonPkgsConfig;
unstablePkgs = import nixpkgs-unstable commonPkgsConfig; unstablePkgs = import nixpkgs-unstable commonPkgsConfig;
in in
@@ -186,10 +191,16 @@
#ildkule-unstable = unstableNixosConfig "ildkule" { }; #ildkule-unstable = unstableNixosConfig "ildkule" { };
skrot = stableNixosConfig "skrot" { skrot = stableNixosConfig "skrot" {
modules = [ modules = [
self.nixosModules.drumknotty
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
inputs.dibbler.nixosModules.default inputs.dibbler.nixosModules.default
inputs.worblehat.nixosModules.default
];
overlays =
[
inputs.dibbler.overlays.default
inputs.worblehat.overlays.default
]; ];
overlays = [inputs.dibbler.overlays.default];
}; };
shark = stableNixosConfig "shark" { }; shark = stableNixosConfig "shark" { };
wenche = stableNixosConfig "wenche" { }; wenche = stableNixosConfig "wenche" { };
@@ -285,6 +296,7 @@
rsync-pull-targets = ./modules/rsync-pull-targets.nix; rsync-pull-targets = ./modules/rsync-pull-targets.nix;
snakeoil-certs = ./modules/snakeoil-certs.nix; snakeoil-certs = ./modules/snakeoil-certs.nix;
snappymail = ./modules/snappymail.nix; snappymail = ./modules/snappymail.nix;
drumknotty = ./modules/drumknotty.nix;
}; };
devShells = forAllSystems (system: { devShells = forAllSystems (system: {

View File

@@ -43,7 +43,7 @@ in
keyFile = config.sops.templates."matrix-livekit-keyfile".path; keyFile = config.sops.templates."matrix-livekit-keyfile".path;
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = lib.mkIf cfg.enable matrixDomain; systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = lib.mkIf cfg.enable (builtins.concatStringsSep "," [ "pvv.ntnu.no" "dodsorf.as" ]);
services.nginx.virtualHosts.${matrixDomain} = lib.mkIf cfg.enable { services.nginx.virtualHosts.${matrixDomain} = lib.mkIf cfg.enable {
locations."^~ /livekit/jwt/" = { locations."^~ /livekit/jwt/" = {

View File

@@ -1,4 +1,4 @@
{ config, pkgs, fp, ... }: { config, pkgs, lib, values, fp, ... }:
let let
cfg = config.services.matrix-ooye; cfg = config.services.matrix-ooye;
in in
@@ -28,6 +28,23 @@ in
}; };
}; };
services.rsync-pull-targets = lib.mkIf cfg.enable {
enable = true;
locations."/var/lib/private/matrix-ooye" = {
user = "root";
rrsyncArgs.ro = true;
authorizedKeysAttrs = [
"restrict"
"from=\"principal.pvv.ntnu.no,${values.hosts.principal.ipv6},${values.hosts.principal.ipv4}\""
"no-agent-forwarding"
"no-port-forwarding"
"no-pty"
"no-X11-forwarding"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE5koYfor5+kKB30Dugj3dAWvmj8h/akQQ2XYDvLobFL matrix_ooye rsync backup";
};
};
services.matrix-ooye = { services.matrix-ooye = {
enable = true; enable = true;
homeserver = "https://matrix.pvv.ntnu.no"; homeserver = "https://matrix.pvv.ntnu.no";

View File

@@ -10,6 +10,59 @@ in
catppuccin = pkgs.gitea-theme-catppuccin; catppuccin = pkgs.gitea-theme-catppuccin;
}; };
services.gitea.settings = {
ui = {
DEFAULT_THEME = "gitea-auto";
REACTIONS = lib.concatStringsSep "," [
"+1"
"-1"
"laugh"
"confused"
"heart"
"hooray"
"rocket"
"eyes"
"100"
"anger"
"astonished"
"no_good"
"ok_hand"
"pensive"
"pizza"
"point_up"
"sob"
"skull"
"upside_down_face"
"shrug"
"huh"
"bruh"
"okiedokie"
"grr"
];
CUSTOM_EMOJIS = lib.concatStringsSep "," [
"bruh"
"grr"
"huh"
"ohyeah"
];
};
"ui.meta" = {
AUTHOR = "Programvareverkstedet";
DESCRIPTION = "Bokstavelig talt programvareverkstedet";
KEYWORDS = lib.concatStringsSep "," [
"git"
"hackerspace"
"nix"
"open source"
"foss"
"organization"
"software"
"student"
];
};
};
systemd.services.gitea-customization = lib.mkIf cfg.enable { systemd.services.gitea-customization = lib.mkIf cfg.enable {
description = "Install extra customization in gitea's CUSTOM_DIR"; description = "Install extra customization in gitea's CUSTOM_DIR";
wantedBy = [ "gitea.service" ]; wantedBy = [ "gitea.service" ];
@@ -57,6 +110,11 @@ in
install -Dm444 ${extraLinksFooter} ${cfg.customDir}/templates/custom/extra_links_footer.tmpl install -Dm444 ${extraLinksFooter} ${cfg.customDir}/templates/custom/extra_links_footer.tmpl
install -Dm444 ${project-labels} ${cfg.customDir}/options/label/project-labels.yaml install -Dm444 ${project-labels} ${cfg.customDir}/options/label/project-labels.yaml
install -Dm644 ${./emotes/bruh.png} ${cfg.customDir}/public/assets/img/emoji/bruh.png
install -Dm644 ${./emotes/huh.gif} ${cfg.customDir}/public/assets/img/emoji/huh.png
install -Dm644 ${./emotes/grr.png} ${cfg.customDir}/public/assets/img/emoji/grr.png
install -Dm644 ${./emotes/okiedokie.jpg} ${cfg.customDir}/public/assets/img/emoji/okiedokie.png
"${lib.getExe pkgs.rsync}" -a "${customTemplates}/" ${cfg.customDir}/templates/ "${lib.getExe pkgs.rsync}" -a "${customTemplates}/" ${cfg.customDir}/templates/
''; '';
}; };

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@@ -83,11 +83,24 @@ in {
AUTO_WATCH_NEW_REPOS = false; AUTO_WATCH_NEW_REPOS = false;
}; };
admin.DEFAULT_EMAIL_NOTIFICATIONS = "onmention"; admin.DEFAULT_EMAIL_NOTIFICATIONS = "onmention";
session.COOKIE_SECURE = true;
security = { security = {
SECRET_KEY = lib.mkForce ""; SECRET_KEY = lib.mkForce "";
SECRET_KEY_URI = "file:${config.sops.secrets."gitea/secret-key".path}"; SECRET_KEY_URI = "file:${config.sops.secrets."gitea/secret-key".path}";
}; };
cache = {
ADAPTER = "redis";
HOST = "redis+socket://${config.services.redis.servers.gitea.unixSocket}?db=0";
ITEM_TTL = "72h";
};
session = {
COOKIE_SECURE = true;
PROVIDER = "redis";
PROVIDER_CONFIG = "redis+socket://${config.services.redis.servers.gitea.unixSocket}?db=1";
};
queue = {
TYPE = "redis";
CONN_STR = "redis+socket://${config.services.redis.servers.gitea.unixSocket}?db=2";
};
database.LOG_SQL = false; database.LOG_SQL = false;
repository = { repository = {
PREFERRED_LICENSES = lib.concatStringsSep "," [ PREFERRED_LICENSES = lib.concatStringsSep "," [
@@ -128,31 +141,6 @@ in {
AVATAR_MAX_ORIGIN_SIZE = 1024 * 1024 * 2; AVATAR_MAX_ORIGIN_SIZE = 1024 * 1024 * 2;
}; };
actions.ENABLED = true; actions.ENABLED = true;
ui = {
REACTIONS = lib.concatStringsSep "," [
"+1"
"-1"
"laugh"
"confused"
"heart"
"hooray"
"rocket"
"eyes"
"100"
"anger"
"astonished"
"no_good"
"ok_hand"
"pensive"
"pizza"
"point_up"
"sob"
"skull"
"upside_down_face"
"shrug"
];
};
"ui.meta".DESCRIPTION = "Bokstavelig talt programvareverkstedet";
}; };
dump = { dump = {
@@ -164,12 +152,26 @@ in {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package ];
systemd.services.gitea.serviceConfig.CPUSchedulingPolicy = "batch"; systemd.services.gitea = lib.mkIf cfg.enable {
wants = [ "redis-gitea.service" ];
after = [ "redis-gitea.service" ];
systemd.services.gitea.serviceConfig.CacheDirectory = "gitea/repo-archive"; serviceConfig = {
systemd.services.gitea.serviceConfig.BindPaths = [ CPUSchedulingPolicy = "batch";
"%C/gitea/repo-archive:${cfg.stateDir}/data/repo-archive" CacheDirectory = "gitea/repo-archive";
]; BindPaths = [
"%C/gitea/repo-archive:${cfg.stateDir}/data/repo-archive"
];
};
};
services.redis.servers.gitea = lib.mkIf cfg.enable {
enable = true;
user = config.services.gitea.user;
save = [ ];
openFirewall = false;
port = 5698;
};
services.nginx.virtualHosts."${domain}" = { services.nginx.virtualHosts."${domain}" = {
forceSSL = true; forceSSL = true;

View File

@@ -28,18 +28,22 @@
sops.secrets = { sops.secrets = {
"dibbler/postgresql/password" = { "dibbler/postgresql/password" = {
owner = "dibbler"; owner = "drumknotty";
group = "dibbler"; group = "drumknotty";
};
"worblehat/postgresql/password" = {
owner = "drumknotty";
group = "drumknotty";
}; };
}; };
services.dibbler = { services.drumknotty = {
enable = true; enable = true;
kioskMode = true; kioskMode = true;
limitScreenWidth = 80; limitScreenWidth = 80;
limitScreenHeight = 42; limitScreenHeight = 42;
settings = { dibblerSettings = {
general.quit_allowed = false; general.quit_allowed = false;
database = { database = {
type = "postgresql"; type = "postgresql";
@@ -51,6 +55,18 @@
}; };
}; };
}; };
worblehatSettings = {
general.quit_allowed = false;
database = {
type = "postgresql";
postgresql = {
username = "worblehat";
dbname = "worblehat";
host = "postgres.pvv.ntnu.no";
password = config.sops.secrets."worblehat/postgresql/password".path;
};
};
};
}; };
systemd.services."serial-getty@ttyUSB0" = lib.mkIf (!config.virtualisation.isVmVariant) { systemd.services."serial-getty@ttyUSB0" = lib.mkIf (!config.virtualisation.isVmVariant) {

379
modules/drumknotty.nix Normal file
View File

@@ -0,0 +1,379 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.drumknotty;
format = pkgs.formats.toml { };
in
{
options.services.drumknotty = {
enable = lib.mkEnableOption "DrumknoTTY";
dibblerPackage = lib.mkPackageOption pkgs "dibbler" { };
worblehatPackage = lib.mkPackageOption pkgs "worblehat" { };
screenPackage = lib.mkPackageOption pkgs "screen" { };
screenSessionName = lib.mkOption {
type = lib.types.str;
default = "drumknotty";
example = "myscreensessionname";
description = ''
Sets the screen session name.
'';
};
createLocalDatabase = lib.mkEnableOption "" // {
description = ''
Whether to set up a local postgres database automatically.
::: {.note}
You must set up postgres manually before enabling this option.
:::
'';
};
kioskMode = lib.mkEnableOption "" // {
description = ''
Whether to let dibbler take over the entire machine.
This will restrict the machine to a single TTY and make the program unquittable.
You can still get access to PTYs via SSH and similar, if enabled.
'';
};
limitScreenHeight = lib.mkOption {
type = with lib.types; nullOr ints.unsigned;
default = null;
example = 42;
description = ''
If set, limits the height of the screen dibbler uses to the given number of lines.
'';
};
limitScreenWidth = lib.mkOption {
type = with lib.types; nullOr ints.unsigned;
default = null;
example = 80;
description = ''
If set, limits the width of the screen dibbler uses to the given number of columns.
'';
};
dibblerSettings = lib.mkOption {
description = "Configuration for dibbler";
default = { };
type = lib.types.submodule {
freeformType = format.type;
};
};
worblehatSettings = lib.mkOption {
description = "Configuration for worblehat";
default = { };
type = lib.types.submodule {
freeformType = format.type;
};
};
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.mkIf cfg.enable (
lib.mkMerge [
{
environment.systemPackages = [
cfg.dibblerPackage
cfg.worblehatPackage
];
environment.etc."dibbler/dibbler.toml".source = format.generate "dibbler.toml" cfg.dibblerSettings;
environment.etc."worblehat/config.toml".source =
format.generate "worblehat-config.toml" cfg.worblehatSettings;
users = {
users.drumknotty = {
group = "drumknotty";
isNormalUser = true;
};
groups.drumknotty = { };
};
services.drumknotty.dibblerSettings = {
limits = {
low_credit_warning_limit = lib.mkDefault (-100);
user_recent_transaction_limit = lib.mkDefault 100;
};
printer = {
label_type = lib.mkDefault "62";
label_rotate = lib.mkDefault false;
};
};
services.drumknotty.worblehatSettings = {
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
];
};
};
services.drumknotty.dibblerSettings.database = lib.mkIf cfg.createLocalDatabase {
type = "postgresql";
postgresql.host = "/run/postgresql";
};
services.postgresql = lib.mkIf cfg.createLocalDatabase {
ensureDatabases = [
"dibbler"
"worblehat"
];
ensureUsers = [
{
name = "drumknotty";
ensureDBOwnership = true;
ensureClauses.login = true;
}
];
};
systemd.services.dibbler-setup-database = lib.mkIf cfg.createLocalDatabase {
description = "Dibbler database setup";
wantedBy = [ "default.target" ];
after = [ "postgresql.service" ];
unitConfig = {
ConditionPathExists = "!/var/lib/dibbler/.db-setup-done";
};
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe cfg.dibblerPackage} --config /etc/dibbler/dibbler.toml create-db";
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/dibbler/.db-setup-done";
StateDirectory = "dibbler";
User = "drumknotty";
Group = "drumknotty";
};
};
systemd.services.worblehat-setup-database = lib.mkIf cfg.createLocalDatabase {
description = "Worblehat database setup";
wantedBy = [ "default.target" ];
after = [ "postgresql.service" ];
unitConfig = {
ConditionPathExists = "!/var/lib/worblehat/.db-setup-done";
};
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe cfg.worblehatPackage} --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.kioskMode {
boot.kernelParams = [
"console=tty1"
];
users.users.drumknotty = {
extraGroups = [ "lp" ];
shell =
(pkgs.writeShellScriptBin "login-shell" "${lib.getExe' cfg.screenPackage "screen"} -x ${cfg.screenSessionName}")
// {
shellPath = "/bin/login-shell";
};
};
services.drumknotty.dibblerSettings.general = {
quit_allowed = false;
stop_allowed = false;
};
services.drumknotty.worblehatSettings.general = {
quit_allowed = false;
stop_allowed = false;
};
systemd.services.drumknotty-screen-session = {
description = "Drumknotty Screen Session";
wantedBy = [
"default.target"
];
after =
if cfg.createLocalDatabase then
[
"postgresql.service"
"dibbler-setup-database.service"
"worblehat-setup-database.service"
]
else
[
"network.target"
];
serviceConfig =
let
dibblerArgs = lib.cli.toCommandLineShellGNU { } {
config = "/etc/dibbler/dibbler.toml";
};
worblehatArgs = lib.cli.toCommandLineShellGNU { } {
config = "/etc/worblehat/config.toml";
};
in
{
Type = "forking";
RemainAfterExit = false;
Restart = "always";
RestartSec = "5s";
SuccessExitStatus = 1;
User = "drumknotty";
Group = "drumknotty";
ExecStartPre = "-${lib.getExe' cfg.screenPackage "screen"} -X -S ${cfg.screenSessionName} kill";
ExecStart =
let
screenArgs = lib.escapeShellArgs [
# -dm creates the screen in detached mode without accessing it
"-dm"
# Session name
"-S"
"${cfg.screenSessionName}"
# Window name
"-t"
"dibbler"
# Set optimal output mode instead of VT100 emulation
"-O"
# Enable login mode, updates utmp entries
"-l"
];
in
"${lib.getExe' cfg.screenPackage "screen"} ${screenArgs} ${lib.getExe cfg.dibblerPackage} ${dibblerArgs} loop";
ExecStartPost = [
"${lib.getExe' cfg.screenPackage "screen"} -S ${cfg.screenSessionName} -X screen -t worblehat ${lib.getExe cfg.worblehatPackage} ${worblehatArgs} cli"
]
++ lib.optionals (cfg.limitScreenWidth != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S ${cfg.screenSessionName} width ${toString cfg.limitScreenWidth}"
]
++ lib.optionals (cfg.limitScreenHeight != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S ${cfg.screenSessionName} height ${toString cfg.limitScreenHeight}"
];
};
};
services.getty.autologinUser = "drumknotty";
})
(lib.mkIf cfg.deadline-daemon.enable {
systemd.timers.worblehat-deadline-daemon = {
description = "Worblehat Deadline Daemon";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.deadline-daemon.onCalendar;
Persistent = true;
};
};
systemd.services.worblehat-deadline-daemon = {
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 = "worblehat";
Group = "worblehat";
};
};
})
]
);
}

View File

@@ -1,6 +1,9 @@
dibbler: dibbler:
postgresql: postgresql:
password: ENC[AES256_GCM,data:3X9A3jOpFVRuBg0gRiCEsZVKfLI=,iv:XC7LBNUhALk9IEhItV8fO5p/m7VKL0REBY1W2IZt7G4=,tag:l18R7EhbOlucZHFQiEvpHw==,type:str] password: ENC[AES256_GCM,data:3X9A3jOpFVRuBg0gRiCEsZVKfLI=,iv:XC7LBNUhALk9IEhItV8fO5p/m7VKL0REBY1W2IZt7G4=,tag:l18R7EhbOlucZHFQiEvpHw==,type:str]
worblehat:
postgresql:
password: ENC[AES256_GCM,data:WpJR6MumY+7WUYdVVgAqv1af+NmqecTMO9aP5lidSpE=,iv:7aoN8mjXckd81LxasMSG3R2vqj0SvzSl7wrEQ1LwToo=,tag:zeeNcEpkYnqyd8be0ZS+kQ==,type:str]
sops: sops:
age: age:
- recipient: age1hzkvnktkr8t5gvtq0ccw69e44z5z6wf00n3xhk3hj24emf07je5s6q2evr - recipient: age1hzkvnktkr8t5gvtq0ccw69e44z5z6wf00n3xhk3hj24emf07je5s6q2evr
@@ -66,8 +69,8 @@ sops:
MmxPMWNPYzJiOFRqY2VYczhvRm5IR3cKpUVV+zsMolsHI2YK9YqC6ecNT6QXv0TV MmxPMWNPYzJiOFRqY2VYczhvRm5IR3cKpUVV+zsMolsHI2YK9YqC6ecNT6QXv0TV
d1SpXRAexZBeWCCHBjSdvQBl8AT4EwrAIP2M2o++6i5DaGoGiEIWZQ== d1SpXRAexZBeWCCHBjSdvQBl8AT4EwrAIP2M2o++6i5DaGoGiEIWZQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-02-10T20:02:28Z" lastmodified: "2026-03-18T14:56:22Z"
mac: ENC[AES256_GCM,data:i8CjVxoD7zdkLNJlI9DCo/tDV5DUI7JdpozLtYZzI7Cu51GayaE2Y3Wg4de6P0L7C3FER04WfRe/h+G9PLZICX/CfSipQysyrEq3Pjt9IKsjytDhP9VYJ36QFGF0PuHUQAMSLts/tAoAvLue6MP+V82l5js9ghvyBrzyBGxoyJw=,iv:QFNxvCYxrSkwy7iT+2BEacNPftDXju1cibprVPDjic0=,tag:496E+oCy/VwTylyaWhQD+A==,type:str] mac: ENC[AES256_GCM,data:nBKtFmFKx/Mt9TIFnKuuznsPAXCQpc3+WIspNu5TN9TpIqw75nzYXpxIb2hxRfRu0nbjHXpBy4bkzeMi41BGkvkvV57CZyq11J5i/iIKwuvllaB1IWrdDT2u+6RH3jIspp3KoyxFWdRqcGfNma9dSmtI+1Dd5z7XaxVaoVK2QMI=,iv:6joviyJ2cXmGh/9HH7VEcoK3+4GK5I6i2N/1d65PAN0=,tag:0BFVPWL3BByJH8HbrBTKOw==,type:str]
pgp: pgp:
- created_at: "2026-02-10T20:01:32Z" - created_at: "2026-02-10T20:01:32Z"
enc: |- enc: |-
@@ -90,4 +93,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: F7D37890228A907440E1FD4846B9228E814A2AAC fp: F7D37890228A907440E1FD4846B9228E814A2AAC
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.11.0 version: 3.12.1