at 21.11-pre 3.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.pixiecore; 7in 8{ 9 meta.maintainers = with maintainers; [ bbigras danderson ]; 10 11 options = { 12 services.pixiecore = { 13 enable = mkEnableOption "Pixiecore"; 14 15 openFirewall = mkOption { 16 type = types.bool; 17 default = false; 18 description = '' 19 Open ports (67, 69 UDP and 4011, 'port', 'statusPort' TCP) in the firewall for Pixiecore. 20 ''; 21 }; 22 23 mode = mkOption { 24 description = "Which mode to use"; 25 default = "boot"; 26 type = types.enum [ "api" "boot" ]; 27 }; 28 29 debug = mkOption { 30 type = types.bool; 31 default = false; 32 description = "Log more things that aren't directly related to booting a recognized client"; 33 }; 34 35 dhcpNoBind = mkOption { 36 type = types.bool; 37 default = false; 38 description = "Handle DHCP traffic without binding to the DHCP server port"; 39 }; 40 41 kernel = mkOption { 42 type = types.str or types.path; 43 default = ""; 44 description = "Kernel path. Ignored unless mode is set to 'boot'"; 45 }; 46 47 initrd = mkOption { 48 type = types.str or types.path; 49 default = ""; 50 description = "Initrd path. Ignored unless mode is set to 'boot'"; 51 }; 52 53 cmdLine = mkOption { 54 type = types.str; 55 default = ""; 56 description = "Kernel commandline arguments. Ignored unless mode is set to 'boot'"; 57 }; 58 59 listen = mkOption { 60 type = types.str; 61 default = "0.0.0.0"; 62 description = "IPv4 address to listen on"; 63 }; 64 65 port = mkOption { 66 type = types.port; 67 default = 80; 68 description = "Port to listen on for HTTP"; 69 }; 70 71 statusPort = mkOption { 72 type = types.port; 73 default = 80; 74 description = "HTTP port for status information (can be the same as --port)"; 75 }; 76 77 apiServer = mkOption { 78 type = types.str; 79 example = "localhost:8080"; 80 description = "host:port to connect to the API. Ignored unless mode is set to 'api'"; 81 }; 82 83 extraArguments = mkOption { 84 type = types.listOf types.str; 85 default = []; 86 description = "Additional command line arguments to pass to Pixiecore"; 87 }; 88 }; 89 }; 90 91 config = mkIf cfg.enable { 92 users.groups.pixiecore = {}; 93 users.users.pixiecore = { 94 description = "Pixiecore daemon user"; 95 group = "pixiecore"; 96 isSystemUser = true; 97 }; 98 99 networking.firewall = mkIf cfg.openFirewall { 100 allowedTCPPorts = [ 4011 cfg.port cfg.statusPort ]; 101 allowedUDPPorts = [ 67 69 ]; 102 }; 103 104 systemd.services.pixiecore = { 105 description = "Pixiecore server"; 106 after = [ "network.target"]; 107 wants = [ "network.target"]; 108 wantedBy = [ "multi-user.target"]; 109 serviceConfig = { 110 User = "pixiecore"; 111 Restart = "always"; 112 AmbientCapabilities = [ "cap_net_bind_service" ] ++ optional cfg.dhcpNoBind "cap_net_raw"; 113 ExecStart = 114 let 115 argString = 116 if cfg.mode == "boot" 117 then [ "boot" cfg.kernel ] 118 ++ optional (cfg.initrd != "") cfg.initrd 119 ++ optionals (cfg.cmdLine != "") [ "--cmdline" cfg.cmdLine ] 120 else [ "api" cfg.apiServer ]; 121 in 122 '' 123 ${pkgs.pixiecore}/bin/pixiecore \ 124 ${lib.escapeShellArgs argString} \ 125 ${optionalString cfg.debug "--debug"} \ 126 ${optionalString cfg.dhcpNoBind "--dhcp-no-bind"} \ 127 --listen-addr ${lib.escapeShellArg cfg.listen} \ 128 --port ${toString cfg.port} \ 129 --status-port ${toString cfg.statusPort} \ 130 ${escapeShellArgs cfg.extraArguments} 131 ''; 132 }; 133 }; 134 }; 135}