1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7
8let
9 cfg = config.services.photonvision;
10in
11{
12 options = {
13 services.photonvision = {
14 enable = lib.mkEnableOption "PhotonVision";
15
16 package = lib.mkPackageOption pkgs "photonvision" { };
17
18 openFirewall = lib.mkOption {
19 description = ''
20 Whether to open the required ports in the firewall.
21 '';
22 default = false;
23 type = lib.types.bool;
24 };
25 };
26 };
27
28 config = lib.mkIf cfg.enable {
29 systemd.services.photonvision = {
30 description = "PhotonVision, the free, fast, and easy-to-use computer vision solution for the FIRST Robotics Competition";
31
32 wantedBy = [ "multi-user.target" ];
33 after = [ "network.target" ];
34
35 serviceConfig = {
36 ExecStart = lib.getExe cfg.package;
37
38 # ephemeral root directory
39 RuntimeDirectory = "photonvision";
40 RootDirectory = "/run/photonvision";
41
42 # setup persistent state and logs directories
43 StateDirectory = "photonvision";
44 LogsDirectory = "photonvision";
45
46 BindReadOnlyPaths = [
47 # mount the nix store read-only
48 "/nix/store"
49
50 # the JRE reads the user.home property from /etc/passwd
51 "/etc/passwd"
52 ];
53 BindPaths = [
54 # mount the configuration and logs directories to the host
55 "/var/lib/photonvision:/photonvision_config"
56 "/var/log/photonvision:/photonvision_config/logs"
57 ];
58
59 # for PhotonVision's dynamic libraries, which it writes to /tmp
60 PrivateTmp = true;
61 };
62 };
63
64 networking.firewall = lib.mkIf cfg.openFirewall {
65 allowedTCPPorts = [ 5800 ];
66 allowedTCPPortRanges = [
67 {
68 from = 1180;
69 to = 1190;
70 }
71 ];
72 };
73 };
74}