diff options
Diffstat (limited to 'nixos/modules')
109 files changed, 2574 insertions, 398 deletions
diff --git a/nixos/modules/config/debug-info.nix b/nixos/modules/config/debug-info.nix index 17cb862d2916..671a59f52f6d 100644 --- a/nixos/modules/config/debug-info.nix +++ b/nixos/modules/config/debug-info.nix @@ -20,7 +20,7 @@ with lib; <!-- FIXME: ugly, see #10721 --> <programlisting> nixpkgs.config.packageOverrides = pkgs: { - hello = overrideDerivation pkgs.hello (attrs: { + hello = pkgs.lib.overrideDerivation pkgs.hello (attrs: { outputs = attrs.outputs or ["out"] ++ ["debug"]; buildInputs = attrs.buildInputs ++ [<nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh>]; }); diff --git a/nixos/modules/config/timezone.nix b/nixos/modules/config/timezone.nix index b9844b4adade..39a45042c6cc 100644 --- a/nixos/modules/config/timezone.nix +++ b/nixos/modules/config/timezone.nix @@ -37,14 +37,15 @@ in environment.sessionVariables.TZDIR = "/etc/zoneinfo"; + # This way services are restarted when tzdata changes. systemd.globalEnvironment.TZDIR = tzdir; environment.etc.localtime = - { source = "${tzdir}/${config.time.timeZone}"; + { source = "/etc/zoneinfo/${config.time.timeZone}"; mode = "direct-symlink"; }; - environment.etc.zoneinfo.source = "${pkgs.tzdata}/share/zoneinfo"; + environment.etc.zoneinfo.source = tzdir; }; diff --git a/nixos/modules/hardware/video/amdgpu-pro.nix b/nixos/modules/hardware/video/amdgpu-pro.nix new file mode 100644 index 000000000000..3723d7690dc6 --- /dev/null +++ b/nixos/modules/hardware/video/amdgpu-pro.nix @@ -0,0 +1,56 @@ +# This module provides the proprietary AMDGPU-PRO drivers. + +{ config, lib, pkgs, pkgs_i686, ... }: + +with lib; + +let + + drivers = config.services.xserver.videoDrivers; + + enabled = elem "amdgpu-pro" drivers; + + package = config.boot.kernelPackages.amdgpu-pro; + package32 = pkgs_i686.linuxPackages.amdgpu-pro.override { libsOnly = true; kernel = null; }; + + opengl = config.hardware.opengl; + +in + +{ + + config = mkIf enabled { + + services.xserver.drivers = singleton + { name = "amdgpu"; modules = [ package ]; libPath = [ package ]; }; + + hardware.opengl.package = package; + hardware.opengl.package32 = package32; + + boot.extraModulePackages = [ package ]; + + boot.blacklistedKernelModules = [ "radeon" ]; + + hardware.firmware = [ package ]; + + system.activationScripts.setup-amdgpu-pro = '' + mkdir -p /run/lib + ln -sfn ${package}/lib ${package.libCompatDir} + '' + optionalString opengl.driSupport32Bit '' + ln -sfn ${package32}/lib ${package32.libCompatDir} + ''; + + environment.etc = { + "amd/amdrc".source = package + "/etc/amd/amdrc"; + "amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb"; + "gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf"; + "OpenCL/vendors/amdocl64.icd".source = package + "/etc/OpenCL/vendors/amdocl64.icd"; + "vulkan/icd.d/amd_icd64.json".source = package + "/etc/vulkan/icd.d/amd_icd64.json"; + } // optionalAttrs opengl.driSupport32Bit { + "OpenCL/vendors/amdocl32.icd".source = package32 + "/etc/OpenCL/vendors/amdocl32.icd"; + "vulkan/icd.d/amd_icd32.json".source = package32 + "/etc/vulkan/icd.d/amd_icd32.json"; + }; + + }; + +} diff --git a/nixos/modules/installer/tools/auto-upgrade.nix b/nixos/modules/installer/tools/auto-upgrade.nix index b21b80c666aa..dfb43d1a1db9 100644 --- a/nixos/modules/installer/tools/auto-upgrade.nix +++ b/nixos/modules/installer/tools/auto-upgrade.nix @@ -84,7 +84,7 @@ let cfg = config.system.autoUpgrade; in ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags} ''; - startAt = optionalString cfg.enable cfg.dates; + startAt = optional cfg.enable cfg.dates; }; }; diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 2881d843760d..8c0f0c2624b1 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -276,6 +276,7 @@ telegraf = 256; gitlab-runner = 257; postgrey = 258; + hound = 259; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -522,6 +523,7 @@ #telegraf = 256; # unused gitlab-runner = 257; postgrey = 258; + hound = 259; # 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 d1a786d8f629..61596265124a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -38,6 +38,7 @@ ./hardware/opengl.nix ./hardware/pcmcia.nix ./hardware/video/amdgpu.nix + ./hardware/video/amdgpu-pro.nix ./hardware/video/ati.nix ./hardware/video/bumblebee.nix ./hardware/video/displaylink.nix @@ -76,6 +77,7 @@ ./programs/man.nix ./programs/mosh.nix ./programs/nano.nix + ./programs/oblogout.nix ./programs/screen.nix ./programs/shadow.nix ./programs/shell.nix @@ -84,6 +86,7 @@ ./programs/ssmtp.nix ./programs/tmux.nix ./programs/venus.nix + ./programs/vim.nix ./programs/wvdial.nix ./programs/xfs_quota.nix ./programs/xonsh.nix @@ -164,6 +167,7 @@ ./services/desktops/gnome3/gnome-keyring.nix ./services/desktops/gnome3/gnome-online-accounts.nix ./services/desktops/gnome3/gnome-online-miners.nix + ./services/desktops/gnome3/gnome-terminal-server.nix ./services/desktops/gnome3/gnome-user-share.nix ./services/desktops/gnome3/gvfs.nix ./services/desktops/gnome3/seahorse.nix @@ -234,7 +238,9 @@ ./services/misc/dictd.nix ./services/misc/dysnomia.nix ./services/misc/disnix.nix + ./services/misc/docker-registry.nix ./services/misc/emby.nix + ./services/misc/errbot.nix ./services/misc/etcd.nix ./services/misc/felix.nix ./services/misc/folding-at-home.nix @@ -308,6 +314,7 @@ ./services/monitoring/uptime.nix ./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-server.nix + ./services/network-filesystems/cachefilesd.nix ./services/network-filesystems/drbd.nix ./services/network-filesystems/netatalk.nix ./services/network-filesystems/nfsd.nix @@ -437,6 +444,7 @@ ./services/networking/wakeonlan.nix ./services/networking/websockify.nix ./services/networking/wicd.nix + ./services/networking/wireguard.nix ./services/networking/wpa_supplicant.nix ./services/networking/xinetd.nix ./services/networking/xl2tpd.nix @@ -450,6 +458,7 @@ ./services/scheduling/fcron.nix ./services/scheduling/marathon.nix ./services/search/elasticsearch.nix + ./services/search/hound.nix ./services/search/kibana.nix ./services/search/solr.nix ./services/security/clamav.nix @@ -479,10 +488,15 @@ ./services/ttys/agetty.nix ./services/ttys/gpm.nix ./services/ttys/kmscon.nix + ./services/web-apps/atlassian/confluence.nix + ./services/web-apps/atlassian/crowd.nix + ./services/web-apps/atlassian/jira.nix ./services/web-apps/mattermost.nix + ./services/web-apps/nixbot.nix ./services/web-apps/pump.io.nix ./services/web-apps/tt-rss.nix ./services/web-apps/selfoss.nix + ./services/web-apps/quassel-webserver.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/caddy.nix ./services/web-servers/fcgiwrap.nix @@ -515,12 +529,14 @@ ./services/x11/hardware/synaptics.nix ./services/x11/hardware/wacom.nix ./services/x11/redshift.nix + ./services/x11/urxvtd.nix ./services/x11/window-managers/awesome.nix #./services/x11/window-managers/compiz.nix ./services/x11/window-managers/default.nix ./services/x11/window-managers/fluxbox.nix ./services/x11/window-managers/icewm.nix ./services/x11/window-managers/bspwm.nix + ./services/x11/window-managers/bspwm-unstable.nix ./services/x11/window-managers/metacity.nix ./services/x11/window-managers/none.nix ./services/x11/window-managers/twm.nix @@ -557,6 +573,7 @@ ./system/boot/stage-1.nix ./system/boot/stage-2.nix ./system/boot/systemd.nix + ./system/boot/systemd-nspawn.nix ./system/boot/timesyncd.nix ./system/boot/tmp.nix ./system/etc/etc.nix diff --git a/nixos/modules/programs/oblogout.nix b/nixos/modules/programs/oblogout.nix new file mode 100644 index 000000000000..79a8ddb7ce37 --- /dev/null +++ b/nixos/modules/programs/oblogout.nix @@ -0,0 +1,160 @@ +# Global configuration for oblogout. + +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.programs.oblogout; + +in +{ + ###### interface + + options = { + + programs.oblogout = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to install OBLogout and create <filename>/etc/oblogout.conf</filename>. + See <filename>${pkgs.oblogout}/share/doc/README</filename>. + ''; + }; + + opacity = mkOption { + type = types.int; + default = 70; + description = '' + ''; + }; + + bgcolor = mkOption { + type = types.str; + default = "black"; + description = '' + ''; + }; + + buttontheme = mkOption { + type = types.str; + default = "simplistic"; + description = '' + ''; + }; + + buttons = mkOption { + type = types.str; + default = "cancel, logout, restart, shutdown, suspend, hibernate"; + description = '' + ''; + }; + + cancel = mkOption { + type = types.str; + default = "Escape"; + description = '' + ''; + }; + + shutdown = mkOption { + type = types.str; + default = "S"; + description = '' + ''; + }; + + restart = mkOption { + type = types.str; + default = "R"; + description = '' + ''; + }; + + suspend = mkOption { + type = types.str; + default = "U"; + description = '' + ''; + }; + + logout = mkOption { + type = types.str; + default = "L"; + description = '' + ''; + }; + + lock = mkOption { + type = types.str; + default = "K"; + description = '' + ''; + }; + + hibernate = mkOption { + type = types.str; + default = "H"; + description = '' + ''; + }; + + clogout = mkOption { + type = types.str; + default = "openbox --exit"; + description = '' + ''; + }; + + clock = mkOption { + type = types.str; + default = ""; + description = '' + ''; + }; + + cswitchuser = mkOption { + type = types.str; + default = ""; + description = '' + ''; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.oblogout ]; + + environment.etc."oblogout.conf".text = '' + [settings] + usehal = false + + [looks] + opacity = ${toString cfg.opacity} + bgcolor = ${cfg.bgcolor} + buttontheme = ${cfg.buttontheme} + buttons = ${cfg.buttons} + + [shortcuts] + cancel = ${cfg.cancel} + shutdown = ${cfg.shutdown} + restart = ${cfg.restart} + suspend = ${cfg.suspend} + logout = ${cfg.logout} + lock = ${cfg.lock} + hibernate = ${cfg.hibernate} + + [commands] + shutdown = systemctl poweroff + restart = systemctl reboot + suspend = systemctl suspend + hibernate = systemctl hibernate + logout = ${cfg.clogout} + lock = ${cfg.clock} + switchuser = ${cfg.cswitchuser} + ''; + }; +} diff --git a/nixos/modules/programs/vim.nix b/nixos/modules/programs/vim.nix new file mode 100644 index 000000000000..8476c1accd31 --- /dev/null +++ b/nixos/modules/programs/vim.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.vim; +in { + options.programs.vim = { + defaultEditor = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + When enabled, installs vim and configures vim to be the default editor + using the EDITOR environment variable. + ''; + }; + }; + + config = mkIf cfg.defaultEditor { + environment.systemPackages = [ pkgs.vim ]; + environment.variables = { EDITOR = mkOverride 900 "vim"; }; + }; +} diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 9abe7d450c93..44e07f4618de 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -156,7 +156,5 @@ with lib; "See the 16.09 release notes for more information.") (mkRemovedOptionModule [ "services" "phpfpm" "phpIni" ] "") (mkRemovedOptionModule [ "services" "dovecot2" "package" ] "") - (mkRemovedOptionModule [ "services" "dockerRegistry" ] - "docker-registry has been deprecated upstream since a long time.") ]; } diff --git a/nixos/modules/security/acme.xml b/nixos/modules/security/acme.xml index 15ed4c04a23d..226cf0382da7 100644 --- a/nixos/modules/security/acme.xml +++ b/nixos/modules/security/acme.xml @@ -74,9 +74,30 @@ options for the <literal>security.acme</literal> module.</para> </para> <programlisting> +security.acme.certs."foo.example.com" = { + webroot = "/var/www/challenges"; + email = "foo@example.com"; + user = "nginx"; + group = "nginx"; + postRun = "systemctl restart nginx.service"; +}; services.nginx.httpConfig = '' server { server_name foo.example.com; + listen 80; + listen [::]:80; + + location /.well-known/acme-challenge { + root /var/www/challenges; + } + + location / { + return 301 https://$host$request_uri; + } + } + + server { + server_name foo.example.com; listen 443 ssl; ssl_certificate ${config.security.acme.directory}/foo.example.com/fullchain.pem; ssl_certificate_key ${config.security.acme.directory}/foo.example.com/key.pem; diff --git a/nixos/modules/security/audit.nix b/nixos/modules/security/audit.nix index ebfe594d0c71..7ac21fd96507 100644 --- a/nixos/modules/security/audit.nix +++ b/nixos/modules/security/audit.nix @@ -104,7 +104,11 @@ in { description = "Kernel Auditing"; wantedBy = [ "basic.target" ]; - unitConfig.ConditionVirtualization = "!container"; + unitConfig = { + ConditionVirtualization = "!container"; + ConditionSecurity = [ "audit" ]; + }; + path = [ pkgs.audit ]; diff --git a/nixos/modules/security/ca.nix b/nixos/modules/security/ca.nix index 849530238e7e..67469be18b41 100644 --- a/nixos/modules/security/ca.nix +++ b/nixos/modules/security/ca.nix @@ -4,10 +4,16 @@ with lib; let + cfg = config.security.pki; + + cacertPackage = pkgs.cacert.override { + blacklist = cfg.caCertificateBlacklist; + }; + caCertificates = pkgs.runCommand "ca-certificates.crt" { files = - config.security.pki.certificateFiles ++ - [ (builtins.toFile "extra.crt" (concatStringsSep "\n" config.security.pki.certificates)) ]; + cfg.certificateFiles ++ + [ (builtins.toFile "extra.crt" (concatStringsSep "\n" cfg.certificates)) ]; } '' cat $files > $out @@ -52,11 +58,27 @@ in ''; }; + security.pki.caCertificateBlacklist = mkOption { + type = types.listOf types.str; + default = []; + example = [ + "WoSign" "WoSign China" + "CA WoSign ECC Root" + "Certification Authority of WoSign G2" + ]; + description = '' + A list of blacklisted CA certificate names that won't be imported from + the Mozilla Trust Store into + <filename>/etc/ssl/certs/ca-certificates.crt</filename>. Use the + names from that file. + ''; + }; + }; config = { - security.pki.certificateFiles = [ "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; + security.pki.certificateFiles = [ "${cacertPackage}/etc/ssl/certs/ca-bundle.crt" ]; # NixOS canonical location + Debian/Ubuntu/Arch/Gentoo compatibility. environment.etc."ssl/certs/ca-certificates.crt".source = caCertificates; diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix index 7ba25f866f24..53c2ace784ef 100644 --- a/nixos/modules/security/grsecurity.nix +++ b/nixos/modules/security/grsecurity.nix @@ -67,9 +67,9 @@ in system.requiredKernelConfig = with config.lib.kernelConfig; [ (isEnabled "GRKERNSEC") (isEnabled "PAX") - (isYES "GRKERNSEC_SYSCTL") - (isYES "GRKERNSEC_SYSCTL_DISTRO") - (isNO "GRKERNSEC_NO_RBAC") + (isYes "GRKERNSEC_SYSCTL") + (isYes "GRKERNSEC_SYSCTL_DISTRO") + (isNo "GRKERNSEC_NO_RBAC") ]; nixpkgs.config.grsecurity = true; diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix index 85e0a7d2ac4e..5ec2e2c26232 100644 --- a/nixos/modules/services/audio/mpd.nix +++ b/nixos/modules/services/audio/mpd.nix @@ -49,7 +49,7 @@ in { }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; description = '' Extra directives added to to the end of MPD's configuration file, diff --git a/nixos/modules/services/backup/bacula.nix b/nixos/modules/services/backup/bacula.nix index ef8e5e55edef..340b0cf07234 100644 --- a/nixos/modules/services/backup/bacula.nix +++ b/nixos/modules/services/backup/bacula.nix @@ -340,6 +340,7 @@ in { extraConfig = mkOption { default = ""; + type = types.lines; description = '' Extra configuration for Bacula Director Daemon. ''; diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix index e5e8a57f4b0e..1180531248f9 100644 --- a/nixos/modules/services/databases/mysql.nix +++ b/nixos/modules/services/databases/mysql.nix @@ -53,7 +53,8 @@ in package = mkOption { type = types.package; default = pkgs.mysql; - example = literalExample "pkgs.mysql"; + defaultText = "pkgs.mysql"; + example = literalExample "pkgs.mysql55"; description = " Which MySQL derivation to use. "; diff --git a/nixos/modules/services/databases/neo4j.nix b/nixos/modules/services/databases/neo4j.nix index 146a604adb2f..7b51f1af6899 100644 --- a/nixos/modules/services/databases/neo4j.nix +++ b/nixos/modules/services/databases/neo4j.nix @@ -5,34 +5,34 @@ with lib; let cfg = config.services.neo4j; - serverConfig = pkgs.writeText "neo4j-server.properties" '' - org.neo4j.server.database.location=${cfg.dataDir}/data/graph.db - org.neo4j.server.webserver.address=${cfg.listenAddress} - org.neo4j.server.webserver.port=${toString cfg.port} + serverConfig = pkgs.writeText "neo4j.conf" '' + dbms.directories.data=${cfg.dataDir}/data + dbms.directories.certificates=${cfg.certDir} + dbms.directories.logs=${cfg.dataDir}/logs + dbms.directories.plugins=${cfg.dataDir}/plugins + dbms.connector.http.type=HTTP + dbms.connector.http.enabled=true + dbms.connector.http.address=${cfg.listenAddress}:${toString cfg.port} + ${optionalString cfg.enableBolt '' + dbms.connector.bolt.type=BOLT + dbms.connector.bolt.enabled=true + dbms.connector.bolt.tls_level=OPTIONAL + dbms.connector.bolt.address=${cfg.listenAddress}:${toString cfg.boltPort} + ''} ${optionalString cfg.enableHttps '' - org.neo4j.server.webserver.https.enabled=true - org.neo4j.server.webserver.https.port=${toString cfg.httpsPort} - org.neo4j.server.webserver.https.cert.location=${cfg.cert} - org.neo4j.server.webserver.https.key.location=${cfg.key} - org.neo4j.server.webserver.https.keystore.location=${cfg.dataDir}/data/keystore + dbms.connector.https.type=HTTP + dbms.connector.https.enabled=true + dbms.connector.https.encryption=TLS + dbms.connector.https.address=${cfg.listenAddress}:${toString cfg.httpsPort} ''} - org.neo4j.server.webadmin.rrdb.location=${cfg.dataDir}/data/rrd - org.neo4j.server.webadmin.data.uri=/db/data/ - org.neo4j.server.webadmin.management.uri=/db/manage/ - org.neo4j.server.db.tuning.properties=${cfg.package}/share/neo4j/conf/neo4j.properties - org.neo4j.server.manage.console_engines=shell + dbms.shell.enabled=true ${cfg.extraServerConfig} ''; - loggingConfig = pkgs.writeText "logging.properties" cfg.loggingConfig; - wrapperConfig = pkgs.writeText "neo4j-wrapper.conf" '' - wrapper.java.additional=-Dorg.neo4j.server.properties=${serverConfig} - wrapper.java.additional=-Djava.util.logging.config.file=${loggingConfig} - wrapper.java.additional=-XX:+UseConcMarkSweepGC - wrapper.java.additional=-XX:+CMSClassUnloadingEnabled - wrapper.pidfile=${cfg.dataDir}/neo4j-server.pid - wrapper.name=neo4j + dbms.jvm.additional=-Dunsupported.dbms.udc.source=tarball + dbms.jvm.additional=-XX:+UseConcMarkSweepGC + dbms.jvm.additional=-XX:+CMSClassUnloadingEnabled ''; in { @@ -65,6 +65,18 @@ in { type = types.int; }; + enableBolt = mkOption { + description = "Enable bolt for Neo4j."; + default = true; + type = types.bool; + }; + + boltPort = mkOption { + description = "Neo4j port to listen for BOLT traffic."; + default = 7687; + type = types.int; + }; + enableHttps = mkOption { description = "Enable https for Neo4j."; default = false; @@ -77,15 +89,9 @@ in { type = types.int; }; - cert = mkOption { - description = "Neo4j https certificate."; - default = "${cfg.dataDir}/conf/ssl/neo4j.cert"; - type = types.path; - }; - - key = mkOption { - description = "Neo4j https certificate key."; - default = "${cfg.dataDir}/conf/ssl/neo4j.key"; + certDir = mkOption { + description = "Neo4j TLS certificates directory."; + default = "${cfg.dataDir}/certificates"; type = types.path; }; @@ -95,26 +101,11 @@ in { type = types.path; }; - loggingConfig = mkOption { - description = "Neo4j logging configuration."; - default = '' - handlers=java.util.logging.ConsoleHandler - .level=INFO - org.neo4j.server.level=INFO - - java.util.logging.ConsoleHandler.level=INFO - java.util.logging.ConsoleHandler.formatter=org.neo4j.server.logging.SimpleConsoleFormatter - java.util.logging.ConsoleHandler.filter=org.neo4j.server.logging.NeoLogFilter - ''; - type = types.lines; - }; - extraServerConfig = mkOption { description = "Extra configuration for neo4j server."; default = ""; type = types.lines; }; - }; ###### implementation @@ -124,14 +115,18 @@ in { description = "Neo4j Daemon"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - environment = { NEO4J_INSTANCE = cfg.dataDir; }; + environment = { + NEO4J_HOME = "${cfg.package}/share/neo4j"; + NEO4J_CONF = "${cfg.dataDir}/conf"; + }; serviceConfig = { ExecStart = "${cfg.package}/bin/neo4j console"; User = "neo4j"; PermissionsStartOnly = true; }; preStart = '' - mkdir -m 0700 -p ${cfg.dataDir}/{data/graph.db,conf} + mkdir -m 0700 -p ${cfg.dataDir}/{data/graph.db,conf,logs} + ln -fs ${serverConfig} ${cfg.dataDir}/conf/neo4j.conf ln -fs ${wrapperConfig} ${cfg.dataDir}/conf/neo4j-wrapper.conf if [ "$(id -u)" = 0 ]; then chown -R neo4j ${cfg.dataDir}; fi ''; @@ -146,5 +141,4 @@ in { home = cfg.dataDir; }; }; - } diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix index 9f22aa7c92b2..b8e6c0cec3dc 100644 --- a/nixos/modules/services/databases/openldap.nix +++ b/nixos/modules/services/databases/openldap.nix @@ -53,6 +53,13 @@ in description = "The database directory."; }; + configDir = mkOption { + type = types.nullOr types.path; + default = null; + description = "Use this optional config directory instead of using slapd.conf"; + example = "/var/db/slapd.d"; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -96,7 +103,7 @@ in mkdir -p ${cfg.dataDir} chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir} ''; - serviceConfig.ExecStart = "${openldap.out}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -h \"${concatStringsSep " " cfg.urlList}\" -f ${configFile}"; + serviceConfig.ExecStart = "${openldap.out}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -h \"${concatStringsSep " " cfg.urlList}\" ${if cfg.configDir == null then "-f "+configFile else "-F "+cfg.configDir}"; }; users.extraUsers.openldap = diff --git a/nixos/modules/services/desktops/gnome3/evolution-data-server.nix b/nixos/modules/services/desktops/gnome3/evolution-data-server.nix index a8f8da0eed56..2db2e2fe1c34 100644 --- a/nixos/modules/services/desktops/gnome3/evolution-data-server.nix +++ b/nixos/modules/services/desktops/gnome3/evolution-data-server.nix @@ -37,6 +37,8 @@ in services.dbus.packages = [ gnome3.evolution_data_server ]; + systemd.packages = [ gnome3.evolution_data_server ]; + }; } diff --git a/nixos/modules/services/desktops/gnome3/gnome-terminal-server.nix b/nixos/modules/services/desktops/gnome3/gnome-terminal-server.nix new file mode 100644 index 000000000000..384cede679c6 --- /dev/null +++ b/nixos/modules/services/desktops/gnome3/gnome-terminal-server.nix @@ -0,0 +1,44 @@ +# GNOME Documents daemon. + +{ config, pkgs, lib, ... }: + +with lib; + +let + gnome3 = config.environment.gnome3.packageSet; +in +{ + + ###### interface + + options = { + + services.gnome3.gnome-terminal-server = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable GNOME Terminal server service, + needed for gnome-terminal. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf config.services.gnome3.gnome-terminal-server.enable { + + environment.systemPackages = [ gnome3.gnome_terminal ]; + + services.dbus.packages = [ gnome3.gnome_terminal ]; + + systemd.packages = [ gnome3.gnome_terminal ]; + + }; + +} diff --git a/nixos/modules/services/desktops/gnome3/gvfs.nix b/nixos/modules/services/desktops/gnome3/gvfs.nix index a07cdadbb12b..6bbabe8d3c56 100644 --- a/nixos/modules/services/desktops/gnome3/gvfs.nix +++ b/nixos/modules/services/desktops/gnome3/gvfs.nix @@ -37,6 +37,8 @@ in services.dbus.packages = [ gnome3.gvfs ]; + systemd.packages = [ gnome3.gvfs ]; + services.udev.packages = [ pkgs.libmtp.bin ]; }; diff --git a/nixos/modules/services/desktops/gnome3/tracker.nix b/nixos/modules/services/desktops/gnome3/tracker.nix index 8c5935a5ee3c..dcaa60103a3b 100644 --- a/nixos/modules/services/desktops/gnome3/tracker.nix +++ b/nixos/modules/services/desktops/gnome3/tracker.nix @@ -37,6 +37,8 @@ in services.dbus.packages = [ gnome3.tracker ]; + systemd.packages = [ gnome3.tracker ]; + }; } diff --git a/nixos/modules/services/editors/emacs.xml b/nixos/modules/services/editors/emacs.xml index 544e4a1076f4..bcaa8b8df3d8 100644 --- a/nixos/modules/services/editors/emacs.xml +++ b/nixos/modules/services/editors/emacs.xml @@ -43,9 +43,10 @@ <title>Installing <application>Emacs</application></title> <para> - Emacs can installed in the normal way for Nix (see <xref - linkend="sec-package-management" />). In addition, a NixOS - <emphasis>service</emphasis> can be enabled. + Emacs can be installed in the normal way for Nix (see + <xref linkend="sec-package-management" />). + In addition, a NixOS <emphasis>service</emphasis> + can be enabled. </para> <section> @@ -564,6 +565,55 @@ services.emacs.install = true; <RET> nixos-rebuild <RET>.</literal> </para> </section> + + <section xml:id="sec-emacs-docbook-xml"> + <title>Editing DocBook 5 XML Documents</title> + <para> + Emacs includes <link + xlink:href="https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html">nXML</link>, + a major-mode for validating and editing XML documents. + When editing DocBook 5.0 documents, such as + <link linkend="book-nixos-manual">this one</link>, + nXML needs to be configured with the relevant schema, which is + not included. + </para> + + <para> + To install the DocBook 5.0 schemas, either add + <varname>pkgs.docbook5</varname> to + <varname>environment.systemPackages</varname> (<link + linkend="sec-declarative-package-mgmt">NixOS</link>), or run + <literal>nix-env -i pkgs.docbook5</literal> + (<link linkend="sec-ad-hoc-packages">Nix</link>). + </para> + + <para> + Then customize the variable <varname>rng-schema-locating-files</varname> to include <filename>~/.emacs.d/schemas.xml</filename> and put the following text into that file: + <example xml:id="ex-emacs-docbook-xml"> + <title>nXML Schema Configuration (<filename>~/.emacs.d/schemas.xml</filename>)</title> + <programlisting language="xml"><![CDATA[ +<?xml version="1.0"?> +<!-- + To let emacs find this file, evaluate: + (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml") +--> +<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0"> + <!-- + Use this variation if pkgs.docbook5 is added to environment.systemPackages + --> + <namespace ns="http://docbook.org/ns/docbook" + uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/> + <!-- + Use this variation if installing schema with "nix-env -iA pkgs.docbook5". + <namespace ns="http://docbook.org/ns/docbook" + uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/> + --> +</locatingRules> +]]></programlisting> + </example> + </para> + + </section> </section> </chapter> diff --git a/nixos/modules/services/hardware/brltty.nix b/nixos/modules/services/hardware/brltty.nix index 03e530b2c96d..b416ba332222 100644 --- a/nixos/modules/services/hardware/brltty.nix +++ b/nixos/modules/services/hardware/brltty.nix @@ -28,7 +28,7 @@ in { }; serviceConfig = { ExecStart = "${pkgs.brltty}/bin/brltty --no-daemon"; - Type = "simple"; # Change to notidy after next releae + Type = "notify"; TimeoutStartSec = 5; TimeoutStopSec = 10; Restart = "always"; diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix index 281d02a8c65e..f36a9e7b4596 100644 --- a/nixos/modules/services/hardware/tlp.nix +++ b/nixos/modules/services/hardware/tlp.nix @@ -40,7 +40,7 @@ in }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; description = "Additional configuration variables for TLP"; }; diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix index e79d5dadd828..4c9df935debe 100644 --- a/nixos/modules/services/mail/dovecot.nix +++ b/nixos/modules/services/mail/dovecot.nix @@ -111,7 +111,7 @@ in }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; example = "mail_debug = yes"; description = "Additional entries to put verbatim into Dovecot's config file."; diff --git a/nixos/modules/services/mail/opensmtpd.nix b/nixos/modules/services/mail/opensmtpd.nix index fb94560e10aa..53acdba42457 100644 --- a/nixos/modules/services/mail/opensmtpd.nix +++ b/nixos/modules/services/mail/opensmtpd.nix @@ -1,17 +1,16 @@ { config, lib, pkgs, ... }: -with pkgs; with lib; let cfg = config.services.opensmtpd; - conf = writeText "smtpd.conf" cfg.serverConfiguration; + conf = pkgs.writeText "smtpd.conf" cfg.serverConfiguration; args = concatStringsSep " " cfg.extraServerArgs; sendmail = pkgs.runCommand "opensmtpd-sendmail" {} '' mkdir -p $out/bin - ln -s ${opensmtpd}/sbin/smtpctl $out/bin/sendmail + ln -s ${pkgs.opensmtpd}/sbin/smtpctl $out/bin/sendmail ''; in { @@ -48,21 +47,19 @@ in { }; serverConfiguration = mkOption { - type = types.string; - default = ""; + type = types.lines; example = '' listen on lo accept for any deliver to lmtp localhost:24 - ''; + ''; description = '' The contents of the smtpd.conf configuration file. See the - OpenSMTPD documentation for syntax information. If this option - is left empty, the OpenSMTPD server will not start. + OpenSMTPD documentation for syntax information. ''; }; procPackages = mkOption { - type = types.listOf types.path; + type = types.listOf types.package; default = []; description = '' Packages to search for filters, tables, queues, and schedulers. @@ -100,12 +97,11 @@ in { systemd.services.opensmtpd = let procEnv = pkgs.buildEnv { name = "opensmtpd-procs"; - paths = [ opensmtpd ] ++ cfg.procPackages; + paths = [ pkgs.opensmtpd ] ++ cfg.procPackages; pathsToLink = [ "/libexec/opensmtpd" ]; }; in { wantedBy = [ "multi-user.target" ]; - wants = [ "network.target" ]; after = [ "network.target" ]; preStart = '' mkdir -p /var/spool/smtpd @@ -119,7 +115,7 @@ in { chown smtpq.root /var/spool/smtpd/purge chmod 700 /var/spool/smtpd/purge ''; - serviceConfig.ExecStart = "${opensmtpd}/sbin/smtpd -d -f ${conf} ${args}"; + serviceConfig.ExecStart = "${pkgs.opensmtpd}/sbin/smtpd -d -f ${conf} ${args}"; environment.OPENSMTPD_PROC_PATH = "${procEnv}/libexec/opensmtpd"; }; diff --git a/nixos/modules/services/misc/bepasty.nix b/nixos/modules/services/misc/bepasty.nix index 5bda73ab64f0..52719222db66 100644 --- a/nixos/modules/services/misc/bepasty.nix +++ b/nixos/modules/services/misc/bepasty.nix @@ -53,7 +53,7 @@ in }; extraConfig = mkOption { - type = types.str; + type = types.lines; description = '' Extra configuration for bepasty server to be appended on the configuration. diff --git a/nixos/modules/services/misc/docker-registry.nix b/nixos/modules/services/misc/docker-registry.nix new file mode 100644 index 000000000000..96ac2a1cf2c9 --- /dev/null +++ b/nixos/modules/services/misc/docker-registry.nix @@ -0,0 +1,66 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.dockerRegistry; + +in { + options.services.dockerRegistry = { + enable = mkEnableOption "Docker Registry"; + + listenAddress = mkOption { + description = "Docker registry host or ip to bind to."; + default = "127.0.0.1"; + type = types.str; + }; + + port = mkOption { + description = "Docker registry port to bind to."; + default = 5000; + type = types.int; + }; + + storagePath = mkOption { + type = types.path; + default = "/var/lib/docker-registry"; + description = "Docker registry storage path."; + }; + + extraConfig = mkOption { + description = '' + Docker extra registry configuration via environment variables. + ''; + default = {}; + type = types.attrsOf types.str; + }; + }; + + config = mkIf cfg.enable { + systemd.services.docker-registry = { + description = "Docker Container Registry"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + environment = { + REGISTRY_HTTP_ADDR = "${cfg.listenAddress}:${toString cfg.port}"; + REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY = cfg.storagePath; + } // cfg.extraConfig; + + script = '' + ${pkgs.docker-distribution}/bin/registry serve \ + ${pkgs.docker-distribution.out}/share/go/src/github.com/docker/distribution/cmd/registry/config-example.yml + ''; + + serviceConfig = { + User = "docker-registry"; + WorkingDirectory = cfg.storagePath; + }; + }; + + users.extraUsers.docker-registry = { + createHome = true; + home = cfg.storagePath; + }; + }; +} diff --git a/nixos/modules/services/misc/errbot.nix b/nixos/modules/services/misc/errbot.nix new file mode 100644 index 000000000000..f573be69925c --- /dev/null +++ b/nixos/modules/services/misc/errbot.nix @@ -0,0 +1,101 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.errbot; + pluginEnv = plugins: pkgs.buildEnv { + name = "errbot-plugins"; + paths = plugins; + }; + mkConfigFile = instanceCfg: dataDir: pkgs.writeText "errbot-config.py" '' + import logging + BACKEND = '${instanceCfg.backend}' + BOT_DATA_DIR = '${dataDir}' + BOT_EXTRA_PLUGIN_DIR = '${pluginEnv instanceCfg.plugins}' + + BOT_LOG_LEVEL = logging.${instanceCfg.logLevel} + BOT_LOG_FILE = False + + BOT_ADMINS = (${concatMapStringsSep "," (name: "'${name}'") instanceCfg.admins}) + + BOT_IDENTITY = ${builtins.toJSON instanceCfg.identity} + + ${instanceCfg.extraConfig} + ''; +in { + options = { + services.errbot.instances = mkOption { + default = {}; + description = "Errbot instance configs"; + type = types.attrsOf (types.submodule { + options = { + dataDir = mkOption { + type = types.nullOr types.path; + default = null; + description = "Data directory for errbot instance."; + }; + + plugins = mkOption { + type = types.listOf types.package; + default = []; + description = "List of errbot plugin derivations."; + }; + + logLevel = mkOption { + type = types.str; + default = "INFO"; + description = "Errbot log level"; + }; + + admins = mkOption { + type = types.listOf types.str; + default = []; + description = "List of identifiers of errbot admins."; + }; + + backend = mkOption { + type = types.str; + default = "XMPP"; + description = "Errbot backend name."; + }; + + identity = mkOption { + type = types.attrs; + description = "Errbot identity configuration"; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = "String to be appended to the config verbatim"; + }; + }; + }); + }; + }; + + config = mkIf (cfg.instances != {}) { + users.extraUsers.errbot.group = "errbot"; + users.extraGroups.errbot = {}; + + systemd.services = mapAttrs' (name: instanceCfg: nameValuePair "errbot-${name}" ( + let + dataDir = if !isNull instanceCfg.dataDir then instanceCfg.dataDir else + "/var/lib/errbot/${name}"; + in { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + preStart = '' + mkdir -p ${dataDir} + chown -R errbot:errbot ${dataDir} + ''; + serviceConfig = { + User = "errbot"; + Restart = "on-failure"; + ExecStart = "${pkgs.errbot}/bin/errbot -c ${mkConfigFile instanceCfg dataDir}"; + PermissionsStartOnly = true; + }; + })) cfg.instances; + }; +} diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index f8881233dceb..3e4584c7a512 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -463,6 +463,7 @@ in { systemd.services.gitlab = { after = [ "network.target" "postgresql.service" "redis.service" ]; + requires = [ "gitlab-sidekiq.service" ]; wantedBy = [ "multi-user.target" ]; environment = gitlabEnv; path = with pkgs; [ diff --git a/nixos/modules/services/misc/nix-gc.nix b/nixos/modules/services/misc/nix-gc.nix index 5c13da6e83dd..304168c65b0b 100644 --- a/nixos/modules/services/misc/nix-gc.nix +++ b/nixos/modules/services/misc/nix-gc.nix @@ -53,7 +53,7 @@ in systemd.services.nix-gc = { description = "Nix Garbage Collector"; script = "exec ${config.nix.package.out}/bin/nix-collect-garbage ${cfg.options}"; - startAt = optionalString cfg.automatic cfg.dates; + startAt = optional cfg.automatic cfg.dates; }; }; diff --git a/nixos/modules/services/misc/nix-optimise.nix b/nixos/modules/services/misc/nix-optimise.nix index 87ce05c5a11b..a76bfd9f1f19 100644 --- a/nixos/modules/services/misc/nix-optimise.nix +++ b/nixos/modules/services/misc/nix-optimise.nix @@ -41,7 +41,7 @@ in systemd.services.nix-optimise = { description = "Nix Store Optimiser"; serviceConfig.ExecStart = "${config.nix.package}/bin/nix-store --optimise"; - startAt = optional cfg.automatic cfg.dates; + startAt = optionals cfg.automatic cfg.dates; }; }; diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix index 7c9483911f21..e3f1ec67cbb3 100644 --- a/nixos/modules/services/misc/redmine.nix +++ b/nixos/modules/services/misc/redmine.nix @@ -71,7 +71,7 @@ in { }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; description = "Extra configuration in configuration.yml"; }; diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix index 6d458feec345..233c47684b7d 100644 --- a/nixos/modules/services/misc/taskserver/default.nix +++ b/nixos/modules/services/misc/taskserver/default.nix @@ -154,7 +154,7 @@ let certtool = "${pkgs.gnutls.bin}/bin/certtool"; - nixos-taskserver = pkgs.buildPythonPackage { + nixos-taskserver = pkgs.pythonPackages.buildPythonPackage { name = "nixos-taskserver"; namePrefix = ""; diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix index 9a1e790d3ab6..496838a131ba 100644 --- a/nixos/modules/services/monitoring/bosun.nix +++ b/nixos/modules/services/monitoring/bosun.nix @@ -107,7 +107,7 @@ in { }; extraConfig = mkOption { - type = types.string; + type = types.lines; default = ""; description = '' Extra configuration options for Bosun. You should describe your diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix index 1de3320dc42c..b8be9296bc97 100644 --- a/nixos/modules/services/monitoring/graphite.nix +++ b/nixos/modules/services/monitoring/graphite.nix @@ -167,7 +167,7 @@ in { CACHE_TYPE: 'filesystem' CACHE_DIR: '/tmp/graphite-api-cache' ''; - type = types.str; + type = types.lines; }; }; diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index aaa041ad4cd6..57df16b58d9c 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -100,6 +100,7 @@ in extraConfig = mkOption { default = ""; + type = types.lines; description = '' <filename>munin-node.conf</filename> extra configuration. See <link xlink:href='http://munin-monitoring.org/wiki/munin-node.conf' /> diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index e6817ee227ab..82b97bd92f87 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -300,13 +300,14 @@ let }; regex = mkOption { type = types.str; + default = "(.*)"; description = '' Regular expression against which the extracted value is matched. ''; }; replacement = mkOption { type = types.str; - default = ""; + default = "$1"; description = '' Replacement value against which a regex replace is performed if the regular expression matches. @@ -314,6 +315,7 @@ let }; action = mkOption { type = types.enum ["replace" "keep" "drop"]; + default = "replace"; description = '' Action to perform based on regex matching. ''; diff --git a/nixos/modules/services/monitoring/riemann-tools.nix b/nixos/modules/services/monitoring/riemann-tools.nix index ce277f09464a..de858813a762 100644 --- a/nixos/modules/services/monitoring/riemann-tools.nix +++ b/nixos/modules/services/monitoring/riemann-tools.nix @@ -50,6 +50,7 @@ in { systemd.services.riemann-health = { wantedBy = [ "multi-user.target" ]; + path = [ procps ]; serviceConfig = { User = "riemanntools"; ExecStart = "${healthLauncher}/bin/riemann-health"; diff --git a/nixos/modules/services/monitoring/zabbix-agent.nix b/nixos/modules/services/monitoring/zabbix-agent.nix index a943075be0c4..88a63b4bf161 100644 --- a/nixos/modules/services/monitoring/zabbix-agent.nix +++ b/nixos/modules/services/monitoring/zabbix-agent.nix @@ -53,6 +53,7 @@ in extraConfig = mkOption { default = ""; + type = types.lines; description = '' Configuration that is injected verbatim into the configuration file. ''; diff --git a/nixos/modules/services/network-filesystems/cachefilesd.nix b/nixos/modules/services/network-filesystems/cachefilesd.nix new file mode 100644 index 000000000000..619813408405 --- /dev/null +++ b/nixos/modules/services/network-filesystems/cachefilesd.nix @@ -0,0 +1,59 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + + cfg = config.services.cachefilesd; + + cfgFile = pkgs.writeText "cachefilesd.conf" '' + dir ${cfg.cacheDir} + ${cfg.extraConfig} + ''; + +in + +{ + options = { + services.cachefilesd = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable cachefilesd network filesystems caching daemon."; + }; + + cacheDir = mkOption { + type = types.str; + default = "/var/cache/fscache"; + description = "Directory to contain filesystem cache."; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = "brun 10%"; + description = "Additional configuration file entries. See cachefilesd.conf(5) for more information."; + }; + + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.cachefilesd = { + description = "Local network file caching management daemon"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.kmod pkgs.cachefilesd ]; + script = '' + modprobe -qab cachefiles + mkdir -p ${cfg.cacheDir} + chmod 700 ${cfg.cacheDir} + exec cachefilesd -n -f ${cfgFile} + ''; + }; + + }; +} diff --git a/nixos/modules/services/network-filesystems/xtreemfs.nix b/nixos/modules/services/network-filesystems/xtreemfs.nix index b051214e1d08..0c6714563d8a 100644 --- a/nixos/modules/services/network-filesystems/xtreemfs.nix +++ b/nixos/modules/services/network-filesystems/xtreemfs.nix @@ -153,6 +153,7 @@ in ''; }; extraConfig = mkOption { + type = types.lines; default = ""; example = '' # specify whether SSL is required @@ -173,6 +174,7 @@ in replication = { enable = mkEnableOption "XtreemFS DIR replication plugin"; extraConfig = mkOption { + type = types.lines; example = '' # participants of the replication including this replica babudb.repl.participant.0 = 192.168.0.10 @@ -269,6 +271,7 @@ in ''; }; extraConfig = mkOption { + type = types.lines; example = '' osd_check_interval = 300 no_atime = true @@ -307,6 +310,7 @@ in replication = { enable = mkEnableOption "XtreemFS MRC replication plugin"; extraConfig = mkOption { + type = types.lines; example = '' # participants of the replication including this replica babudb.repl.participant.0 = 192.168.0.10 @@ -385,6 +389,7 @@ in ''; }; extraConfig = mkOption { + type = types.lines; example = '' local_clock_renewal = 0 remote_time_sync = 30000 diff --git a/nixos/modules/services/networking/atftpd.nix b/nixos/modules/services/networking/atftpd.nix index d875ddc63528..e7fd48c99a85 100644 --- a/nixos/modules/services/networking/atftpd.nix +++ b/nixos/modules/services/networking/atftpd.nix @@ -20,13 +20,27 @@ in default = false; type = types.bool; description = '' - Whenever to enable the atftpd TFTP server. + Whether to enable the atftpd TFTP server. By default, the server + binds to address 0.0.0.0. + ''; + }; + + extraOptions = mkOption { + default = []; + type = types.listOf types.str; + example = literalExample '' + [ "--bind-address 192.168.9.1" + "--verbose=7" + ] + ''; + description = '' + Extra command line arguments to pass to atftp. ''; }; root = mkOption { - default = "/var/empty"; - type = types.str; + default = "/srv/tftp"; + type = types.path; description = '' Document root directory for the atftpd. ''; @@ -39,11 +53,11 @@ in config = mkIf cfg.enable { systemd.services.atftpd = { - description = "atftpd TFTP server"; + description = "TFTP Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; # runs as nobody - serviceConfig.ExecStart = "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address 0.0.0.0 ${cfg.root}"; + serviceConfig.ExecStart = "${pkgs.atftp}/sbin/atftpd --daemon --no-fork ${lib.concatStringsSep " " cfg.extraOptions} ${cfg.root}"; }; }; diff --git a/nixos/modules/services/networking/avahi-daemon.nix b/nixos/modules/services/networking/avahi-daemon.nix index ecc091d1d03d..6a786e75bbc8 100644 --- a/nixos/modules/services/networking/avahi-daemon.nix +++ b/nixos/modules/services/networking/avahi-daemon.nix @@ -175,11 +175,20 @@ in environment.systemPackages = [ pkgs.avahi ]; + systemd.sockets.avahi-daemon = + { description = "Avahi mDNS/DNS-SD Stack Activation Socket"; + listenStreams = [ "/var/run/avahi-daemon/socket" ]; + wantedBy = [ "sockets.target" ]; + }; + systemd.services.avahi-daemon = - { description = "Avahi daemon"; + { description = "Avahi mDNS/DNS-SD Stack"; wantedBy = [ "multi-user.target" ]; - # Receive restart event after resume - partOf = [ "post-resume.target" ]; + requires = [ "avahi-daemon.socket" ]; + + serviceConfig."NotifyAccess" = "main"; + serviceConfig."BusName" = "org.freedesktop.Avahi"; + serviceConfig."Type" = "dbus"; path = [ pkgs.coreutils pkgs.avahi ]; diff --git a/nixos/modules/services/networking/bind.nix b/nixos/modules/services/networking/bind.nix index 41d7128ec31e..72110e625766 100644 --- a/nixos/modules/services/networking/bind.nix +++ b/nixos/modules/services/networking/bind.nix @@ -113,6 +113,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; description = " Extra lines to be added verbatim to the generated named configuration file. diff --git a/nixos/modules/services/networking/chrony.nix b/nixos/modules/services/networking/chrony.nix index a38142b4a08f..d40865ebbd5b 100644 --- a/nixos/modules/services/networking/chrony.nix +++ b/nixos/modules/services/networking/chrony.nix @@ -51,6 +51,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; description = '' Extra configuration directives that should be added to diff --git a/nixos/modules/services/networking/cjdns-hosts.sh b/nixos/modules/services/networking/cjdns-hosts.sh deleted file mode 100644 index 8a2b47e52143..000000000000 --- a/nixos/modules/services/networking/cjdns-hosts.sh +++ /dev/null @@ -1,11 +0,0 @@ -pubs=($pubs) -hosts=($hosts) - -lines="''\n" -for ((i = 0; i < ${#pubs[*]}; i++)); do - addr=$($cjdns/bin/publictoip6 ${pubs[i]}) - lines="${lines}$addr ${hosts[i]}\n" -done -lines="${lines}''" - -echo -ne $lines > $out diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index cb00139c5f1c..5e15e40ea0c1 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -28,21 +28,18 @@ let }; }; - peers = mapAttrsToList (n: v: v) (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo); - - pubs = toString (map (p: if p.hostname == "" then "" else p.publicKey) peers); - hosts = toString (map (p: if p.hostname == "" then "" else p.hostname) peers); - - cjdnsHosts = - if hosts != "" then - import (pkgs.stdenv.mkDerivation { - name = "cjdns-hosts"; - builder = ./cjdns-hosts.sh; - - inherit (pkgs) cjdns; - inherit pubs hosts; - }) - else ""; + # Additional /etc/hosts entries for peers with an associated hostname + cjdnsExtraHosts = import (pkgs.runCommand "cjdns-hosts" {} + # Generate a builder that produces an output usable as a Nix string value + '' + exec >$out + echo \'\' + ${concatStringsSep "\n" (mapAttrsToList (k: v: + optionalString (v.hostname != "") + "echo $(${pkgs.cjdns}/bin/publictoip6 ${x.key}) ${x.host}") + (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))} + echo \'\' + ''); parseModules = x: x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; }; @@ -95,8 +92,8 @@ in }; confFile = mkOption { - type = types.str; - default = ""; + type = types.nullOr types.path; + default = null; example = "/etc/cjdroute.conf"; description = '' Ignore all other cjdns options and load configuration from this file. @@ -112,14 +109,14 @@ in "49275fut6tmzu354pq70sr5b95qq0vj" ]; description = '' - Any remote cjdns nodes that offer these passwords on + Any remote cjdns nodes that offer these passwords on connection will be allowed to route through this node. ''; }; - + admin = { bind = mkOption { - type = types.string; + type = types.str; default = "127.0.0.1:11234"; description = '' Bind the administration port to this address and port. @@ -129,7 +126,7 @@ in UDPInterface = { bind = mkOption { - type = types.string; + type = types.str; default = ""; example = "192.168.1.32:43211"; description = '' @@ -154,6 +151,7 @@ in ETHInterface = { bind = mkOption { + type = types.str; default = ""; example = "eth0"; description = @@ -201,7 +199,7 @@ in }; - config = mkIf config.services.cjdns.enable { + config = mkIf cfg.enable { boot.kernelModules = [ "tun" ]; @@ -212,7 +210,7 @@ in wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - preStart = if cfg.confFile != "" then "" else '' + preStart = if cfg.confFile != null then "" else '' [ -e /etc/cjdns.keys ] && source /etc/cjdns.keys if [ -z "$CJDNS_PRIVATE_KEY" ]; then @@ -228,13 +226,13 @@ in fi if [ -z "$CJDNS_ADMIN_PASSWORD" ]; then - echo "CJDNS_ADMIN_PASSWORD=$(${pkgs.coreutils}/bin/head -c 96 /dev/urandom | ${pkgs.coreutils}/bin/tr -dc A-Za-z0-9)" \ + echo "CJDNS_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 96)" \ >> /etc/cjdns.keys fi ''; script = ( - if cfg.confFile != "" then "${pkg}/bin/cjdroute < ${cfg.confFile}" else + if cfg.confFile != null then "${pkg}/bin/cjdroute < ${cfg.confFile}" else '' source /etc/cjdns.keys echo '${cjdrouteConf}' | sed \ @@ -247,13 +245,16 @@ in serviceConfig = { Type = "forking"; Restart = "on-failure"; + + ProtectHome = true; + PrivateTmp = true; }; }; - networking.extraHosts = "${cjdnsHosts}"; + networking.extraHosts = cjdnsExtraHosts; assertions = [ - { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != "" ); + { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null ); message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined."; } { assertion = config.networking.enableIPv6; diff --git a/nixos/modules/services/networking/cntlm.nix b/nixos/modules/services/networking/cntlm.nix index 76c0fd7d0ea3..890ff5084078 100644 --- a/nixos/modules/services/networking/cntlm.nix +++ b/nixos/modules/services/networking/cntlm.nix @@ -61,6 +61,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; description = "Verbatim contents of <filename>cntlm.conf</filename>."; }; diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index e74d68cad902..5050ecbd7492 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -89,7 +89,7 @@ in extraConfig = mkOption { default = ""; - type = str; + type = lines; description = '' Extra configuration. Contents will be added verbatim to the configuration file. ''; diff --git a/nixos/modules/services/networking/dhcpd.nix b/nixos/modules/services/networking/dhcpd.nix index 900df67b53aa..d2cd00e74a1f 100644 --- a/nixos/modules/services/networking/dhcpd.nix +++ b/nixos/modules/services/networking/dhcpd.nix @@ -47,6 +47,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; example = '' option subnet-mask 255.255.255.0; @@ -66,6 +67,14 @@ in "; }; + extraFlags = mkOption { + default = ""; + example = "-6"; + description = " + Additional command line flags to be passed to the dhcpd daemon. + "; + }; + configFile = mkOption { default = null; description = " @@ -138,6 +147,7 @@ in { ExecStart = "@${pkgs.dhcp}/sbin/dhcpd dhcpd" + " -pf /run/dhcpd/dhcpd.pid -cf ${configFile}" + " -lf ${stateDir}/dhcpd.leases -user dhcpd -group nogroup" + + " ${cfg.extraFlags}" + " ${toString cfg.interfaces}"; Restart = "always"; Type = "forking"; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix index 2714e8d75993..5a24db8ccba0 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy.nix @@ -35,7 +35,11 @@ in options = { services.dnscrypt-proxy = { - enable = mkEnableOption "DNSCrypt client proxy"; + enable = mkOption { + default = false; + type = types.bool; + description = "Whether to enable the DNSCrypt client proxy"; + }; localAddress = mkOption { default = "127.0.0.1"; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.xml b/nixos/modules/services/networking/dnscrypt-proxy.xml index e212a8d3e2c3..982961833ad2 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.xml +++ b/nixos/modules/services/networking/dnscrypt-proxy.xml @@ -49,8 +49,8 @@ <para> <programlisting> { - services.dnsmasq.enable = true; - services.dnsmasq.servers = [ "127.0.0.1#43" ]; + services.dnsmasq.enable = true; + services.dnsmasq.servers = [ "127.0.0.1#43" ]; } </programlisting> </para> @@ -60,12 +60,9 @@ <para> <programlisting> { - networking.nameservers = [ "127.0.0.1" ]; - services.unbound.enable = true; - services.unbound.forwardAddresses = [ "127.0.0.1@43" ]; - services.unbound.extraConfig = '' - do-not-query-localhost: no - ''; + networking.nameservers = [ "127.0.0.1" ]; + services.unbound.enable = true; + services.unbound.forwardAddresses = [ "127.0.0.1@43" ]; } </programlisting> </para> diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 942fcc03f59b..1c0ea5034df3 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -100,13 +100,13 @@ let # 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) '' + ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' # Clean up rpfilter rules ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true ip46tables -t raw -F nixos-fw-rpfilter 2> /dev/null || true ip46tables -t raw -N nixos-fw-rpfilter 2> /dev/null || true - ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter -j RETURN + ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN # Allows this host to act as a DHCPv4 server iptables -t raw -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN @@ -200,7 +200,7 @@ let # Clean up after added ruleset ip46tables -D INPUT -j nixos-fw 2>/dev/null || true - ${optionalString (kernelHasRPFilter && cfg.checkReversePath) '' + ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true ''} @@ -373,7 +373,7 @@ in networking.firewall.checkReversePath = mkOption { default = kernelHasRPFilter; - type = types.bool; + type = types.either types.bool (types.enum ["strict" "loose"]); description = '' Performs a reverse path filter test on a packet. @@ -381,7 +381,8 @@ in that the packet arrived on, it is refused. If using asymmetric routing or other complicated routing, - disable this setting and setup your own counter-measures. + set this option to loose mode or disable it and setup your + own counter-measures. (needs kernel 3.3+) ''; @@ -482,7 +483,7 @@ in options nf_conntrack nf_conntrack_helper=0 ''; - assertions = [ { assertion = ! cfg.checkReversePath || kernelHasRPFilter; + assertions = [ { assertion = (cfg.checkReversePath != false) || kernelHasRPFilter; message = "This kernel does not support rpfilter"; } { assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers; message = "This kernel does not support disabling conntrack helpers"; } diff --git a/nixos/modules/services/networking/hostapd.nix b/nixos/modules/services/networking/hostapd.nix index 287964aab072..51f95af48029 100644 --- a/nixos/modules/services/networking/hostapd.nix +++ b/nixos/modules/services/networking/hostapd.nix @@ -140,7 +140,7 @@ in ieee80211n=1 ht_capab=[HT40-][SHORT-GI-40][DSSS_CCK-40] ''; - type = types.string; + type = types.lines; description = "Extra configuration options to put in hostapd.conf."; }; }; diff --git a/nixos/modules/services/networking/ircd-hybrid/builder.sh b/nixos/modules/services/networking/ircd-hybrid/builder.sh index f2c92878a4dc..38312210df25 100644 --- a/nixos/modules/services/networking/ircd-hybrid/builder.sh +++ b/nixos/modules/services/networking/ircd-hybrid/builder.sh @@ -12,7 +12,7 @@ for i in $scripts; do if test "$(echo $i | cut -c1-2)" = "=>"; then subDir=$(echo $i | cut -c3-) else - dst=$out/$subDir/$((stripHash $i; echo $strippedName) | sed 's/\.in//') + dst=$out/$subDir/$(stripHash $i | sed 's/\.in//') doSub $i $dst chmod +x $dst # !!! fi @@ -23,7 +23,7 @@ for i in $substFiles; do if test "$(echo $i | cut -c1-2)" = "=>"; then subDir=$(echo $i | cut -c3-) else - dst=$out/$subDir/$((stripHash $i; echo $strippedName) | sed 's/\.in//') + dst=$out/$subDir/$(stripHash $i | sed 's/\.in//') doSub $i $dst fi done diff --git a/nixos/modules/services/networking/kippo.nix b/nixos/modules/services/networking/kippo.nix index 5f3efcd133a1..834de4fdc09f 100644 --- a/nixos/modules/services/networking/kippo.nix +++ b/nixos/modules/services/networking/kippo.nix @@ -46,7 +46,7 @@ rec { }; extraConfig = mkOption { default = ""; - type = types.string; + type = types.lines; description = ''Extra verbatim configuration added to the end of kippo.cfg.''; }; }; @@ -54,7 +54,7 @@ rec { }; config = mkIf cfg.enable { environment.systemPackages = with pkgs.pythonPackages; [ - python twisted_11 pycrypto pyasn1 ]; + python pkgs.kippo.twisted pycrypto pyasn1 ]; environment.etc."kippo.cfg".text = '' # Automatically generated by NixOS. @@ -84,7 +84,7 @@ rec { description = "Kippo Web Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment.PYTHONPATH = "${pkgs.kippo}/src/:${pkgs.pythonPackages.pycrypto}/lib/python2.7/site-packages/:${pkgs.pythonPackages.pyasn1}/lib/python2.7/site-packages/:${pkgs.pythonPackages.python}/lib/python2.7/site-packages/:${pkgs.pythonPackages.twisted_11}/lib/python2.7/site-packages/:."; + environment.PYTHONPATH = "${pkgs.kippo}/src/:${pkgs.pythonPackages.pycrypto}/lib/python2.7/site-packages/:${pkgs.pythonPackages.pyasn1}/lib/python2.7/site-packages/:${pkgs.pythonPackages.python}/lib/python2.7/site-packages/:${pkgs.kippo.twisted}/lib/python2.7/site-packages/:."; preStart = '' if [ ! -d ${cfg.varPath}/ ] ; then mkdir -p ${cfg.logPath}/tty @@ -107,7 +107,7 @@ rec { fi ''; - serviceConfig.ExecStart = "${pkgs.pythonPackages.twisted_11}/bin/twistd -y ${pkgs.kippo}/src/kippo.tac --syslog --rundir=${cfg.varPath}/ --pidfile=${cfg.pidPath}/kippo.pid --prefix=kippo -n"; + serviceConfig.ExecStart = "${pkgs.kippo.twisted}/bin/twistd -y ${pkgs.kippo}/src/kippo.tac --syslog --rundir=${cfg.varPath}/ --pidfile=${cfg.pidPath}/kippo.pid --prefix=kippo -n"; serviceConfig.PermissionsStartOnly = true; serviceConfig.User = "kippo"; serviceConfig.Group = "kippo"; diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix index 134544cda681..81f968ae9fe1 100644 --- a/nixos/modules/services/networking/murmur.nix +++ b/nixos/modules/services/networking/murmur.nix @@ -230,7 +230,7 @@ in }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; description = "Extra configuration to put into mumur.ini."; }; diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 65ffaece4772..8f353979d3fc 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -198,6 +198,9 @@ in { { source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name"; target = "NetworkManager/VPN/nm-l2tp-service.name"; } + { source = "${networkmanager_strongswan}/etc/NetworkManager/VPN/nm-strongswan-service.name"; + target = "NetworkManager/VPN/nm-strongswan-service.name"; + } ] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == []) { source = overrideNameserversScript; target = "NetworkManager/dispatcher.d/02overridedns"; diff --git a/nixos/modules/services/networking/openfire.nix b/nixos/modules/services/networking/openfire.nix index ed91b45ec945..454b504eda21 100644 --- a/nixos/modules/services/networking/openfire.nix +++ b/nixos/modules/services/networking/openfire.nix @@ -47,7 +47,7 @@ with lib; export HOME=/tmp mkdir /var/log/openfire || true mkdir /etc/openfire || true - for i in ${openfire}/conf.inst/*; do + for i in ${pkgs.openfire}/conf.inst/*; do if ! test -f /etc/openfire/$(basename $i); then cp $i /etc/openfire/ fi diff --git a/nixos/modules/services/networking/prayer.nix b/nixos/modules/services/networking/prayer.nix index cb8fe6bf4fe9..9d63f549b23a 100644 --- a/nixos/modules/services/networking/prayer.nix +++ b/nixos/modules/services/networking/prayer.nix @@ -56,6 +56,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = "" ; description = '' Extra configuration. Contents will be added verbatim to the configuration file. diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index 247c4f1efb07..5682b506344c 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -195,6 +195,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ''''; description = "Additional prosody configuration"; }; diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index f7a5926dc64b..0c1f8d8cdb91 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -6,31 +6,39 @@ let cfg = config.services.smokeping; smokepingHome = "/var/lib/smokeping"; smokepingPidDir = "/run"; - configFile = '' - *** General *** - owner = ${cfg.owner} - contact = ${cfg.ownerEmail} - mailhost = ${cfg.mailHost} - #sendmail = /var/setuid-wrappers/sendmail - imgcache = ${smokepingHome}/cache - imgurl = http://${cfg.hostName}:${builtins.toString cfg.port}/cache - datadir = ${smokepingHome}/data - piddir = ${smokepingPidDir} - cgiurl = http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi - smokemail = ${cfg.smokeMailTemplate} - *** Presentation *** - template = ${cfg.presentationTemplate} - ${cfg.presentationConfig} - #*** Alerts *** - #${cfg.alertConfig} - *** Database *** - ${cfg.databaseConfig} - *** Probes *** - ${cfg.probeConfig} - *** Targets *** - ${cfg.targetConfig} - ${cfg.extraConfig} - ''; + configFile = + if cfg.config == null + then + '' + *** General *** + owner = ${cfg.owner} + contact = ${cfg.ownerEmail} + ${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"} + ${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"} + imgcache = ${smokepingHome}/cache + imgurl = http://${cfg.hostName}:${builtins.toString cfg.port}/cache + datadir = ${smokepingHome}/data + pagedir = ${smokepingHome}/cache + piddir = ${smokepingPidDir} + cgiurl = http://${cfg.hostName}:${builtins.toString cfg.port}/smokeping.cgi + linkstyle = ${cfg.linkStyle} + smokemail = ${cfg.smokeMailTemplate} + *** Presentation *** + template = ${cfg.presentationTemplate} + ${cfg.presentationConfig} + *** Alerts *** + ${cfg.alertConfig} + *** Database *** + ${cfg.databaseConfig} + *** Probes *** + ${cfg.probeConfig} + *** Targets *** + ${cfg.targetConfig} + ${cfg.extraConfig} + '' + else + cfg.config; + configPath = pkgs.writeText "smokeping.conf" configFile; cgiHome = pkgs.writeScript "smokeping.fcgi" '' #!${pkgs.bash}/bin/bash @@ -59,8 +67,15 @@ in }; mailHost = mkOption { type = types.string; - default = "127.0.0.1"; - description = "Use this SMTP server rather than localhost"; + default = ""; + example = "localhost"; + description = "Use this SMTP server to send alerts"; + }; + sendmail = mkOption { + type = types.nullOr types.path; + default = null; + example = "/var/setuid-wrappers/sendmail"; + description = "Use this sendmail compatible script to deliver alerts"; }; smokeMailTemplate = mkOption { type = types.string; @@ -71,6 +86,7 @@ in package = mkOption { type = types.package; default = pkgs.smokeping; + defaultText = "pkgs.smokeping"; description = "Specify a custom smokeping package"; }; owner = mkOption { @@ -85,6 +101,12 @@ in example = "somewhere.example.com"; description = "DNS name for the urls generated in the cgi."; }; + linkStyle = mkOption { + type = types.enum ["original" "absolute" "relative"]; + default = "relative"; + example = "absolute"; + description = "DNS name for the urls generated in the cgi."; + }; port = mkOption { type = types.int; default = 8081; @@ -132,7 +154,10 @@ in }; alertConfig = mkOption { type = types.string; - default = ""; + default = '' + to = root@localhost + from = smokeping@localhost + ''; example = literalExample '' to = alertee@address.somewhere from = smokealert@company.xy @@ -219,16 +244,30 @@ in description = "Target configuration"; }; extraConfig = mkOption { - type = types.string; + type = types.lines; default = ""; description = "Any additional customization not already included."; }; + config = mkOption { + type = types.nullOr types.string; + default = null; + description = "Full smokeping config supplied by the user. Overrides " + + "and replaces any other configuration supplied."; + }; }; }; config = mkIf cfg.enable { + assertions = [ + { + assertion = !(cfg.sendmail != null && cfg.mailHost != ""); + message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; + } + ]; + security.setuidPrograms = [ "fping" ]; + environment.systemPackages = [ pkgs.fping ]; users.extraUsers = singleton { name = cfg.user; isNormalUser = false; @@ -243,9 +282,12 @@ in serviceConfig.PermissionsStartOnly = true; preStart = '' mkdir -m 0755 -p ${smokepingHome}/cache ${smokepingHome}/data + rm -f ${smokepingHome}/cropper + ln -s ${cfg.package}/htdocs/cropper ${smokepingHome}/cropper chown -R ${cfg.user} ${smokepingHome} cp ${cgiHome} ${smokepingHome}/smokeping.fcgi ${cfg.package}/bin/smokeping --check --config=${configPath} + ${cfg.package}/bin/smokeping --static --config=${configPath} ''; script = ''${cfg.package}/bin/smokeping --config=${configPath} --nodaemon''; }; @@ -253,8 +295,9 @@ in wantedBy = [ "multi-user.target"]; requires = [ "smokeping.service"]; partOf = [ "smokeping.service"]; - path = with pkgs; [ bash rrdtool smokeping ]; - script = ''${pkgs.thttpd}/bin/thttpd -u ${cfg.user} -c "**.fcgi" -d ${smokepingHome} -p ${builtins.toString cfg.port} -D''; + path = with pkgs; [ bash rrdtool smokeping thttpd ]; + script = ''thttpd -u ${cfg.user} -c "**.fcgi" -d ${smokepingHome} -p ${builtins.toString cfg.port} -D -nos''; + serviceConfig.Restart = "always"; }; }; } diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 3e9fae35847e..81941ce1cfb6 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -242,7 +242,7 @@ in systemd = let - service = + sshd-service = { description = "SSH Daemon"; wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target"; @@ -253,16 +253,8 @@ in environment.LD_LIBRARY_PATH = nssModulesPath; - preStart = - '' - mkdir -m 0755 -p /etc/ssh - - ${flip concatMapStrings cfg.hostKeys (k: '' - if ! [ -f "${k.path}" ]; then - ssh-keygen -t "${k.type}" ${if k ? bits then "-b ${toString k.bits}" else ""} -f "${k.path}" -N "" - fi - '')} - ''; + wants = [ "sshd-keygen.service" ]; + after = [ "sshd-keygen.service" ]; serviceConfig = { ExecStart = @@ -278,6 +270,26 @@ in PIDFile = "/run/sshd.pid"; }); }; + + sshd-keygen-service = + { description = "SSH Host Key Generation"; + path = [ cfgc.package ]; + script = + '' + mkdir -m 0755 -p /etc/ssh + ${flip concatMapStrings cfg.hostKeys (k: '' + if ! [ -f "${k.path}" ]; then + ssh-keygen -t "${k.type}" ${if k ? bits then "-b ${toString k.bits}" else ""} -f "${k.path}" -N "" + fi + '')} + ''; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + }; + }; + in if cfg.startWhenNeeded then { @@ -289,11 +301,13 @@ in socketConfig.Accept = true; }; - services."sshd@" = service; + services.sshd-keygen = sshd-keygen-service; + services."sshd@" = sshd-service; } else { - services.sshd = service; + services.sshd-keygen = sshd-keygen-service; + services.sshd = sshd-service; }; diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix index e433ec7c5b9b..0c459fb1dd0c 100644 --- a/nixos/modules/services/networking/supplicant.nix +++ b/nixos/modules/services/networking/supplicant.nix @@ -34,7 +34,8 @@ let ''; in { description = "Supplicant ${iface}${optionalString (iface=="WLAN"||iface=="LAN") " %I"}"; - wantedBy = [ "network.target" ] ++ deps; + wantedBy = [ "multi-user.target" ] ++ deps; + wants = [ "network.target" ]; bindsTo = deps; after = deps; before = [ "network.target" ]; diff --git a/nixos/modules/services/networking/syncthing.nix b/nixos/modules/services/networking/syncthing.nix index 8a430734319b..dcdc203bdc62 100644 --- a/nixos/modules/services/networking/syncthing.nix +++ b/nixos/modules/services/networking/syncthing.nix @@ -3,46 +3,11 @@ with lib; let - cfg = config.services.syncthing; defaultUser = "syncthing"; - - header = { - description = "Syncthing service"; - after = [ "network.target" ]; - environment = { - STNORESTART = "yes"; - STNOUPGRADE = "yes"; - inherit (cfg) all_proxy; - } // config.networking.proxy.envVars; - }; - - service = { - Restart = "on-failure"; - SuccessExitStatus = "2 3 4"; - RestartForceExitStatus="3 4"; - }; - - iNotifyHeader = { - description = "Syncthing Inotify File Watcher service"; - after = [ "network.target" "syncthing.service" ]; - requires = [ "syncthing.service" ]; - }; - - iNotifyService = { - SuccessExitStatus = "2"; - RestartForceExitStatus = "3"; - Restart = "on-failure"; - }; - -in - -{ - +in { ###### interface - options = { - services.syncthing = { enable = mkEnableOption '' @@ -100,6 +65,19 @@ in ''; }; + openDefaultPorts = mkOption { + type = types.bool; + default = false; + example = literalExample "true"; + description = '' + Open the default ports in the firewall: + - TCP 22000 for transfers + - UDP 21027 for discovery + If multiple users are running syncthing on this machine, you will need to manually open a set of ports for each instance and leave this disabled. + Alternatively, if are running only a single instance on this machine using the default ports, enable this. + ''; + }; + package = mkOption { type = types.package; default = pkgs.syncthing; @@ -117,6 +95,14 @@ in config = mkIf cfg.enable { + networking.firewall = mkIf cfg.openDefaultPorts { + allowedTCPPorts = [ 22000 ]; + allowedUDPPorts = [ 21027 ]; + }; + + systemd.packages = [ pkgs.syncthing ] + ++ lib.optional cfg.useInotify pkgs.syncthing-inotify; + users = mkIf (cfg.user == defaultUser) { extraUsers."${defaultUser}" = { group = cfg.group; @@ -131,39 +117,44 @@ in }; systemd.services = { - syncthing = mkIf cfg.systemService (header // { - wants = mkIf cfg.useInotify [ "syncthing-inotify.service" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = service // { - User = cfg.user; - Group = cfg.group; - PermissionsStartOnly = true; - ExecStart = "${cfg.package}/bin/syncthing -no-browser -home=${cfg.dataDir}"; - }; - }); - - syncthing-inotify = mkIf (cfg.systemService && cfg.useInotify) (iNotifyHeader // { + syncthing = mkIf cfg.systemService { + description = "Syncthing service"; + after = [ "network.target" ]; + environment = { + STNORESTART = "yes"; + STNOUPGRADE = "yes"; + inherit (cfg) all_proxy; + } // config.networking.proxy.envVars; + wants = mkIf cfg.useInotify [ "syncthing-inotify.service" ]; wantedBy = [ "multi-user.target" ]; - serviceConfig = iNotifyService // { + serviceConfig = { + Restart = "on-failure"; + SuccessExitStatus = "2 3 4"; + RestartForceExitStatus="3 4"; User = cfg.user; - ExecStart = "${pkgs.syncthing-inotify.bin}/bin/syncthing-inotify -home=${cfg.dataDir} -logflags=0"; + Group = cfg.group; + PermissionsStartOnly = true; + ExecStart = "${cfg.package}/bin/syncthing -no-browser -home=${cfg.dataDir}"; }; - }); - }; + }; - systemd.user.services = { - syncthing = header // { - serviceConfig = service // { - ExecStart = "${cfg.package}/bin/syncthing -no-browser"; - }; + syncthing-resume = { + wantedBy = [ "suspend.target" ]; }; - syncthing-inotify = mkIf cfg.useInotify (iNotifyHeader // { - serviceConfig = iNotifyService // { - ExecStart = "${pkgs.syncthing-inotify.bin}/bin/syncthing-inotify -logflags=0"; + syncthing-inotify = mkIf (cfg.systemService && cfg.useInotify) { + description = "Syncthing Inotify File Watcher service"; + after = [ "network.target" "syncthing.service" ]; + requires = [ "syncthing.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + SuccessExitStatus = "2"; + RestartForceExitStatus = "3"; + Restart = "on-failure"; + User = cfg.user; + ExecStart = "${pkgs.syncthing-inotify.bin}/bin/syncthing-inotify -home=${cfg.dataDir} -logflags=0"; }; - }); + }; }; - }; } diff --git a/nixos/modules/services/networking/tftpd.nix b/nixos/modules/services/networking/tftpd.nix index 9b3cc6b8ec4f..c9c0a2b321d5 100644 --- a/nixos/modules/services/networking/tftpd.nix +++ b/nixos/modules/services/networking/tftpd.nix @@ -13,12 +13,13 @@ with lib; default = false; description = '' Whether to enable tftpd, a Trivial File Transfer Protocol server. + The server will be run as an xinetd service. ''; }; services.tftpd.path = mkOption { type = types.path; - default = "/home/tftp"; + default = "/srv/tftp"; description = '' Where the tftp server files are stored. ''; diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix index 6375ebee3209..f3a04d97c98e 100644 --- a/nixos/modules/services/networking/unbound.nix +++ b/nixos/modules/services/networking/unbound.nix @@ -79,7 +79,7 @@ in extraConfig = mkOption { default = ""; - type = types.str; + type = types.lines; description = '' Extra unbound config. See <citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8 diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix new file mode 100644 index 000000000000..35918e42b402 --- /dev/null +++ b/nixos/modules/services/networking/wireguard.nix @@ -0,0 +1,225 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.networking.wireguard; + + kernel = config.boot.kernelPackages; + + # interface options + + interfaceOpts = { name, ... }: { + + options = { + + ips = mkOption { + example = [ "192.168.2.1/24" ]; + default = []; + type = with types; listOf str; + description = "The IP addresses of the interface."; + }; + + privateKey = mkOption { + example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="; + type = types.str; + description = "Base64 private key generated by wg genkey."; + }; + + presharedKey = mkOption { + default = null; + example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I="; + type = with types; nullOr str; + description = ''base64 preshared key generated by wg genpsk. Optional, + and may be omitted. This option adds an additional layer of + symmetric-key cryptography to be mixed into the already existing + public-key cryptography, for post-quantum resistance.''; + }; + + listenPort = mkOption { + default = null; + type = with types; nullOr int; + example = 51820; + description = ''16-bit port for listening. Optional; if not specified, + automatically generated based on interface name.''; + }; + + preSetup = mkOption { + example = literalExample ['' + ${pkgs.iproute}/bin/ip netns add foo + '']; + default = []; + type = with types; listOf str; + description = ''A list of commands called at the start of the interface + setup.''; + }; + + postSetup = mkOption { + example = literalExample ['' + ${pkgs.bash} -c 'printf "nameserver 10.200.100.1" | ${pkgs.openresolv}/bin/resolvconf -a wg0 -m 0' + '']; + default = []; + type = with types; listOf str; + description = "A list of commands called at the end of the interface setup."; + }; + + postShutdown = mkOption { + example = literalExample ["${pkgs.openresolv}/bin/resolvconf -d wg0"]; + default = []; + type = with types; listOf str; + description = "A list of commands called after shutting down the interface."; + }; + + peers = mkOption { + default = []; + description = "Peers linked to the interface."; + type = with types; listOf (submodule peerOpts); + }; + + }; + + }; + + # peer options + + peerOpts = { + + options = { + + publicKey = mkOption { + example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="; + type = types.str; + description = "The base64 public key the peer."; + }; + + allowedIPs = mkOption { + example = [ "10.192.122.3/32" "10.192.124.1/24" ]; + type = with types; listOf str; + description = ''List of IP (v4 or v6) addresses with CIDR masks from + which this peer is allowed to send incoming traffic and to which + outgoing traffic for this peer is directed. The catch-all 0.0.0.0/0 may + be specified for matching all IPv4 addresses, and ::/0 may be specified + for matching all IPv6 addresses.''; + }; + + endpoint = mkOption { + default = null; + example = "demo.wireguard.io:12913"; + type = with types; nullOr str; + description = ''Endpoint IP or hostname of the peer, followed by a colon, + and then a port number of the peer.''; + }; + + persistentKeepalive = mkOption { + default = null; + type = with types; nullOr int; + example = 25; + description = ''This is optional and is by default off, because most + users will not need it. It represents, in seconds, between 1 and 65535 + inclusive, how often to send an authenticated empty packet to the peer, + for the purpose of keeping a stateful firewall or NAT mapping valid + persistently. For example, if the interface very rarely sends traffic, + but it might at anytime receive traffic from a peer, and it is behind + NAT, the interface might benefit from having a persistent keepalive + interval of 25 seconds; however, most users will not need this.''; + }; + + }; + + }; + + generateConf = name: values: pkgs.writeText "wireguard-${name}.conf" '' + [Interface] + PrivateKey = ${values.privateKey} + ${optionalString (values.presharedKey != null) "PresharedKey = ${values.presharedKey}"} + ${optionalString (values.listenPort != null) "ListenPort = ${toString values.listenPort}"} + + ${concatStringsSep "\n\n" (map (peer: '' + [Peer] + PublicKey = ${peer.publicKey} + ${optionalString (peer.allowedIPs != []) "AllowedIPs = ${concatStringsSep ", " peer.allowedIPs}"} + ${optionalString (peer.endpoint != null) "Endpoint = ${peer.endpoint}"} + ${optionalString (peer.persistentKeepalive != null) "PersistentKeepalive = ${toString peer.persistentKeepalive}"} + '') values.peers)} + ''; + + ipCommand = "${pkgs.iproute}/bin/ip"; + wgCommand = "${pkgs.wireguard}/bin/wg"; + + generateUnit = name: values: + nameValuePair "wireguard-${name}" + { + description = "WireGuard Tunnel - ${name}"; + wantedBy = [ "ip-up.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = lib.flatten([ + values.preSetup + + "-${ipCommand} link del dev ${name}" + "${ipCommand} link add dev ${name} type wireguard" + "${wgCommand} setconf ${name} ${generateConf name values}" + + (map (ip: + ''${ipCommand} address add ${ip} dev ${name}'' + ) values.ips) + + "${ipCommand} link set up dev ${name}" + + (flatten (map (peer: (map (ip: + "${ipCommand} route add ${ip} dev ${name}" + ) peer.allowedIPs)) values.peers)) + + values.postSetup + ]); + + ExecStop = [ ''${ipCommand} link del dev "${name}"'' ] ++ values.postShutdown; + }; + }; + +in + +{ + + ###### interface + + options = { + + networking.wireguard = { + + interfaces = mkOption { + description = "Wireguard interfaces."; + default = {}; + example = { + wg0 = { + ips = [ "192.168.20.4/24" ]; + privateKey = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="; + peers = [ + { allowedIPs = [ "192.168.20.1/32" ]; + publicKey = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="; + endpoint = "demo.wireguard.io:12913"; } + ]; + }; + }; + type = with types; attrsOf (submodule interfaceOpts); + }; + + }; + + }; + + + ###### implementation + + config = mkIf (cfg.interfaces != {}) { + + boot.extraModulePackages = [ kernel.wireguard ]; + environment.systemPackages = [ pkgs.wireguard ]; + + systemd.services = mapAttrs' generateUnit cfg.interfaces; + + }; + +} diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index a344d7855463..5657b91c1e72 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -128,9 +128,11 @@ in { in { description = "WPA Supplicant"; - after = [ "network.target" ] ++ lib.concatMap deviceUnit ifaces; + after = lib.concatMap deviceUnit ifaces; + before = [ "network.target" ]; + wants = [ "network.target" ]; requires = lib.concatMap deviceUnit ifaces; - wantedBy = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; path = [ pkgs.wpa_supplicant ]; diff --git a/nixos/modules/services/networking/xinetd.nix b/nixos/modules/services/networking/xinetd.nix index 270122ee659c..002245027804 100644 --- a/nixos/modules/services/networking/xinetd.nix +++ b/nixos/modules/services/networking/xinetd.nix @@ -124,7 +124,7 @@ in }; extraConfig = mkOption { - type = types.string; + type = types.lines; default = ""; description = "Extra configuration-lines added to the section of the service."; }; diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix index 196a14dd40ed..676e82aa8937 100644 --- a/nixos/modules/services/networking/znc.nix +++ b/nixos/modules/services/networking/znc.nix @@ -26,53 +26,35 @@ let }; # Keep znc.conf in nix store, then symlink or copy into `dataDir`, depending on `mutable`. + notNull = a: ! isNull a; mkZncConf = confOpts: '' - // Also check http://en.znc.in/wiki/Configuration - - AnonIPLimit = 10 - ConnectDelay = 5 - # Add `LoadModule = x` for each module... + Version = 1.6.3 ${concatMapStrings (n: "LoadModule = ${n}\n") confOpts.modules} - MaxBufferSize = 500 - ProtectWebSessions = true - SSLCertFile = ${cfg.dataDir}/znc.pem - ServerThrottle = 30 - Skin = dark-clouds - StatusPrefix = * - Version = 1.2 - - <Listener listener0> - AllowIRC = true - AllowWeb = true + + <Listener l> + Port = ${toString confOpts.port} IPv4 = true - IPv6 = false - Port = ${if confOpts.useSSL then "+" else ""}${toString confOpts.port} + IPv6 = true SSL = ${if confOpts.useSSL then "true" else "false"} </Listener> <User ${confOpts.userName}> + ${confOpts.passBlock} Admin = true - Allow = * - AltNick = ${confOpts.nick}_ - AppendTimestamp = false - AutoClearChanBuffer = false - Buffer = 150 - ChanModes = +stn - DenyLoadMod = false - DenySetBindHost = false - Ident = ident - JoinTries = 10 - MaxJoins = 0 - MaxNetworks = 1 - MultiClients = true Nick = ${confOpts.nick} - PrependTimestamp = true - QuitMsg = Quit + AltNick = ${confOpts.nick}_ + Ident = ${confOpts.nick} RealName = ${confOpts.nick} - TimestampFormat = [%H:%M:%S] ${concatMapStrings (n: "LoadModule = ${n}\n") confOpts.userModules} - - ${confOpts.passBlock} + + ${ lib.concatStringsSep "\n" (lib.mapAttrsToList (name: net: '' + <Network ${name}> + ${concatMapStrings (m: "LoadModule = ${m}\n") net.modules} + Server = ${net.server} ${if net.useSSL then "+" else ""}${toString net.port} + + ${concatMapStrings (c: "<Chan #${c}>\n</Chan>\n") net.channels} + </Network> + '') confOpts.networks) } </User> ${confOpts.extraZncConf} ''; @@ -84,6 +66,62 @@ let else mkZncConf cfg.confOptions; }; + networkOpts = { ... }: { + options = { + server = mkOption { + type = types.str; + example = "chat.freenode.net"; + description = '' + IRC server address. + ''; + }; + + port = mkOption { + type = types.int; + default = 6697; + example = 6697; + description = '' + IRC server port. + ''; + }; + + useSSL = mkOption { + type = types.bool; + default = true; + description = '' + Whether to use SSL to connect to the IRC server. + ''; + }; + + modulePackages = mkOption { + type = types.listOf types.package; + default = []; + example = [ "pkgs.zncModules.push" "pkgs.zncModules.fish" ]; + description = '' + External ZNC modules to build. + ''; + }; + + modules = mkOption { + type = types.listOf types.str; + default = [ "simple_away" ]; + example = literalExample "[ simple_away sasl ]"; + description = '' + ZNC modules to load. + ''; + }; + + channels = mkOption { + type = types.listOf types.str; + default = []; + example = [ "nixos" ]; + description = '' + IRC channels to join. + ''; + }; + }; + }; + in { @@ -111,6 +149,15 @@ in ''; }; + group = mkOption { + default = ""; + example = "users"; + type = types.string; + description = '' + Group to own the ZNCserver process. + ''; + }; + dataDir = mkOption { default = "/var/lib/znc/"; example = "/home/john/.znc/"; @@ -125,27 +172,16 @@ in example = "See: http://wiki.znc.in/Configuration"; type = types.lines; description = '' - The contents of the `znc.conf` file to use when creating it. + Config file as generated with `znc --makeconf` to use for the whole ZNC configuration. If specified, `confOptions` will be ignored, and this value, as-is, will be used. If left empty, a conf file with default values will be used. - Recommended to generate with `znc --makeconf` command. ''; }; - /* TODO: add to the documentation of the current module: - - Values to use when creating a `znc.conf` file. - - confOptions = { - modules = [ "log" ]; - userName = "john"; - nick = "johntron"; - }; - */ confOptions = { modules = mkOption { type = types.listOf types.str; - default = [ "partyline" "webadmin" "adminlog" "log" ]; + default = [ "webadmin" "adminlog" ]; example = [ "partyline" "webadmin" "adminlog" "log" ]; description = '' A list of modules to include in the `znc.conf` file. @@ -154,8 +190,8 @@ in userModules = mkOption { type = types.listOf types.str; - default = [ ]; - example = [ "fish" "push" ]; + default = [ "chansaver" "controlpanel" ]; + example = [ "chansaver" "controlpanel" "fish" "push" ]; description = '' A list of user modules to include in the `znc.conf` file. ''; @@ -166,9 +202,25 @@ in example = "johntron"; type = types.string; description = '' - The user name to use when generating the `znc.conf` file. - This is the user name used by the user logging into the ZNC web admin. + The user name used to log in to the ZNC web admin interface. + ''; + }; + + networks = mkOption { + default = { }; + type = types.loaOf types.optionSet; + description = '' + IRC networks to connect the user to. ''; + options = [ networkOpts ]; + example = { + "freenode" = { + server = "chat.freenode.net"; + port = 6697; + ssl = true; + modules = [ "simple_away" ]; + }; + }; }; nick = mkOption { @@ -176,19 +228,16 @@ in example = "john"; type = types.string; description = '' - The IRC nick to use when generating the `znc.conf` file. + The IRC nick. ''; }; passBlock = mkOption { - default = defaultPassBlock; - example = "Must be the block generated by the `znc --makepass` command."; + example = defaultPassBlock; type = types.string; description = '' - The pass block to use when generating the `znc.conf` file. - This is the password used by the user logging into the ZNC web admin. - This is the block generated by the `znc --makepass` command. - !!! If not specified, please change this after starting the service. !!! + Generate with znc --makepass. + This is the password used to log in to the ZNC web admin interface. ''; }; @@ -206,7 +255,7 @@ in example = true; type = types.bool; description = '' - Indicates whether the ZNC server should use SSL when listening on the specified port. + Indicates whether the ZNC server should use SSL when listening on the specified port. A self-signed certificate will be generated. ''; }; @@ -214,7 +263,7 @@ in default = ""; type = types.lines; description = '' - Extra config to `znc.conf` file + Extra config to `znc.conf` file. ''; }; }; @@ -265,6 +314,7 @@ in after = [ "network.service" ]; serviceConfig = { User = cfg.user; + Group = cfg.group; Restart = "always"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; diff --git a/nixos/modules/services/search/hound.nix b/nixos/modules/services/search/hound.nix new file mode 100644 index 000000000000..708f57a5eb7c --- /dev/null +++ b/nixos/modules/services/search/hound.nix @@ -0,0 +1,123 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.hound; +in { + options = { + services.hound = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the hound code search daemon. + ''; + }; + + user = mkOption { + default = "hound"; + type = types.str; + description = '' + User the hound daemon should execute under. + ''; + }; + + group = mkOption { + default = "hound"; + type = types.str; + description = '' + Group the hound daemon should execute under. + ''; + }; + + extraGroups = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "dialout" ]; + description = '' + List of extra groups that the "hound" user should be a part of. + ''; + }; + + home = mkOption { + default = "/var/lib/hound"; + type = types.path; + description = '' + The path to use as hound's $HOME. If the default user + "hound" is configured then this is the home of the "hound" + user. + ''; + }; + + package = mkOption { + default = pkgs.hound; + description = '' + Package for running hound. + ''; + }; + + config = mkOption { + type = types.str; + description = '' + The full configuration of the Hound daemon. Note the dbpath + should be an absolute path to a writable location on disk. + ''; + example = '' + { + "max-concurrent-indexers" : 2, + "dbpath" : "''${services.hound.home}/data", + "repos" : { + "nixpkgs": { + "url" : "https://www.github.com/NixOS/nixpkgs.git" + } + } + } + ''; + }; + + listen = mkOption { + type = types.str; + default = "0.0.0.0:6080"; + example = "127.0.0.1:6080 or just :6080"; + description = '' + Listen on this IP:port / :port + ''; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraGroups = optional (cfg.group == "hound") { + name = "hound"; + gid = config.ids.gids.hound; + }; + + users.extraUsers = optional (cfg.user == "hound") { + name = "hound"; + description = "hound code search"; + createHome = true; + home = cfg.home; + group = cfg.group; + extraGroups = cfg.extraGroups; + uid = config.ids.uids.hound; + }; + + systemd.services.hound = { + description = "Hound Code Search"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + WorkingDirectory = cfg.home; + ExecStartPre = "${pkgs.git}/bin/git config --global --replace-all http.sslCAinfo /etc/ssl/certs/ca-certificates.crt"; + ExecStart = "${cfg.package}/bin/houndd" + + " -addr ${cfg.listen}" + + " -conf ${pkgs.writeText "hound.json" cfg.config}"; + + }; + path = [ pkgs.git ]; + }; + }; + +} diff --git a/nixos/modules/services/torrent/deluge.nix b/nixos/modules/services/torrent/deluge.nix index becd57055d41..a9c08b66eb82 100644 --- a/nixos/modules/services/torrent/deluge.nix +++ b/nixos/modules/services/torrent/deluge.nix @@ -5,26 +5,36 @@ with lib; let cfg = config.services.deluge; cfg_web = config.services.deluge.web; + openFilesLimit = 4096; + in { options = { - services.deluge = { - enable = mkOption { - default = false; - example = true; - description = '' - Start Deluge daemon. - ''; - }; - }; + services = { + deluge = { + enable = mkOption { + default = false; + example = true; + description = "Start the Deluge daemon"; + }; + + openFilesLimit = mkOption { + default = openFilesLimit; + example = 8192; + description = '' + Number of files to allow deluged to open. + ''; + }; + }; - services.deluge.web = { - enable = mkOption { - default = false; - example = true; - description = '' - Start Deluge Web daemon. - ''; - }; + deluge.web = { + enable = mkOption { + default = false; + example = true; + description = '' + Start Deluge Web daemon. + ''; + }; + }; }; }; @@ -35,11 +45,14 @@ in { description = "Deluge BitTorrent Daemon"; wantedBy = [ "multi-user.target" ]; path = [ pkgs.pythonPackages.deluge ]; - serviceConfig.ExecStart = "${pkgs.pythonPackages.deluge}/bin/deluged -d"; - # To prevent "Quit & shutdown daemon" from working; we want systemd to manage it! - serviceConfig.Restart = "on-success"; - serviceConfig.User = "deluge"; - serviceConfig.Group = "deluge"; + serviceConfig = { + ExecStart = "${pkgs.pythonPackages.deluge}/bin/deluged -d"; + # To prevent "Quit & shutdown daemon" from working; we want systemd to manage it! + Restart = "on-success"; + User = "deluge"; + Group = "deluge"; + LimitNOFILE = cfg.openFilesLimit; + }; }; systemd.services.delugeweb = mkIf cfg_web.enable { diff --git a/nixos/modules/services/web-apps/atlassian/confluence.nix b/nixos/modules/services/web-apps/atlassian/confluence.nix new file mode 100644 index 000000000000..2d9287577de8 --- /dev/null +++ b/nixos/modules/services/web-apps/atlassian/confluence.nix @@ -0,0 +1,141 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.confluence; + + pkg = pkgs.atlassian-confluence; + +in + +{ + options = { + services.confluence = { + enable = mkEnableOption "Atlassian Confluence service"; + + user = mkOption { + type = types.str; + default = "confluence"; + description = "User which runs confluence."; + }; + + group = mkOption { + type = types.str; + default = "confluence"; + description = "Group which runs confluence."; + }; + + home = mkOption { + type = types.str; + default = "/var/lib/confluence"; + description = "Home directory of the confluence instance."; + }; + + listenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Address to listen on."; + }; + + listenPort = mkOption { + type = types.int; + default = 8090; + description = "Port to listen on."; + }; + + catalinaOptions = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-Xms1024m" "-Xmx2048m" "-Dconfluence.disable.peopledirectory.all=true" ]; + description = "Java options to pass to catalina/tomcat."; + }; + + proxy = { + enable = mkEnableOption "proxy support"; + + name = mkOption { + type = types.str; + example = "confluence.example.com"; + description = "Virtual hostname at the proxy"; + }; + + port = mkOption { + type = types.int; + default = 443; + example = 80; + description = "Port used at the proxy"; + }; + + scheme = mkOption { + type = types.str; + default = "https"; + example = "http"; + description = "Protocol used at the proxy."; + }; + }; + + jrePackage = let + jreSwitch = unfree: free: if config.nixpkgs.config.allowUnfree or false then unfree else free; + in mkOption { + type = types.package; + default = jreSwitch pkgs.oraclejre8 pkgs.openjdk8.jre; + defaultText = jreSwitch "pkgs.oraclejre8" "pkgs.openjdk8.jre"; + example = literalExample "pkgs.openjdk8.jre"; + description = "Java Runtime to use for Confluence. Note that Atlassian recommends the Oracle JRE."; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers."${cfg.user}" = { + isSystemUser = true; + group = cfg.group; + }; + + users.extraGroups."${cfg.group}" = {}; + + systemd.services.confluence = { + description = "Atlassian Confluence"; + + wantedBy = [ "multi-user.target" ]; + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + path = [ cfg.jrePackage ]; + + environment = { + CONF_USER = cfg.user; + JAVA_HOME = "${cfg.jrePackage}"; + CATALINA_OPTS = concatStringsSep " " cfg.catalinaOptions; + }; + + preStart = '' + mkdir -p ${cfg.home}/{logs,work,temp,deploy} + + mkdir -p /run/confluence + ln -sf ${cfg.home}/{logs,work,temp,server.xml} /run/confluence + ln -sf ${cfg.home} /run/confluence/home + + chown -R ${cfg.user} ${cfg.home} + + sed -e 's,port="8090",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \ + '' + (lib.optionalString cfg.proxy.enable '' + -e 's,protocol="org.apache.coyote.http11.Http11NioProtocol",protocol="org.apache.coyote.http11.Http11NioProtocol" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}",' \ + '') + '' + ${pkg}/conf/server.xml.dist > ${cfg.home}/server.xml + ''; + + script = "${pkg}/bin/start-confluence.sh -fg"; + stopScript = "${pkg}/bin/stop-confluence.sh"; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + PrivateTmp = true; + PermissionsStartOnly = true; + }; + }; + }; +} diff --git a/nixos/modules/services/web-apps/atlassian/crowd.nix b/nixos/modules/services/web-apps/atlassian/crowd.nix new file mode 100644 index 000000000000..5e79678023da --- /dev/null +++ b/nixos/modules/services/web-apps/atlassian/crowd.nix @@ -0,0 +1,147 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.crowd; + + pkg = pkgs.atlassian-crowd; + +in + +{ + options = { + services.crowd = { + enable = mkEnableOption "Atlassian Crowd service"; + + user = mkOption { + type = types.str; + default = "crowd"; + description = "User which runs Crowd."; + }; + + group = mkOption { + type = types.str; + default = "crowd"; + description = "Group which runs Crowd."; + }; + + home = mkOption { + type = types.str; + default = "/var/lib/crowd"; + description = "Home directory of the Crowd instance."; + }; + + listenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Address to listen on."; + }; + + listenPort = mkOption { + type = types.int; + default = 8092; + description = "Port to listen on."; + }; + + catalinaOptions = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-Xms1024m" "-Xmx2048m" ]; + description = "Java options to pass to catalina/tomcat."; + }; + + proxy = { + enable = mkEnableOption "reverse proxy support"; + + name = mkOption { + type = types.str; + example = "crowd.example.com"; + description = "Virtual hostname at the proxy"; + }; + + port = mkOption { + type = types.int; + default = 443; + example = 80; + description = "Port used at the proxy"; + }; + + scheme = mkOption { + type = types.str; + default = "https"; + example = "http"; + description = "Protocol used at the proxy."; + }; + + secure = mkOption { + type = types.bool; + default = true; + example = false; + description = "Whether the connections to the proxy should be considered secure."; + }; + }; + + jrePackage = let + jreSwitch = unfree: free: if config.nixpkgs.config.allowUnfree or false then unfree else free; + in mkOption { + type = types.package; + default = jreSwitch pkgs.oraclejre8 pkgs.openjdk8.jre; + defaultText = jreSwitch "pkgs.oraclejre8" "pkgs.openjdk8.jre"; + example = literalExample "pkgs.openjdk8.jre"; + description = "Java Runtime to use for Crowd. Note that Atlassian recommends the Oracle JRE."; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers."${cfg.user}" = { + isSystemUser = true; + group = cfg.group; + }; + + users.extraGroups."${cfg.group}" = {}; + + systemd.services.atlassian-crowd = { + description = "Atlassian Crowd"; + + wantedBy = [ "multi-user.target" ]; + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + path = [ cfg.jrePackage ]; + + environment = { + JAVA_HOME = "${cfg.jrePackage}"; + CATALINA_OPTS = concatStringsSep " " cfg.catalinaOptions; + CATALINA_TMPDIR = "/tmp"; + }; + + preStart = '' + mkdir -p ${cfg.home}/{logs,work} + + mkdir -p /run/atlassian-crowd + ln -sf ${cfg.home}/{work,server.xml} /run/atlassian-crowd + + chown -R ${cfg.user} ${cfg.home} + + sed -e 's,port="8095",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \ + '' + (lib.optionalString cfg.proxy.enable '' + -e 's,compression="on",compression="off" protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${toString cfg.proxy.secure}",' \ + '') + '' + ${pkg}/apache-tomcat/conf/server.xml.dist > ${cfg.home}/server.xml + ''; + + script = "${pkg}/start_crowd.sh"; + #stopScript = "${pkg}/bin/stop_crowd.sh"; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + PrivateTmp = true; + PermissionsStartOnly = true; + }; + }; + }; +} diff --git a/nixos/modules/services/web-apps/atlassian/jira.nix b/nixos/modules/services/web-apps/atlassian/jira.nix new file mode 100644 index 000000000000..6e31d20d0681 --- /dev/null +++ b/nixos/modules/services/web-apps/atlassian/jira.nix @@ -0,0 +1,149 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.jira; + + pkg = pkgs.atlassian-jira; + +in + +{ + options = { + services.jira = { + enable = mkEnableOption "Atlassian JIRA service"; + + user = mkOption { + type = types.str; + default = "jira"; + description = "User which runs JIRA."; + }; + + group = mkOption { + type = types.str; + default = "jira"; + description = "Group which runs JIRA."; + }; + + home = mkOption { + type = types.str; + default = "/var/lib/jira"; + description = "Home directory of the JIRA instance."; + }; + + listenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Address to listen on."; + }; + + listenPort = mkOption { + type = types.int; + default = 8091; + description = "Port to listen on."; + }; + + catalinaOptions = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-Xms1024m" "-Xmx2048m" ]; + description = "Java options to pass to catalina/tomcat."; + }; + + proxy = { + enable = mkEnableOption "reverse proxy support"; + + name = mkOption { + type = types.str; + example = "jira.example.com"; + description = "Virtual hostname at the proxy"; + }; + + port = mkOption { + type = types.int; + default = 443; + example = 80; + description = "Port used at the proxy"; + }; + + scheme = mkOption { + type = types.str; + default = "https"; + example = "http"; + description = "Protocol used at the proxy."; + }; + + secure = mkOption { + type = types.bool; + default = true; + example = false; + description = "Whether the connections to the proxy should be considered secure."; + }; + }; + + jrePackage = let + jreSwitch = unfree: free: if config.nixpkgs.config.allowUnfree or false then unfree else free; + in mkOption { + type = types.package; + default = jreSwitch pkgs.oraclejre8 pkgs.openjdk8.jre; + defaultText = jreSwitch "pkgs.oraclejre8" "pkgs.openjdk8.jre"; + example = literalExample "pkgs.openjdk8.jre"; + description = "Java Runtime to use for JIRA. Note that Atlassian recommends the Oracle JRE."; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers."${cfg.user}" = { + isSystemUser = true; + group = cfg.group; + }; + + users.extraGroups."${cfg.group}" = {}; + + systemd.services.atlassian-jira = { + description = "Atlassian JIRA"; + + wantedBy = [ "multi-user.target" ]; + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + path = [ cfg.jrePackage ]; + + environment = { + JIRA_USER = cfg.user; + JIRA_HOME = cfg.home; + JAVA_HOME = "${cfg.jrePackage}"; + CATALINA_OPTS = concatStringsSep " " cfg.catalinaOptions; + }; + + preStart = '' + mkdir -p ${cfg.home}/{logs,work,temp,deploy} + + mkdir -p /run/atlassian-jira + ln -sf ${cfg.home}/{logs,work,temp,server.xml} /run/atlassian-jira + ln -sf ${cfg.home} /run/atlassian-jira/home + + chown -R ${cfg.user} ${cfg.home} + + sed -e 's,port="8080",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \ + '' + (lib.optionalString cfg.proxy.enable '' + -e 's,protocol="HTTP/1.1",protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${toString cfg.proxy.secure}",' \ + '') + '' + ${pkg}/conf/server.xml.dist > ${cfg.home}/server.xml + ''; + + script = "${pkg}/bin/start-jira.sh -fg"; + stopScript = "${pkg}/bin/stop-jira.sh"; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + PrivateTmp = true; + PermissionsStartOnly = true; + }; + }; + }; +} diff --git a/nixos/modules/services/web-apps/nixbot.nix b/nixos/modules/services/web-apps/nixbot.nix new file mode 100644 index 000000000000..0592d01bf369 --- /dev/null +++ b/nixos/modules/services/web-apps/nixbot.nix @@ -0,0 +1,149 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.nixbot; + pyramidIni = '' + ### + # app configuration + # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html + ### + + [app:main] + use = egg:nixbot + + nixbot.github_token = ${cfg.githubToken} + nixbot.bot_name = ${cfg.botName} + nixbot.repo = ${cfg.repo} + nixbot.pr_repo = ${cfg.prRepo} + nixbot.hydra_jobsets_repo = ${cfg.hydraJobsetsRepo} + nixbot.github_secret = justnotsorandom + nixbot.public_url = ${cfg.publicUrl} + nixbot.repo_dir = ${cfg.repoDir} + + pyramid.reload_templates = false + pyramid.debug_authorization = false + pyramid.debug_notfound = false + pyramid.debug_routematch = false + pyramid.default_locale_name = en + + # By default, the toolbar only appears for clients from IP addresses + # '127.0.0.1' and '::1'. + # debugtoolbar.hosts = 127.0.0.1 ::1 + + ### + # wsgi server configuration + ### + + [server:main] + use = egg:waitress#main + host = 0.0.0.0 + port = 6543 + + ### + # logging configuration + # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html + ### + + [loggers] + keys = root, nixbot + + [handlers] + keys = console + + [formatters] + keys = generic + + [logger_root] + level = INFO + handlers = console + + [logger_nixbot] + level = INFO + handlers = + qualname = nixbot + + [handler_console] + class = StreamHandler + args = (sys.stderr,) + level = NOTSET + formatter = generic + + [formatter_generic] + format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s + ''; +in { + options = { + services.nixbot = { + enable = mkEnableOption "nixbot"; + + botName = mkOption { + type = types.str; + description = "The bot's github user account name."; + default = "nixbot"; + }; + + githubToken = mkOption { + type = types.str; + description = "The bot's github user account token."; + example = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + }; + + repo = mkOption { + type = types.str; + description = "The github repository to check for PRs."; + example = "nixos/nixpkgs"; + }; + + prRepo = mkOption { + type = types.str; + description = "The github repository to push the testing branches to."; + example = "nixos/nixpkgs-pr"; + }; + + hydraJobsetsRepo = mkOption { + type = types.str; + description = "The github repository to push the hydra jobset definitions to."; + example = "nixos/hydra-jobsets"; + }; + + publicUrl = mkOption { + type = types.str; + description = "The public URL the bot is reachable at (Github hook endpoint)."; + example = "https://nixbot.nixos.org"; + }; + + repoDir = mkOption { + type = types.path; + description = "The directory the repositories are stored in."; + default = "/var/lib/nixbot"; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers.nixbot = { + createHome = true; + home = cfg.repoDir; + }; + + systemd.services.nixbot = let + env = pkgs.python3.buildEnv.override { + extraLibs = [ pkgs.nixbot ]; + }; + in { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = '' + ${env}/bin/pserve ${pkgs.writeText "production.ini" pyramidIni} + ''; + + serviceConfig = { + User = "nixbot"; + Group = "nogroup"; + PermissionsStartOnly = true; + }; + }; + }; +} diff --git a/nixos/modules/services/web-apps/quassel-webserver.nix b/nixos/modules/services/web-apps/quassel-webserver.nix new file mode 100644 index 000000000000..7de9480d4c46 --- /dev/null +++ b/nixos/modules/services/web-apps/quassel-webserver.nix @@ -0,0 +1,99 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.quassel-webserver; + quassel-webserver = cfg.pkg; + settings = '' + module.exports = { + default: { + host: '${cfg.quasselCoreHost}', // quasselcore host + port: ${toString cfg.quasselCorePort}, // quasselcore port + initialBacklogLimit: ${toString cfg.initialBacklogLimit}, // Amount of backlogs to fetch per buffer on connection + backlogLimit: ${toString cfg.backlogLimit}, // Amount of backlogs to fetch per buffer after first retrieval + securecore: ${if cfg.secureCore then "true" else "false"}, // Connect to the core using SSL + theme: '${cfg.theme}' // Default UI theme + }, + themes: ['default', 'darksolarized'], // Available themes + forcedefault: ${if cfg.forceHostAndPort then "true" else "false"}, // Will force default host and port to be used, and will hide the corresponding fields in the UI + prefixpath: '${cfg.prefixPath}' // Configure this if you use a reverse proxy + }; + ''; + settingsFile = pkgs.writeText "settings-user.js" settings; +in { + options = { + services.quassel-webserver = { + enable = mkOption { + default = false; + type = types.bool; + description = "Whether to enable the quassel webclient service"; + }; + pkg = mkOption { + default = pkgs.quassel-webserver; + description = "The quassel-webserver package"; + }; + quasselCoreHost = mkOption { + default = ""; + type = types.str; + description = "The default host of the quassel core"; + }; + quasselCorePort = mkOption { + default = 4242; + type = types.int; + description = "The default quassel core port"; + }; + initialBacklogLimit = mkOption { + default = 20; + type = types.int; + description = "Amount of backlogs to fetch per buffer on connection"; + }; + backlogLimit = mkOption { + default = 100; + type = types.int; + description = "Amount of backlogs to fetch per buffer after first retrieval"; + }; + secureCore = mkOption { + default = true; + type = types.bool; + description = "Connect to the core using SSL"; + }; + theme = mkOption { + default = "default"; + type = types.str; + description = "default or darksolarized"; + }; + prefixPath = mkOption { + default = ""; + type = types.str; + description = "Configure this if you use a reverse proxy. Must start with a '/'"; + example = "/quassel"; + }; + port = mkOption { + default = 60443; + type = types.int; + description = "The port the quassel webserver should listen on"; + }; + useHttps = mkOption { + default = true; + type = types.bool; + description = "Whether the quassel webserver connection should be a https connection"; + }; + forceHostAndPort = mkOption { + default = false; + type = types.bool; + description = "Force the users to use the quasselCoreHost and quasselCorePort defaults"; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.quassel-webserver = { + description = "A web server/client for Quassel"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${quassel-webserver}/lib/node_modules/quassel-webserver/bin/www -p ${toString cfg.port} -m ${if cfg.useHttps == true then "https" else "http"} -c ${settingsFile}"; + }; + }; + }; +} diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix index 4f9e9f52f9e0..1ed489bcb095 100644 --- a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix +++ b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix @@ -288,6 +288,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; example = '' diff --git a/nixos/modules/services/web-servers/apache-httpd/moodle.nix b/nixos/modules/services/web-servers/apache-httpd/moodle.nix index aa00e89967db..d525348d5c7e 100644 --- a/nixos/modules/services/web-servers/apache-httpd/moodle.nix +++ b/nixos/modules/services/web-servers/apache-httpd/moodle.nix @@ -164,6 +164,7 @@ in extraConfig = mkOption { + type = types.lines; default = ""; example = '' diff --git a/nixos/modules/services/web-servers/apache-httpd/trac.nix b/nixos/modules/services/web-servers/apache-httpd/trac.nix index 3196edc2838b..87ed36e35305 100644 --- a/nixos/modules/services/web-servers/apache-httpd/trac.nix +++ b/nixos/modules/services/web-servers/apache-httpd/trac.nix @@ -102,7 +102,6 @@ in pkgs.setuptools pkgs.pythonPackages.genshi pkgs.pythonPackages.psycopg2 - pkgs.python.modules.sqlite3 subversion ]; }; diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix index 2315c4729aec..32dd4439675a 100644 --- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix +++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix @@ -212,6 +212,7 @@ in example = "[ \"en_GB\" \"de_DE\" ];"; }; extraConfig = mkOption { + type = types.lines; default = ""; example = '' diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 443bd8c10000..166e5a6b2cea 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -392,8 +392,13 @@ in security.acme.certs = filterAttrs (n: v: v != {}) ( mapAttrs (vhostName: vhostConfig: optionalAttrs vhostConfig.enableACME { + user = cfg.user; + group = cfg.group; webroot = vhostConfig.acmeRoot; extraDomains = genAttrs vhostConfig.serverAliases (alias: null); + postRun = '' + systemctl reload nginx + ''; } ) virtualHosts ); diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix index a3a23b222fbb..ed537e7122a2 100644 --- a/nixos/modules/services/web-servers/phpfpm/default.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -7,8 +7,6 @@ let stateDir = "/run/phpfpm"; - pidFile = "${stateDir}/phpfpm.pid"; - mkPool = n: p: '' [${n}] listen = ${p.listen} @@ -17,9 +15,8 @@ let cfgFile = pkgs.writeText "phpfpm.conf" '' [global] - pid = ${pidFile} error_log = syslog - daemonize = yes + daemonize = no ${cfg.extraConfig} ${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)} @@ -43,7 +40,7 @@ in { description = '' Extra configuration that should be put in the global section of the PHP-FPM configuration file. Do not specify the options - <literal>pid</literal>, <literal>error_log</literal> or + <literal>error_log</literal> or <literal>daemonize</literal> here, since they are generated by NixOS. ''; @@ -129,10 +126,10 @@ in { mkdir -p "${stateDir}" ''; serviceConfig = { + Type = "notify"; ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}"; - PIDFile = pidFile; + ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; }; }; - }; } diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 1ea7b5ccf16a..31412ae70142 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 ./kde5.nix - ./enlightenment.nix ./gnome3.nix ./kodi.nix + ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ]; options = { diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index dc71531759b8..5d1af09e7aa7 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -82,7 +82,7 @@ in { environment.gnome3.packageSet = mkOption { default = null; - example = literalExample "pkgs.gnome3_20"; + example = literalExample "pkgs.gnome3_22"; description = "Which GNOME 3 package set to use."; apply = p: if p == null then pkgs.gnome3 else p; }; @@ -108,6 +108,7 @@ in { services.gnome3.gnome-documents.enable = mkDefault true; services.gnome3.gnome-keyring.enable = true; services.gnome3.gnome-online-accounts.enable = mkDefault true; + services.gnome3.gnome-terminal-server.enable = mkDefault true; services.gnome3.gnome-user-share.enable = mkDefault true; services.gnome3.gvfs.enable = true; services.gnome3.seahorse.enable = mkDefault true; diff --git a/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixos/modules/services/x11/desktop-managers/lxqt.nix new file mode 100644 index 000000000000..d13b7352c95e --- /dev/null +++ b/nixos/modules/services/x11/desktop-managers/lxqt.nix @@ -0,0 +1,83 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.lxqt; + +in + +{ + options = { + + services.xserver.desktopManager.lxqt.enable = mkOption { + type = types.bool; + default = false; + description = "Enable the LXQt desktop manager"; + }; + + }; + + + config = mkIf (xcfg.enable && cfg.enable) { + + services.xserver.desktopManager.session = singleton { + name = "lxqt"; + start = '' + exec ${pkgs.lxqt.lxqt-common}/bin/startlxqt + ''; + }; + + environment.systemPackages = [ + pkgs.kde5.kwindowsystem # provides some QT5 plugins needed by lxqt-panel + pkgs.kde5.libkscreen # provides plugins for screen management software + pkgs.kde5.oxygen-icons5 # default icon theme + pkgs.libfm + pkgs.libfm-extra + pkgs.lxmenu-data + pkgs.lxqt.compton-conf + pkgs.lxqt.libfm-qt + pkgs.lxqt.liblxqt + pkgs.lxqt.libqtxdg + pkgs.lxqt.libsysstat + pkgs.lxqt.lximage-qt + pkgs.lxqt.lxqt-about + pkgs.lxqt.lxqt-admin + pkgs.lxqt.lxqt-common + pkgs.lxqt.lxqt-config + pkgs.lxqt.lxqt-globalkeys + pkgs.lxqt.lxqt-l10n + pkgs.lxqt.lxqt-notificationd + pkgs.lxqt.lxqt-openssh-askpass + pkgs.lxqt.lxqt-panel + pkgs.lxqt.lxqt-policykit + pkgs.lxqt.lxqt-powermanagement + pkgs.lxqt.lxqt-qtplugin + pkgs.lxqt.lxqt-runner + pkgs.lxqt.lxqt-session + pkgs.lxqt.lxqt-sudo + pkgs.lxqt.obconf-qt + pkgs.lxqt.pavucontrol-qt + pkgs.lxqt.pcmanfm-qt + pkgs.lxqt.qlipper + pkgs.lxqt.qps + pkgs.lxqt.qterminal + pkgs.lxqt.qtermwidget + pkgs.lxqt.screengrab + pkgs.menu-cache + pkgs.openbox # default window manager + pkgs.qt5.qtsvg # provides QT5 plugins for svg icons + pkgs.xscreensaver + ]; + + # Link some extra directories in /run/current-system/software/share + environment.pathsToLink = [ + "/share/desktop-directories" + "/share/icons" + "/share/lxqt" + ]; + + }; +} diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 51d7d905d587..530468be5f96 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -69,7 +69,7 @@ in services.xserver.updateDbusEnvironment = true; environment.systemPackages = - [ pkgs.gtk2 # To get GTK+'s themes. + [ pkgs.gtk2.out # To get GTK+'s themes and gtk-update-icon-cache pkgs.hicolor_icon_theme pkgs.tango-icon-theme pkgs.shared_mime_info diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix index 52847d2f8d2c..d3aa63fd4284 100644 --- a/nixos/modules/services/x11/display-managers/gdm.nix +++ b/nixos/modules/services/x11/display-managers/gdm.nix @@ -95,9 +95,8 @@ in services.xserver.displayManager.job = { environment = { - GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}"; + GDM_X_SERVER_EXTRA_ARGS = "${cfg.xserverArgs}"; GDM_SESSIONS_DIR = "${cfg.session.desktops}"; - XDG_CONFIG_DIRS = "${gnome3.gnome_settings_daemon}/etc/xdg"; # Find the mouse XCURSOR_PATH = "~/.icons:${config.system.path}/share/icons"; }; @@ -108,10 +107,12 @@ in systemd.services.display-manager.wants = [ "systemd-machined.service" ]; systemd.services.display-manager.after = [ "systemd-machined.service" ]; - systemd.services.display-manager.path = [ gnome3.gnome_shell gnome3.caribou pkgs.xorg.xhost pkgs.dbus_tools ]; + systemd.services.display-manager.path = [ gnome3.gnome_session ]; services.dbus.packages = [ gdm ]; + systemd.user.services.dbus.wantedBy = [ "default.target" ]; + programs.dconf.profiles.gdm = "${gdm}/share/dconf/profile/gdm"; # Use AutomaticLogin if delay is zero, because it's immediate. diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index 33cd51f37c68..1d309aa34292 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -207,6 +207,9 @@ in services.dbus.enable = true; services.dbus.packages = [ lightdm ]; + # lightdm uses the accounts daemon to rember language/window-manager per user + services.accounts-daemon.enable = true; + security.pam.services.lightdm = { allowNullPassword = true; startSession = true; diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 4d2ddedca1ea..36daf55a36a5 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -14,7 +14,7 @@ let xserverWrapper = pkgs.writeScript "xserver-wrapper" '' #!/bin/sh ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} - exec ${dmcfg.xserverBin} ${dmcfg.xserverArgs} "$@" + exec systemd-cat ${dmcfg.xserverBin} ${dmcfg.xserverArgs} "$@" ''; Xsetup = pkgs.writeScript "Xsetup" '' @@ -86,7 +86,7 @@ in }; extraConfig = mkOption { - type = types.str; + type = types.lines; default = ""; example = '' [Autologin] diff --git a/nixos/modules/services/x11/urxvtd.nix b/nixos/modules/services/x11/urxvtd.nix new file mode 100644 index 000000000000..ab47f4547aea --- /dev/null +++ b/nixos/modules/services/x11/urxvtd.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: + +# maintainer: siddharthist + +with lib; + +let + cfg = config.services.urxvtd; +in { + + options.services.urxvtd.enable = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Enable urxvtd, the urxvt terminal daemon. To use urxvtd, run + "urxvtc". + ''; + }; + + config = mkIf cfg.enable { + systemd.user = { + sockets.urxvtd = { + description = "socket for urxvtd, the urxvt terminal daemon"; + after = [ "graphical.target" ]; + wants = [ "graphical.target" ]; + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenStream = "%t/urxvtd-socket"; + }; + }; + + services.urxvtd = { + description = "urxvt terminal daemon"; + serviceConfig = { + ExecStart = "${pkgs.rxvt_unicode-with-plugins}/bin/urxvtd -o"; + Environment = "RXVT_SOCKET=%t/urxvtd-socket"; + Restart = "on-failure"; + RestartSec = "5s"; + }; + }; + + }; + + environment.systemPackages = [ pkgs.rxvt_unicode-with-plugins ]; + environment.variables.RXVT_SOCKET = "/run/user/$(id -u)/urxvtd-socket"; + }; + +} diff --git a/nixos/modules/services/x11/window-managers/bspwm-unstable.nix b/nixos/modules/services/x11/window-managers/bspwm-unstable.nix new file mode 100644 index 000000000000..3282e0d0851f --- /dev/null +++ b/nixos/modules/services/x11/window-managers/bspwm-unstable.nix @@ -0,0 +1,48 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.bspwm-unstable; +in + +{ + options = { + services.xserver.windowManager.bspwm-unstable = { + enable = mkEnableOption "bspwm-unstable"; + startThroughSession = mkOption { + type = with types; bool; + default = false; + description = " + Start the window manager through the script defined in + sessionScript. Defaults to the the bspwm-session script + provided by bspwm + "; + }; + sessionScript = mkOption { + default = "${pkgs.bspwm-unstable}/bin/bspwm-session"; + defaultText = "(pkgs.bspwm-unstable)/bin/bspwm-session"; + description = " + The start-session script to use. Defaults to the + provided bspwm-session script from the bspwm package. + + Does nothing unless `bspwm.startThroughSession` is enabled + "; + }; + }; + }; + + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "bspwm-unstable"; + start = if cfg.startThroughSession + then cfg.sessionScript + else '' + export _JAVA_AWT_WM_NONREPARENTING=1 + SXHKD_SHELL=/bin/sh ${pkgs.sxhkd-unstable}/bin/sxhkd -f 100 & + ${pkgs.bspwm-unstable}/bin/bspwm + ''; + }; + environment.systemPackages = [ pkgs.bspwm-unstable ]; + }; +} diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index f005decfa33c..dabe2c26a72f 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -10,6 +10,7 @@ in imports = [ ./afterstep.nix ./bspwm.nix + ./bspwm-unstable.nix ./compiz.nix ./dwm.nix ./exwm.nix diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index ec2f3a4f8bb1..f5ed52338182 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -515,6 +515,7 @@ in { description = "X11 Server"; after = [ "systemd-udev-settle.service" "local-fs.target" "acpid.service" "systemd-logind.service" ]; + wants = [ "systemd-udev-settle.service" ]; restartIfChanged = false; @@ -539,6 +540,10 @@ in Restart = "always"; RestartSec = "200ms"; SyslogIdentifier = "display-manager"; + # Stop restarting if the display manager stops (crashes) 2 times + # in one minute. Starting X typically takes 3-4s. + StartLimitInterval = "30s"; + StartLimitBurst = "3"; }; }; diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 4a16a6762935..dcf105eb7844 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -145,6 +145,7 @@ in ${pkgs.e2fsprogs}/bin/chattr -f -i /var/empty || true find /var/empty -mindepth 1 -delete chmod 0555 /var/empty + chown root:root /var/empty ${pkgs.e2fsprogs}/bin/chattr -f +i /var/empty || true ''; diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix index 2d1b0ffb54ce..0c08375da646 100644 --- a/nixos/modules/system/activation/top-level.nix +++ b/nixos/modules/system/activation/top-level.nix @@ -98,7 +98,7 @@ let # `switch-to-configuration' that activates the configuration and # makes it bootable. baseSystem = showWarnings ( - if [] == failed then pkgs.stdenv.mkDerivation { + if [] == failed then pkgs.stdenvNoCC.mkDerivation { name = let hn = config.networking.hostName; nn = if (hn != "") then hn else "unnamed"; in "nixos-system-${nn}-${config.system.nixosLabel}"; diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix index ba15d0318b17..e751ff141f70 100644 --- a/nixos/modules/system/boot/kernel.nix +++ b/nixos/modules/system/boot/kernel.nix @@ -4,7 +4,9 @@ with lib; let - kernel = config.boot.kernelPackages.kernel; + inherit (config.boot) kernelPatches; + + inherit (config.boot.kernelPackages) kernel; kernelModulesConf = pkgs.writeText "nixos.conf" '' @@ -21,6 +23,11 @@ in boot.kernelPackages = mkOption { default = pkgs.linuxPackages; + apply = kernelPackages: kernelPackages.extend (self: super: { + kernel = super.kernel.override { + kernelPatches = super.kernel.kernelPatches ++ kernelPatches; + }; + }); # We don't want to evaluate all of linuxPackages for the manual # - some of it might not even evaluate correctly. defaultText = "pkgs.linuxPackages"; @@ -39,6 +46,13 @@ in ''; }; + boot.kernelPatches = mkOption { + type = types.listOf types.attrs; + default = []; + example = literalExample "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; + description = "A list of additional patches to apply to the kernel."; + }; + boot.kernelParams = mkOption { type = types.listOf types.str; default = [ ]; @@ -200,8 +214,8 @@ in "hid_generic" "hid_lenovo" "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat" - # Misc. stuff. - "pcips2" "atkbd" + # Misc. keyboard stuff. + "pcips2" "atkbd" "i8042" # Temporary fix for https://github.com/NixOS/nixpkgs/issues/18451 # Remove as soon as upstream gets fixed - marking it: diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index abab5f20baac..7803f1bd1aaf 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -498,8 +498,7 @@ eval "exec $logOutFd>&- $logErrFd>&-" # # Storage daemons are distinguished by an @ in front of their command line: # https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/ -local pidsToKill="$(pgrep -v -f '^@')" -for pid in $pidsToKill; do +for pid in $(pgrep -v -f '^@'); do # Make sure we don't kill kernel processes, see #15226 and: # http://stackoverflow.com/questions/12213445/identifying-kernel-threads readlink "/proc/$pid/exe" &> /dev/null || continue diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 8d02cd81e0e1..61def24efd88 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -34,7 +34,7 @@ let # copy what we need. Instead of using statically linked binaries, # we just copy what we need from Glibc and use patchelf to make it # work. - extraUtils = pkgs.runCommand "extra-utils" + extraUtils = pkgs.runCommandCC "extra-utils" { buildInputs = [pkgs.nukeReferences]; allowedReferences = [ "out" ]; # prevent accidents like glibc being included in the initrd } diff --git a/nixos/modules/system/boot/systemd-nspawn.nix b/nixos/modules/system/boot/systemd-nspawn.nix new file mode 100644 index 000000000000..f765db275e79 --- /dev/null +++ b/nixos/modules/system/boot/systemd-nspawn.nix @@ -0,0 +1,122 @@ +{ config, lib , pkgs, ...}: + +with lib; +with import ./systemd-unit-options.nix { inherit config lib; }; +with import ./systemd-lib.nix { inherit config lib pkgs; }; + +let + cfg = config.systemd.nspawn; + assertions = [ + # boot = true -> processtwo != true + ]; + + checkExec = checkUnitConfig "Exec" [ + (assertOnlyFields [ + "Boot" "ProcessTwo" "Parameters" "Environment" "User" "WorkingDirectory" + "Capability" "DropCapability" "KillSignal" "Personality" "MachineId" + "PrivateUsers" + ]) + (assertValueOneOf "Boot" boolValues) + (assertValueOneOf "ProcessTwo" boolValues) + (assertValueOneOf "PrivateUsers" (boolValues ++ [ "pick" ])) + ]; + + checkFiles = checkUnitConfig "Files" [ + (assertOnlyFields [ + "ReadOnly" "Volatile" "Bind" "BindReadOnly" "TemporaryFileSystems" + "PrivateUsersChown" + ]) + (assertValueOneOf "ReadOnly" boolValues) + (assertValueOneOf "Volatile" (boolValues ++ [ "state" ])) + (assertValueOneOf "PrivateUsersChown" boolValues) + ]; + + checkNetwork = checkUnitConfig "Network" [ + (assertOnlyFields [ + "Private" "VirtualEthernet" "VirtualEthernetExtra" "Interface" "MACVLAN" + "IPVLAN" "Bridge" "Zone" "Port" + ]) + (assertValueOneOf "Private" boolValues) + (assertValueOneOf "VirtualEthernet" boolValues) + ]; + + instanceOptions = { + options = { + + execConfig = mkOption { + default = {}; + example = { Parameters = "/bin/sh"; }; + type = types.addCheck (types.attrsOf unitOption) checkExec; + description = '' + Each attribute in this set specifies an option in the + <literal>[Exec]</literal> section of this unit. See + <citerefentry><refentrytitle>systemd.nspawn</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + ''; + }; + + filesConfig = mkOption { + default = {}; + example = { Bind = [ "/home/alice" ]; }; + type = types.addCheck (types.attrsOf unitOption) checkFiles; + description = '' + Each attribute in this set specifies an option in the + <literal>[Files]</literal> section of this unit. See + <citerefentry><refentrytitle>systemd.nspawn</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + ''; + }; + + networkConfig = mkOption { + default = {}; + example = { Private = false; }; + type = types.addCheck (types.attrsOf unitOption) checkNetwork; + description = '' + Each attribute in this set specifies an option in the + <literal>[Network]</literal> section of this unit. See + <citerefentry><refentrytitle>systemd.nspawn</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + ''; + }; + }; + + }; + + instanceToUnit = name: def: + { text = '' + [Exec] + ${attrsToSection def.execConfig} + + [Files] + ${attrsToSection def.filesConfig} + + [Network] + ${attrsToSection def.networkConfig} + ''; + }; + +in { + + options = { + + systemd.nspawn = mkOption { + default = {}; + type = with types; attrsOf (submodule instanceOptions); + description = "Definition of systemd-nspawn configurations."; + }; + + }; + + config = + let + units = mapAttrs' (n: v: nameValuePair "${n}.nspawn" (instanceToUnit n v)) cfg.instances; + in mkIf (cfg != {}) { + + environment.etc."systemd/nspawn".source = generateUnits "nspawn" units [] []; + + systemd.services."systemd-nspawn@" = { + wantedBy = [ "machine.target" ]; + }; + }; + +} diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index 731b1701e00d..4c3fc30358c1 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -316,7 +316,7 @@ in rec { startAt = mkOption { type = with types; either str (listOf str); - default = ""; + default = []; example = "Sun 14:00:00"; description = '' Automatically start this unit at the given date/time, which @@ -326,6 +326,7 @@ in rec { to adding a corresponding timer unit with <option>OnCalendar</option> set to the value given here. ''; + apply = v: if isList v then v else [ v ]; }; }; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index d44c2e234b0f..d1f3f923e5e3 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -777,7 +777,7 @@ in { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = service.startAt; }) - (filterAttrs (name: service: service.enable && service.startAt != "") cfg.services); + (filterAttrs (name: service: service.enable && service.startAt != []) cfg.services); # Generate timer units for all services that have a ‘startAt’ value. systemd.user.timers = @@ -785,7 +785,7 @@ in { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = service.startAt; }) - (filterAttrs (name: service: service.startAt != "") cfg.user.services); + (filterAttrs (name: service: service.startAt != []) cfg.user.services); systemd.sockets.systemd-journal-gatewayd.wantedBy = optional config.services.journald.enableHttpGateway "sockets.target"; diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix index dac36229408f..fd6e58cd5b43 100644 --- a/nixos/modules/system/etc/etc.nix +++ b/nixos/modules/system/etc/etc.nix @@ -8,7 +8,7 @@ let etc' = filter (f: f.enable) (attrValues config.environment.etc); - etc = pkgs.stdenv.mkDerivation { + etc = pkgs.stdenvNoCC.mkDerivation { name = "etc"; builder = ./make-etc.sh; diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 6a8f20bab5b6..c50ea5c79643 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -46,6 +46,23 @@ in systemd.services = let + deviceDependency = dev: + if (config.boot.isContainer == false) + then + # Trust udev when not in the container + optional (dev != null) (subsystemDevice dev) + else + # When in the container, check whether the interface is built from other definitions + if (hasAttr dev cfg.bridges) || + (hasAttr dev cfg.bonds) || + (hasAttr dev cfg.macvlans) || + (hasAttr dev cfg.sits) || + (hasAttr dev cfg.vlans) || + (hasAttr dev cfg.vswitches) || + (hasAttr dev cfg.wlanInterfaces) + then [ "${dev}-netdev.service" ] + else []; + networkLocalCommands = { after = [ "network-setup.service" ]; bindsTo = [ "network-setup.service" ]; @@ -120,8 +137,8 @@ in # order before network-setup because the routes that are configured # there may need ip addresses configured before = [ "network-setup.service" ]; - bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) "network-pre.target" ]; + bindsTo = deviceDependency i.name; + after = [ "network-pre.target" ] ++ (deviceDependency i.name); serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -179,7 +196,7 @@ in createBridgeDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); in { description = "Bridge Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) ]; @@ -220,7 +237,7 @@ in createVswitchDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; in { description = "Open vSwitch Interface ${n}"; @@ -253,7 +270,7 @@ in createBondDevice = n: v: nameValuePair "${n}-netdev" (let - deps = map subsystemDevice v.interfaces; + deps = concatLists (map deviceDependency v.interfaces); in { description = "Bond Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) ]; @@ -291,7 +308,7 @@ in createMacvlanDevice = n: v: nameValuePair "${n}-netdev" (let - deps = [ (subsystemDevice v.interface) ]; + deps = deviceDependency v.interface; in { description = "Vlan Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) ]; @@ -316,7 +333,7 @@ in createSitDevice = n: v: nameValuePair "${n}-netdev" (let - deps = optional (v.dev != null) (subsystemDevice v.dev); + deps = deviceDependency v.dev; in { description = "6-to-4 Tunnel Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) ]; @@ -344,7 +361,7 @@ in createVlanDevice = n: v: nameValuePair "${n}-netdev" (let - deps = [ (subsystemDevice v.interface) ]; + deps = deviceDependency v.interface; in { description = "Vlan Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) ]; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index cac7e6b02eba..aae4dc5fdadf 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -310,9 +310,9 @@ in generate a random 32-bit ID using the following commands: <literal>cksum /etc/machine-id | while read c rest; do printf "%x" $c; done</literal> - + (this derives it from the machine-id that systemd generates) or - + <literal>head -c4 /dev/urandom | od -A none -t x4</literal> ''; }; @@ -972,12 +972,17 @@ in ''; }; } // (listToAttrs (flip map interfaces (i: + let + deviceDependency = if config.boot.isContainer + then [] + else [ (subsystemDevice i.name) ]; + in nameValuePair "network-link-${i.name}" { description = "Link configuration of ${i.name}"; wantedBy = [ "network-interfaces.target" ]; before = [ "network-interfaces.target" ]; - bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) "network-pre.target" ]; + bindsTo = deviceDependency; + after = [ "network-pre.target" ] ++ deviceDependency; path = [ pkgs.iproute ]; serviceConfig = { Type = "oneshot"; diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix index 5e1cfcdfc6fb..aa28a25be7ac 100644 --- a/nixos/modules/virtualisation/containers.nix +++ b/nixos/modules/virtualisation/containers.nix @@ -473,7 +473,7 @@ in }; extraVeths = mkOption { - type = with types; attrsOf (submodule networkOptions); + type = with types; attrsOf (submodule { options = networkOptions; }); default = {}; description = '' Extra veth-pairs to be created for the container |