| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  | with lib; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cfg = config.services.mongodb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mongodb = cfg.package; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |   mongoCnf = cfg: pkgs.writeText "mongodb.conf" | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |   ''
 | 
					
						
							| 
									
										
										
										
											2016-09-14 11:58:29 +09:00
										 |  |  |     net.bindIp: ${cfg.bind_ip} | 
					
						
							|  |  |  |     ${optionalString cfg.quiet "systemLog.quiet: true"} | 
					
						
							|  |  |  |     systemLog.destination: syslog | 
					
						
							|  |  |  |     storage.dbPath: ${cfg.dbpath} | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |     ${optionalString cfg.enableAuth "security.authorization: enabled"} | 
					
						
							| 
									
										
										
										
											2016-09-14 11:58:29 +09:00
										 |  |  |     ${optionalString (cfg.replSetName != "") "replication.replSetName: ${cfg.replSetName}"} | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |     ${cfg.extraConfig} | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |   '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### interface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.mongodb = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = "
 | 
					
						
							|  |  |  |           Whether to enable the MongoDB server. | 
					
						
							|  |  |  |         ";
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       package = mkOption { | 
					
						
							| 
									
										
										
										
											2013-03-22 21:11:15 +01:00
										 |  |  |         default = pkgs.mongodb; | 
					
						
							| 
									
										
										
										
											2016-01-17 19:34:55 +01:00
										 |  |  |         defaultText = "pkgs.mongodb"; | 
					
						
							| 
									
										
										
										
											2014-02-27 13:22:04 +01:00
										 |  |  |         type = types.package; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |         description = "
 | 
					
						
							|  |  |  |           Which MongoDB derivation to use. | 
					
						
							|  |  |  |         ";
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       user = mkOption { | 
					
						
							|  |  |  |         default = "mongodb"; | 
					
						
							|  |  |  |         description = "User account under which MongoDB runs"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       bind_ip = mkOption { | 
					
						
							|  |  |  |         default = "127.0.0.1"; | 
					
						
							|  |  |  |         description = "IP to bind to"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       quiet = mkOption { | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = "quieter output"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |       enableAuth = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = "Enable client authentication. Creates a default superuser with username root!"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       initialRootPassword = mkOption { | 
					
						
							|  |  |  |         type = types.nullOr types.string; | 
					
						
							|  |  |  |         default = null; | 
					
						
							|  |  |  |         description = "Password for the root user if auth is enabled."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |       dbpath = mkOption { | 
					
						
							|  |  |  |         default = "/var/db/mongodb"; | 
					
						
							|  |  |  |         description = "Location where MongoDB stores its files"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |       pidFile = mkOption { | 
					
						
							| 
									
										
										
										
											2018-12-19 22:35:49 +01:00
										 |  |  |         default = "/run/mongodb.pid"; | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |         description = "Location of MongoDB pid file"; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-01 10:54:08 +00:00
										 |  |  |       replSetName = mkOption { | 
					
						
							|  |  |  |         default = ""; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           If this instance is part of a replica set, set its name here. | 
					
						
							|  |  |  |           Otherwise, leave empty to run as single node. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       extraConfig = mkOption { | 
					
						
							|  |  |  |         default = ""; | 
					
						
							|  |  |  |         example = ''
 | 
					
						
							| 
									
										
										
										
											2016-09-14 11:58:29 +09:00
										 |  |  |           storage.journal.enabled: false | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2016-09-14 11:58:29 +09:00
										 |  |  |         description = "MongoDB extra configuration in YAML format"; | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       initialScript = mkOption { | 
					
						
							|  |  |  |         type = types.nullOr types.path; | 
					
						
							|  |  |  |         default = null; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           A file containing MongoDB statements to execute on first startup. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### implementation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf config.services.mongodb.enable { | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |     assertions = [ | 
					
						
							|  |  |  |       { assertion = !cfg.enableAuth || cfg.initialRootPassword != null; | 
					
						
							|  |  |  |         message = "`enableAuth` requires `initialRootPassword` to be set."; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.users.mongodb = mkIf (cfg.user == "mongodb") | 
					
						
							| 
									
										
										
										
											2013-11-07 11:25:14 +01:00
										 |  |  |       { name = "mongodb"; | 
					
						
							|  |  |  |         uid = config.ids.uids.mongodb; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |         description = "MongoDB server user"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 20:20:50 +01:00
										 |  |  |     environment.systemPackages = [ mongodb ]; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 12:33:18 +01:00
										 |  |  |     systemd.services.mongodb = | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |       { description = "MongoDB server"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 20:20:50 +01:00
										 |  |  |         wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  |         after = [ "network.target" ]; | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 20:20:50 +01:00
										 |  |  |         serviceConfig = { | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |           ExecStart = "${mongodb}/bin/mongod --config ${mongoCnf cfg} --fork --pidfilepath ${cfg.pidFile}"; | 
					
						
							| 
									
										
										
										
											2012-12-18 20:20:50 +01:00
										 |  |  |           User = cfg.user; | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |           PIDFile = cfg.pidFile; | 
					
						
							|  |  |  |           Type = "forking"; | 
					
						
							|  |  |  |           TimeoutStartSec=120; # intial creating of journal can take some time | 
					
						
							|  |  |  |           PermissionsStartOnly = true; | 
					
						
							| 
									
										
										
										
											2012-12-18 20:20:50 +01:00
										 |  |  |         }; | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |         preStart = let | 
					
						
							|  |  |  |           cfg_ = cfg // { enableAuth = false; bind_ip = "127.0.0.1"; }; | 
					
						
							|  |  |  |         in ''
 | 
					
						
							| 
									
										
										
										
											2015-02-23 20:39:33 +01:00
										 |  |  |           rm ${cfg.dbpath}/mongod.lock || true | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |           if ! test -e ${cfg.dbpath}; then | 
					
						
							|  |  |  |               install -d -m0700 -o ${cfg.user} ${cfg.dbpath} | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |               # See postStart! | 
					
						
							|  |  |  |               touch ${cfg.dbpath}/.first_startup | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |           fi | 
					
						
							|  |  |  |           if ! test -e ${cfg.pidFile}; then | 
					
						
							|  |  |  |               install -D -o ${cfg.user} /dev/null ${cfg.pidFile} | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |           fi '' + lib.optionalString cfg.enableAuth '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if ! test -e "${cfg.dbpath}/.auth_setup_complete"; then | 
					
						
							|  |  |  |             systemd-run --unit=mongodb-for-setup --uid=${cfg.user} ${mongodb}/bin/mongod --config ${mongoCnf cfg_} | 
					
						
							|  |  |  |             # wait for mongodb | 
					
						
							|  |  |  |             while ! ${mongodb}/bin/mongo --eval "db.version()" > /dev/null 2>&1; do sleep 0.1; done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ${mongodb}/bin/mongo <<EOF | 
					
						
							|  |  |  |             use admin | 
					
						
							|  |  |  |             db.createUser( | 
					
						
							|  |  |  |               { | 
					
						
							|  |  |  |                 user: "root", | 
					
						
							|  |  |  |                 pwd: "${cfg.initialRootPassword}", | 
					
						
							|  |  |  |                 roles: [ | 
					
						
							|  |  |  |                   { role: "userAdminAnyDatabase", db: "admin" }, | 
					
						
							|  |  |  |                   { role: "dbAdminAnyDatabase", db: "admin" }, | 
					
						
							|  |  |  |                   { role: "readWriteAnyDatabase", db: "admin" } | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           EOF | 
					
						
							|  |  |  |             touch "${cfg.dbpath}/.auth_setup_complete" | 
					
						
							|  |  |  |             systemctl stop mongodb-for-setup | 
					
						
							| 
									
										
										
										
											2014-09-16 10:24:35 +02:00
										 |  |  |           fi | 
					
						
							|  |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2019-05-25 11:09:30 +02:00
										 |  |  |         postStart = ''
 | 
					
						
							|  |  |  |             if test -e "${cfg.dbpath}/.first_startup"; then | 
					
						
							|  |  |  |               ${optionalString (cfg.initialScript != null) ''
 | 
					
						
							|  |  |  |                 ${mongodb}/bin/mongo -u root -p ${cfg.initialRootPassword} admin "${cfg.initialScript}" | 
					
						
							|  |  |  |               ''}
 | 
					
						
							|  |  |  |               rm -f "${cfg.dbpath}/.first_startup" | 
					
						
							|  |  |  |             fi | 
					
						
							|  |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2012-01-18 20:34:07 +00:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |