1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.couchdb;
7 configFile = pkgs.writeText "couchdb.ini" (
8 ''
9 [couchdb]
10 database_dir = ${cfg.databaseDir}
11 uri_file = ${cfg.uriFile}
12 view_index_dir = ${cfg.viewIndexDir}
13 '' + (optionalString (cfg.adminPass != null) ''
14 [admins]
15 ${cfg.adminUser} = ${cfg.adminPass}
16 '' + ''
17 [chttpd]
18 '') +
19 ''
20 port = ${toString cfg.port}
21 bind_address = ${cfg.bindAddress}
22
23 [log]
24 file = ${cfg.logFile}
25 '');
26 executable = "${cfg.package}/bin/couchdb";
27
28in {
29
30 ###### interface
31
32 options = {
33
34 services.couchdb = {
35
36 enable = mkOption {
37 type = types.bool;
38 default = false;
39 description = ''
40 Whether to run CouchDB Server.
41 '';
42 };
43
44 package = mkOption {
45 type = types.package;
46 default = pkgs.couchdb;
47 defaultText = "pkgs.couchdb";
48 example = literalExample "pkgs.couchdb";
49 description = ''
50 CouchDB package to use.
51 '';
52 };
53
54 adminUser = mkOption {
55 type = types.str;
56 default = "admin";
57 description = ''
58 Couchdb (i.e. fauxton) account with permission for all dbs and
59 tasks.
60 '';
61 };
62
63 adminPass = mkOption {
64 type = types.nullOr types.str;
65 default = null;
66 description = ''
67 Couchdb (i.e. fauxton) account with permission for all dbs and
68 tasks.
69 '';
70 };
71
72 user = mkOption {
73 type = types.str;
74 default = "couchdb";
75 description = ''
76 User account under which couchdb runs.
77 '';
78 };
79
80 group = mkOption {
81 type = types.str;
82 default = "couchdb";
83 description = ''
84 Group account under which couchdb runs.
85 '';
86 };
87
88 # couchdb options: http://docs.couchdb.org/en/latest/config/index.html
89
90 databaseDir = mkOption {
91 type = types.path;
92 default = "/var/lib/couchdb";
93 description = ''
94 Specifies location of CouchDB database files (*.couch named). This
95 location should be writable and readable for the user the CouchDB
96 service runs as (couchdb by default).
97 '';
98 };
99
100 uriFile = mkOption {
101 type = types.path;
102 default = "/run/couchdb/couchdb.uri";
103 description = ''
104 This file contains the full URI that can be used to access this
105 instance of CouchDB. It is used to help discover the port CouchDB is
106 running on (if it was set to 0 (e.g. automatically assigned any free
107 one). This file should be writable and readable for the user that
108 runs the CouchDB service (couchdb by default).
109 '';
110 };
111
112 viewIndexDir = mkOption {
113 type = types.path;
114 default = "/var/lib/couchdb";
115 description = ''
116 Specifies location of CouchDB view index files. This location should
117 be writable and readable for the user that runs the CouchDB service
118 (couchdb by default).
119 '';
120 };
121
122 bindAddress = mkOption {
123 type = types.str;
124 default = "127.0.0.1";
125 description = ''
126 Defines the IP address by which CouchDB will be accessible.
127 '';
128 };
129
130 port = mkOption {
131 type = types.int;
132 default = 5984;
133 description = ''
134 Defined the port number to listen.
135 '';
136 };
137
138 logFile = mkOption {
139 type = types.path;
140 default = "/var/log/couchdb.log";
141 description = ''
142 Specifies the location of file for logging output.
143 '';
144 };
145
146 extraConfig = mkOption {
147 type = types.lines;
148 default = "";
149 description = ''
150 Extra configuration. Overrides any other cofiguration.
151 '';
152 };
153
154 configFile = mkOption {
155 type = types.path;
156 description = ''
157 Configuration file for persisting runtime changes. File
158 needs to be readable and writable from couchdb user/group.
159 '';
160 };
161
162 };
163
164 };
165
166 ###### implementation
167
168 config = mkIf config.services.couchdb.enable {
169
170 environment.systemPackages = [ cfg.package ];
171
172 services.couchdb.configFile = mkDefault "/var/lib/couchdb/local.ini";
173
174 systemd.tmpfiles.rules = [
175 "d '${dirOf cfg.uriFile}' - ${cfg.user} ${cfg.group} - -"
176 "f '${cfg.logFile}' - ${cfg.user} ${cfg.group} - -"
177 "d '${cfg.databaseDir}' - ${cfg.user} ${cfg.group} - -"
178 "d '${cfg.viewIndexDir}' - ${cfg.user} ${cfg.group} - -"
179 ];
180
181 systemd.services.couchdb = {
182 description = "CouchDB Server";
183 wantedBy = [ "multi-user.target" ];
184
185 preStart = ''
186 touch ${cfg.configFile}
187 '';
188
189 environment = {
190 # we are actually specifying 4 configuration files:
191 # 1. the preinstalled default.ini
192 # 2. the module configuration
193 # 3. the extraConfig from the module options
194 # 4. the locally writable config file, which couchdb itself writes to
195 ERL_FLAGS= ''-couch_ini ${cfg.package}/etc/default.ini ${configFile} ${pkgs.writeText "couchdb-extra.ini" cfg.extraConfig} ${cfg.configFile}'';
196 };
197
198 serviceConfig = {
199 User = cfg.user;
200 Group = cfg.group;
201 ExecStart = executable;
202 };
203 };
204
205 users.users.couchdb = {
206 description = "CouchDB Server user";
207 group = "couchdb";
208 uid = config.ids.uids.couchdb;
209 };
210
211 users.groups.couchdb.gid = config.ids.gids.couchdb;
212
213 };
214}