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:
@@ -7,3 +7,5 @@ dist
|
|||||||
test.db
|
test.db
|
||||||
|
|
||||||
.ruff_cache
|
.ruff_cache
|
||||||
|
|
||||||
|
*.qcow2
|
||||||
|
|||||||
@@ -21,29 +21,27 @@ Deretter kan du kjøre programmet med
|
|||||||
|
|
||||||
```console
|
```console
|
||||||
python -m dibbler -c example-config.ini create-db
|
python -m dibbler -c example-config.ini create-db
|
||||||
|
python -m dibbler -c example-config.ini seed-data
|
||||||
python -m dibbler -c example-config.ini loop
|
python -m dibbler -c example-config.ini loop
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nix
|
## Nix
|
||||||
|
|
||||||
### Bygge nytt image
|
Du kan enklest komme i gang med nix-utvikling ved å kjøre VM-en:
|
||||||
|
|
||||||
For å bygge et image trenger du en builder som takler å bygge for arkitekturen du skal lage et image for.
|
```console
|
||||||
|
nix run .#vm
|
||||||
|
|
||||||
(Eller be til gudene om at cross compile funker)
|
# Eller hvis du trenger tilgang til terminalen i VM-en også:
|
||||||
|
nix run .#vm-non-kiosk
|
||||||
|
```
|
||||||
|
|
||||||
Flaket exposer en modul som autologger inn med en bruker som automatisk kjører dibbler, og setter opp et minimalistisk miljø.
|
Du kan også bygge pakken manuelt, eller kjøre den direkte:
|
||||||
|
|
||||||
Før du bygger imaget burde du kopiere og endre `example-config.ini` lokalt til å inneholde instillingene dine. **NB: Denne kommer til å ligge i nix storen, ikke si noe her som du ikke vil at moren din skal høre.**
|
```console
|
||||||
|
nix build .#dibbler
|
||||||
|
|
||||||
Du kan også endre hvilken config-fil som blir brukt direkte i pakken eller i modulen.
|
nix run .# -- --config example-config.ini create-db
|
||||||
|
nix run .# -- --config example-config.ini seed-data
|
||||||
Se eksempelet for hvordan skrot er satt opp i `flake.nix` og `nix/skrott.nix`
|
nix run .# -- --config example-config.ini loop
|
||||||
|
```
|
||||||
### Bygge image for skrot
|
|
||||||
Skrot har et image definert i flake.nix:
|
|
||||||
|
|
||||||
1. endre `example-config.ini`
|
|
||||||
2. `nix build .#images.skrot`
|
|
||||||
3. ???
|
|
||||||
4. non-profit
|
|
||||||
|
|||||||
@@ -17,21 +17,31 @@
|
|||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
in f system pkgs);
|
in f system pkgs);
|
||||||
in {
|
in {
|
||||||
packages = forAllSystems (system: pkgs: {
|
apps = let
|
||||||
default = self.packages.${system}.dibbler;
|
mkApp = program: description: {
|
||||||
dibbler = pkgs.callPackage ./nix/dibbler.nix {
|
type = "app";
|
||||||
python3Packages = pkgs.python312Packages;
|
program = toString program;
|
||||||
|
meta = {
|
||||||
|
inherit description;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
skrot = self.nixosConfigurations.skrot.config.system.build.sdImage;
|
mkVm = name: mkApp "${self.nixosConfigurations.${name}.config.system.build.vm}/bin/run-nixos-vm";
|
||||||
});
|
in forAllSystems (system: pkgs: {
|
||||||
|
|
||||||
apps = forAllSystems (system: pkgs: {
|
|
||||||
default = self.apps.${system}.dibbler;
|
default = self.apps.${system}.dibbler;
|
||||||
dibbler = flake-utils.lib.mkApp {
|
dibbler = flake-utils.lib.mkApp {
|
||||||
drv = self.packages.${system}.dibbler;
|
drv = self.packages.${system}.dibbler;
|
||||||
};
|
};
|
||||||
|
vm = mkVm "vm" "Start a NixOS VM with dibbler installed in kiosk-mode";
|
||||||
|
vm-non-kiosk = mkVm "vm-non-kiosk" "Start a NixOS VM with dibbler installed in nonkiosk-mode";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nixosModules.default = import ./nix/module.nix;
|
||||||
|
|
||||||
|
nixosConfigurations = {
|
||||||
|
vm = import ./nix/nixos-configurations/vm.nix { inherit self nixpkgs; };
|
||||||
|
vm-non-kiosk = import ./nix/nixos-configurations/vm-non-kiosk.nix { inherit self nixpkgs; };
|
||||||
|
};
|
||||||
|
|
||||||
overlays = {
|
overlays = {
|
||||||
default = self.overlays.dibbler;
|
default = self.overlays.dibbler;
|
||||||
dibbler = final: prev: {
|
dibbler = final: prev: {
|
||||||
@@ -46,20 +56,11 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
# Note: using the module requires that you have applied the overlay first
|
packages = forAllSystems (system: pkgs: {
|
||||||
nixosModules.default = import ./nix/module.nix;
|
default = self.packages.${system}.dibbler;
|
||||||
|
dibbler = pkgs.callPackage ./nix/package.nix {
|
||||||
nixosConfigurations.skrot = nixpkgs.lib.nixosSystem (rec {
|
python3Packages = pkgs.python312Packages;
|
||||||
system = "aarch64-linux";
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [ self.overlays.dibbler ];
|
|
||||||
};
|
};
|
||||||
modules = [
|
|
||||||
(nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64.nix")
|
|
||||||
self.nixosModules.default
|
|
||||||
./nix/skrott.nix
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+155
-49
@@ -8,6 +8,45 @@ in {
|
|||||||
|
|
||||||
package = lib.mkPackageOption pkgs "dibbler" { };
|
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 {
|
settings = lib.mkOption {
|
||||||
description = "Configuration for dibbler";
|
description = "Configuration for dibbler";
|
||||||
default = { };
|
default = { };
|
||||||
@@ -17,61 +56,128 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
screen = "${pkgs.screen}/bin/screen";
|
{
|
||||||
in lib.mkIf cfg.enable {
|
services.dibbler.settings = lib.pipe ../example-config.ini [
|
||||||
services.dibbler.settings = lib.pipe ../example-config.ini [
|
builtins.readFile
|
||||||
builtins.readFile
|
builtins.fromTOML
|
||||||
builtins.fromTOML
|
(lib.mapAttrsRecursive (_: lib.mkDefault))
|
||||||
(lib.mapAttrsRecursive (_: lib.mkDefault))
|
];
|
||||||
];
|
}
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
boot = {
|
environment.etc."dibbler/dibbler.conf".source = format.generate "dibbler.conf" cfg.settings;
|
||||||
consoleLogLevel = 0;
|
|
||||||
enableContainers = false;
|
|
||||||
loader.grub.enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
users = {
|
users = {
|
||||||
groups.dibbler = { };
|
users.dibbler = {
|
||||||
users.dibbler = {
|
group = "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" ];
|
extraGroups = [ "lp" ];
|
||||||
isNormalUser = true;
|
shell = (pkgs.writeShellScriptBin "login-shell" "${lib.getExe cfg.screenPackage} -x dibbler") // {
|
||||||
shell = (pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler") // {shellPath = "/bin/login-shell";};
|
shellPath = "/bin/login-shell";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.screen-daemon = {
|
services.dibbler.settings.general = {
|
||||||
description = "Dibbler service screen";
|
quit_allowed = false;
|
||||||
wantedBy = [ "default.target" ];
|
stop_allowed = false;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/84105
|
systemd.services.dibbler-screen-session = {
|
||||||
boot.kernelParams = [
|
description = "Dibbler Screen Session";
|
||||||
"console=ttyUSB0,9600"
|
wantedBy = [
|
||||||
"console=tty1"
|
"default.target"
|
||||||
];
|
];
|
||||||
systemd.services."serial-getty@ttyUSB0" = {
|
after = if cfg.createLocalDatabase then [
|
||||||
enable = true;
|
"postgresql.service"
|
||||||
wantedBy = [ "getty.target" ]; # to start at boot
|
"dibbler-setup-database.service"
|
||||||
serviceConfig.Restart = "always"; # restart when session is closed
|
] 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";
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{ lib
|
{ lib
|
||||||
, python3Packages
|
, python3Packages
|
||||||
, fetchFromGitHub
|
, makeWrapper
|
||||||
|
, less
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
pyproject = builtins.fromTOML (builtins.readFile ../pyproject.toml);
|
pyproject = builtins.fromTOML (builtins.readFile ../pyproject.toml);
|
||||||
@@ -16,7 +17,10 @@ python3Packages.buildPythonApplication {
|
|||||||
# https://github.com/NixOS/nixpkgs/issues/285234
|
# https://github.com/NixOS/nixpkgs/issues/285234
|
||||||
dontCheckRuntimeDeps = true;
|
dontCheckRuntimeDeps = true;
|
||||||
|
|
||||||
nativeBuildInputs = with python3Packages; [ setuptools ];
|
nativeBuildInputs = with python3Packages; [
|
||||||
|
setuptools
|
||||||
|
makeWrapper
|
||||||
|
];
|
||||||
propagatedBuildInputs = with python3Packages; [
|
propagatedBuildInputs = with python3Packages; [
|
||||||
brother-ql
|
brother-ql
|
||||||
matplotlib
|
matplotlib
|
||||||
@@ -24,4 +28,14 @@ python3Packages.buildPythonApplication {
|
|||||||
python-barcode
|
python-barcode
|
||||||
sqlalchemy
|
sqlalchemy
|
||||||
];
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
wrapProgram $out/bin/dibbler \
|
||||||
|
--prefix PATH : "${lib.makeBinPath [ less ]}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "The little kiosk that could";
|
||||||
|
mainProgram = "dibbler";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -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" ];
|
|
||||||
# };
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user