diff --git a/nix/module.nix b/nix/module.nix new file mode 100644 index 0000000..0e4a400 --- /dev/null +++ b/nix/module.nix @@ -0,0 +1,71 @@ +self: { + config, + pkgs, + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption mkIf types; + + cfg = config.services.pi-air-quality-monitor; +in { + options.services.pi-air-quality-monitor = { + enable = mkEnableOption "pi-air-quality-monitor"; + package = mkOption { + type = types.package; + default = self.packages.${pkgs.system}.pi-air-quality-monitor; + }; + openFirewall = mkOption { + type = types.bool; + default = true; + description = "Whether to open the firewall for the server"; + }; + + settings = { + port = mkOption { + type = types.int; + default = 8080; + description = "Port to run the server on"; + }; + + user = mkOption { + type = types.str; + default = "pi-aqm"; + description = "User to run the server as"; + }; + + group = mkOption { + type = types.str; + default = "pi-aqm"; + description = "Group to run the server as"; + }; + }; + }; + + config = mkIf config.services.pi-air-quality-monitor.enable { + networking.firewall.allowedTCPPorts = [cfg.settings.port]; + users = { + users.pi-aqm = { + isSystemUser = true; + group = "pi-aqm"; + home = "/var/lib/pi-aqm"; + createHome = true; + }; + + groups.pi-aqm = {}; + }; + + systemd.services."pi-air-quality-monitor" = { + description = "An air quality monitoring service with a Raspberry Pi and a SDS011 sensor"; + wantedBy = ["multi-user.target"]; + after = ["network.target"]; + serviceConfig = { + Type = "simple"; + User = cfg.settings.user; + Group = cfg.settings.group; + WorkingDirectory = "/var/lib/pi-aqm"; + ExecStart = "${lib.getExe cfg.package}"; + Restart = "always"; + }; + }; + }; +} diff --git a/nix/tests/checks/basic.nix b/nix/tests/checks/basic.nix new file mode 100644 index 0000000..92b35b0 --- /dev/null +++ b/nix/tests/checks/basic.nix @@ -0,0 +1,56 @@ +{ + nixosTest, + self, + ... +}: +nixosTest { + name = "basic"; + + nodes = { + client = {pkgs, ...}: { + imports = [../profiles/test-setup.nix]; + + environment.systemPackages = with pkgs; [ + netcat + ]; + }; + + server = {pkgs, ...}: { + imports = [ + ../profiles/test-setup.nix + self.nixosModules.pi-air-quality-monitor + ]; + + users.users.test = { + isNormalUser = true; + extraGroups = ["wheel"]; + packages = with pkgs; [ + tree + ]; + }; + + services.pi-air-quality-monitor = { + enable = true; + openFirewall = true; + + settings = { + port = 8080; + user = "pi-aqm"; + group = "pi-aqm"; + }; + }; + + system.stateVersion = "23.11"; + }; + }; + + testScript = '' + server.wait_for_unit("default.target") + server.succeed("ls -lah /dev/ttyUSB0") + server.succeed('systemctl status pi-air-quality-monitor | grep \"Active: active (running)\" || return 0') + #server.succeed('nc -vz server 8080') + + #client.wait_for_unit("default.target") + #client.succeed("nc -vz server 8080") + ''; +} diff --git a/nix/tests/default.nix b/nix/tests/default.nix new file mode 100644 index 0000000..ce65c23 --- /dev/null +++ b/nix/tests/default.nix @@ -0,0 +1,26 @@ +{ + self, + config, + inputs, + lib, + ... +}: { + perSystem = { + pkgs, + self', + ... + }: let + callPackage = lib.callPackageWith (pkgs + // { + inherit (config.flake) nixosModules; + inherit inputs; + }); + in { + packages.test = self'.checks.basic.driverInteractive; + + checks = { + basic = callPackage ./checks/basic.nix {inherit self;}; + default = self'.checks.basic; + }; + }; +} diff --git a/nix/tests/profiles/test-setup.nix b/nix/tests/profiles/test-setup.nix new file mode 100644 index 0000000..d8653ff --- /dev/null +++ b/nix/tests/profiles/test-setup.nix @@ -0,0 +1,12 @@ +{ + virtualisation = { + cores = 2; + memorySize = 1024; + qemu.options = [ + "-nographic" + "-vga none -enable-kvm" + "-device virtio-gpu-pci,xres=720,yres=1440" + "-serial pty" + ]; + }; +}