drumknotty: init

This commit is contained in:
Vegard Bieker Matthey
2026-03-07 20:35:06 +01:00
parent b592f0100a
commit 352f25f6fe
4 changed files with 387 additions and 66 deletions
Generated
+45 -1
View File
@@ -161,6 +161,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": [
@@ -391,7 +412,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": {
@@ -522,6 +544,28 @@
"repo": "sops-nix", "repo": "sops-nix",
"type": "github" "type": "github"
} }
},
"worblehat": {
"inputs": {
"libdib": "libdib",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1770887951,
"narHash": "sha256-6LGqM9yhONtfCXHtPNn3S0GFsmB2dCchyozHDevwmiQ=",
"ref": "main",
"rev": "911063041f24d594a772a2a699d71d3d94953ce8",
"revCount": 101,
"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",
+24 -24
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";
@@ -171,8 +174,12 @@
stableNixosConfig = name: extraArgs: stableNixosConfig = name: extraArgs:
nixosConfig nixpkgs name ./hosts/${name}/configuration.nix extraArgs; nixosConfig nixpkgs name ./hosts/${name}/configuration.nix extraArgs;
in in {
{ bakke = stableNixosConfig "bakke" {
modules = [
inputs.disko.nixosModules.disko
];
};
bicep = stableNixosConfig "bicep" { bicep = stableNixosConfig "bicep" {
modules = [ modules = [
inputs.matrix-next.nixosModules.default inputs.matrix-next.nixosModules.default
@@ -192,45 +199,37 @@
bekkalokk = stableNixosConfig "bekkalokk" { bekkalokk = stableNixosConfig "bekkalokk" {
overlays = [ overlays = [
(final: prev: { (final: prev: {
mediawiki-extensions = final.callPackage ./packages/mediawiki-extensions {}; mediawiki-extensions = final.callPackage ./packages/mediawiki-extensions { };
simplesamlphp = final.callPackage ./packages/simplesamlphp {}; simplesamlphp = final.callPackage ./packages/simplesamlphp { };
bluemap = final.callPackage ./packages/bluemap.nix { };
}) })
inputs.pvv-nettsiden.overlays.default inputs.pvv-nettsiden.overlays.default
inputs.qotd.overlays.default inputs.qotd.overlays.default
]; ];
modules = [ modules = [
inputs.pvv-nettsiden.nixosModules.default inputs.pvv-nettsiden.nixosModules.default
self.nixosModules.bluemap
inputs.qotd.nixosModules.default inputs.qotd.nixosModules.default
]; ];
}; };
ildkule = stableNixosConfig "ildkule" { ildkule = stableNixosConfig "ildkule" { };
modules = [ #ildkule-unstable = unstableNixosConfig "ildkule" { };
inputs.disko.nixosModules.disko
];
};
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];
};
shark = stableNixosConfig "shark" {};
wenche = stableNixosConfig "wenche" {};
temmie = stableNixosConfig "temmie" {
overlays = [ overlays = [
inputs.bro.overlays.default inputs.dibbler.overlays.default
]; inputs.worblehat.overlays.default
modules = [
inputs.bro.nixosModules.default
]; ];
}; };
gluttony = stableNixosConfig "gluttony" { shark = stableNixosConfig "shark" { };
overlays = [ wenche = stableNixosConfig "wenche" { };
(final: prev: { bluemap = final.callPackage ./packages/bluemap.nix {}; }) temmie = stableNixosConfig "temmie" { };
]; gluttony = stableNixosConfig "gluttony" { };
modules = [ self.nixosModules.bluemap ];
};
kommode = stableNixosConfig "kommode" { kommode = stableNixosConfig "kommode" {
overlays = [ overlays = [
@@ -284,6 +283,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: {
+20 -4
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 = "pvv_vv";
dbname = "pvv_vv";
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) {
+261
View File
@@ -0,0 +1,261 @@
{
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;
};
};
};
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.dibbler.settings.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";
})
]
);
}