{config, pkgs, lib, self, system, ... }: let cfg = config.services.gatekeeper; in { options = { services.gatekeeper = { enable = lib.mkEnableOption "Enable the gatekeeper api service."; envFile = lib.mkOption { type = lib.types.nullOr lib.types.path; description = "The path to a .env file with all the other options"; }; db = lib.mkOption { type = lib.types.path; description = "Where to save the database."; default = "/var/lib/gatekeeper"; }; mock = lib.mkOption { type = lib.types.str; default = "False"; description = "Mock the doorcontroller. Has to be a string!"; }; }; }; config = lib.mkIf cfg.enable { users.groups.gatekeeper = {}; users.groups.gpio = {}; users.users.gatekeeper = { description = "gatekeeper user"; group = "gatekeeper"; extraGroups = ["gpio"]; isSystemUser = true; }; services.udev.extraRules = lib.mkBefore '' KERNEL=="gpiomem", GROUP="gpio", MODE="0660" SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="${pkgs.bash}/bin/bash -c '${pkgs.coreutils}/bin/chgrp gpio /dev/%k && chmod 660 /dev/%k && ${pkgs.coreutils}/bin/chgrp -R gpio /sys/class/gpio && ${pkgs.coreutils}/bin/chmod -R g=u /sys/class/gpio'" SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="${pkgs.bash}/bin/bash -c '${pkgs.coreutils}/bin/chgrp -R gpio /sys%p && ${pkgs.coreutils}/bin/chmod -R g=u /sys%p'" ''; boot.kernelParams = [ "iomem=relaxed" # for pigpiod "strict-devmem=0" ]; services.pcscd = { enable = true; plugins = [ pkgs.acsccid ]; }; networking.firewall.allowedTCPPorts = [ 8000 ]; systemd.services.gatekeeper = { description = "Runs the gatekeeper api"; script = '' export LD_LIBRARY_PATH="${lib.getLib pkgs.pcsclite}/lib''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" exec ${self.packages.${system}.default}/bin/uvicorn --host 0.0.0.0 --port 8000 --app-dir ${self} app.main:app ''; after = [ "network.target" ]; wantedBy = ["multi-user.target"]; serviceConfig = { User = "gatekeeper"; Restart = "on-failure"; RestartSec = "20"; StateDirectory = "gatekeeper"; WorkingDirectory = "/var/lib/gatekeeper"; EnvironmentFile = cfg.envFile; }; environment = { SQLALCHEMY_DATABASE_URL = "sqlite:///${cfg.db}/gatekeeper.db"; ALEMBIC_CONFIG = "${self}/alembic.ini"; MOCK = cfg.mock; }; }; }; }