8 Commits

Author SHA1 Message Date
25c604cbca worbling... 2026-02-15 12:42:06 +01:00
6e0b207284 thing 2026-02-15 12:17:18 +01:00
fa51ede141 other test thing 2026-02-15 12:16:50 +01:00
e6d276e3ac test other thing 2026-02-15 12:05:54 +01:00
8ad532878e don't use not builtin 2026-02-15 11:31:05 +01:00
978c5fbb51 testing 2026-02-15 00:08:59 +01:00
55457fbeac init 2026-02-14 23:28:47 +01:00
a4c4079324 use convention for yes/no questions 2026-02-14 19:36:51 +01:00
2 changed files with 148 additions and 119 deletions

View File

@@ -642,7 +642,7 @@ class ConfirmMenu(Menu):
self.timeout = timeout self.timeout = timeout
def _execute(self, **_kwargs) -> bool: def _execute(self, **_kwargs) -> bool:
options = {True: "[y]/n", False: "y/[n]", None: "y/n"}[self.default] options = {True: "[Y/n]", False: "[y/N]", None: "[y/n]"}[self.default]
while True: while True:
result = self.input_str( result = self.input_str(
f"{self.prompt} ({options})", f"{self.prompt} ({options})",

View File

@@ -1,8 +1,16 @@
{ config, pkgs, lib, ... }: let {
config,
pkgs,
lib,
...
}:
let
cfg = config.services.dibbler; cfg = config.services.dibbler;
worbleCfg = config.services.worblehat;
format = pkgs.formats.toml { }; format = pkgs.formats.toml { };
in { in
{
options.services.dibbler = { options.services.dibbler = {
enable = lib.mkEnableOption "dibbler, the little kiosk computer"; enable = lib.mkEnableOption "dibbler, the little kiosk computer";
@@ -56,131 +64,152 @@ in {
}; };
}; };
config = lib.mkIf cfg.enable (lib.mkMerge [ config = lib.mkIf cfg.enable (
{ lib.mkMerge [
services.dibbler.settings = lib.pipe ../example-config.toml [ {
builtins.readFile services.dibbler.settings = lib.pipe ../example-config.toml [
builtins.fromTOML builtins.readFile
(lib.mapAttrsRecursive (_: lib.mkDefault)) builtins.fromTOML
]; (lib.mapAttrsRecursive (_: lib.mkDefault))
}
{
environment.systemPackages = [ cfg.package ];
environment.etc."dibbler/dibbler.toml".source = format.generate "dibbler.toml" cfg.settings;
users = {
users.dibbler = {
group = "dibbler";
isNormalUser = true;
};
groups.dibbler = { };
};
services.dibbler.settings.database = lib.mkIf cfg.createLocalDatabase {
type = "postgresql";
postgresql.host = "/run/postgresql";
};
services.postgresql = lib.mkIf cfg.createLocalDatabase {
ensureDatabases = [ "dibbler" ];
ensureUsers = [{
name = "dibbler";
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.package} --config /etc/dibbler/dibbler.toml create-db";
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/dibbler/.db-setup-done";
StateDirectory = "dibbler";
User = "dibbler";
Group = "dibbler";
};
};
}
(lib.mkIf cfg.kioskMode {
boot.kernelParams = [
"console=tty1"
];
users.users.dibbler = {
extraGroups = [ "lp" ];
shell = (pkgs.writeShellScriptBin "login-shell" "${lib.getExe' cfg.screenPackage "screen"} -x dibbler") // {
shellPath = "/bin/login-shell";
};
};
services.dibbler.settings.general = {
quit_allowed = false;
stop_allowed = false;
};
systemd.services.dibbler-screen-session = {
description = "Dibbler Screen Session";
wantedBy = [
"default.target"
]; ];
after = if cfg.createLocalDatabase then [ }
"postgresql.service" {
"dibbler-setup-database.service" environment.systemPackages = [
] else [ cfg.package
"network.target" worbleCfg.package
]; ];
serviceConfig = {
Type = "forking";
RemainAfterExit = false;
Restart = "always";
RestartSec = "5s";
SuccessExitStatus = 1;
User = "dibbler"; environment.etc."dibbler/dibbler.toml".source = format.generate "dibbler.toml" cfg.settings;
Group = "dibbler";
ExecStartPre = "-${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler kill"; users = {
ExecStart = let users.dibbler = {
screenArgs = lib.escapeShellArgs [ group = "dibbler";
# -dm creates the screen in detached mode without accessing it isNormalUser = true;
"-dm" };
groups.dibbler = { };
};
# Session name services.dibbler.settings.database = lib.mkIf cfg.createLocalDatabase {
"-S" type = "postgresql";
"dibbler" postgresql.host = "/run/postgresql";
};
# Set optimal output mode instead of VT100 emulation services.postgresql = lib.mkIf cfg.createLocalDatabase {
"-O" ensureDatabases = [ "dibbler" ];
ensureUsers = [
{
name = "dibbler";
ensureDBOwnership = true;
ensureClauses.login = true;
}
];
};
# Enable login mode, updates utmp entries systemd.services.dibbler-setup-database = lib.mkIf cfg.createLocalDatabase {
"-l" 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.package} --config /etc/dibbler/dibbler.toml create-db";
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/dibbler/.db-setup-done";
StateDirectory = "dibbler";
dibblerArgs = lib.cli.toCommandLineShellGNU { } { User = "dibbler";
config = "/etc/dibbler/dibbler.toml"; Group = "dibbler";
};
};
}
(lib.mkIf cfg.kioskMode {
boot.kernelParams = [
"console=tty1"
];
users.users.dibbler = {
extraGroups = [ "lp" ];
shell =
(pkgs.writeShellScriptBin "login-shell" "${lib.getExe' cfg.screenPackage "screen"} -x dibbler")
// {
shellPath = "/bin/login-shell";
}; };
in "${lib.getExe' cfg.screenPackage "screen"} ${screenArgs} ${lib.getExe cfg.package} ${dibblerArgs} loop";
ExecStartPost =
lib.optionals (cfg.limitScreenWidth != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler width ${toString cfg.limitScreenWidth}"
]
++ lib.optionals (cfg.limitScreenHeight != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler height ${toString cfg.limitScreenHeight}"
];
}; };
};
services.getty.autologinUser = "dibbler"; services.dibbler.settings.general = {
}) quit_allowed = false;
]); stop_allowed = false;
};
systemd.services.dibbler-screen-session = {
description = "Dibbler Screen Session";
wantedBy = [
"default.target"
];
after =
if cfg.createLocalDatabase then
[
"postgresql.service"
"dibbler-setup-database.service"
]
else
[
"network.target"
];
serviceConfig = {
Type = "forking";
RemainAfterExit = false;
Restart = "always";
RestartSec = "5s";
SuccessExitStatus = 1;
User = "dibbler";
Group = "dibbler";
ExecStartPre = "-${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler kill";
ExecStart =
let
screenArgs = lib.escapeShellArgs [
# -dm creates the screen in detached mode without accessing it
"-dm"
# Session name
"-S"
"dibbler"
# Set optimal output mode instead of VT100 emulation
"-O"
# Enable login mode, updates utmp entries
"-l"
# Set window name
"-t"
"dibblerino"
];
dibblerArgs = lib.cli.toCommandLineShellGNU { } {
config = "/etc/dibbler/dibbler.toml";
};
in
"${lib.getExe' cfg.screenPackage "screen"} ${screenArgs} ${lib.getExe cfg.package} ${dibblerArgs} loop";
ExecStartPost =
lib.optionals (cfg.limitScreenWidth != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler width ${toString cfg.limitScreenWidth}"
]
++ lib.optionals (cfg.limitScreenHeight != null) [
"${lib.getExe' cfg.screenPackage "screen"} -X -S dibbler height ${toString cfg.limitScreenHeight}"
]
++ [
"${lib.getExe' cfg.screenPackage "screen"} -S dibbler -X screen -t worblehat ${lib.getExe worbleCfg.package}"
];
};
};
services.getty.autologinUser = "dibbler";
})
]
);
} }