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