at 18.03-beta 6.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.elasticsearch; 7 8 es5 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "5" >= 0; 9 es6 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "6" >= 0; 10 11 esConfig = '' 12 network.host: ${cfg.listenAddress} 13 cluster.name: ${cfg.cluster_name} 14 15 ${if es5 then '' 16 http.port: ${toString cfg.port} 17 transport.tcp.port: ${toString cfg.tcp_port} 18 '' else '' 19 network.port: ${toString cfg.port} 20 network.tcp.port: ${toString cfg.tcp_port} 21 # TODO: find a way to enable security manager 22 security.manager.enabled: false 23 ''} 24 25 ${cfg.extraConf} 26 ''; 27 28 configDir = pkgs.buildEnv { 29 name = "elasticsearch-config"; 30 paths = [ 31 (pkgs.writeTextDir "elasticsearch.yml" esConfig) 32 (if es5 then (pkgs.writeTextDir "log4j2.properties" cfg.logging) 33 else (pkgs.writeTextDir "logging.yml" cfg.logging)) 34 ]; 35 # Elasticsearch 5.x won't start when the scripts directory does not exist 36 postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/scripts" else ""; 37 }; 38 39 esPlugins = pkgs.buildEnv { 40 name = "elasticsearch-plugins"; 41 paths = cfg.plugins; 42 # Elasticsearch 5.x won't start when the plugins directory does not exist 43 postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/plugins" else ""; 44 }; 45 46in { 47 48 ###### interface 49 50 options.services.elasticsearch = { 51 enable = mkOption { 52 description = "Whether to enable elasticsearch."; 53 default = false; 54 type = types.bool; 55 }; 56 57 package = mkOption { 58 description = "Elasticsearch package to use."; 59 default = pkgs.elasticsearch2; 60 defaultText = "pkgs.elasticsearch2"; 61 type = types.package; 62 }; 63 64 listenAddress = mkOption { 65 description = "Elasticsearch listen address."; 66 default = "127.0.0.1"; 67 type = types.str; 68 }; 69 70 port = mkOption { 71 description = "Elasticsearch port to listen for HTTP traffic."; 72 default = 9200; 73 type = types.int; 74 }; 75 76 tcp_port = mkOption { 77 description = "Elasticsearch port for the node to node communication."; 78 default = 9300; 79 type = types.int; 80 }; 81 82 cluster_name = mkOption { 83 description = "Elasticsearch name that identifies your cluster for auto-discovery."; 84 default = "elasticsearch"; 85 type = types.str; 86 }; 87 88 extraConf = mkOption { 89 description = "Extra configuration for elasticsearch."; 90 default = ""; 91 type = types.str; 92 example = '' 93 node.name: "elasticsearch" 94 node.master: true 95 node.data: false 96 ''; 97 }; 98 99 logging = mkOption { 100 description = "Elasticsearch logging configuration."; 101 default = 102 if es5 then '' 103 logger.action.name = org.elasticsearch.action 104 logger.action.level = info 105 106 appender.console.type = Console 107 appender.console.name = console 108 appender.console.layout.type = PatternLayout 109 appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n 110 111 rootLogger.level = info 112 rootLogger.appenderRef.console.ref = console 113 '' else '' 114 rootLogger: INFO, console 115 logger: 116 action: INFO 117 com.amazonaws: WARN 118 appender: 119 console: 120 type: console 121 layout: 122 type: consolePattern 123 conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n" 124 ''; 125 type = types.str; 126 }; 127 128 dataDir = mkOption { 129 type = types.path; 130 default = "/var/lib/elasticsearch"; 131 description = '' 132 Data directory for elasticsearch. 133 ''; 134 }; 135 136 extraCmdLineOptions = mkOption { 137 description = "Extra command line options for the elasticsearch launcher."; 138 default = []; 139 type = types.listOf types.str; 140 }; 141 142 extraJavaOptions = mkOption { 143 description = "Extra command line options for Java."; 144 default = []; 145 type = types.listOf types.str; 146 example = [ "-Djava.net.preferIPv4Stack=true" ]; 147 }; 148 149 plugins = mkOption { 150 description = "Extra elasticsearch plugins"; 151 default = []; 152 type = types.listOf types.package; 153 }; 154 155 }; 156 157 ###### implementation 158 159 config = mkIf cfg.enable { 160 systemd.services.elasticsearch = { 161 description = "Elasticsearch Daemon"; 162 wantedBy = [ "multi-user.target" ]; 163 after = [ "network.target" ]; 164 path = [ pkgs.inetutils ]; 165 environment = { 166 ES_HOME = cfg.dataDir; 167 ES_JAVA_OPTS = toString ( optional (!es6) [ "-Des.path.conf=${configDir}" ] 168 ++ cfg.extraJavaOptions); 169 } // optionalAttrs es6 { 170 ES_PATH_CONF = configDir; 171 }; 172 serviceConfig = { 173 ExecStart = "${cfg.package}/bin/elasticsearch ${toString cfg.extraCmdLineOptions}"; 174 User = "elasticsearch"; 175 PermissionsStartOnly = true; 176 LimitNOFILE = "1024000"; 177 }; 178 preStart = '' 179 ${optionalString (!config.boot.isContainer) '' 180 # Only set vm.max_map_count if lower than ES required minimum 181 # This avoids conflict if configured via boot.kernel.sysctl 182 if [ `${pkgs.procps}/bin/sysctl -n vm.max_map_count` -lt 262144 ]; then 183 ${pkgs.procps}/bin/sysctl -w vm.max_map_count=262144 184 fi 185 ''} 186 187 mkdir -m 0700 -p ${cfg.dataDir} 188 189 # Install plugins 190 ln -sfT ${esPlugins}/plugins ${cfg.dataDir}/plugins 191 ln -sfT ${cfg.package}/lib ${cfg.dataDir}/lib 192 ln -sfT ${cfg.package}/modules ${cfg.dataDir}/modules 193 if [ "$(id -u)" = 0 ]; then chown -R elasticsearch ${cfg.dataDir}; fi 194 ''; 195 }; 196 197 environment.systemPackages = [ cfg.package ]; 198 199 users = { 200 groups.elasticsearch.gid = config.ids.gids.elasticsearch; 201 users.elasticsearch = { 202 uid = config.ids.uids.elasticsearch; 203 description = "Elasticsearch daemon user"; 204 home = cfg.dataDir; 205 group = "elasticsearch"; 206 }; 207 }; 208 }; 209}