1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 inherit (lib) types;
10 cfg = config.services.ocis;
11 defaultUser = "ocis";
12 defaultGroup = defaultUser;
13in
14{
15 options = {
16 services.ocis = {
17 enable = lib.mkEnableOption "ownCloud Infinite Scale";
18
19 package = lib.mkOption {
20 type = types.package;
21 description = "Which package to use for the ownCloud Infinite Scale instance.";
22 relatedPackages = [ "ocis_5-bin" ];
23 };
24
25 configDir = lib.mkOption {
26 type = types.nullOr types.path;
27 default = null;
28 example = "/var/lib/ocis/config";
29 description = ''
30 Path to directory containing oCIS config file.
31
32 Example config can be generated by `ocis init --config-path fileName --admin-password "adminPass"`.
33 Add `--insecure true` if SSL certificates are generated and managed externally (e.g. using oCIS behind reverse proxy).
34
35 Note: This directory must contain at least a `ocis.yaml`. Ensure
36 [user](#opt-services.ocis.user) has read/write access to it. In some
37 circumstances you may need to add additional oCIS configuration files (e.g.,
38 `proxy.yaml`) to this directory.
39 '';
40 };
41
42 environmentFile = lib.mkOption {
43 type = types.nullOr types.path;
44 default = null;
45 example = "/run/keys/ocis.env";
46 description = ''
47 An environment file as defined in {manpage}`systemd.exec(5)`.
48
49 Configuration provided in this file will override those from [configDir](#opt-services.ocis.configDir)/ocis.yaml.
50 '';
51 };
52
53 user = lib.mkOption {
54 type = types.str;
55 default = defaultUser;
56 example = "yourUser";
57 description = ''
58 The user to run oCIS as.
59 By default, a user named `${defaultUser}` will be created whose home
60 directory is [stateDir](#opt-services.ocis.stateDir).
61 '';
62 };
63
64 group = lib.mkOption {
65 type = types.str;
66 default = defaultGroup;
67 example = "yourGroup";
68 description = ''
69 The group to run oCIS under.
70 By default, a group named `${defaultGroup}` will be created.
71 '';
72 };
73
74 address = lib.mkOption {
75 type = types.str;
76 default = "127.0.0.1";
77 description = "Web interface address.";
78 };
79
80 port = lib.mkOption {
81 type = types.port;
82 default = 9200;
83 description = "Web interface port.";
84 };
85
86 url = lib.mkOption {
87 type = types.str;
88 default = "https://localhost:9200";
89 example = "https://some-hostname-or-ip:9200";
90 description = "Web interface address.";
91 };
92
93 stateDir = lib.mkOption {
94 default = "/var/lib/ocis";
95 type = types.str;
96 description = "ownCloud data directory.";
97 };
98
99 environment = lib.mkOption {
100 type = types.attrsOf types.str;
101 default = { };
102 description = ''
103 Extra config options.
104
105 See [the documentation](https://doc.owncloud.com/ocis/next/deployment/services/services.html) for available options.
106 See [notes for environment variables](https://doc.owncloud.com/ocis/next/deployment/services/env-var-note.html) for more information.
107
108 Note that all the attributes here will be copied to /nix/store/ and will be world readable. Options like *_PASSWORD or *_SECRET should be part of [environmentFile](#opt-services.ocis.environmentFile) instead, and are only provided here for illustrative purpose.
109
110 Configuration here will override those from [environmentFile](#opt-services.ocis.environmentFile) and will have highest precedence, at the cost of security. Do NOT put security sensitive stuff here.
111 '';
112 example = {
113 OCIS_INSECURE = "false";
114 OCIS_LOG_LEVEL = "error";
115 OCIS_JWT_SECRET = "super_secret";
116 OCIS_TRANSFER_SECRET = "foo";
117 OCIS_MACHINE_AUTH_API_KEY = "foo";
118 OCIS_SYSTEM_USER_ID = "123";
119 OCIS_MOUNT_ID = "123";
120 OCIS_STORAGE_USERS_MOUNT_ID = "123";
121 GATEWAY_STORAGE_USERS_MOUNT_ID = "123";
122 CS3_ALLOW_INSECURE = "true";
123 OCIS_INSECURE_BACKENDS = "true";
124 TLS_INSECURE = "true";
125 TLS_SKIP_VERIFY_CLIENT_CERT = "true";
126 WEBDAV_ALLOW_INSECURE = "true";
127 IDP_TLS = "false";
128 GRAPH_APPLICATION_ID = "1234";
129 IDM_IDPSVC_PASSWORD = "password";
130 IDM_REVASVC_PASSWORD = "password";
131 IDM_SVC_PASSWORD = "password";
132 IDP_ISS = "https://localhost:9200";
133 OCIS_LDAP_BIND_PASSWORD = "password";
134 OCIS_SERVICE_ACCOUNT_ID = "foo";
135 OCIS_SERVICE_ACCOUNT_SECRET = "foo";
136 OCIS_SYSTEM_USER_API_KEY = "foo";
137 STORAGE_USERS_MOUNT_ID = "123";
138 };
139 };
140 };
141 };
142
143 config = lib.mkIf cfg.enable {
144 services.ocis.package = lib.mkDefault pkgs.ocis_5-bin;
145
146 users.users.${defaultUser} = lib.mkIf (cfg.user == defaultUser) {
147 group = cfg.group;
148 home = cfg.stateDir;
149 isSystemUser = true;
150 createHome = true;
151 description = "ownCloud Infinite Scale daemon user";
152 };
153
154 users.groups = lib.mkIf (cfg.group == defaultGroup) { ${defaultGroup} = { }; };
155
156 systemd = {
157 services.ocis = {
158 description = "ownCloud Infinite Scale Stack";
159 wantedBy = [ "multi-user.target" ];
160 environment = {
161 PROXY_HTTP_ADDR = "${cfg.address}:${toString cfg.port}";
162 OCIS_URL = cfg.url;
163 OCIS_CONFIG_DIR = if (cfg.configDir == null) then "${cfg.stateDir}/config" else cfg.configDir;
164 OCIS_BASE_DATA_PATH = cfg.stateDir;
165 } // cfg.environment;
166 serviceConfig = {
167 Type = "simple";
168 ExecStart = "${lib.getExe cfg.package} server";
169 WorkingDirectory = cfg.stateDir;
170 User = cfg.user;
171 Group = cfg.group;
172 Restart = "always";
173 EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile;
174 ReadWritePaths = [ cfg.stateDir ];
175 ReadOnlyPaths = [ cfg.configDir ];
176 MemoryDenyWriteExecute = true;
177 NoNewPrivileges = true;
178 PrivateTmp = true;
179 PrivateDevices = true;
180 ProtectSystem = "strict";
181 ProtectHome = true;
182 ProtectControlGroups = true;
183 ProtectKernelModules = true;
184 ProtectKernelTunables = true;
185 ProtectKernelLogs = true;
186 RestrictAddressFamilies = [
187 "AF_UNIX"
188 "AF_INET"
189 "AF_INET6"
190 "AF_NETLINK"
191 ];
192 RestrictNamespaces = true;
193 RestrictRealtime = true;
194 RestrictSUIDSGID = true;
195 LockPersonality = true;
196 SystemCallArchitectures = "native";
197 };
198 };
199 };
200 };
201
202 meta.maintainers = with lib.maintainers; [
203 bhankas
204 danth
205 ramblurr
206 ];
207}