summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/networking.nix12
-rw-r--r--nixos/modules/hardware/video/nvidia.nix5
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/programs/zsh/zsh-syntax-highlighting.nix37
-rw-r--r--nixos/modules/services/databases/postgresql.nix20
-rw-r--r--nixos/modules/services/monitoring/graphite.nix4
-rw-r--r--nixos/modules/services/network-filesystems/glusterfs.nix5
-rw-r--r--nixos/modules/services/networking/dnschain.nix16
-rw-r--r--nixos/modules/services/networking/i2pd.nix3
-rw-r--r--nixos/modules/services/networking/networkmanager.nix21
-rw-r--r--nixos/modules/services/networking/resilio.nix268
-rw-r--r--nixos/modules/services/search/elasticsearch.nix76
-rw-r--r--nixos/modules/services/x11/window-managers/qtile.nix2
14 files changed, 409 insertions, 63 deletions
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index ae30a710bf6f..d503f5a8b20e 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -222,13 +222,11 @@ in
             '' + cfg.extraResolvconfConf + ''
             '';
 
-      } // (optionalAttrs config.services.resolved.enable (
-        if dnsmasqResolve then {
-          "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
-        } else {
-          "resolv.conf".source = "/run/systemd/resolve/resolv.conf";
-        }
-      ));
+      } // optionalAttrs config.services.resolved.enable {
+        "resolv.conf".source = "/run/systemd/resolve/resolv.conf";
+      } // optionalAttrs (config.services.resolved.enable && dnsmasqResolve) {
+        "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
+      };
 
       networking.proxy.envVars =
         optionalAttrs (cfg.proxy.default != null) {
diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix
index 161ed9457af9..80abec95c03d 100644
--- a/nixos/modules/hardware/video/nvidia.nix
+++ b/nixos/modules/hardware/video/nvidia.nix
@@ -28,7 +28,7 @@ let
   nvidia_libs32 = (nvidiaForKernel pkgs_i686.linuxPackages).override { libsOnly = true; kernel = null; };
 
   nvidiaPackage = nvidia: pkgs:
-    if !nvidia.useGLVND then nvidia
+    if !nvidia.useGLVND then nvidia.out
     else pkgs.buildEnv {
       name = "nvidia-libs";
       paths = [ pkgs.libglvnd nvidia.out ];
@@ -56,7 +56,8 @@ in
     hardware.opengl.package = nvidiaPackage nvidia_x11 pkgs;
     hardware.opengl.package32 = nvidiaPackage nvidia_libs32 pkgs_i686;
 
-    environment.systemPackages = [ nvidia_x11.bin nvidia_x11.settings nvidia_x11.persistenced ];
+    environment.systemPackages = [ nvidia_x11.bin nvidia_x11.settings ]
+      ++ lib.filter (p: p != null) [ nvidia_x11.persistenced ];
 
     boot.extraModulePackages = [ nvidia_x11.bin ];
 
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index d217b3452fb5..d7459e3fe91c 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -294,6 +294,7 @@
       jackett = 276;
       aria2 = 277;
       clickhouse = 278;
+      rslsync = 279;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -557,6 +558,7 @@
       jackett = 276;
       aria2 = 277;
       clickhouse = 278;
+      rslsync = 279;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index cae081aa73f0..13924f7e507e 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -486,6 +486,7 @@
   ./services/networking/radvd.nix
   ./services/networking/rdnssd.nix
   ./services/networking/redsocks.nix
+  ./services/networking/resilio.nix
   ./services/networking/rpcbind.nix
   ./services/networking/sabnzbd.nix
   ./services/networking/searx.nix
diff --git a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
index 39176b287843..9452489e2fb4 100644
--- a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
+++ b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix
@@ -8,13 +8,7 @@ in
   {
     options = {
       programs.zsh.syntaxHighlighting = {
-        enable = mkOption {
-          default = false;
-          type = types.bool;
-          description = ''
-            Enable zsh-syntax-highlighting.
-          '';
-        };
+        enable = mkEnableOption "zsh-syntax-highlighting";
 
         highlighters = mkOption {
           default = [ "main" ];
@@ -38,13 +32,13 @@ in
         };
 
         patterns = mkOption {
-          default = [];
-          type = types.listOf(types.listOf(types.string));
+          default = {};
+          type = types.attrsOf types.string;
 
           example = literalExample ''
-            [
-              ["rm -rf *" "fg=white,bold,bg=red"]
-            ]
+            {
+              "rm -rf *" = "fg=white,bold,bg=red";
+            }
           '';
 
           description = ''
@@ -67,14 +61,17 @@ in
           "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})"
         }
 
-        ${optionalString (length(cfg.patterns) > 0)
-          (assert(elem "pattern" cfg.highlighters); (foldl (
-            a: b:
-              assert(length(b) == 2); ''
-                ${a}
-                ZSH_HIGHLIGHT_PATTERNS+=('${elemAt b 0}' '${elemAt b 1}')
-              ''
-          ) "") cfg.patterns)
+        ${let
+            n = attrNames cfg.patterns;
+          in
+            optionalString (length(n) > 0)
+              (assert(elem "pattern" cfg.highlighters); (foldl (
+                a: b:
+                  ''
+                    ${a}
+                    ZSH_HIGHLIGHT_PATTERNS+=('${b}' '${attrByPath [b] "" cfg.patterns}')
+                  ''
+              ) "") n)
         }
       '';
     };
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 24ef4637ec98..d06e03a52978 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -38,6 +38,10 @@ let
 
   pre84 = versionOlder (builtins.parseDrvName postgresql.name).version "8.4";
 
+  # NixOS traditionally used `root` as superuser, most other distros use `postgres`. From 17.09
+  # we also try to follow this standard
+  superuser = (if versionAtLeast config.system.stateVersion "17.09" then "postgres" else "root");
+
 in
 
 {
@@ -74,7 +78,7 @@ in
 
       dataDir = mkOption {
         type = types.path;
-        default = "/var/db/postgresql";
+        example = "/var/lib/postgresql/9.6";
         description = ''
           Data directory for PostgreSQL.
         '';
@@ -160,7 +164,13 @@ in
       # Note: when changing the default, make it conditional on
       # ‘system.stateVersion’ to maintain compatibility with existing
       # systems!
-      mkDefault (if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql95 else pkgs.postgresql94);
+      mkDefault (if versionAtLeast config.system.stateVersion "17.09" then pkgs.postgresql96
+            else if versionAtLeast config.system.stateVersion "16.03" then pkgs.postgresql95
+            else pkgs.postgresql94);
+
+    services.postgresql.dataDir =
+      mkDefault (if versionAtLeast config.system.stateVersion "17.09" then "/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}"
+                 else "/var/db/postgresql");
 
     services.postgresql.authentication = mkAfter
       ''
@@ -205,7 +215,7 @@ in
           ''
             # Initialise the database.
             if ! test -e ${cfg.dataDir}/PG_VERSION; then
-              initdb -U root
+              initdb -U ${superuser}
               # See postStart!
               touch "${cfg.dataDir}/.first_startup"
             fi
@@ -237,14 +247,14 @@ in
         # Wait for PostgreSQL to be ready to accept connections.
         postStart =
           ''
-            while ! psql --port=${toString cfg.port} postgres -c "" 2> /dev/null; do
+            while ! ${pkgs.sudo}/bin/sudo -u ${superuser} psql --port=${toString cfg.port} -d postgres -c "" 2> /dev/null; do
                 if ! kill -0 "$MAINPID"; then exit 1; fi
                 sleep 0.1
             done
 
             if test -e "${cfg.dataDir}/.first_startup"; then
               ${optionalString (cfg.initialScript != null) ''
-                psql -f "${cfg.initialScript}" --port=${toString cfg.port} postgres
+                ${pkgs.sudo}/bin/sudo -u ${superuser} psql -f "${cfg.initialScript}" --port=${toString cfg.port} -d postgres
               ''}
               rm -f "${cfg.dataDir}/.first_startup"
             fi
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index 6b24ac2c7c62..332a04634d06 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -488,9 +488,7 @@ in {
             # create index
             ${pkgs.python27Packages.graphite_web}/bin/build-index.sh
 
-            chown graphite:graphite ${cfg.dataDir}
-            chown graphite:graphite ${cfg.dataDir}/whisper
-            chown -R graphite:graphite ${cfg.dataDir}/log
+            chown -R graphite:graphite ${cfg.dataDir}
 
             touch ${dataDir}/db-created
           fi
diff --git a/nixos/modules/services/network-filesystems/glusterfs.nix b/nixos/modules/services/network-filesystems/glusterfs.nix
index a2f2c0339515..f7fed793066a 100644
--- a/nixos/modules/services/network-filesystems/glusterfs.nix
+++ b/nixos/modules/services/network-filesystems/glusterfs.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  inherit (pkgs) glusterfs;
+  inherit (pkgs) glusterfs rsync;
 
   cfg = config.services.glusterfs;
 
@@ -50,8 +50,11 @@ in
       after = [ "rpcbind.service" "network.target" "local-fs.target" ];
       before = [ "network-online.target" ];
 
+      # The copying of hooks is due to upstream bug https://bugzilla.redhat.com/show_bug.cgi?id=1452761
       preStart = ''
         install -m 0755 -d /var/log/glusterfs
+        mkdir -p /var/lib/glusterd/hooks/
+        ${rsync}/bin/rsync -a ${glusterfs}/var/lib/glusterd/hooks/ /var/lib/glusterd/hooks/
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/networking/dnschain.nix b/nixos/modules/services/networking/dnschain.nix
index b64929960576..ab7bbb15ad4f 100644
--- a/nixos/modules/services/networking/dnschain.nix
+++ b/nixos/modules/services/networking/dnschain.nix
@@ -17,7 +17,7 @@ let
     host = ${cfg.dns.address}
     port = ${toString cfg.dns.port}
     oldDNSMethod = NO_OLD_DNS
-    externalIP = ${cfg.dns.address}
+    externalIP = ${cfg.dns.externalAddress}
 
     [http]
     host = ${cfg.api.hostname}
@@ -47,8 +47,18 @@ in
         type = types.str;
         default = "127.0.0.1";
         description = ''
-          The IP address that will be used to reach this machine.
-          Leave this unchanged if you do not wish to directly expose the DNSChain resolver.
+          The IP address the DNSChain resolver will bind to.
+          Leave this unchanged if you do not wish to directly expose the resolver.
+        '';
+      };
+
+      dns.externalAddress = mkOption {
+        type = types.str;
+        default = cfg.dns.address;
+        description = ''
+           The IP address used by clients to reach the resolver and the value of
+           the <literal>namecoin.dns</literal> record. Set this in case the bind address
+           is not the actual IP address (e.g. the machine is behind a NAT).
         '';
       };
 
diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
index 4e176353fc28..7622f030f832 100644
--- a/nixos/modules/services/networking/i2pd.nix
+++ b/nixos/modules/services/networking/i2pd.nix
@@ -212,7 +212,8 @@ in
         type = with types; nullOr int;
         default = null;
         description = ''
-           Set a router bandwidth limit integer in kbps or letters: L (32), O (256), P (2048), X (>9000)
+           Set a router bandwidth limit integer in KBps.
+           If not set, i2pd defaults to 32KBps.
         '';
       };
 
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 876dbe1524e4..f8b7f26f5f2f 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -12,6 +12,7 @@ let
   configFile = writeText "NetworkManager.conf" ''
     [main]
     plugins=keyfile
+    dhcp=${cfg.dhcp}
     dns=${if cfg.useDnsmasq then "dnsmasq" else "default"}
 
     [keyfile]
@@ -21,7 +22,7 @@ let
       ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''}
 
     [logging]
-    level=WARN
+    level=${cfg.logLevel}
 
     [connection]
     ipv6.ip6-privacy=2
@@ -138,6 +139,22 @@ in {
         apply = list: (attrValues cfg.basePackages) ++ list;
       };
 
+      dhcp = mkOption {
+        type = types.enum [ "dhclient" "dhcpcd" "internal" ];
+        default = "dhclient";
+        description = ''
+          Which program (or internal library) should be used for DHCP.
+        '';
+      };
+
+      logLevel = mkOption {
+        type = types.enum [ "OFF" "ERR" "WARN" "INFO" "DEBUG" "TRACE" ];
+        default = "WARN";
+        description = ''
+          Set the default logging verbosity level.
+        '';
+      };
+
       appendNameservers = mkOption {
         type = types.listOf types.str;
         default = [];
@@ -181,7 +198,7 @@ in {
             };
 
             type = mkOption {
-              type = types.enum (attrNames dispatcherTypesSubdirMap); 
+              type = types.enum (attrNames dispatcherTypesSubdirMap);
               default = "basic";
               description = ''
                 Dispatcher hook type. Only basic hooks are currently available.
diff --git a/nixos/modules/services/networking/resilio.nix b/nixos/modules/services/networking/resilio.nix
new file mode 100644
index 000000000000..6d2b7bdbca1b
--- /dev/null
+++ b/nixos/modules/services/networking/resilio.nix
@@ -0,0 +1,268 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.resilio;
+
+  resilioSync = pkgs.resilio-sync;
+
+  sharedFoldersRecord = map (entry: {
+    secret = entry.secret;
+    dir = entry.directory;
+
+    use_relay_server = entry.useRelayServer;
+    use_tracker = entry.useTracker;
+    use_dht = entry.useDHT;
+
+    search_lan = entry.searchLAN;
+    use_sync_trash = entry.useSyncTrash;
+    known_hosts = knownHosts;
+  }) cfg.sharedFolders;
+
+  configFile = pkgs.writeText "config.json" (builtins.toJSON ({
+    device_name = cfg.deviceName;
+    storage_path = cfg.storagePath;
+    listening_port = cfg.listeningPort;
+    use_gui = false;
+    check_for_updates = cfg.checkForUpdates;
+    use_upnp = cfg.useUpnp;
+    download_limit = cfg.downloadLimit;
+    upload_limit = cfg.uploadLimit;
+    lan_encrypt_data = cfg.encryptLAN;
+  } // optionalAttrs cfg.enableWebUI {
+    webui = { listen = "${cfg.httpListenAddr}:${toString cfg.httpListenPort}"; } //
+      (optionalAttrs (cfg.httpLogin != "") { login = cfg.httpLogin; }) //
+      (optionalAttrs (cfg.httpPass != "") { password = cfg.httpPass; }) //
+      (optionalAttrs (cfg.apiKey != "") { api_key = cfg.apiKey; }) //
+      (optionalAttrs (cfg.directoryRoot != "") { directory_root = cfg.directoryRoot; });
+  } // optionalAttrs (sharedFoldersRecord != []) {
+    shared_folders = sharedFoldersRecord;
+  }));
+
+in
+{
+  options = {
+    services.resilio = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          If enabled, start the Resilio Sync daemon. Once enabled, you can
+          interact with the service through the Web UI, or configure it in your
+          NixOS configuration. Enabling the <literal>resilio</literal> service
+          also installs a systemd user unit which can be used to start
+          user-specific copies of the daemon. Once installed, you can use
+          <literal>systemctl --user start resilio</literal> as your user to start
+          the daemon using the configuration file located at
+          <literal>$HOME/.config/resilio-sync/config.json</literal>.
+        '';
+      };
+
+      deviceName = mkOption {
+        type = types.str;
+        example = "Voltron";
+        default = config.networking.hostName;
+        description = ''
+          Name of the Resilio Sync device.
+        '';
+      };
+
+      listeningPort = mkOption {
+        type = types.int;
+        default = 0;
+        example = 44444;
+        description = ''
+          Listening port. Defaults to 0 which randomizes the port.
+        '';
+      };
+
+      checkForUpdates = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Determines whether to check for updates and alert the user
+          about them in the UI.
+        '';
+      };
+
+      useUpnp = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Use Universal Plug-n-Play (UPnP)
+        '';
+      };
+
+      downloadLimit = mkOption {
+        type = types.int;
+        default = 0;
+        example = 1024;
+        description = ''
+          Download speed limit. 0 is unlimited (default).
+        '';
+      };
+
+      uploadLimit = mkOption {
+        type = types.int;
+        default = 0;
+        example = 1024;
+        description = ''
+          Upload speed limit. 0 is unlimited (default).
+        '';
+      };
+
+      httpListenAddr = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        example = "1.2.3.4";
+        description = ''
+          HTTP address to bind to.
+        '';
+      };
+
+      httpListenPort = mkOption {
+        type = types.int;
+        default = 9000;
+        description = ''
+          HTTP port to bind on.
+        '';
+      };
+
+      httpLogin = mkOption {
+        type = types.str;
+        example = "allyourbase";
+        default = "";
+        description = ''
+          HTTP web login username.
+        '';
+      };
+
+      httpPass = mkOption {
+        type = types.str;
+        example = "arebelongtous";
+        default = "";
+        description = ''
+          HTTP web login password.
+        '';
+      };
+
+      encryptLAN = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Encrypt LAN data.";
+      };
+
+      enableWebUI = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable Web UI for administration. Bound to the specified
+          <literal>httpListenAddress</literal> and
+          <literal>httpListenPort</literal>.
+          '';
+      };
+
+      storagePath = mkOption {
+        type = types.path;
+        default = "/var/lib/resilio-sync/";
+        description = ''
+          Where BitTorrent Sync will store it's database files (containing
+          things like username info and licenses). Generally, you should not
+          need to ever change this.
+        '';
+      };
+
+      apiKey = mkOption {
+        type = types.str;
+        default = "";
+        description = "API key, which enables the developer API.";
+      };
+
+      directoryRoot = mkOption {
+        type = types.str;
+        default = "";
+        example = "/media";
+        description = "Default directory to add folders in the web UI.";
+      };
+
+      sharedFolders = mkOption {
+        default = [];
+        example =
+          [ { secret         = "AHMYFPCQAHBM7LQPFXQ7WV6Y42IGUXJ5Y";
+              directory      = "/home/user/sync_test";
+              useRelayServer = true;
+              useTracker     = true;
+              useDHT         = false;
+              searchLAN      = true;
+              useSyncTrash   = true;
+              knownHosts     = [
+                "192.168.1.2:4444"
+                "192.168.1.3:4444"
+              ];
+            }
+          ];
+        description = ''
+          Shared folder list. If enabled, web UI must be
+          disabled. Secrets can be generated using <literal>rslsync
+          --generate-secret</literal>. Note that this secret will be
+          put inside the Nix store, so it is realistically not very
+          secret.
+
+          If you would like to be able to modify the contents of this
+          directories, it is recommended that you make your user a
+          member of the <literal>resilio</literal> group.
+
+          Directories in this list should be in the
+          <literal>resilio</literal> group, and that group must have
+          write access to the directory. It is also recommended that
+          <literal>chmod g+s</literal> is applied to the directory
+          so that any sub directories created will also belong to
+          the <literal>resilio</literal> group. Also,
+          <literal>setfacl -d -m group:resilio:rwx</literal> and
+          <literal>setfacl -m group:resilio:rwx</literal> should also
+          be applied so that the sub directories are writable by
+          the group.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    assertions =
+      [ { assertion = cfg.deviceName != "";
+          message   = "Device name cannot be empty.";
+        }
+        { assertion = cfg.enableWebUI -> cfg.sharedFolders == [];
+          message   = "If using shared folders, the web UI cannot be enabled.";
+        }
+        { assertion = cfg.apiKey != "" -> cfg.enableWebUI;
+          message   = "If you're using an API key, you must enable the web server.";
+        }
+      ];
+
+    users.extraUsers.rslsync = {
+      description     = "Resilio Sync Service user";
+      home            = cfg.storagePath;
+      createHome      = true;
+      uid             = config.ids.uids.rslsync;
+      group           = "rslsync";
+    };
+
+    users.extraGroups = [ { name = "rslsync"; } ];
+
+    systemd.services.resilio = with pkgs; {
+      description = "Resilio Sync Service";
+      wantedBy    = [ "multi-user.target" ];
+      after       = [ "network.target" "local-fs.target" ];
+      serviceConfig = {
+        Restart   = "on-abort";
+        UMask     = "0002";
+        User      = "rslsync";
+        ExecStart = ''
+          ${resilioSync}/bin/rslsync --nodaemon --config ${configFile}
+        '';
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix
index 574f74d547a5..c76c86b0cadc 100644
--- a/nixos/modules/services/search/elasticsearch.nix
+++ b/nixos/modules/services/search/elasticsearch.nix
@@ -5,13 +5,22 @@ with lib;
 let
   cfg = config.services.elasticsearch;
 
+  es5 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "5" >= 0;
+
   esConfig = ''
     network.host: ${cfg.listenAddress}
-    network.port: ${toString cfg.port}
-    network.tcp.port: ${toString cfg.tcp_port}
-    # TODO: find a way to enable security manager
-    security.manager.enabled: false
     cluster.name: ${cfg.cluster_name}
+
+    ${if es5 then ''
+      http.port: ${toString cfg.port}
+      transport.tcp.port: ${toString cfg.tcp_port}
+    '' else ''
+      network.port: ${toString cfg.port}
+      network.tcp.port: ${toString cfg.tcp_port}
+      # TODO: find a way to enable security manager
+      security.manager.enabled: false
+    ''}
+
     ${cfg.extraConf}
   '';
 
@@ -19,13 +28,18 @@ let
     name = "elasticsearch-config";
     paths = [
       (pkgs.writeTextDir "elasticsearch.yml" esConfig)
-      (pkgs.writeTextDir "logging.yml" cfg.logging)
+      (if es5 then (pkgs.writeTextDir "log4j2.properties" cfg.logging)
+              else (pkgs.writeTextDir "logging.yml" cfg.logging))
     ];
+    # Elasticsearch 5.x won't start when the scripts directory does not exist
+    postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/scripts" else "";
   };
 
   esPlugins = pkgs.buildEnv {
     name = "elasticsearch-plugins";
     paths = cfg.plugins;
+    # Elasticsearch 5.x won't start when the plugins directory does not exist
+    postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/plugins" else "";
   };
 
 in {
@@ -85,18 +99,30 @@ in {
 
     logging = mkOption {
       description = "Elasticsearch logging configuration.";
-      default = ''
-        rootLogger: INFO, console
-        logger:
-          action: INFO
-          com.amazonaws: WARN
-        appender:
-          console:
-            type: console
-            layout:
-              type: consolePattern
-              conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
-      '';
+      default =
+        if es5 then ''
+          logger.action.name = org.elasticsearch.action
+          logger.action.level = info
+
+          appender.console.type = Console
+          appender.console.name = console
+          appender.console.layout.type = PatternLayout
+          appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n
+
+          rootLogger.level = info
+          rootLogger.appenderRef.console.ref = console
+        '' else ''
+          rootLogger: INFO, console
+          logger:
+            action: INFO
+            com.amazonaws: WARN
+          appender:
+            console:
+              type: console
+              layout:
+                type: consolePattern
+                conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+        '';
       type = types.str;
     };
 
@@ -112,6 +138,12 @@ in {
       description = "Extra command line options for the elasticsearch launcher.";
       default = [];
       type = types.listOf types.str;
+    };
+
+    extraJavaOptions = mkOption {
+      description = "Extra command line options for Java.";
+      default = [];
+      type = types.listOf types.str;
       example = [ "-Djava.net.preferIPv4Stack=true" ];
     };
 
@@ -133,13 +165,21 @@ in {
       path = [ pkgs.inetutils ];
       environment = {
         ES_HOME = cfg.dataDir;
+        ES_JAVA_OPTS = toString ([ "-Des.path.conf=${configDir}" ] ++ cfg.extraJavaOptions);
       };
       serviceConfig = {
-        ExecStart = "${cfg.package}/bin/elasticsearch -Des.path.conf=${configDir} ${toString cfg.extraCmdLineOptions}";
+        ExecStart = "${cfg.package}/bin/elasticsearch ${toString cfg.extraCmdLineOptions}";
         User = "elasticsearch";
         PermissionsStartOnly = true;
+        LimitNOFILE = "1024000";
       };
       preStart = ''
+        # Only set vm.max_map_count if lower than ES required minimum
+        # This avoids conflict if configured via boot.kernel.sysctl
+        if [ `${pkgs.procps}/bin/sysctl -n vm.max_map_count` -lt 262144 ]; then
+          ${pkgs.procps}/bin/sysctl -w vm.max_map_count=262144
+        fi
+
         mkdir -m 0700 -p ${cfg.dataDir}
 
         # Install plugins
diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix
index 37f84f0903c3..ad3b65150b01 100644
--- a/nixos/modules/services/x11/window-managers/qtile.nix
+++ b/nixos/modules/services/x11/window-managers/qtile.nix
@@ -15,7 +15,7 @@ in
     services.xserver.windowManager.session = [{
       name = "qtile";
       start = ''
-        ${pkgs.qtile}/bin/qtile
+        ${pkgs.qtile}/bin/qtile &
         waitPID=$!
       '';
     }];