nix: yeet skrott, massive module modifications tm, wrap package and more

Sorry for the kinda big commit that does everything at once

This change does the following:
- yeets skrott and skrot-specific settings from the NixOS module,
- adds a bunch more settings and generalizations to the NixOS module,
- adds two VM NixOS configurations for interactive testing
- wraps the nix package so that `less` is always present in `$PATH`
- yeah, that's about it

kthxbye
This commit is contained in:
2026-01-06 14:01:36 +09:00
parent 78161a96be
commit 4ed68ff05c
8 changed files with 292 additions and 115 deletions

View File

@@ -8,6 +8,45 @@ in {
package = lib.mkPackageOption pkgs "dibbler" { };
screenPackage = lib.mkPackageOption pkgs "screen" { };
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.
'';
};
settings = lib.mkOption {
description = "Configuration for dibbler";
default = { };
@@ -17,61 +56,128 @@ in {
};
};
config = let
screen = "${pkgs.screen}/bin/screen";
in lib.mkIf cfg.enable {
services.dibbler.settings = lib.pipe ../example-config.ini [
builtins.readFile
builtins.fromTOML
(lib.mapAttrsRecursive (_: lib.mkDefault))
];
config = lib.mkIf cfg.enable (lib.mkMerge [
{
services.dibbler.settings = lib.pipe ../example-config.ini [
builtins.readFile
builtins.fromTOML
(lib.mapAttrsRecursive (_: lib.mkDefault))
];
}
{
environment.systemPackages = [ cfg.package ];
boot = {
consoleLogLevel = 0;
enableContainers = false;
loader.grub.enable = false;
};
environment.etc."dibbler/dibbler.conf".source = format.generate "dibbler.conf" cfg.settings;
users = {
groups.dibbler = { };
users.dibbler = {
group = "dibbler";
users = {
users.dibbler = {
group = "dibbler";
isNormalUser = true;
};
groups.dibbler = { };
};
services.dibbler.settings.database.url = lib.mkIf cfg.createLocalDatabase "postgresql://dibbler?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.conf 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" ];
isNormalUser = true;
shell = (pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler") // {shellPath = "/bin/login-shell";};
shell = (pkgs.writeShellScriptBin "login-shell" "${lib.getExe cfg.screenPackage} -x dibbler") // {
shellPath = "/bin/login-shell";
};
};
};
systemd.services.screen-daemon = {
description = "Dibbler service screen";
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStartPre = "-${screen} -X -S dibbler kill";
ExecStart = let
config = format.generate "dibbler-config.ini" cfg.settings;
in "${screen} -dmS dibbler -O -l ${cfg.package}/bin/dibbler --config ${config} loop";
ExecStartPost = "${screen} -X -S dibbler width 42 80";
User = "dibbler";
Group = "dibbler";
Type = "forking";
RemainAfterExit = false;
Restart = "always";
RestartSec = "5s";
SuccessExitStatus = 1;
services.dibbler.settings.general = {
quit_allowed = false;
stop_allowed = false;
};
};
# https://github.com/NixOS/nixpkgs/issues/84105
boot.kernelParams = [
"console=ttyUSB0,9600"
"console=tty1"
];
systemd.services."serial-getty@ttyUSB0" = {
enable = true;
wantedBy = [ "getty.target" ]; # to start at boot
serviceConfig.Restart = "always"; # restart when session is closed
};
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;
services.getty.autologinUser = lib.mkForce "dibbler";
};
User = "dibbler";
Group = "dibbler";
ExecStartPre = "-${lib.getExe cfg.screenPackage} -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"
];
dibblerArgs = lib.cli.toCommandLineShellGNU { } {
config = "/etc/dibbler/dibbler.conf";
};
in "${lib.getExe cfg.screenPackage} ${screenArgs} ${lib.getExe cfg.package} ${dibblerArgs} loop";
ExecStartPost =
lib.optionals (cfg.limitScreenWidth != null) [
"${lib.getExe cfg.screenPackage} -X -S dibbler width ${toString cfg.limitScreenWidth}"
]
++ lib.optionals (cfg.limitScreenHeight != null) [
"${lib.getExe cfg.screenPackage} -X -S dibbler height ${toString cfg.limitScreenHeight}"
];
};
};
services.getty.autologinUser = "dibbler";
})
]);
}

View File

@@ -0,0 +1,54 @@
{ self, nixpkgs, ... }:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
pkgs = import nixpkgs {
system = "x86_64-linux";
overlays = [
self.overlays.dibbler
];
};
modules = [
"${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix"
"${nixpkgs}/nixos/tests/common/user-account.nix"
self.nixosModules.default
({ config, ... }: {
system.stateVersion = config.system.nixos.release;
virtualisation.graphics = false;
users.motd = ''
=================================
Welcome to the dibbler non-kiosk vm!
Try running:
${config.services.dibbler.package.meta.mainProgram} loop
Password for dibbler is 'dibbler'
To exit, press Ctrl+A, then X
=================================
'';
users.users.dibbler = {
isNormalUser = true;
password = "dibbler";
extraGroups = [ "wheel" ];
};
services.getty.autologinUser = "dibbler";
programs.vim = {
enable = true;
defaultEditor = true;
};
services.postgresql.enable = true;
services.dibbler = {
enable = true;
createLocalDatabase = true;
};
})
];
}

View File

@@ -0,0 +1,29 @@
{ self, nixpkgs, ... }:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
pkgs = import nixpkgs {
system = "x86_64-linux";
overlays = [
self.overlays.default
];
};
modules = [
"${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix"
"${nixpkgs}/nixos/tests/common/user-account.nix"
self.nixosModules.default
({ config, ... }: {
system.stateVersion = config.system.nixos.release;
virtualisation.graphics = false;
services.postgresql.enable = true;
services.dibbler = {
enable = true;
createLocalDatabase = true;
kioskMode = true;
};
})
];
}

View File

@@ -1,6 +1,7 @@
{ lib
, python3Packages
, fetchFromGitHub
, makeWrapper
, less
}:
let
pyproject = builtins.fromTOML (builtins.readFile ../pyproject.toml);
@@ -16,7 +17,10 @@ python3Packages.buildPythonApplication {
# https://github.com/NixOS/nixpkgs/issues/285234
dontCheckRuntimeDeps = true;
nativeBuildInputs = with python3Packages; [ setuptools ];
nativeBuildInputs = with python3Packages; [
setuptools
makeWrapper
];
propagatedBuildInputs = with python3Packages; [
brother-ql
matplotlib
@@ -24,4 +28,14 @@ python3Packages.buildPythonApplication {
python-barcode
sqlalchemy
];
postInstall = ''
wrapProgram $out/bin/dibbler \
--prefix PATH : "${lib.makeBinPath [ less ]}"
'';
meta = {
description = "The little kiosk that could";
mainProgram = "dibbler";
};
}

View File

@@ -1,27 +0,0 @@
{...}: {
system.stateVersion = "25.05";
services.dibbler.enable = true;
networking = {
hostName = "skrot";
domain = "pvv.ntnu.no";
nameservers = [ "129.241.0.200" "129.241.0.201" ];
defaultGateway = "129.241.210.129";
interfaces.eth0 = {
useDHCP = false;
ipv4.addresses = [{
address = "129.241.210.235";
prefixLength = 25;
}];
};
};
# services.resolved.enable = true;
# systemd.network.enable = true;
# systemd.network.networks."30-network" = {
# matchConfig.Name = "*";
# DHCP = "no";
# address = [ "129.241.210.235/25" ];
# gateway = [ "129.241.210.129" ];
# };
}