grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / misc / devpi-server.nix
blobad72a8ced69a3e27f9999058afff83a14bf2987d
2   pkgs,
3   lib,
4   config,
5   ...
6 }:
7 let
8   cfg = config.services.devpi-server;
10   secretsFileName = "devpi-secret-file";
12   stateDirName = "devpi";
14   runtimeDir = "/run/${stateDirName}";
15   serverDir = "/var/lib/${stateDirName}";
18   options.services.devpi-server = {
19     enable = lib.mkEnableOption "Devpi Server";
21     package = lib.mkPackageOption pkgs "devpi-server" { };
23     primaryUrl = lib.mkOption {
24       type = lib.types.str;
25       description = "Url for the primary node. Required option for replica nodes.";
26     };
28     replica = lib.mkOption {
29       type = lib.types.bool;
30       default = false;
31       description = ''
32         Run node as a replica.
33         Requires the secretFile option and the primaryUrl to be enabled.
34       '';
35     };
37     secretFile = lib.mkOption {
38       type = lib.types.nullOr lib.types.path;
39       default = null;
40       description = ''
41         Path to a shared secret file used for synchronization,
42         Required for all nodes in a replica/primary setup.
43       '';
44     };
46     host = lib.mkOption {
47       type = lib.types.str;
48       default = "localhost";
49       description = ''
50         domain/ip address to listen on
51       '';
52     };
54     port = lib.mkOption {
55       type = lib.types.port;
56       default = 3141;
57       description = "The port on which Devpi Server will listen.";
58     };
60     openFirewall = lib.mkEnableOption "opening the default ports in the firewall for Devpi Server";
61   };
63   config = lib.mkIf cfg.enable {
65     systemd.services.devpi-server = {
66       enable = true;
67       description = "devpi PyPI-compatible server";
68       documentation = [ "https://devpi.net/docs/devpi/devpi/stable/+d/index.html" ];
69       wants = [ "network-online.target" ];
70       wantedBy = [ "multi-user.target" ];
71       after = [ "network-online.target" ];
72       # Since at least devpi-server 6.10.0, devpi requires the secrets file to
73       # have 0600 permissions.
74       preStart =
75         ''
76           ${lib.optionalString (!isNull cfg.secretFile)
77             "install -Dm 0600 \${CREDENTIALS_DIRECTORY}/devpi-secret ${runtimeDir}/${secretsFileName}"
78           }
80           if [ -f ${serverDir}/.nodeinfo ]; then
81             # already initialized the package index, exit gracefully
82             exit 0
83           fi
84           ${cfg.package}/bin/devpi-init --serverdir ${serverDir} ''
85         + lib.optionalString cfg.replica "--role=replica --master-url=${cfg.primaryUrl}";
87       serviceConfig = {
88         LoadCredential = lib.mkIf (! isNull cfg.secretFile) [
89           "devpi-secret:${cfg.secretFile}"
90         ];
91         Restart = "always";
92         ExecStart =
93           let
94             args =
95               [
96                 "--request-timeout=5"
97                 "--serverdir=${serverDir}"
98                 "--host=${cfg.host}"
99                 "--port=${builtins.toString cfg.port}"
100               ]
101               ++ lib.optionals (! isNull cfg.secretFile) [
102                 "--secretfile=${runtimeDir}/${secretsFileName}"
103               ]
104               ++ (
105                 if cfg.replica then
106                   [
107                     "--role=replica"
108                     "--master-url=${cfg.primaryUrl}"
109                   ]
110                 else
111                   [ "--role=master" ]
112               );
113           in
114           "${cfg.package}/bin/devpi-server ${lib.concatStringsSep " " args}";
115         DynamicUser = true;
116         StateDirectory = stateDirName;
117         RuntimeDirectory = stateDirName;
118         PrivateDevices = true;
119         PrivateTmp = true;
120         ProtectHome = true;
121         ProtectSystem = "strict";
122       };
123     };
125     networking.firewall = lib.mkIf cfg.openFirewall {
126       allowedTCPPorts = [ cfg.port ];
127     };
129     meta.maintainers = [ lib.maintainers.cafkafk ];
130   };