summary refs log tree commit diff
path: root/nixos/modules/services/networking/pixiecore.nix
blob: d2642c82c2d3716a64c406d9a62895982565ac98 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.services.pixiecore;
in
{
  meta.maintainers = with maintainers; [ bbigras danderson ];

  options = {
    services.pixiecore = {
      enable = mkEnableOption "Pixiecore";

      openFirewall = mkOption {
        type = types.bool;
        default = false;
        description = ''
          Open ports (67, 69 UDP and 4011, 'port', 'statusPort' TCP) in the firewall for Pixiecore.
        '';
      };

      mode = mkOption {
        description = "Which mode to use";
        default = "boot";
        type = types.enum [ "api" "boot" ];
      };

      debug = mkOption {
        type = types.bool;
        default = false;
        description = "Log more things that aren't directly related to booting a recognized client";
      };

      dhcpNoBind = mkOption {
        type = types.bool;
        default = false;
        description = "Handle DHCP traffic without binding to the DHCP server port";
      };

      kernel = mkOption {
        type = types.str or types.path;
        default = "";
        description = "Kernel path. Ignored unless mode is set to 'boot'";
      };

      initrd = mkOption {
        type = types.str or types.path;
        default = "";
        description = "Initrd path. Ignored unless mode is set to 'boot'";
      };

      cmdLine = mkOption {
        type = types.str;
        default = "";
        description = "Kernel commandline arguments. Ignored unless mode is set to 'boot'";
      };

      listen = mkOption {
        type = types.str;
        default = "0.0.0.0";
        description = "IPv4 address to listen on";
      };

      port = mkOption {
        type = types.port;
        default = 80;
        description = "Port to listen on for HTTP";
      };

      statusPort = mkOption {
        type = types.port;
        default = 80;
        description = "HTTP port for status information (can be the same as --port)";
      };

      apiServer = mkOption {
        type = types.str;
        example = "localhost:8080";
        description = "host:port to connect to the API. Ignored unless mode is set to 'api'";
      };

      extraArguments = mkOption {
        type = types.listOf types.str;
        default = [];
        description = "Additional command line arguments to pass to Pixiecore";
      };
    };
  };

  config = mkIf cfg.enable {
    users.groups.pixiecore = {};
    users.users.pixiecore = {
      description = "Pixiecore daemon user";
      group = "pixiecore";
      isSystemUser = true;
    };

    networking.firewall = mkIf cfg.openFirewall {
      allowedTCPPorts = [ 4011 cfg.port cfg.statusPort ];
      allowedUDPPorts = [ 67 69 ];
    };

    systemd.services.pixiecore = {
      description = "Pixiecore server";
      after = [ "network.target"];
      wants = [ "network.target"];
      wantedBy = [ "multi-user.target"];
      serviceConfig = {
        User = "pixiecore";
        Restart = "always";
        AmbientCapabilities = [ "cap_net_bind_service" ] ++ optional cfg.dhcpNoBind "cap_net_raw";
        ExecStart =
          let
            argString =
              if cfg.mode == "boot"
              then [ "boot" cfg.kernel ]
                   ++ optional (cfg.initrd != "") cfg.initrd
                   ++ optionals (cfg.cmdLine != "") [ "--cmdline" cfg.cmdLine ]
              else [ "api" cfg.apiServer ];
          in
            ''
              ${pkgs.pixiecore}/bin/pixiecore \
                ${lib.escapeShellArgs argString} \
                ${optionalString cfg.debug "--debug"} \
                ${optionalString cfg.dhcpNoBind "--dhcp-no-bind"} \
                --listen-addr ${lib.escapeShellArg cfg.listen} \
                --port ${toString cfg.port} \
                --status-port ${toString cfg.statusPort} \
                ${escapeShellArgs cfg.extraArguments}
              '';
      };
    };
  };
}