elk: add elasticsearch6, logstash6, kibana6 and the beats at v6.1.0

This change is backwards compatible since the ELK tools at version 5.x
remain unchanged.

The test suite now both tests ELK-5 and ELK-6.

+306 -85
+5 -3
nixos/modules/services/search/elasticsearch.nix
··· 6 6 cfg = config.services.elasticsearch; 7 7 8 8 es5 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "5" >= 0; 9 + es6 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "6" >= 0; 9 10 10 11 esConfig = '' 11 12 network.host: ${cfg.listenAddress} ··· 92 93 node.name: "elasticsearch" 93 94 node.master: true 94 95 node.data: false 95 - index.number_of_shards: 5 96 - index.number_of_replicas: 1 97 96 ''; 98 97 }; 99 98 ··· 165 164 path = [ pkgs.inetutils ]; 166 165 environment = { 167 166 ES_HOME = cfg.dataDir; 168 - ES_JAVA_OPTS = toString ([ "-Des.path.conf=${configDir}" ] ++ cfg.extraJavaOptions); 167 + ES_JAVA_OPTS = toString ( optional (!es6) [ "-Des.path.conf=${configDir}" ] 168 + ++ cfg.extraJavaOptions); 169 + } // optionalAttrs es6 { 170 + ES_PATH_CONF = configDir; 169 171 }; 170 172 serviceConfig = { 171 173 ExecStart = "${cfg.package}/bin/elasticsearch ${toString cfg.extraCmdLineOptions}";
+1 -1
nixos/release.nix
··· 260 260 tests.etcd = hydraJob (import tests/etcd.nix { system = "x86_64-linux"; }); 261 261 tests.ec2-nixops = hydraJob (import tests/ec2.nix { system = "x86_64-linux"; }).boot-ec2-nixops; 262 262 tests.ec2-config = hydraJob (import tests/ec2.nix { system = "x86_64-linux"; }).boot-ec2-config; 263 - tests.elk = hydraJob (import tests/elk.nix { system = "x86_64-linux"; }); 263 + tests.elk = callSubTests tests/elk.nix { system = "x86_64-linux"; }; 264 264 tests.env = callTest tests/env.nix {}; 265 265 tests.ferm = callTest tests/ferm.nix {}; 266 266 tests.firefox = callTest tests/firefox.nix {};
+92 -80
nixos/tests/elk.nix
··· 1 - # Test the ELK stack: Elasticsearch, Logstash and Kibana. 2 - 3 - import ./make-test.nix ({ pkgs, ...} : 1 + { system ? builtins.currentSystem }: 2 + with import ../lib/testing.nix { inherit system; }; 3 + with pkgs.lib; 4 4 let 5 5 esUrl = "http://localhost:9200"; 6 - in { 7 - name = "ELK"; 8 - meta = with pkgs.stdenv.lib.maintainers; { 9 - maintainers = [ eelco chaoflow offline basvandijk ]; 10 - }; 11 6 12 - nodes = { 13 - one = 14 - { config, pkgs, ... }: { 15 - # Not giving the machine at least 2060MB results in elasticsearch failing with the following error: 16 - # 17 - # OpenJDK 64-Bit Server VM warning: 18 - # INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) 19 - # failed; error='Cannot allocate memory' (errno=12) 20 - # 21 - # There is insufficient memory for the Java Runtime Environment to continue. 22 - # Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory. 23 - # 24 - # When setting this to 2500 I got "Kernel panic - not syncing: Out of 25 - # memory: compulsory panic_on_oom is enabled" so lets give it even a 26 - # bit more room: 27 - virtualisation.memorySize = 3000; 7 + mkElkTest = name : elk : makeTest { 8 + inherit name; 9 + meta = with pkgs.stdenv.lib.maintainers; { 10 + maintainers = [ eelco chaoflow offline basvandijk ]; 11 + }; 12 + nodes = { 13 + one = 14 + { config, pkgs, ... }: { 15 + # Not giving the machine at least 2060MB results in elasticsearch failing with the following error: 16 + # 17 + # OpenJDK 64-Bit Server VM warning: 18 + # INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) 19 + # failed; error='Cannot allocate memory' (errno=12) 20 + # 21 + # There is insufficient memory for the Java Runtime Environment to continue. 22 + # Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory. 23 + # 24 + # When setting this to 2500 I got "Kernel panic - not syncing: Out of 25 + # memory: compulsory panic_on_oom is enabled" so lets give it even a 26 + # bit more room: 27 + virtualisation.memorySize = 3000; 28 28 29 - # For querying JSON objects returned from elasticsearch and kibana. 30 - environment.systemPackages = [ pkgs.jq ]; 29 + # For querying JSON objects returned from elasticsearch and kibana. 30 + environment.systemPackages = [ pkgs.jq ]; 31 31 32 - services = { 33 - logstash = { 34 - enable = true; 35 - package = pkgs.logstash5; 36 - inputConfig = '' 37 - exec { command => "echo -n flowers" interval => 1 type => "test" } 38 - exec { command => "echo -n dragons" interval => 1 type => "test" } 39 - ''; 40 - filterConfig = '' 41 - if [message] =~ /dragons/ { 42 - drop {} 43 - } 44 - ''; 45 - outputConfig = '' 46 - file { 47 - path => "/tmp/logstash.out" 48 - codec => line { format => "%{message}" } 49 - } 50 - elasticsearch { 51 - hosts => [ "${esUrl}" ] 52 - } 53 - ''; 54 - }; 32 + services = { 33 + logstash = { 34 + enable = true; 35 + package = elk.logstash; 36 + inputConfig = '' 37 + exec { command => "echo -n flowers" interval => 1 type => "test" } 38 + exec { command => "echo -n dragons" interval => 1 type => "test" } 39 + ''; 40 + filterConfig = '' 41 + if [message] =~ /dragons/ { 42 + drop {} 43 + } 44 + ''; 45 + outputConfig = '' 46 + file { 47 + path => "/tmp/logstash.out" 48 + codec => line { format => "%{message}" } 49 + } 50 + elasticsearch { 51 + hosts => [ "${esUrl}" ] 52 + } 53 + ''; 54 + }; 55 55 56 - elasticsearch = { 57 - enable = true; 58 - package = pkgs.elasticsearch5; 59 - }; 56 + elasticsearch = { 57 + enable = true; 58 + package = elk.elasticsearch; 59 + }; 60 60 61 - kibana = { 62 - enable = true; 63 - package = pkgs.kibana5; 64 - elasticsearch.url = esUrl; 61 + kibana = { 62 + enable = true; 63 + package = elk.kibana; 64 + elasticsearch.url = esUrl; 65 + }; 65 66 }; 66 67 }; 67 - }; 68 - }; 68 + }; 69 69 70 - testScript = '' 71 - startAll; 70 + testScript = '' 71 + startAll; 72 72 73 - $one->waitForUnit("elasticsearch.service"); 73 + $one->waitForUnit("elasticsearch.service"); 74 74 75 - # Continue as long as the status is not "red". The status is probably 76 - # "yellow" instead of "green" because we are using a single elasticsearch 77 - # node which elasticsearch considers risky. 78 - # 79 - # TODO: extend this test with multiple elasticsearch nodes and see if the status turns "green". 80 - $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_cluster/health' | jq .status | grep -v red"); 75 + # Continue as long as the status is not "red". The status is probably 76 + # "yellow" instead of "green" because we are using a single elasticsearch 77 + # node which elasticsearch considers risky. 78 + # 79 + # TODO: extend this test with multiple elasticsearch nodes and see if the status turns "green". 80 + $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_cluster/health' | jq .status | grep -v red"); 81 81 82 - # Perform some simple logstash tests. 83 - $one->waitForUnit("logstash.service"); 84 - $one->waitUntilSucceeds("cat /tmp/logstash.out | grep flowers"); 85 - $one->waitUntilSucceeds("cat /tmp/logstash.out | grep -v dragons"); 82 + # Perform some simple logstash tests. 83 + $one->waitForUnit("logstash.service"); 84 + $one->waitUntilSucceeds("cat /tmp/logstash.out | grep flowers"); 85 + $one->waitUntilSucceeds("cat /tmp/logstash.out | grep -v dragons"); 86 86 87 - # See if kibana is healthy. 88 - $one->waitForUnit("kibana.service"); 89 - $one->waitUntilSucceeds("curl --silent --show-error 'http://localhost:5601/api/status' | jq .status.overall.state | grep green"); 87 + # See if kibana is healthy. 88 + $one->waitForUnit("kibana.service"); 89 + $one->waitUntilSucceeds("curl --silent --show-error 'http://localhost:5601/api/status' | jq .status.overall.state | grep green"); 90 90 91 - # See if logstash messages arive in elasticsearch. 92 - $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_search' -H 'Content-Type: application/json' -d '{\"query\" : { \"match\" : { \"message\" : \"flowers\"}}}' | jq .hits.total | grep -v 0"); 93 - $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_search' -H 'Content-Type: application/json' -d '{\"query\" : { \"match\" : { \"message\" : \"dragons\"}}}' | jq .hits.total | grep 0"); 94 - ''; 95 - }) 91 + # See if logstash messages arive in elasticsearch. 92 + $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_search' -H 'Content-Type: application/json' -d '{\"query\" : { \"match\" : { \"message\" : \"flowers\"}}}' | jq .hits.total | grep -v 0"); 93 + $one->waitUntilSucceeds("curl --silent --show-error '${esUrl}/_search' -H 'Content-Type: application/json' -d '{\"query\" : { \"match\" : { \"message\" : \"dragons\"}}}' | jq .hits.total | grep 0"); 94 + ''; 95 + }; 96 + in mapAttrs mkElkTest { 97 + "ELK-5" = { 98 + elasticsearch = pkgs.elasticsearch5; 99 + logstash = pkgs.logstash5; 100 + kibana = pkgs.kibana5; 101 + }; 102 + "ELK-6" = { 103 + elasticsearch = pkgs.elasticsearch6; 104 + logstash = pkgs.logstash6; 105 + kibana = pkgs.kibana6; 106 + }; 107 + }
+40
pkgs/development/tools/misc/kibana/6.x.nix
··· 1 + { stdenv, makeWrapper, fetchurl, elk6Version, nodejs, coreutils, which }: 2 + 3 + with stdenv.lib; 4 + let 5 + inherit (builtins) elemAt; 6 + info = splitString "-" stdenv.system; 7 + arch = elemAt info 0; 8 + plat = elemAt info 1; 9 + shas = { 10 + "x86_64-linux" = "08lkjj9h4ij25b53bgdz825j2ccymlllijbhv9kw1q1liv2irr34"; 11 + "x86_64-darwin" = "1iqzj01s9walj5arfdlw0dgbmrv6mjp64mch11rx5aybcafv4z9h"; 12 + }; 13 + in stdenv.mkDerivation rec { 14 + name = "kibana-${version}"; 15 + version = elk6Version; 16 + 17 + src = fetchurl { 18 + url = "https://artifacts.elastic.co/downloads/kibana/${name}-${plat}-${arch}.tar.gz"; 19 + sha256 = shas."${stdenv.system}" or (throw "Unknown architecture"); 20 + }; 21 + 22 + buildInputs = [ makeWrapper ]; 23 + 24 + installPhase = '' 25 + mkdir -p $out/libexec/kibana $out/bin 26 + mv * $out/libexec/kibana/ 27 + rm -r $out/libexec/kibana/node 28 + makeWrapper $out/libexec/kibana/bin/kibana $out/bin/kibana \ 29 + --prefix PATH : "${stdenv.lib.makeBinPath [ nodejs coreutils which ]}" 30 + sed -i 's@NODE=.*@NODE=${nodejs}/bin/node@' $out/libexec/kibana/bin/kibana 31 + ''; 32 + 33 + meta = { 34 + description = "Visualize logs and time-stamped data"; 35 + homepage = http://www.elasticsearch.org/overview/kibana; 36 + license = licenses.asl20; 37 + maintainers = with maintainers; [ offline rickynils basvandijk ]; 38 + platforms = with platforms; unix; 39 + }; 40 + }
+42
pkgs/misc/logging/beats/6.x.nix
··· 1 + { stdenv, fetchFromGitHub, elk6Version, buildGoPackage, libpcap }: 2 + 3 + let beat = package : extraArgs : buildGoPackage (rec { 4 + name = "${package}-${version}"; 5 + version = elk6Version; 6 + 7 + src = fetchFromGitHub { 8 + owner = "elastic"; 9 + repo = "beats"; 10 + rev = "v${version}"; 11 + sha256 = "0pp4in66byggcfmvf8yx0m1vra98cs77m7mbr45sdla4hinvaqar"; 12 + }; 13 + 14 + goPackagePath = "github.com/elastic/beats"; 15 + 16 + subPackages = [ package ]; 17 + 18 + meta = with stdenv.lib; { 19 + homepage = https://www.elastic.co/products/beats; 20 + license = licenses.asl20; 21 + maintainers = with maintainers; [ fadenb basvandijk ]; 22 + platforms = platforms.linux; 23 + }; 24 + } // extraArgs); 25 + in { 26 + filebeat = beat "filebeat" {meta.description = "Lightweight shipper for logfiles";}; 27 + heartbeat = beat "heartbeat" {meta.description = "Lightweight shipper for uptime monitoring";}; 28 + metricbeat = beat "metricbeat" {meta.description = "Lightweight shipper for metrics";}; 29 + packetbeat = beat "packetbeat" { 30 + buildInputs = [ libpcap ]; 31 + meta.description = "Network packet analyzer that ships data to Elasticsearch"; 32 + meta.longDescription = '' 33 + Packetbeat is an open source network packet analyzer that ships the 34 + data to Elasticsearch. 35 + 36 + Think of it like a distributed real-time Wireshark with a lot more 37 + analytics features. The Packetbeat shippers sniff the traffic between 38 + your application processes, parse on the fly protocols like HTTP, MySQL, 39 + PostgreSQL, Redis or Thrift and correlate the messages into transactions. 40 + ''; 41 + }; 42 + }
pkgs/misc/logging/beats/default.nix pkgs/misc/logging/beats/5.x.nix
+45
pkgs/servers/search/elasticsearch/6.x.nix
··· 1 + { stdenv, fetchurl, elk6Version, makeWrapper, jre_headless, utillinux, getopt }: 2 + 3 + with stdenv.lib; 4 + 5 + stdenv.mkDerivation rec { 6 + version = elk6Version; 7 + name = "elasticsearch-${version}"; 8 + 9 + src = fetchurl { 10 + url = "https://artifacts.elastic.co/downloads/elasticsearch/${name}.tar.gz"; 11 + sha256 = "1mq8lnpv5y82a7d8vxn5np6hrg2pys22v85l5l9jynk3k0kgwyf8"; 12 + }; 13 + 14 + patches = [ ./es-home-6.x.patch ]; 15 + 16 + postPatch = '' 17 + sed -i "s|ES_CLASSPATH=\"\$ES_HOME/lib/\*\"|ES_CLASSPATH=\"$out/lib/*\"|" ./bin/elasticsearch-env 18 + ''; 19 + 20 + buildInputs = [ makeWrapper jre_headless ] ++ 21 + (if (!stdenv.isDarwin) then [utillinux] else [getopt]); 22 + 23 + installPhase = '' 24 + mkdir -p $out 25 + cp -R bin config lib modules plugins $out 26 + 27 + chmod -x $out/bin/*.* 28 + 29 + wrapProgram $out/bin/elasticsearch \ 30 + ${if (!stdenv.isDarwin) 31 + then ''--prefix PATH : "${utillinux}/bin/"'' 32 + else ''--prefix PATH : "${getopt}/bin"''} \ 33 + --set JAVA_HOME "${jre_headless}" \ 34 + --set ES_JVM_OPTIONS "$out/config/jvm.options" 35 + 36 + wrapProgram $out/bin/elasticsearch-plugin --set JAVA_HOME "${jre_headless}" 37 + ''; 38 + 39 + meta = { 40 + description = "Open Source, Distributed, RESTful Search Engine"; 41 + license = licenses.asl20; 42 + platforms = platforms.unix; 43 + maintainers = with maintainers; [ apeschar basvandijk ]; 44 + }; 45 + }
+26
pkgs/servers/search/elasticsearch/es-home-6.x.patch
··· 1 + diff -Naur a/bin/elasticsearch-env b/bin/elasticsearch-env 2 + --- a/bin/elasticsearch-env 2017-12-12 13:31:51.000000000 +0100 3 + +++ b/bin/elasticsearch-env 2017-12-18 19:51:12.282809695 +0100 4 + @@ -19,18 +19,10 @@ 5 + fi 6 + done 7 + 8 + -# determine Elasticsearch home; to do this, we strip from the path until we find 9 + -# bin, and then strip bin (there is an assumption here that there is no nested 10 + -# directory under bin also named bin) 11 + -ES_HOME=`dirname "$SCRIPT"` 12 + - 13 + -# now make ES_HOME absolute 14 + -ES_HOME=`cd "$ES_HOME"; pwd` 15 + - 16 + -while [ "`basename "$ES_HOME"`" != "bin" ]; do 17 + - ES_HOME=`dirname "$ES_HOME"` 18 + -done 19 + -ES_HOME=`dirname "$ES_HOME"` 20 + +if [ -z "$ES_HOME" ]; then 21 + + echo "You must set the ES_HOME var" >&2 22 + + exit 1 23 + +fi 24 + 25 + # now set the classpath 26 + ES_CLASSPATH="$ES_HOME/lib/*"
+39
pkgs/tools/misc/logstash/6.x.nix
··· 1 + { stdenv, fetchurl, elk6Version, makeWrapper, jre }: 2 + 3 + stdenv.mkDerivation rec { 4 + version = elk6Version; 5 + name = "logstash-${version}"; 6 + 7 + src = fetchurl { 8 + url = "https://artifacts.elastic.co/downloads/logstash/${name}.tar.gz"; 9 + sha256 = "1s2w8d2siryg2wy8i9lwqbp4mjf1sv80lf3sllxwa2vqwsv6l64p"; 10 + }; 11 + 12 + dontBuild = true; 13 + dontPatchELF = true; 14 + dontStrip = true; 15 + dontPatchShebangs = true; 16 + 17 + buildInputs = [ 18 + makeWrapper jre 19 + ]; 20 + 21 + installPhase = '' 22 + mkdir -p $out 23 + cp -r {Gemfile*,modules,vendor,lib,bin,config,data,logstash-core,logstash-core-plugin-api} $out 24 + 25 + wrapProgram $out/bin/logstash \ 26 + --set JAVA_HOME "${jre}" 27 + 28 + wrapProgram $out/bin/logstash-plugin \ 29 + --set JAVA_HOME "${jre}" 30 + ''; 31 + 32 + meta = with stdenv.lib; { 33 + description = "Logstash is a data pipeline that helps you process logs and other event data from a variety of systems"; 34 + homepage = https://www.elastic.co/products/logstash; 35 + license = licenses.asl20; 36 + platforms = platforms.unix; 37 + maintainers = with maintainers; [ wjlroe offline basvandijk ]; 38 + }; 39 + }
+16 -1
pkgs/top-level/all-packages.nix
··· 741 741 742 742 bchunk = callPackage ../tools/cd-dvd/bchunk { }; 743 743 744 - inherit (callPackages ../misc/logging/beats { }) 744 + inherit (callPackages ../misc/logging/beats/5.x.nix { }) 745 745 filebeat 746 746 heartbeat 747 747 metricbeat 748 748 packetbeat; 749 + 750 + inherit (let beats6 = callPackages ../misc/logging/beats/6.x.nix { }; in { 751 + filebeat6 = beats6.filebeat; 752 + heartbeat6 = beats6.heartbeat; 753 + metricbeat6 = beats6.metricbeat; 754 + packetbeat6 = beats6.packetbeat; 755 + }) 756 + filebeat6 757 + heartbeat6 758 + metricbeat6 759 + packetbeat6; 749 760 750 761 bfr = callPackage ../tools/misc/bfr { }; 751 762 ··· 1949 1960 1950 1961 # The latest version used by elasticsearch, logstash, kibana and the the beats from elastic. 1951 1962 elk5Version = "5.6.5"; 1963 + elk6Version = "6.1.0"; 1952 1964 1953 1965 elasticsearch = callPackage ../servers/search/elasticsearch { }; 1954 1966 elasticsearch2 = callPackage ../servers/search/elasticsearch/2.x.nix { }; 1955 1967 elasticsearch5 = callPackage ../servers/search/elasticsearch/5.x.nix { }; 1968 + elasticsearch6 = callPackage ../servers/search/elasticsearch/6.x.nix { }; 1956 1969 1957 1970 elasticsearchPlugins = recurseIntoAttrs ( 1958 1971 callPackage ../servers/search/elasticsearch/plugins.nix { } ··· 2956 2969 2957 2970 kibana = callPackage ../development/tools/misc/kibana { }; 2958 2971 kibana5 = callPackage ../development/tools/misc/kibana/5.x.nix { }; 2972 + kibana6 = callPackage ../development/tools/misc/kibana/6.x.nix { }; 2959 2973 2960 2974 kismet = callPackage ../applications/networking/sniffers/kismet { }; 2961 2975 ··· 3022 3036 3023 3037 logstash = callPackage ../tools/misc/logstash { }; 3024 3038 logstash5 = callPackage ../tools/misc/logstash/5.x.nix { }; 3039 + logstash6 = callPackage ../tools/misc/logstash/6.x.nix { }; 3025 3040 3026 3041 logstash-contrib = callPackage ../tools/misc/logstash/contrib.nix { }; 3027 3042