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