python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / misc / etebase-server.nix
blobc3723d188146b7ad1f3784f32a0660d61950c584
1 { config, pkgs, lib, ... }:
3 with lib;
5 let
6   cfg = config.services.etebase-server;
8   pythonEnv = pkgs.python3.withPackages (ps: with ps;
9     [ etebase-server daphne ]);
11   iniFmt = pkgs.formats.ini {};
13   configIni = iniFmt.generate "etebase-server.ini" cfg.settings;
15   defaultUser = "etebase-server";
18   imports = [
19     (mkRemovedOptionModule
20       [ "services" "etebase-server" "customIni" ]
21       "Set the option `services.etebase-server.settings' instead.")
22     (mkRemovedOptionModule
23       [ "services" "etebase-server" "database" ]
24       "Set the option `services.etebase-server.settings.database' instead.")
25     (mkRenamedOptionModule
26       [ "services" "etebase-server" "secretFile" ]
27       [ "services" "etebase-server" "settings" "secret_file" ])
28     (mkRenamedOptionModule
29       [ "services" "etebase-server" "host" ]
30       [ "services" "etebase-server" "settings" "allowed_hosts" "allowed_host1" ])
31   ];
33   options = {
34     services.etebase-server = {
35       enable = mkOption {
36         type = types.bool;
37         default = false;
38         example = true;
39         description = lib.mdDoc ''
40           Whether to enable the Etebase server.
42           Once enabled you need to create an admin user by invoking the
43           shell command `etebase-server createsuperuser` with
44           the user specified by the `user` option or a superuser.
45           Then you can login and create accounts on your-etebase-server.com/admin
46         '';
47       };
49       dataDir = mkOption {
50         type = types.str;
51         default = "/var/lib/etebase-server";
52         description = lib.mdDoc "Directory to store the Etebase server data.";
53       };
55       port = mkOption {
56         type = with types; nullOr port;
57         default = 8001;
58         description = lib.mdDoc "Port to listen on.";
59       };
61       openFirewall = mkOption {
62         type = types.bool;
63         default = false;
64         description = lib.mdDoc ''
65           Whether to open ports in the firewall for the server.
66         '';
67       };
69       unixSocket = mkOption {
70         type = with types; nullOr str;
71         default = null;
72         description = lib.mdDoc "The path to the socket to bind to.";
73         example = "/run/etebase-server/etebase-server.sock";
74       };
76       settings = mkOption {
77         type = lib.types.submodule {
78           freeformType = iniFmt.type;
80           options = {
81             global = {
82               debug = mkOption {
83                 type = types.bool;
84                 default = false;
85                 description = lib.mdDoc ''
86                   Whether to set django's DEBUG flag.
87                 '';
88               };
89               secret_file = mkOption {
90                 type = with types; nullOr str;
91                 default = null;
92                 description = lib.mdDoc ''
93                   The path to a file containing the secret
94                   used as django's SECRET_KEY.
95                 '';
96               };
97               static_root = mkOption {
98                 type = types.str;
99                 default = "${cfg.dataDir}/static";
100                 defaultText = literalExpression ''"''${config.services.etebase-server.dataDir}/static"'';
101                 description = lib.mdDoc "The directory for static files.";
102               };
103               media_root = mkOption {
104                 type = types.str;
105                 default = "${cfg.dataDir}/media";
106                 defaultText = literalExpression ''"''${config.services.etebase-server.dataDir}/media"'';
107                 description = lib.mdDoc "The media directory.";
108               };
109             };
110             allowed_hosts = {
111               allowed_host1 = mkOption {
112                 type = types.str;
113                 default = "0.0.0.0";
114                 example = "localhost";
115                 description = lib.mdDoc ''
116                   The main host that is allowed access.
117                 '';
118               };
119             };
120             database = {
121               engine = mkOption {
122                 type = types.enum [ "django.db.backends.sqlite3" "django.db.backends.postgresql" ];
123                 default = "django.db.backends.sqlite3";
124                 description = lib.mdDoc "The database engine to use.";
125               };
126               name = mkOption {
127                 type = types.str;
128                 default = "${cfg.dataDir}/db.sqlite3";
129                 defaultText = literalExpression ''"''${config.services.etebase-server.dataDir}/db.sqlite3"'';
130                 description = lib.mdDoc "The database name.";
131               };
132             };
133           };
134         };
135         default = {};
136         description = lib.mdDoc ''
137           Configuration for `etebase-server`. Refer to
138           <https://github.com/etesync/server/blob/master/etebase-server.ini.example>
139           and <https://github.com/etesync/server/wiki>
140           for details on supported values.
141         '';
142         example = {
143           global = {
144             debug = true;
145             media_root = "/path/to/media";
146           };
147           allowed_hosts = {
148             allowed_host2 = "localhost";
149           };
150         };
151       };
153       user = mkOption {
154         type = types.str;
155         default = defaultUser;
156         description = lib.mdDoc "User under which Etebase server runs.";
157       };
158     };
159   };
161   config = mkIf cfg.enable {
163     environment.systemPackages = with pkgs; [
164       (runCommand "etebase-server" {
165         nativeBuildInputs = [ makeWrapper ];
166       } ''
167         makeWrapper ${pythonEnv}/bin/etebase-server \
168           $out/bin/etebase-server \
169           --chdir ${escapeShellArg cfg.dataDir} \
170           --prefix ETEBASE_EASY_CONFIG_PATH : "${configIni}"
171       '')
172     ];
174     systemd.tmpfiles.rules = [
175       "d '${cfg.dataDir}' - ${cfg.user} ${config.users.users.${cfg.user}.group} - -"
176     ];
178     systemd.services.etebase-server = {
179       description = "An Etebase (EteSync 2.0) server";
180       after = [ "network.target" "systemd-tmpfiles-setup.service" ];
181       wantedBy = [ "multi-user.target" ];
182       serviceConfig = {
183         User = cfg.user;
184         Restart = "always";
185         WorkingDirectory = cfg.dataDir;
186       };
187       environment = {
188         PYTHONPATH = "${pythonEnv}/${pkgs.python3.sitePackages}";
189         ETEBASE_EASY_CONFIG_PATH = configIni;
190       };
191       preStart = ''
192         # Auto-migrate on first run or if the package has changed
193         versionFile="${cfg.dataDir}/src-version"
194         if [[ $(cat "$versionFile" 2>/dev/null) != ${pkgs.etebase-server} ]]; then
195           ${pythonEnv}/bin/etebase-server migrate --no-input
196           ${pythonEnv}/bin/etebase-server collectstatic --no-input --clear
197           echo ${pkgs.etebase-server} > "$versionFile"
198         fi
199       '';
200       script =
201         let
202           networking = if cfg.unixSocket != null
203           then "-u ${cfg.unixSocket}"
204           else "-b 0.0.0.0 -p ${toString cfg.port}";
205         in ''
206           cd "${pythonEnv}/lib/etebase-server";
207           ${pythonEnv}/bin/daphne ${networking} \
208             etebase_server.asgi:application
209         '';
210     };
212     users = optionalAttrs (cfg.user == defaultUser) {
213       users.${defaultUser} = {
214         isSystemUser = true;
215         group = defaultUser;
216         home = cfg.dataDir;
217       };
219       groups.${defaultUser} = {};
220     };
222     networking.firewall = mkIf cfg.openFirewall {
223       allowedTCPPorts = [ cfg.port ];
224     };
225   };