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