{ description = "gatekeeper using uv2nix"; ##python packaging on nix is so ass :( inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; pyproject-nix = { url = "github:pyproject-nix/pyproject.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; uv2nix = { url = "github:pyproject-nix/uv2nix"; inputs.pyproject-nix.follows = "pyproject-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; pyproject-build-systems = { url = "github:pyproject-nix/build-system-pkgs"; inputs.pyproject-nix.follows = "pyproject-nix"; inputs.uv2nix.follows = "uv2nix"; inputs.nixpkgs.follows = "nixpkgs"; }; nixos-hardware = { url = "github:NixOS/nixos-hardware/master"; inputs.nixpkgs.follows = "nixpkgs"; }; nixos-raspberrypi = { url = "github:nvmd/nixos-raspberrypi/main"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { nixpkgs, pyproject-nix, uv2nix, pyproject-build-systems, nixos-hardware, ... }: let inherit (nixpkgs) lib; forAllSystems = lib.genAttrs lib.systems.flakeExposed; workspace = uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; overlay = workspace.mkPyprojectOverlay { sourcePreference = "wheel"; }; editableOverlay = workspace.mkEditablePyprojectOverlay { root = "$REPO_ROOT"; }; pythonSets = forAllSystems ( system: let pkgs = nixpkgs.legacyPackages.${system}; python = pkgs.python3; in (pkgs.callPackage pyproject-nix.build.packages { inherit python; }).overrideScope ( lib.composeManyExtensions [ pyproject-build-systems.overlays.wheel overlay (final: prev: { pyscard = prev.pyscard.overrideAttrs (old: { nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ pkgs.swig pkgs.pkg-config]; buildInputs = (old.buildInputs or []) ++ [ pkgs.pcsclite.dev ]; NIX_CFLAGS_COMPILE = "-I${pkgs.pcsclite.dev}/include/PCSC"; }); }) ] ) ); in { devShells = forAllSystems ( system: let pkgs = nixpkgs.legacyPackages.${system}; pythonSet = pythonSets.${system}.overrideScope editableOverlay; virtualenv = pythonSet.mkVirtualEnv "gatekeeper" workspace.deps.all; in { default = pkgs.mkShell { packages = [ virtualenv pkgs.uv pkgs.pcsclite pkgs.pcsclite.dev pkgs.swig pkgs.pkg-config ]; env = { UV_NO_SYNC = "1"; UV_PYTHON = pythonSet.python.interpreter; UV_PYTHON_DOWNLOADS = "never"; LD_LIBRARY_PATH = "${lib.getLib pkgs.pcsclite}/lib"; }; shellHook = '' unset PYTHONPATH export REPO_ROOT=$(git rev-parse --show-toplevel) ''; }; } ); packages = forAllSystems (system: { default = pythonSets.${system}.mkVirtualEnv "gatekeeper" workspace.deps.default; }); nixosConfigurations = { gatekeeper-rpi = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; specialArgs = { inherit workspace overlay; }; modules = [ "${nixpkgs}/nixos/modules/profiles/headless.nix" "${nixpkgs}/nixos/modules/profiles/minimal.nix" "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix" nixos-hardware.nixosModules.raspberry-pi-3 ({ pkgs, ... }: { nix.nixPath = [ "nixpkgs=${pkgs.path}" ]; nix.settings = { trusted-users = [ "root" "@wheel" ]; experimental-features = [ "nix-command" "flakes" ]; auto-optimise-store = true; }; }) ({ config, pkgs, packages, ...}: let gatekeeper-app = pkgs.python3Packages.buildPythonPackage { pname = "gatekeeper-app"; version = "0.0.1"; propagatedBuildInputs = [packages.gatekeeper]; src = ./app; format = "pyproject"; }; in { boot.loader.grub.enable = false; boot.loader.generic-extlinux-compatible.enable = true; boot.kernelPackages = pkgs.linuxPackages; boot.tmp.cleanOnBoot = true; hardware.enableRedistributableFirmware = true; networking.hostName = "gatekeeper-rpi"; #minimal documentation.man.enable = false; xdg.icons.enable = false; xdg.mime.enable = false; xdg.sounds.enable = false; users.users.root.openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICKaEcGaSKU0xC5qCwzj2oCLLG4PYjWHZ7/CXHw4urVk atlan@nixos"]; users.groups = { gatekeeper = {}; }; users.users.admin = { isNormalUser = true; extraGroups = [ "wheel" "networkmanager" "gatekeeper" ]; }; users.users.gatekeeper = { isNormalUser = true; extraGroups = ["gatekeeper"]; }; services.openssh = { enable = true; ports = [ 22 ]; settings = { PasswordAuthentication = false; }; }; environment.systemPackages = with pkgs; [ git htop pcsclite gatekeeper-app ]; environment.etc."gatekeeper-env".source = pythonSets.aarch64-linux.mkVirtualEnv "gatekeeper" workspace.deps.default; services.pcscd.enable = true; systemd.services.gatekeeper = { enable = true; description = "Gatekeeper service"; after = [ "network.target" "pcscd.service"]; wantedBy = [ "multi-user.target" ]; environment = { LD_LIBRARY_PATH = "${lib.getLib pkgs.pcsclite}/lib"; PYTHONPATH = "/etc/gatekeeper-env/lib/python3.x/site-packages"; }; serviceConfig = { Type = "simple"; User = "gatekeeper"; Group = "gatekeeper"; WorkingDirectory = "/var/lib/gatekeeper"; ExecStart = "${pythonSets.aarch64-linux.mkVirtualEnv "gatekeeper" workspace.deps.default}/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8000"; Restart = "always"; RestartSec = "10"; }; # Create working directory and log directory preStart = '' mkdir -p /var/lib/gatekeeper mkdir -p /var/log/gatekeeper chown -R gatekeeper:gatekeeper /var/lib/gatekeeper chown -R gatekeeper:gatekeeper /var/log/gatekeeper ''; }; networking.firewall.allowedTCPPorts = [ 8000 ]; time.timeZone = "Europe/Berlin"; system.stateVersion = "25.11"; }) ]; }; }; }; }