From 5c49a35534a9764e773e98fde23f2d4ba836aa47 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Tue, 22 Aug 2017 11:15:39 +0100 Subject: services: Add elasticsearch. --- gnu/services/databases.scm | 174 +++++++++++++++++++++++++++++++++++++++++++++ gnu/tests/databases.scm | 57 ++++++++++++++- 2 files changed, 230 insertions(+), 1 deletion(-) diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm index ec31489d48..6b365288a0 100644 --- a/gnu/services/databases.scm +++ b/gnu/services/databases.scm @@ -56,6 +56,19 @@ postgresql-service postgresql-service-type + + elasticsearch-configuration + elasticsearch-configuration? + elasticsearch-configuration-elasticsearch + elasticsearch-configuration-data-path + elasticsearch-configuration-logs-path + elasticsearch-configuration-port + elasticsearch-configuration-transport-port + elasticsearch-configuration-extra-config + + elasticsearch-service + elasticsearch-service-type + memcached-service-type memcached-configuration @@ -298,6 +311,167 @@ and stores the database cluster in @var{data-directory}." (data-directory data-directory) (extension-packages extension-packages)))) + +;;; +;;; Elasticsearch +;;; + +(define-record-type* + elasticsearch-configuration make-elasticsearch-configuration + elasticsearch-configuration? + (elasticsearch elasticsearch-configuration-elasticsearch + (default elasticsearch)) + (data-path elasticsearch-configuration-data-path + (default "/var/lib/")) + (logs-path elasticsearch-configuration-logs-path + (default "/var/log/elasticsearch")) + (http-port elasticsearch-configuration-port + (default 9200)) + (transport-port elasticsearch-configuration-transport-port + (default 9300)) + (extra-config elasticsearch-configuration-extra-config + (default '()))) + +(define (elasticsearch-configuration-directory data-path + logs-path + http-port + transport-port + extra-config) + (define contents + (append-map + (match-lambda + ((key) '()) + ((key . #f) '()) + ((key values ...) `(,key ": " ,@values "\n"))) + + `(("path.data" ,data-path) + ("path.logs" ,logs-path) + ("http.port" ,(number->string http-port)) + ("transport.tcp.port" ,(number->string transport-port)) + ,@extra-config))) + + (computed-file + "elasticsearch-config" + #~(begin + (mkdir #$output) + (mkdir (string-append #$output "/scripts")) + (call-with-output-file (string-append #$output "/log4j2.properties") + (lambda (port) + (display "" port))) + (call-with-output-file (string-append #$output "/jvm.options") + (lambda (port) + (display " +-Xms100m +-Xmx100m + +-XX:+UseConcMarkSweepGC +-XX:CMSInitiatingOccupancyFraction=75 +-XX:+UseCMSInitiatingOccupancyOnly + +## optimizations + +# pre-touch memory pages used by the JVM during initialization +-XX:+AlwaysPreTouch + +## basic + +# force the server VM (remove on 32-bit client JVMs) +-server + +# explicitly set the stack size (reduce to 320k on 32-bit client JVMs) +-Xss1m + +# set to headless, just in case +-Djava.awt.headless=true + +# ensure UTF-8 encoding by default (e.g. filenames) +-Dfile.encoding=UTF-8 + +# use our provided JNA always versus the system one +-Djna.nosys=true + +# use old-style file permissions on JDK9 +-Djdk.io.permissionsUseCanonicalPath=true + +# flags to configure Netty +-Dio.netty.noUnsafe=true +-Dio.netty.noKeySetOptimization=true +-Dio.netty.recycler.maxCapacityPerThread=0 + +# log4j 2 +-Dlog4j.shutdownHookEnabled=false +-Dlog4j2.disable.jmx=true +-Dlog4j.skipJansi=true +" port))) + (call-with-output-file (string-append #$output "/elasticsearch.yml") + (lambda (port) + (display + (string-append #$@contents) + port)))))) + +(define %elasticsearch-accounts + (list (user-group (name "elasticsearch") (system? #t)) + (user-account + (name "elasticsearch") + (group "elasticsearch") + (system? #t) + (comment "Elasticsearch server user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))) + +(define elasticsearch-activation + (match-lambda + (($ elasticsearch data-path logs-path + http-port transport-port) + #~(begin + (use-modules (guix build utils) + (ice-9 match)) + + (let ((user (getpwnam "elasticsearch"))) + ;; Create db state directory. + (for-each + (lambda (path) + (mkdir-p path) + (chown path (passwd:uid user) (passwd:gid user))) + '(#$data-path #$logs-path "/var/run/elasticsearch"))))))) + +(define elasticsearch-shepherd-service + (match-lambda + (($ elasticsearch data-path logs-path + http-port transport-port extra-config) + (list (shepherd-service + (provision '(elasticsearch)) + (documentation "Run the Elasticsearch daemon.") + (requirement '(user-processes syslogd)) + (start #~(let ((config-directory + #$(elasticsearch-configuration-directory + data-path logs-path http-port transport-port + extra-config))) + (make-forkexec-constructor + (list + (string-append #$elasticsearch "/bin/elasticsearch") + "-d" + "-p" "/var/run/elasticsearch/pid" + (string-append "-Epath.conf=" config-directory)) + #:user "elasticsearch" + #:pid-file "/var/run/elasticsearch/pid" + #:environment-variables + (list (string-append "ES_JVM_OPTIONS=" + config-directory "/jvm.options")) + #:log-file "/var/log/elasticsearch.log"))) + (stop #~(make-kill-destructor))))))) + +(define elasticsearch-service-type + (service-type (name 'elasticsearch) + (extensions + (list (service-extension shepherd-root-service-type + elasticsearch-shepherd-service) + (service-extension activation-service-type + elasticsearch-activation) + (service-extension account-service-type + (const %elasticsearch-accounts)))) + (default-value (elasticsearch-configuration)))) + ;;; ;;; Memcached diff --git a/gnu/tests/databases.scm b/gnu/tests/databases.scm index e0544bbcd2..eb6f3ec5cc 100644 --- a/gnu/tests/databases.scm +++ b/gnu/tests/databases.scm @@ -31,7 +31,8 @@ #:export (%test-memcached %test-mongodb %test-postgresql - %test-mysql)) + %test-mysql + %test-elasticsearch)) (define %memcached-os (simple-operating-system @@ -319,3 +320,57 @@ (name "mysql") (description "Start the MySQL service.") (value (run-mysql-test)))) + + +;;; +;;; The Elasticsearch service. +;;; + +(define %elasticsearch-os + (simple-operating-system + (service elasticsearch-service-type))) + +(define (run-elasticsearch-test) + "Run tests in %ELASTICSEARCH-OS." + (define os + (marionette-operating-system + %elasticsearch-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (memory-size 512))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-64) + (gnu build marionette)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "elasticsearch") + + (test-assert "service running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'elasticsearch)) + marionette)) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "elasticsearch-test" test)) + +(define %test-elasticsearch + (system-test + (name "elasticsearch") + (description "Start the Elasticsearch service.") + (value (run-elasticsearch-test)))) -- cgit v1.2.3