diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-09-18 22:28:35 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-09-18 22:28:35 +0200 |
commit | 91ec6e0d90073b9ca3d8931261142bda12a29093 (patch) | |
tree | 3c083a5d153c7fa928505da807b61d7719f91390 /nixos | |
parent | f32e964cc44de8b4259873be383f6ba60af4ec1e (diff) | |
parent | aa67e95bb5845323ed1b4b9c516b6efb762fc243 (diff) | |
download | nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar.gz nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar.bz2 nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar.lz nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar.xz nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.tar.zst nixlib-91ec6e0d90073b9ca3d8931261142bda12a29093.zip |
Merge remote-tracking branch 'origin/master' into staging
Diffstat (limited to 'nixos')
25 files changed, 832 insertions, 328 deletions
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix index fb5715022b78..297b3a82d6c1 100644 --- a/nixos/modules/config/pulseaudio.nix +++ b/nixos/modules/config/pulseaudio.nix @@ -71,8 +71,7 @@ in { }; configFile = mkOption { - type = types.uniq types.path; - default = "${cfg.package}/etc/pulse/default.pa"; + type = types.path; description = '' The path to the configuration the PulseAudio server should use. By default, the "default.pa" configuration @@ -112,6 +111,8 @@ in { target = "pulse/client.conf"; source = clientConf; }; + + hardware.pulseaudio.configFile = mkDefault "${cfg.package}/etc/pulse/default.pa"; } (mkIf cfg.enable { diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 37531ad1cdfd..cdce7d1a893e 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -151,6 +151,7 @@ dnsmasq = 141; uhub = 142; yandexdisk=143; + collectd=144; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e40d08c8ecfe..25827656608d 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -85,7 +85,8 @@ ./services/amqp/activemq/default.nix ./services/amqp/rabbitmq.nix ./services/audio/alsa.nix - ./services/audio/fuppes.nix + # Disabled as fuppes it does no longer builds. + # ./services/audio/fuppes.nix ./services/audio/mpd.nix ./services/audio/mopidy.nix ./services/backup/almir.nix @@ -178,6 +179,7 @@ ./services/misc/uhub.nix ./services/misc/zookeeper.nix ./services/monitoring/apcupsd.nix + ./services/monitoring/collectd.nix ./services/monitoring/dd-agent.nix ./services/monitoring/graphite.nix ./services/monitoring/monit.nix diff --git a/nixos/modules/services/amqp/rabbitmq.nix b/nixos/modules/services/amqp/rabbitmq.nix index a930098bfeec..77487ec1ab91 100644 --- a/nixos/modules/services/amqp/rabbitmq.nix +++ b/nixos/modules/services/amqp/rabbitmq.nix @@ -89,6 +89,8 @@ in { wantedBy = [ "multi-user.target" ]; after = [ "network-interfaces.target" ]; + path = [ pkgs.rabbitmq_server ]; + environment = { RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia"; RABBITMQ_NODE_IP_ADDRESS = cfg.listenAddress; @@ -119,6 +121,8 @@ in { mkdir -p /var/log/rabbitmq && chmod 0700 /var/log/rabbitmq chown rabbitmq:rabbitmq /var/log/rabbitmq ''; + + postStart = mkBefore "until rabbitmqctl status; do sleep 1; done"; }; }; diff --git a/nixos/modules/services/databases/influxdb.nix b/nixos/modules/services/databases/influxdb.nix index 61fe96d5d641..b57ccebae16e 100644 --- a/nixos/modules/services/databases/influxdb.nix +++ b/nixos/modules/services/databases/influxdb.nix @@ -224,6 +224,11 @@ in mkdir -m 0770 -p ${cfg.dataDir} if [ "$(id -u)" = 0 ]; then chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}; fi ''; + postStart = mkBefore '' + until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.bindAddress}:${toString cfg.apiPort}/'; do + sleep 1; + done + ''; }; users.extraUsers = optional (cfg.user == "influxdb") { diff --git a/nixos/modules/services/databases/mongodb.nix b/nixos/modules/services/databases/mongodb.nix index fe82ca430e13..02e44ad88704 100644 --- a/nixos/modules/services/databases/mongodb.nix +++ b/nixos/modules/services/databases/mongodb.nix @@ -15,9 +15,11 @@ let bind_ip = ${cfg.bind_ip} ${optionalString cfg.quiet "quiet = true"} dbpath = ${cfg.dbpath} - logpath = ${cfg.logpath} - logappend = ${b2s cfg.logappend} + syslog = true + fork = true + pidfilepath = ${cfg.pidFile} ${optionalString (cfg.replSetName != "") "replSet = ${cfg.replSetName}"} + ${cfg.extraConfig} ''; in @@ -65,14 +67,9 @@ in description = "Location where MongoDB stores its files"; }; - logpath = mkOption { - default = "/var/log/mongodb/mongod.log"; - description = "Location where MongoDB stores its logfile"; - }; - - logappend = mkOption { - default = true; - description = "Append logfile instead over overwriting"; + pidFile = mkOption { + default = "/var/run/mongodb.pid"; + description = "Location of MongoDB pid file"; }; replSetName = mkOption { @@ -82,6 +79,14 @@ in Otherwise, leave empty to run as single node. ''; }; + + extraConfig = mkOption { + default = ""; + example = '' + nojournal = true + ''; + description = "MongoDB extra configuration"; + }; }; }; @@ -99,22 +104,6 @@ in environment.systemPackages = [ mongodb ]; - systemd.services.mongodb_init = - { description = "MongoDB server initialisation"; - - wantedBy = [ "mongodb.service" ]; - before = [ "mongodb.service" ]; - - serviceConfig.Type = "oneshot"; - - script = '' - if ! test -e ${cfg.dbpath}; then - install -d -m0700 -o ${cfg.user} ${cfg.dbpath} - install -d -m0755 -o ${cfg.user} `dirname ${cfg.logpath}` - fi - ''; - }; - systemd.services.mongodb = { description = "MongoDB server"; @@ -124,7 +113,20 @@ in serviceConfig = { ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}"; User = cfg.user; + PIDFile = cfg.pidFile; + Type = "forking"; + TimeoutStartSec=120; # intial creating of journal can take some time + PermissionsStartOnly = true; }; + + preStart = '' + if ! test -e ${cfg.dbpath}; then + install -d -m0700 -o ${cfg.user} ${cfg.dbpath} + fi + if ! test -e ${cfg.pidFile}; then + install -D -o ${cfg.user} /dev/null ${cfg.pidFile} + fi + ''; }; }; diff --git a/nixos/modules/services/hardware/pommed.nix b/nixos/modules/services/hardware/pommed.nix index 04db46999b0a..a24557b40ba1 100644 --- a/nixos/modules/services/hardware/pommed.nix +++ b/nixos/modules/services/hardware/pommed.nix @@ -4,30 +4,34 @@ with lib; { - options.services.hardware.pommed = { - enable = mkOption { - default = false; - description = '' - Whether to use the pommed tool to handle Apple laptop keyboard hotkeys. - ''; + options = { + + services.hardware.pommed = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to use the pommed tool to handle Apple laptop keyboard hotkeys. + ''; + }; + + configFile = mkOption { + type = types.path; + description = '' + The path to the <filename>pommed.conf</filename> file. + ''; + }; }; - configFile = mkOption { - default = "${pkgs.pommed}/etc/pommed.conf"; - description = '' - The contents of the pommed.conf file. - ''; - }; }; config = mkIf config.services.hardware.pommed.enable { environment.systemPackages = [ pkgs.polkit ]; - environment.etc = [ - { source = config.services.hardware.pommed.configFile; - target = "pommed.conf"; - } - ]; + environment.etc."pommed.conf".source = config.services.hardware.pommed.configFile; + + services.hardware.pommed.configFile = "${pkgs.pommed}/etc/pommed.conf"; services.dbus.packages = [ pkgs.pommed ]; diff --git a/nixos/modules/services/logging/syslog-ng.nix b/nixos/modules/services/logging/syslog-ng.nix index 0b3f0cabb007..4a16b19134a0 100644 --- a/nixos/modules/services/logging/syslog-ng.nix +++ b/nixos/modules/services/logging/syslog-ng.nix @@ -18,7 +18,7 @@ let syslogngOptions = [ "--foreground" - "--module-path=${concatStringsSep ":" (["${pkgs.syslogng}/lib/syslog-ng"] ++ cfg.extraModulePaths)}" + "--module-path=${concatStringsSep ":" (["${cfg.package}/lib/syslog-ng"] ++ cfg.extraModulePaths)}" "--cfgfile=${syslogngConfig}" "--control=${ctrlSocket}" "--persist-file=${persistFile}" @@ -37,6 +37,13 @@ in { Whether to enable the syslog-ng daemon. ''; }; + package = mkOption { + type = types.package; + default = pkgs.syslogng; + description = '' + The package providing syslog-ng binaries. + ''; + }; serviceName = mkOption { type = types.str; default = "syslog-ng"; @@ -77,7 +84,7 @@ in { Sockets = "syslog.socket"; StandardOutput = "null"; Restart = "on-failure"; - ExecStart = "${pkgs.syslogng}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}"; + ExecStart = "${cfg.package}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}"; }; }; }; diff --git a/nixos/modules/services/monitoring/collectd.nix b/nixos/modules/services/monitoring/collectd.nix new file mode 100644 index 000000000000..717c2c481683 --- /dev/null +++ b/nixos/modules/services/monitoring/collectd.nix @@ -0,0 +1,116 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.collectd; + + conf = pkgs.writeText "collectd.conf" '' + BaseDir "${cfg.dataDir}" + PIDFile "${cfg.pidFile}" + AutoLoadPlugin ${if cfg.autoLoadPlugin then "true" else "false"} + Hostname ${config.networking.hostName} + + LoadPlugin syslog + <Plugin "syslog"> + LogLevel "info" + NotifyLevel "OKAY" + </Plugin> + + ${concatMapStrings (f: '' + Include "${f}" + '') cfg.include} + + ${cfg.extraConfig} + ''; + +in { + options.services.collectd = with types; { + enable = mkOption { + default = false; + description = '' + Whether to enable collectd agent. + ''; + type = bool; + }; + + user = mkOption { + default = "collectd"; + description = '' + User under which to run collectd. + ''; + type = nullOr str; + }; + + dataDir = mkOption { + default = "/var/lib/collectd"; + description = '' + Data directory for collectd agent. + ''; + type = path; + }; + + pidFile = mkOption { + default = "/var/run/collectd.pid"; + description = '' + Location of collectd pid file. + ''; + type = path; + }; + + autoLoadPlugin = mkOption { + default = false; + description = '' + Enable plugin autoloading. + ''; + type = bool; + }; + + include = mkOption { + default = []; + description = '' + Additional paths to load config from. + ''; + type = listOf str; + }; + + extraConfig = mkOption { + default = ""; + description = '' + Extra configuration for collectd. + ''; + type = lines; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.collectd = { + description = "Collectd Monitoring Agent"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = "${pkgs.collectd}/sbin/collectd -C ${conf} -P ${cfg.pidFile}"; + Type = "forking"; + PIDFile = cfg.pidFile; + User = optional (cfg.user!="root") cfg.user; + PermissionsStartOnly = true; + }; + + preStart = '' + mkdir -m 0700 -p ${cfg.dataDir} + install -D /dev/null ${cfg.pidFile} + if [ "$(id -u)" = 0 ]; then + chown -R ${cfg.user} ${cfg.dataDir}; + chown ${cfg.user} ${cfg.pidFile} + fi + ''; + }; + + users.extraUsers = optional (cfg.user == "collectd") { + name = "collectd"; + uid = config.ids.uids.collectd; + }; + }; +} diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix index dbfe0ee182a0..3d97c31b7a17 100644 --- a/nixos/modules/services/monitoring/graphite.nix +++ b/nixos/modules/services/monitoring/graphite.nix @@ -8,6 +8,22 @@ let dataDir = cfg.dataDir; + graphiteApiConfig = pkgs.writeText "graphite-api.yaml" '' + time_zone: ${config.time.timeZone} + search_index: ${dataDir}/index + ${optionalString (cfg.api.finders != []) ''finders:''} + ${concatMapStringsSep "\n" (f: " - " + f.moduleName) cfg.api.finders} + ${optionalString (cfg.api.functions != []) ''functions:''} + ${concatMapStringsSep "\n" (f: " - " + f) cfg.api.functions} + ${cfg.api.extraConfig} + ''; + + seyrenConfig = { + SEYREN_URL = cfg.seyren.seyrenUrl; + MONGO_URL = cfg.seyren.mongoUrl; + GRAPHITE_URL = cfg.seyren.graphiteUrl; + } // cfg.seyren.extraConfig; + configDir = pkgs.buildEnv { name = "graphite-config"; paths = lists.filter (el: el != null) [ @@ -65,6 +81,72 @@ in { }; }; + api = { + enable = mkOption { + description = "Whether to enable graphite api."; + default = false; + type = types.uniq types.bool; + }; + + finders = mkOption { + description = "List of finder plugins load."; + default = []; + example = [ pkgs.python27Packages.graphite_influxdb ]; + type = types.listOf types.package; + }; + + functions = mkOption { + description = "List of functions to load."; + default = [ + "graphite_api.functions.SeriesFunctions" + "graphite_api.functions.PieFunctions" + ]; + type = types.listOf types.str; + }; + + host = mkOption { + description = "Graphite web service listen address."; + default = "127.0.0.1"; + type = types.str; + }; + + port = mkOption { + description = "Graphite api service port."; + default = 8080; + type = types.int; + }; + + package = mkOption { + description = "Package to use for graphite api."; + default = pkgs.python27Packages.graphite_api; + type = types.package; + }; + + extraConfig = mkOption { + description = "Extra configuration for graphite api."; + default = '' + whisper: + directories: + - ${dataDir}/whisper + ''; + example = literalExample '' + allowed_origins: + - dashboard.example.com + cheat_times: true + influxdb: + host: localhost + port: 8086 + user: influxdb + pass: influxdb + db: metrics + cache: + CACHE_TYPE: 'filesystem' + CACHE_DIR: '/tmp/graphite-api-cache' + ''; + type = types.str; + }; + }; + carbon = { config = mkOption { description = "Content of carbon configuration file."; @@ -172,11 +254,65 @@ in { ''; }; }; + + seyren = { + enable = mkOption { + description = "Whether to enable seyren service."; + default = false; + type = types.uniq types.bool; + }; + + port = mkOption { + description = "Seyren listening port."; + default = 8081; + type = types.int; + }; + + seyrenUrl = mkOption { + default = "http://localhost:${toString cfg.seyren.port}/"; + description = "Host where seyren is accessible."; + type = types.str; + }; + + graphiteUrl = mkOption { + default = "http://${cfg.web.host}:${toString cfg.web.port}"; + description = "Host where graphite service runs."; + type = types.str; + }; + + mongoUrl = mkOption { + default = "mongodb://${config.services.mongodb.bind_ip}:27017/seyren"; + description = "Mongodb connection string."; + type = types.str; + }; + + extraConfig = mkOption { + default = {}; + description = '' + Extra seyren configuration. See + <link xlink:href='https://github.com/scobal/seyren#config' /> + ''; + type = types.attrsOf types.str; + example = literalExample '' + { + GRAPHITE_USERNAME = "user"; + GRAPHITE_PASSWORD = "pass"; + } + ''; + }; + }; }; ###### implementation - config = mkIf (cfg.carbon.enableAggregator || cfg.carbon.enableCache || cfg.carbon.enableRelay || cfg.web.enable) { + config = mkIf ( + cfg.carbon.enableAggregator || + cfg.carbon.enableCache || + cfg.carbon.enableRelay || + cfg.web.enable || + cfg.api.enable || + cfg.seyren.enable + ) { systemd.services.carbonCache = { enable = cfg.carbon.enableCache; description = "Graphite Data Storage Backend"; @@ -189,10 +325,6 @@ in { Group = "graphite"; PermissionsStartOnly = true; }; - restartTriggers = [ - pkgs.pythonPackages.carbon - configDir - ]; preStart = '' mkdir -p ${cfg.dataDir}/whisper chmod 0700 ${cfg.dataDir}/whisper @@ -211,10 +343,6 @@ in { User = "graphite"; Group = "graphite"; }; - restartTriggers = [ - pkgs.pythonPackages.carbon - configDir - ]; }; systemd.services.carbonRelay = { @@ -228,10 +356,6 @@ in { User = "graphite"; Group = "graphite"; }; - restartTriggers = [ - pkgs.pythonPackages.carbon - configDir - ]; }; systemd.services.graphiteWeb = { @@ -243,7 +367,7 @@ in { environment = { PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages"; DJANGO_SETTINGS_MODULE = "graphite.settings"; - GRAPHITE_CONF_DIR = "/etc/graphite/"; + GRAPHITE_CONF_DIR = configDir; GRAPHITE_STORAGE_DIR = dataDir; }; serviceConfig = { @@ -271,11 +395,64 @@ in { chown -R graphite:graphite ${cfg.dataDir} fi ''; - restartTriggers = [ - pkgs.python27Packages.graphite_web - ]; }; + systemd.services.graphiteApi = { + enable = cfg.api.enable; + description = "Graphite Api Interface"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment = { + PYTHONPATH = + "${cfg.api.package}/lib/python2.7/site-packages:" + + concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders; + GRAPHITE_API_CONFIG = graphiteApiConfig; + LD_LIBRARY_PATH = "${pkgs.cairo}/lib"; + }; + serviceConfig = { + ExecStart = '' + ${pkgs.python27Packages.waitress}/bin/waitress-serve \ + --host=${cfg.api.host} --port=${toString cfg.api.port} \ + graphite_api.app:app + ''; + User = "graphite"; + Group = "graphite"; + PermissionsStartOnly = true; + }; + preStart = '' + if ! test -e ${dataDir}/db-created; then + mkdir -p ${dataDir}/cache/ + chmod 0700 ${dataDir}/cache/ + + touch ${dataDir}/db-created + + chown -R graphite:graphite ${cfg.dataDir} + fi + ''; + }; + + systemd.services.seyren = { + enable = cfg.seyren.enable; + description = "Graphite Alerting Dashboard"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" "mongodb.service" ]; + environment = seyrenConfig; + serviceConfig = { + ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}"; + WorkingDirectory = dataDir; + User = "graphite"; + Group = "graphite"; + }; + preStart = '' + if ! test -e ${dataDir}/db-created; then + mkdir -p ${dataDir} + chown -R graphite:graphite ${dataDir} + fi + ''; + }; + + services.mongodb.enable = mkDefault cfg.seyren.enable; + environment.systemPackages = [ pkgs.pythonPackages.carbon pkgs.python27Packages.graphite_web diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 42914bfe5d62..68aac3d30de1 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -37,6 +37,180 @@ let } ''; + writeShScript = name: text: let dir = pkgs.writeScriptBin name '' + #! ${pkgs.stdenv.shell} -e + ${text} + ''; in "${dir}/bin/${name}"; + + startScript = writeShScript "firewall-start" '' + ${helpers} + + # Flush the old firewall rules. !!! Ideally, updating the + # firewall would be atomic. Apparently that's possible + # with iptables-restore. + ip46tables -D INPUT -j nixos-fw 2> /dev/null || true + for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do + ip46tables -F "$chain" 2> /dev/null || true + ip46tables -X "$chain" 2> /dev/null || true + done + + + # The "nixos-fw-accept" chain just accepts packets. + ip46tables -N nixos-fw-accept + ip46tables -A nixos-fw-accept -j ACCEPT + + + # The "nixos-fw-refuse" chain rejects or drops packets. + ip46tables -N nixos-fw-refuse + + ${if cfg.rejectPackets then '' + # Send a reset for existing TCP connections that we've + # somehow forgotten about. Send ICMP "port unreachable" + # for everything else. + ip46tables -A nixos-fw-refuse -p tcp ! --syn -j REJECT --reject-with tcp-reset + ip46tables -A nixos-fw-refuse -j REJECT + '' else '' + ip46tables -A nixos-fw-refuse -j DROP + ''} + + + # The "nixos-fw-log-refuse" chain performs logging, then + # jumps to the "nixos-fw-refuse" chain. + ip46tables -N nixos-fw-log-refuse + + ${optionalString cfg.logRefusedConnections '' + ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: " + ''} + ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) '' + ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \ + -j LOG --log-level info --log-prefix "rejected broadcast: " + ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \ + -j LOG --log-level info --log-prefix "rejected multicast: " + ''} + ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse + ${optionalString cfg.logRefusedPackets '' + ip46tables -A nixos-fw-log-refuse \ + -j LOG --log-level info --log-prefix "rejected packet: " + ''} + ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse + + + # The "nixos-fw" chain does the actual work. + ip46tables -N nixos-fw + + # Perform a reverse-path test to refuse spoofers + # For now, we just drop, as the raw table doesn't have a log-refuse yet + ${optionalString (kernelHasRPFilter && cfg.checkReversePath) '' + if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then + echo "<2>failed to initialise rpfilter support" >&2 + fi + ''} + + # Accept all traffic on the trusted interfaces. + ${flip concatMapStrings cfg.trustedInterfaces (iface: '' + ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept + '')} + + # Accept packets from established or related connections. + ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept + + # Accept connections to the allowed TCP ports. + ${concatMapStrings (port: + '' + ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept + '' + ) cfg.allowedTCPPorts + } + + # Accept connections to the allowed TCP port ranges. + ${concatMapStrings (rangeAttr: + let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in + '' + ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept + '' + ) cfg.allowedTCPPortRanges + } + + # Accept packets on the allowed UDP ports. + ${concatMapStrings (port: + '' + ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept + '' + ) cfg.allowedUDPPorts + } + + # Accept packets on the allowed UDP port ranges. + ${concatMapStrings (rangeAttr: + let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in + '' + ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept + '' + ) cfg.allowedUDPPortRanges + } + + # Accept IPv4 multicast. Not a big security risk since + # probably nobody is listening anyway. + #iptables -A nixos-fw -d 224.0.0.0/4 -j nixos-fw-accept + + # Optionally respond to ICMPv4 pings. + ${optionalString cfg.allowPing '' + iptables -w -A nixos-fw -p icmp --icmp-type echo-request ${optionalString (cfg.pingLimit != null) + "-m limit ${cfg.pingLimit} " + }-j nixos-fw-accept + ''} + + # Accept all ICMPv6 messages except redirects and node + # information queries (type 139). See RFC 4890, section + # 4.4. + ${optionalString config.networking.enableIPv6 '' + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP + ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept + ''} + + ${cfg.extraCommands} + + # Reject/drop everything else. + ip46tables -A nixos-fw -j nixos-fw-log-refuse + + + # Enable the firewall. + ip46tables -A INPUT -j nixos-fw + ''; + + stopScript = writeShScript "firewall-stop" '' + ${helpers} + + # Clean up in case reload fails + ip46tables -D INPUT -j nixos-drop 2>/dev/null || true + + # Clean up after added ruleset + ip46tables -D INPUT -j nixos-fw 2>/dev/null || true + + ${cfg.extraStopCommands} + ''; + + reloadScript = writeShScript "firewall-reload" '' + ${helpers} + + # Create a unique drop rule + ip46tables -D INPUT -j nixos-drop 2>/dev/null || true + ip46tables -F nixos-drop 2>/dev/null || true + ip46tables -X nixos-drop 2>/dev/null || true + ip46tables -N nixos-drop + ip46tables -A nixos-drop -j DROP + + # Don't allow traffic to leak out until the script has completed + ip46tables -A INPUT -j nixos-drop + if ${startScript}; then + ip46tables -D INPUT -j nixos-drop 2>/dev/null || true + else + echo "Failed to reload firewall... Stopping" + ${stopScript} + exit 1 + fi + ''; + kernelPackages = config.boot.kernelPackages; kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false; @@ -240,6 +414,18 @@ in ''; }; + networking.firewall.extraStopCommands = mkOption { + type = types.lines; + default = ""; + example = "iptables -P INPUT ACCEPT"; + description = + '' + Additional shell commands executed as part of the firewall + shutdown script. These are executed just after the removal + of the nixos input rule, or if the service enters a failed state. + ''; + }; + }; @@ -264,166 +450,28 @@ in message = "This kernel does not support disabling conntrack helpers"; } ]; - systemd.services.firewall = - { description = "Firewall"; - - wantedBy = [ "network.target" ]; - after = [ "network-interfaces.target" "systemd-modules-load.service" ]; - - path = [ pkgs.iptables ]; - - # FIXME: this module may also try to load kernel modules, but - # containers don't have CAP_SYS_MODULE. So the host system had - # better have all necessary modules already loaded. - unitConfig.ConditionCapability = "CAP_NET_ADMIN"; - - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; - - script = - '' - ${helpers} - - # Flush the old firewall rules. !!! Ideally, updating the - # firewall would be atomic. Apparently that's possible - # with iptables-restore. - ip46tables -D INPUT -j nixos-fw 2> /dev/null || true - for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do - ip46tables -F "$chain" 2> /dev/null || true - ip46tables -X "$chain" 2> /dev/null || true - done - - - # The "nixos-fw-accept" chain just accepts packets. - ip46tables -N nixos-fw-accept - ip46tables -A nixos-fw-accept -j ACCEPT - - - # The "nixos-fw-refuse" chain rejects or drops packets. - ip46tables -N nixos-fw-refuse - - ${if cfg.rejectPackets then '' - # Send a reset for existing TCP connections that we've - # somehow forgotten about. Send ICMP "port unreachable" - # for everything else. - ip46tables -A nixos-fw-refuse -p tcp ! --syn -j REJECT --reject-with tcp-reset - ip46tables -A nixos-fw-refuse -j REJECT - '' else '' - ip46tables -A nixos-fw-refuse -j DROP - ''} - - - # The "nixos-fw-log-refuse" chain performs logging, then - # jumps to the "nixos-fw-refuse" chain. - ip46tables -N nixos-fw-log-refuse - - ${optionalString cfg.logRefusedConnections '' - ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: " - ''} - ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) '' - ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \ - -j LOG --log-level info --log-prefix "rejected broadcast: " - ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \ - -j LOG --log-level info --log-prefix "rejected multicast: " - ''} - ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse - ${optionalString cfg.logRefusedPackets '' - ip46tables -A nixos-fw-log-refuse \ - -j LOG --log-level info --log-prefix "rejected packet: " - ''} - ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse - - - # The "nixos-fw" chain does the actual work. - ip46tables -N nixos-fw - - # Perform a reverse-path test to refuse spoofers - # For now, we just drop, as the raw table doesn't have a log-refuse yet - ${optionalString (kernelHasRPFilter && cfg.checkReversePath) '' - if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then - echo "<2>failed to initialise rpfilter support" >&2 - fi - ''} - - # Accept all traffic on the trusted interfaces. - ${flip concatMapStrings cfg.trustedInterfaces (iface: '' - ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept - '')} - - # Accept packets from established or related connections. - ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept - - # Accept connections to the allowed TCP ports. - ${concatMapStrings (port: - '' - ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept - '' - ) cfg.allowedTCPPorts - } - - # Accept connections to the allowed TCP port ranges. - ${concatMapStrings (rangeAttr: - let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in - '' - ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept - '' - ) cfg.allowedTCPPortRanges - } - - # Accept packets on the allowed UDP ports. - ${concatMapStrings (port: - '' - ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept - '' - ) cfg.allowedUDPPorts - } - - # Accept packets on the allowed UDP port ranges. - ${concatMapStrings (rangeAttr: - let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in - '' - ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept - '' - ) cfg.allowedUDPPortRanges - } - - # Accept IPv4 multicast. Not a big security risk since - # probably nobody is listening anyway. - #iptables -A nixos-fw -d 224.0.0.0/4 -j nixos-fw-accept - - # Optionally respond to ICMPv4 pings. - ${optionalString cfg.allowPing '' - iptables -w -A nixos-fw -p icmp --icmp-type echo-request ${optionalString (cfg.pingLimit != null) - "-m limit ${cfg.pingLimit} " - }-j nixos-fw-accept - ''} - - # Accept all ICMPv6 messages except redirects and node - # information queries (type 139). See RFC 4890, section - # 4.4. - ${optionalString config.networking.enableIPv6 '' - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP - ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept - ''} - - ${cfg.extraCommands} - - # Reject/drop everything else. - ip46tables -A nixos-fw -j nixos-fw-log-refuse - - - # Enable the firewall. - ip46tables -A INPUT -j nixos-fw - ''; - - postStop = - '' - ${helpers} - ip46tables -D INPUT -j nixos-fw || true - #ip46tables -P INPUT ACCEPT - ''; + systemd.services.firewall = { + description = "Firewall"; + wantedBy = [ "network.target" ]; + after = [ "network-interfaces.target" "systemd-modules-load.service" ]; + + path = [ pkgs.iptables ]; + + # FIXME: this module may also try to load kernel modules, but + # containers don't have CAP_SYS_MODULE. So the host system had + # better have all necessary modules already loaded. + unitConfig.ConditionCapability = "CAP_NET_ADMIN"; + + reloadIfChanged = true; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "@${startScript} firewall-start"; + ExecReload = "@${reloadScript} firewall-reload"; + ExecStop = "@${stopScript} firewall-stop"; }; + }; }; diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index 4a4c06503c29..35e376e7b3a6 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -12,6 +12,41 @@ let dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; + flushNat = '' + iptables -w -t nat -F PREROUTING + iptables -w -t nat -F POSTROUTING + iptables -w -t nat -X + ''; + + setupNat = '' + # We can't match on incoming interface in POSTROUTING, so + # mark packets coming from the external interfaces. + ${concatMapStrings (iface: '' + iptables -w -t nat -A PREROUTING \ + -i '${iface}' -j MARK --set-mark 1 + '') cfg.internalInterfaces} + + # NAT the marked packets. + ${optionalString (cfg.internalInterfaces != []) '' + iptables -w -t nat -A POSTROUTING -m mark --mark 1 \ + -o ${cfg.externalInterface} ${dest} + ''} + + # NAT packets coming from the internal IPs. + ${concatMapStrings (range: '' + iptables -w -t nat -A POSTROUTING \ + -s '${range}' -o ${cfg.externalInterface} ${dest} + '') cfg.internalIPs} + + # NAT from external ports to internal ports. + ${concatMapStrings (fwd: '' + iptables -w -t nat -A PREROUTING \ + -i ${cfg.externalInterface} -p tcp \ + --dport ${builtins.toString fwd.sourcePort} \ + -j DNAT --to-destination ${fwd.destination} + '') cfg.forwardPorts} + ''; + in { @@ -109,57 +144,34 @@ in environment.systemPackages = [ pkgs.iptables ]; - boot.kernelModules = [ "nf_nat_ftp" ]; - - jobs.nat = - { description = "Network Address Translation"; - - startOn = "started network-interfaces"; - - path = [ pkgs.iptables ]; - - preStart = - '' - iptables -w -t nat -F PREROUTING - iptables -w -t nat -F POSTROUTING - iptables -w -t nat -X - - # We can't match on incoming interface in POSTROUTING, so - # mark packets coming from the external interfaces. - ${concatMapStrings (iface: '' - iptables -w -t nat -A PREROUTING \ - -i '${iface}' -j MARK --set-mark 1 - '') cfg.internalInterfaces} - - # NAT the marked packets. - ${optionalString (cfg.internalInterfaces != []) '' - iptables -w -t nat -A POSTROUTING -m mark --mark 1 \ - -o ${cfg.externalInterface} ${dest} - ''} - - # NAT packets coming from the internal IPs. - ${concatMapStrings (range: '' - iptables -w -t nat -A POSTROUTING \ - -s '${range}' -o ${cfg.externalInterface} ${dest} - '') cfg.internalIPs} - - # NAT from external ports to internal ports. - ${concatMapStrings (fwd: '' - iptables -w -t nat -A PREROUTING \ - -i ${cfg.externalInterface} -p tcp \ - --dport ${builtins.toString fwd.sourcePort} \ - -j DNAT --to-destination ${fwd.destination} - '') cfg.forwardPorts} - - echo 1 > /proc/sys/net/ipv4/ip_forward - ''; - - postStop = - '' - iptables -w -t nat -F PREROUTING - iptables -w -t nat -F POSTROUTING - iptables -w -t nat -X - ''; + boot = { + kernelModules = [ "nf_nat_ftp" ]; + kernel.sysctl = mkOverride 99 { + "net.ipv4.conf.all.forwarding" = true; + "net.ipv4.conf.default.forwarding" = true; }; + }; + + networking.firewall = mkIf config.networking.firewall.enable { + extraCommands = mkMerge [ (mkBefore flushNat) setupNat ]; + extraStopCommands = flushNat; + }; + + systemd.services = mkIf (!config.networking.firewall.enable) { nat = { + description = "Network Address Translation"; + wantedBy = [ "network.target" ]; + after = [ "network-interfaces.target" "systemd-modules-load.service" ]; + path = [ pkgs.iptables ]; + unitConfig.ConditionCapability = "CAP_NET_ADMIN"; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = flushNat + setupNat; + + postStop = flushNat; + }; }; }; } diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix index 9b26b2b32448..b39aea04521b 100644 --- a/nixos/modules/services/networking/znc.nix +++ b/nixos/modules/services/networking/znc.nix @@ -305,7 +305,6 @@ in uid = config.ids.uids.znc; home = cfg.dataDir; createHome = true; - createUser = true; }; users.extraGroups = optional (cfg.user == defaultUser) diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix index b74ef4370d76..12f163db463d 100644 --- a/nixos/modules/services/search/elasticsearch.nix +++ b/nixos/modules/services/search/elasticsearch.nix @@ -135,6 +135,11 @@ in { rm ${cfg.dataDir}/plugins || true ln -s ${esPlugins}/plugins ${cfg.dataDir}/plugins ''; + postStart = mkBefore '' + until ${pkgs.curl}/bin/curl -s -o /dev/null ${cfg.host}:${toString cfg.port}; do + sleep 1 + done + ''; }; environment.systemPackages = [ pkgs.elasticsearch ]; diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index 9ac28373dacb..85458a2ab565 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -208,16 +208,12 @@ let </Directory> ''; - robotsTxt = pkgs.writeText "robots.txt" '' - ${# If this is a vhost, the include the entries for the main server as well. - if isMainServer then "" - else concatMapStrings (svc: svc.robotsEntries) mainSubservices} - ${concatMapStrings (svc: svc.robotsEntries) subservices} - ''; - - robotsConf = '' - Alias /robots.txt ${robotsTxt} - ''; + robotsTxt = + concatStringsSep "\n" (filter (x: x != "") ( + # If this is a vhost, the include the entries for the main server as well. + (if isMainServer then [] else [mainCfg.robotsEntries] ++ map (svc: svc.robotsEntries) mainSubservices) + ++ [cfg.robotsEntries] + ++ (map (svc: svc.robotsEntries) subservices))); in '' ServerName ${serverInfo.canonicalName} @@ -245,7 +241,9 @@ let CustomLog ${mainCfg.logDir}/access_log-${cfg.hostName} ${cfg.logFormat} '' else ""} - ${robotsConf} + ${optionalString (robotsTxt != "") '' + Alias /robots.txt ${pkgs.writeText "robots.txt" robotsTxt} + ''} ${if isMainServer || maybeDocumentRoot != null then documentRootConf else ""} diff --git a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix index b8e863345398..76f55a63e326 100644 --- a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix +++ b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix @@ -142,9 +142,19 @@ with lib; type = types.str; default = "common"; example = "combined"; - description = " + description = '' Log format for Apache's log files. Possible values are: combined, common, referer, agent. - "; + ''; + }; + + robotsEntries = mkOption { + type = types.lines; + default = ""; + example = "Disallow: /foo/"; + description = '' + Specification of pages to be ignored by web crawlers. See <link + xlink:href='http://www.robotstxt.org/'/> for details. + ''; }; } diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index c62beca60d84..ebdb2ad06491 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -19,7 +19,7 @@ in # E.g., if KDE is enabled, it supersedes xterm. imports = [ ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix - ./e17.nix ./e18.nix ./gnome3.nix ./xbmc.nix + ./e17.nix ./e18.nix ./e19.nix ./gnome3.nix ./xbmc.nix ]; options = { diff --git a/nixos/modules/services/x11/desktop-managers/e19.nix b/nixos/modules/services/x11/desktop-managers/e19.nix new file mode 100644 index 000000000000..dd9becb0f6ca --- /dev/null +++ b/nixos/modules/services/x11/desktop-managers/e19.nix @@ -0,0 +1,94 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.e19; + e19_enlightenment = pkgs.e19.enlightenment.override { set_freqset_setuid = true; }; + +in + +{ + options = { + + services.xserver.desktopManager.e19.enable = mkOption { + default = false; + example = true; + description = "Enable the E19 desktop environment."; + }; + + }; + + config = mkIf (xcfg.enable && cfg.enable) { + + environment.systemPackages = [ + pkgs.e19.efl pkgs.e19.evas pkgs.e19.emotion pkgs.e19.elementary e19_enlightenment + pkgs.e19.terminology pkgs.e19.econnman + pkgs.xorg.xauth # used by kdesu + pkgs.gtk # To get GTK+'s themes. + pkgs.tango-icon-theme + pkgs.shared_mime_info + pkgs.gnome.gnomeicontheme + pkgs.xorg.xcursorthemes + ]; + + environment.pathsToLink = [ "/etc/enlightenment" "/etc/xdg" "/share/enlightenment" "/share/elementary" "/share/applications" "/share/locale" "/share/icons" "/share/themes" "/share/mime" "/share/desktop-directories" ]; + + services.xserver.desktopManager.session = [ + { name = "E19"; + start = '' + # Set GTK_DATA_PREFIX so that GTK+ can find the themes + export GTK_DATA_PREFIX=${config.system.path} + # find theme engines + export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0 + export XDG_MENU_PREFIX=enlightenment + + # make available for D-BUS user services + #export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}:${config.system.path}/share:${pkgs.e19.efl}/share + + # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/ + ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update + + ${e19_enlightenment}/bin/enlightenment_start + waitPID=$! + ''; + }]; + + security.setuidPrograms = [ "e19_freqset" ]; + + environment.etc = singleton + { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + }; + + fonts.fonts = [ pkgs.dejavu_fonts pkgs.ubuntu_font_family ]; + + services.udisks2.enable = true; + services.upower.enable = config.powerManagement.enable; + + #services.dbus.packages = [ pkgs.efl ]; # dbus-1 folder is not in /etc but in /share, so needs fixing first + + systemd.user.services.efreet = + { enable = true; + description = "org.enlightenment.Efreet"; + serviceConfig = + { ExecStart = "${pkgs.e19.efl}/bin/efreetd"; + StandardOutput = "null"; + }; + }; + + systemd.user.services.ethumb = + { enable = true; + description = "org.enlightenment.Ethumb"; + serviceConfig = + { ExecStart = "${pkgs.e19.efl}/bin/ethumbd"; + StandardOutput = "null"; + }; + }; + + + }; + +} diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 633b6f4960a6..3c13e866eb17 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -77,7 +77,7 @@ in { services.gnome3.tracker.enable = mkDefault true; hardware.pulseaudio.enable = mkDefault true; services.telepathy.enable = mkDefault true; - networking.networkmanager.enable = true; + networking.networkmanager.enable = mkDefault true; services.upower.enable = config.powerManagement.enable; services.upower.package = gnome3.upower; diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 6e61576f501f..004ea6ef49ac 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -169,7 +169,6 @@ in xserverBin = mkOption { type = types.path; - default = "${xorg.xorgserver}/bin/X"; description = "Path to the X server used by display managers."; }; @@ -280,4 +279,10 @@ in }; + config = { + + services.xserver.displayManager.xserverBin = "${xorg.xorgserver}/bin/X"; + + }; + } diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index a6183c47eb1b..48c3564ba078 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -230,6 +230,15 @@ in rec { ''; }; + reload = mkOption { + type = types.lines; + default = ""; + description = '' + Shell commands executed when the service's main process + is reloaded. + ''; + }; + preStop = mkOption { type = types.lines; default = ""; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 366faf1b73de..13d6c6d7990a 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -246,6 +246,12 @@ let ${config.postStart} ''; }) + (mkIf (config.reload != "") + { serviceConfig.ExecReload = makeJobScript "${name}-reload" '' + #! ${pkgs.stdenv.shell} -e + ${config.reload} + ''; + }) (mkIf (config.preStop != "") { serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" '' #! ${pkgs.stdenv.shell} -e diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index c902b9e07905..16752ce7e1b5 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -54,12 +54,16 @@ in ###### implementation - config = mkIf (any (fs: fs == "nfs" || fs == "nfs4") config.boot.supportedFilesystems) ({ + config = mkIf (any (fs: fs == "nfs" || fs == "nfs4") config.boot.supportedFilesystems) { services.rpcbind.enable = true; system.fsPackages = [ pkgs.nfsUtils ]; + boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) '' + options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort} + ''; + boot.kernelModules = [ "sunrpc" ]; boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; @@ -117,9 +121,5 @@ in serviceConfig.Restart = "always"; }; - } // mkIf (cfg.lockdPort != null) { - boot.extraModprobeConfig = '' - options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort} - ''; - }); + }; } diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 318460f4c2cf..2d03f0544b67 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -129,12 +129,12 @@ in # config file. But this path can unfortunately be garbage collected # while still being used by the virtual machine. So update the # emulator path on each startup to something valid (re-scan $PATH). - for file in /etc/libvirt/qemu/*.xml; do + for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do test -f "$file" || continue # get (old) emulator path from config file emulator=$(grep "^[[:space:]]*<emulator>" "$file" | sed 's,^[[:space:]]*<emulator>\(.*\)</emulator>.*,\1,') # get a (definitely) working emulator path by re-scanning $PATH - new_emulator=$(command -v $(basename "$emulator")) + new_emulator=$(PATH=${pkgs.libvirt}/libexec:$PATH command -v $(basename "$emulator")) # write back sed -i "s,^[[:space:]]*<emulator>.*, <emulator>$new_emulator</emulator> <!-- WARNING: emulator dirname is auto-updated by the nixos libvirtd module -->," "$file" done diff --git a/nixos/release.nix b/nixos/release.nix index d8cc1c8291bd..b3039afb18c1 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -11,7 +11,9 @@ let forAllSystems = pkgs.lib.genAttrs supportedSystems; - callTest = fn: args: forAllSystems (system: import fn ({ inherit system; } // args)); + scrubDrv = drv: let res = { inherit (drv) drvPath outPath type name; outputName = "out"; out = res; }; in res; + + callTest = fn: args: forAllSystems (system: scrubDrv (import fn ({ inherit system; } // args))); pkgs = import nixpkgs { system = "x86_64-linux"; }; @@ -40,7 +42,7 @@ let in # Declare the ISO as a build product so that it shows up in Hydra. - runCommand "nixos-iso-${config.system.nixosVersion}" + scrubDrv (runCommand "nixos-iso-${config.system.nixosVersion}" { meta = { description = "NixOS installation CD (${description}) - ISO image for ${system}"; maintainers = map (x: lib.getAttr x lib.maintainers) maintainers; @@ -51,7 +53,7 @@ let '' mkdir -p $out/nix-support echo "file iso" $iso/iso/*.iso* >> $out/nix-support/hydra-build-products - ''; # */ + ''); # */ makeSystemTarball = @@ -78,14 +80,17 @@ let }; - makeClosure = module: forAllSystems (system: (import ./lib/eval-config.nix { + makeClosure = module: buildFromConfig module (config: config.system.build.toplevel); + + + buildFromConfig = module: sel: forAllSystems (system: scrubDrv (sel (import ./lib/eval-config.nix { inherit system; - modules = [ module ] ++ lib.singleton + modules = [ module versionModule ] ++ lib.singleton ({ config, lib, ... }: { fileSystems."/".device = lib.mkDefault "/dev/sda1"; boot.loader.grub.device = lib.mkDefault "/dev/sda"; }); - }).config.system.build.toplevel); + }).config)); in rec { @@ -122,9 +127,9 @@ in rec { }; - manual = forAllSystems (system: (builtins.getAttr system iso_minimal).config.system.build.manual.manual); - manualPDF = iso_minimal.x86_64-linux.config.system.build.manual.manualPDF; - manpages = forAllSystems (system: (builtins.getAttr system iso_minimal).config.system.build.manual.manpages); + manual = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manual); + manualPDF = (buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manualPDF)).x86_64-linux; + manpages = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manpages); iso_minimal = forAllSystems (system: makeIso { @@ -147,12 +152,6 @@ in rec { inherit system; }); - iso_graphical_new_kernel = forAllSystems (system: makeIso { - module = ./modules/installer/cd-dvd/installation-cd-graphical-new-kernel.nix; - type = "graphical-new-kernel"; - inherit system; - }); - # A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF). ova = forAllSystems (system: @@ -171,7 +170,7 @@ in rec { in # Declare the OVA as a build product so that it shows up in Hydra. - runCommand "nixos-ova-${config.system.nixosVersion}-${system}" + scrubDrv (runCommand "nixos-ova-${config.system.nixosVersion}-${system}" { meta = { description = "NixOS VirtualBox appliance (${system})"; maintainers = lib.maintainers.eelco; @@ -182,7 +181,7 @@ in rec { mkdir -p $out/nix-support fn=$(echo $ova/*.ova) echo "file ova $fn" >> $out/nix-support/hydra-build-products - '' # */ + '') # */ ); @@ -222,17 +221,17 @@ in rec { tests.firefox = callTest tests/firefox.nix {}; tests.firewall = callTest tests/firewall.nix {}; tests.gnome3 = callTest tests/gnome3.nix {}; - tests.installer.efi = forAllSystems (system: (import tests/installer.nix { inherit system; }).efi.test); - tests.installer.grub1 = forAllSystems (system: (import tests/installer.nix { inherit system; }).grub1.test); - tests.installer.lvm = forAllSystems (system: (import tests/installer.nix { inherit system; }).lvm.test); - tests.installer.rebuildCD = forAllSystems (system: (import tests/installer.nix { inherit system; }).rebuildCD.test); - tests.installer.separateBoot = forAllSystems (system: (import tests/installer.nix { inherit system; }).separateBoot.test); - tests.installer.simple = forAllSystems (system: (import tests/installer.nix { inherit system; }).simple.test); - tests.installer.simpleLabels = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleLabels.test); - tests.installer.simpleProvided = forAllSystems (system: (import tests/installer.nix { inherit system; }).simpleProvided.test); - tests.installer.btrfsSimple = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSimple.test); - tests.installer.btrfsSubvols = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSubvols.test); - tests.installer.btrfsSubvolDefault = forAllSystems (system: (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test); + tests.installer.efi = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).efi.test); + tests.installer.grub1 = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).grub1.test); + tests.installer.lvm = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).lvm.test); + tests.installer.rebuildCD = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).rebuildCD.test); + tests.installer.separateBoot = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).separateBoot.test); + tests.installer.simple = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).simple.test); + tests.installer.simpleLabels = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).simpleLabels.test); + tests.installer.simpleProvided = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).simpleProvided.test); + tests.installer.btrfsSimple = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).btrfsSimple.test); + tests.installer.btrfsSubvols = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).btrfsSubvols.test); + tests.installer.btrfsSubvolDefault = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test); tests.influxdb = callTest tests/influxdb.nix {}; tests.ipv6 = callTest tests/ipv6.nix {}; tests.jenkins = callTest tests/jenkins.nix {}; |