diff --git a/modules/services/audio/pulseaudio.nix b/modules/services/audio/pulseaudio.nix index 7b71571337f..d322c6b51ea 100644 --- a/modules/services/audio/pulseaudio.nix +++ b/modules/services/audio/pulseaudio.nix @@ -1,89 +1,88 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; uid = config.ids.uids.pulseaudio; gid = config.ids.gids.pulseaudio; - options = { - services = { - pulseaudio = { - enable = mkOption { - default = false; - description = '' - Whether to enable the PulseAudio system-wide audio server. - Note that the documentation recommends running PulseAudio - daemons per-user rather than system-wide on desktop machines. - ''; - }; - - logLevel = mkOption { - default = "notice"; - example = "debug"; - description = '' - A string denoting the log level: one of - error, warn, - notice, info, - or debug. - ''; - }; - }; - }; - }; in -###### implementation +{ + ###### interface -mkIf config.services.pulseaudio.enable { - require = [ - options - ]; + options = { + + services.pulseaudio = { + + enable = mkOption { + default = false; + description = '' + Whether to enable the PulseAudio system-wide audio server. + Note that the documentation recommends running PulseAudio + daemons per-user rather than system-wide on desktop machines. + ''; + }; - environment = { - systemPackages = [pkgs.pulseaudio]; + logLevel = mkOption { + default = "notice"; + example = "debug"; + description = '' + A string denoting the log level: one of + error, warn, + notice, info, + or debug. + ''; + }; + + }; + }; + - users = { - extraUsers = [ + ###### implementation + + config = mkIf config.services.pulseaudio.enable { + + environment.systemPackages = [ pkgs.pulseaudio ]; + + users.extraUsers = singleton { name = "pulse"; # For some reason, PulseAudio wants UID == GID. uid = assert uid == gid; uid; group = "pulse"; description = "PulseAudio system-wide daemon"; home = "/var/run/pulse"; - } - ]; + }; - extraGroups = [ + users.extraGroups = singleton { name = "pulse"; inherit gid; - } - ]; - }; - - services = { - extraJobs = [{ - name = "pulseaudio"; - - job = '' - description "PulseAudio system-wide server" - - start on startup - stop on shutdown - - start script - test -d /var/run/pulse || \ - ( mkdir -p --mode 755 /var/run/pulse && \ - chown pulse:pulse /var/run/pulse ) - end script - - respawn ${pkgs.pulseaudio}/bin/pulseaudio \ - --system --daemonize \ - --log-level="${config.services.pulseaudio.logLevel}" - ''; - }]; + }; + + jobAttrs.pulseaudio = + { description = "PulseAudio system-wide server"; + + startOn = "startup"; + stopOn = "shutdown"; + + preStart = + '' + test -d /var/run/pulse || \ + ( mkdir -p --mode 755 /var/run/pulse && \ + chown pulse:pulse /var/run/pulse ) + ''; + + exec = + '' + ${pkgs.pulseaudio}/bin/pulseaudio \ + --system --daemonize \ + --log-level="${config.services.pulseaudio.logLevel}" + ''; + }; + }; + } diff --git a/modules/services/logging/klogd.nix b/modules/services/logging/klogd.nix index 59ab51fea92..f8c26e0f166 100644 --- a/modules/services/logging/klogd.nix +++ b/modules/services/logging/klogd.nix @@ -1,8 +1,8 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: ###### implementation + let - inherit (pkgs.lib); klogdCmd = "${pkgs.sysklogd}/sbin/klogd -c 1 -2 -k $(dirname $(readlink -f /var/run/booted-system/kernel))/System.map"; @@ -10,24 +10,20 @@ in { - services = { - extraJobs = [{ - name = "klogd"; - - job = '' - description "Kernel log daemon" - - start on syslogd - stop on shutdown + jobAttrs.klogd = + { description = "Kernel log daemon"; - start script + startOn = "syslogd"; + stopOn = "shutdown"; + + preStart = + '' # !!! this hangs for some reason (it blocks reading from # /proc/kmsg). #${klogdCmd} -o - end script + ''; - respawn ${klogdCmd} -n - ''; - }]; - }; + exec = "${klogdCmd} -n"; + }; + } diff --git a/modules/services/mail/dovecot.nix b/modules/services/mail/dovecot.nix index 79442f959c6..950c748ff8c 100644 --- a/modules/services/mail/dovecot.nix +++ b/modules/services/mail/dovecot.nix @@ -1,8 +1,9 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: with pkgs.lib; -let +let + startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; cfg = config.services.dovecot; @@ -112,23 +113,18 @@ in gid = config.ids.gids.dovecot; }; - services.extraJobs = singleton - { name = "dovecot"; + jobAttrs.dovecot = + { description = "Dovecot IMAP/POP3 server"; - job = + startOn = "${startingDependency}/started"; + + preStart = '' - description "Dovecot IMAP/POP3 server" - - start on ${startingDependency}/started - stop on never - - start script - ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot /var/run/dovecot/login - ${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot - end script - - respawn ${pkgs.dovecot}/sbin/dovecot -F -c ${confFile} + ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot /var/run/dovecot/login + ${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot ''; + + exec = "${pkgs.dovecot}/sbin/dovecot -F -c ${confFile}"; }; }; diff --git a/modules/services/mail/postfix.nix b/modules/services/mail/postfix.nix index 9e1ec488ae2..ec218608980 100644 --- a/modules/services/mail/postfix.nix +++ b/modules/services/mail/postfix.nix @@ -1,155 +1,9 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - postfix = { - enable = mkOption { - default = false; - description =" - Whether to run the Postfix mail server. - "; - }; - user = mkOption { - default = "postfix"; - description = " - How to call postfix user (must be used only for postfix). - "; - }; - group = mkOption { - default = "postfix"; - description = " - How to call postfix group (must be used only for postfix). - "; - }; - setgidGroup = mkOption { - default = "postdrop"; - description = " - How to call postfix setgid group (for postdrop). Should - be uniquely used group. - "; - }; - networks = mkOption { - default = null; - example = ["192.168.0.1/24"]; - description = " - Net masks for trusted - allowed to relay mail to third parties - - hosts. Leave empty to use mynetworks_style configuration or use - default (localhost-only). - "; - }; - networksStyle = mkOption { - default = ""; - description = " - Name of standard way of trusted network specification to use, - leave blank if you specify it explicitly or if you want to use - default (localhost-only). - "; - }; - hostname = mkOption { - default = ""; - description =" - Hostname to use. Leave blank to use just the hostname of machine. - It should be FQDN. - "; - }; - domain = mkOption { - default = ""; - description =" - Domain to use. Leave blank to use hostname minus first component. - "; - }; - origin = mkOption { - default = ""; - description =" - Origin to use in outgoing e-mail. Leave blank to use hostname. - "; - }; - destination = mkOption { - default = null; - example = ["localhost"]; - description = " - Full (!) list of domains we deliver locally. Leave blank for - acceptable Postfix default. - "; - }; - relayDomains = mkOption { - default = null; - example = ["localdomain"]; - description = " - List of domains we agree to relay to. Default is the same as - destination. - "; - }; - relayHost = mkOption { - default = ""; - description = " - Mail relay for outbound mail. - "; - }; - lookupMX = mkOption { - default = false; - description = " - Whether relay specified is just domain whose MX must be used. - "; - }; - postmasterAlias = mkOption { - default = "root"; - description = " - Who should receive postmaster e-mail. - "; - }; - rootAlias = mkOption { - default = ""; - description = " - Who should receive root e-mail. Blank for no redirection. - "; - }; - extraAliases = mkOption { - default = ""; - description = " - Additional entries to put verbatim into aliases file. - "; - }; - - sslCert = mkOption { - default = ""; - description = " - SSL certificate to use. - "; - }; - sslCACert = mkOption { - default = ""; - description = " - SSL certificate of CA. - "; - }; - sslKey = mkOption { - default = ""; - description =" - SSL key to use. - "; - }; - - recipientDelimiter = mkOption { - default = ""; - example = "+"; - description = " - Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test - "; - }; - - }; - }; - }; -in - -###### implementation +with pkgs.lib; let + startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; cfg = config.services.postfix; @@ -157,94 +11,86 @@ let group = cfg.group; setgidGroup = cfg.setgidGroup; - optionalString = pkgs.lib.optionalString; - concatStringsSep = pkgs.lib.concatStringsSep; mainCf = - '' - queue_directory = /var/postfix/queue - command_directory = ${pkgs.postfix}/sbin - daemon_directory = ${pkgs.postfix}/libexec/postfix + '' + queue_directory = /var/postfix/queue + command_directory = ${pkgs.postfix}/sbin + daemon_directory = ${pkgs.postfix}/libexec/postfix - mail_owner = ${user} - default_privs = nobody + mail_owner = ${user} + default_privs = nobody - '' - + optionalString (config.services.gw6c.enable || config.networking.nativeIPv6) ('' - inet_protocols = all - '') - + - (if cfg.networks!=null then - ('' - mynetworks = ${concatStringsSep ", " cfg.networks} - '') - else if (cfg.networksStyle != "") then - ('' - mynetworks_style = ${cfg.networksStyle} + '' + + optionalString (config.services.gw6c.enable || config.networking.nativeIPv6) ('' + inet_protocols = all '') - else - # Postfix default is subnet, but let's play safe - ('' - mynetworks_style = host - '') - ) - + optionalString (cfg.hostname != "") ('' - myhostname = ${cfg.hostname} - '') - + optionalString (cfg.domain != "") ('' - mydomain = ${cfg.domain} - '') - + optionalString (cfg.origin != "") ('' - myorigin = ${cfg.origin} - '') - + optionalString (cfg.destination != null) ('' - mydestination = ${concatStringsSep ", " cfg.destination} - '') - + optionalString (cfg.relayDomains != null) ('' - relay_domains = ${concatStringsSep ", " cfg.relayDomains} - '') - + '' - local_recipient_maps = - '' - + ('' - relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then - cfg.relayHost - else - "[" + cfg.relayHost + "]"} - '') - + ('' - alias_maps = hash:/var/postfix/conf/aliases + + (if cfg.networks != null then + '' + mynetworks = ${concatStringsSep ", " cfg.networks} + '' + else if cfg.networksStyle != "" then + '' + mynetworks_style = ${cfg.networksStyle} + '' + else + # Postfix default is subnet, but let's play safe + '' + mynetworks_style = host + '') + + optionalString (cfg.hostname != "") '' + myhostname = ${cfg.hostname} + '' + + optionalString (cfg.domain != "") '' + mydomain = ${cfg.domain} + '' + + optionalString (cfg.origin != "") '' + myorigin = ${cfg.origin} + '' + + optionalString (cfg.destination != null) '' + mydestination = ${concatStringsSep ", " cfg.destination} + '' + + optionalString (cfg.relayDomains != null) '' + relay_domains = ${concatStringsSep ", " cfg.relayDomains} + '' + + '' + local_recipient_maps = + + relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then + cfg.relayHost + else + "[" + cfg.relayHost + "]"} + + alias_maps = hash:/var/postfix/conf/aliases - mail_spool_directory = /var/spool/mail/ + mail_spool_directory = /var/spool/mail/ - setgid_group = ${setgidGroup} - '') - + optionalString (cfg.sslCert != "") ('' + setgid_group = ${setgidGroup} + '' + + optionalString (cfg.sslCert != "") '' - smtp_tls_CAfile = ${cfg.sslCACert} - smtp_tls_cert_file = ${cfg.sslCert} - smtp_tls_key_file = ${cfg.sslKey} + smtp_tls_CAfile = ${cfg.sslCACert} + smtp_tls_cert_file = ${cfg.sslCert} + smtp_tls_key_file = ${cfg.sslKey} - smtp_use_tls = yes + smtp_use_tls = yes - smtpd_tls_CAfile = ${cfg.sslCACert} - smtpd_tls_cert_file = ${cfg.sslCert} - smtpd_tls_key_file = ${cfg.sslKey} + smtpd_tls_CAfile = ${cfg.sslCACert} + smtpd_tls_cert_file = ${cfg.sslCert} + smtpd_tls_key_file = ${cfg.sslKey} - smtpd_use_tls = yes + smtpd_use_tls = yes - recipientDelimiter = ${cfg.recipientDelimiter} + recipientDelimiter = ${cfg.recipientDelimiter} - '') - ; + ''; aliases = - (optionalString (cfg.postmasterAlias != "") ('' + optionalString (cfg.postmasterAlias != "") '' postmaster: ${cfg.postmasterAlias} - '')) - + - (optionalString (cfg.rootAlias != "") ('' + '' + + optionalString (cfg.rootAlias != "") '' root: ${cfg.rootAlias} - '')) + '' + cfg.extraAliases ; @@ -253,54 +99,194 @@ let in -mkIf config.services.postfix.enable { - require = [ - options - ]; +{ + + ###### interface + + options = { + + services.postfix = { + + enable = mkOption { + default = false; + description = "Whether to run the Postfix mail server."; + }; + + user = mkOption { + default = "postfix"; + description = "What to call the Postfix user (must be used only for postfix)."; + }; + + group = mkOption { + default = "postfix"; + description = "What to call the Postfix group (must be used only for postfix)."; + }; + + setgidGroup = mkOption { + default = "postdrop"; + description = " + How to call postfix setgid group (for postdrop). Should + be uniquely used group. + "; + }; + + networks = mkOption { + default = null; + example = ["192.168.0.1/24"]; + description = " + Net masks for trusted - allowed to relay mail to third parties - + hosts. Leave empty to use mynetworks_style configuration or use + default (localhost-only). + "; + }; + + networksStyle = mkOption { + default = ""; + description = " + Name of standard way of trusted network specification to use, + leave blank if you specify it explicitly or if you want to use + default (localhost-only). + "; + }; + + hostname = mkOption { + default = ""; + description =" + Hostname to use. Leave blank to use just the hostname of machine. + It should be FQDN. + "; + }; + + domain = mkOption { + default = ""; + description =" + Domain to use. Leave blank to use hostname minus first component. + "; + }; + + origin = mkOption { + default = ""; + description =" + Origin to use in outgoing e-mail. Leave blank to use hostname. + "; + }; + + destination = mkOption { + default = null; + example = ["localhost"]; + description = " + Full (!) list of domains we deliver locally. Leave blank for + acceptable Postfix default. + "; + }; + + relayDomains = mkOption { + default = null; + example = ["localdomain"]; + description = " + List of domains we agree to relay to. Default is the same as + destination. + "; + }; + + relayHost = mkOption { + default = ""; + description = " + Mail relay for outbound mail. + "; + }; + + lookupMX = mkOption { + default = false; + description = " + Whether relay specified is just domain whose MX must be used. + "; + }; + + postmasterAlias = mkOption { + default = "root"; + description = "Who should receive postmaster e-mail."; + }; + + rootAlias = mkOption { + default = ""; + description = " + Who should receive root e-mail. Blank for no redirection. + "; + }; + + extraAliases = mkOption { + default = ""; + description = " + Additional entries to put verbatim into aliases file. + "; + }; + + sslCert = mkOption { + default = ""; + description = "SSL certificate to use."; + }; + + sslCACert = mkOption { + default = ""; + description = "SSL certificate of CA."; + }; + + sslKey = mkOption { + default = ""; + description = "SSL key to use."; + }; + + recipientDelimiter = mkOption { + default = ""; + example = "+"; + description = " + Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test + "; + }; + + }; - environment = { - etc = [{ - source = "/var/postfix/conf"; - target = "postfix"; - }]; }; - users = { - extraUsers = [ + + ###### implementation + + config = mkIf config.services.postfix.enable { + + environment.etc = singleton + { source = "/var/postfix/conf"; + target = "postfix"; + }; + + users.extraUsers = singleton { name = user; description = "Postfix mail server user"; uid = config.ids.uids.postfix; group = group; - } - ]; - - extraGroups = [ - { name = group; - gid = config.ids.gids.postfix; - } - { name = setgidGroup; - gid = config.ids.gids.postdrop; - } - ]; - }; - - services = { - extraJobs = [{ - name = "postfix"; + }; + users.extraGroups = + [ { name = group; + gid = config.ids.gids.postfix; + } + { name = setgidGroup; + gid = config.ids.gids.postdrop; + } + ]; + jobAttrs.postfix = # I copy _lots_ of shipped configuration filed # that can be left as is. I am afraid the exact # will list slightly change in next Postfix # release, so listing them all one-by-one in an # accurate way is unlikely to be better. - job = '' - description "Postfix mail server job" + { description = "Postfix mail server"; - start on ${startingDependency}/started - stop on never + startOn = "${startingDependency}/started"; - script + script = + '' if ! [ -d /var/spool/postfix ]; then ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue fi @@ -318,10 +304,11 @@ mkIf config.services.postfix.enable { ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start - end script - ''; + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start + ''; # */ + + }; - }]; }; + } diff --git a/modules/services/misc/autofs.nix b/modules/services/misc/autofs.nix index 1e506836a3e..757d38a1280 100644 --- a/modules/services/misc/autofs.nix +++ b/modules/services/misc/autofs.nix @@ -1,107 +1,99 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; - options = { - services = { - - autofs = { - enable = mkOption { - default = false; - description = " - automatically mount and unmount filesystems - "; - }; - - autoMaster = mkOption { - example = '' - autoMaster = let - mapConf = pkgs.writeText "auto" ''' - kernel -ro,soft,intr ftp.kernel.org:/pub/linux - boot -fstype=ext2 :/dev/hda1 - windoze -fstype=smbfs ://windoze/c - removable -fstype=ext2 :/dev/hdd - cd -fstype=iso9660,ro :/dev/hdc - floppy -fstype=auto :/dev/fd0 - server -rw,hard,intr / -ro myserver.me.org:/ \ - /usr myserver.me.org:/usr \ - /home myserver.me.org:/home - '''; - in ''' - /auto file:''${mapConf} - ''' - ''; - description = " - file contents of /etc/auto.master. See man auto.master - see - man auto.master and man 5 autofs - "; - }; - - timeout = mkOption { - default = 600; - description = "Set the global minimum timeout, in seconds, until directories are unmounted"; - }; - - debug = mkOption { - default = false; - description = "pass -d to automount and write log to /var/log/autofs"; - }; - }; - }; - }; - -###### implementation - - inherit (pkgs) lib writeTextopenssh autofs5; - - cfg = (config.services.autofs); - - modprobe = config.system.sbin.modprobe; + cfg = config.services.autofs; in -mkIf cfg.enable { +{ - require = [ - options - ]; + ###### interface - environment = { - etc = - [ { - target = "auto.master"; + options = { + + services.autofs = { + + enable = mkOption { + default = false; + description = " + automatically mount and unmount filesystems + "; + }; + + autoMaster = mkOption { + example = '' + autoMaster = let + mapConf = pkgs.writeText "auto" ''' + kernel -ro,soft,intr ftp.kernel.org:/pub/linux + boot -fstype=ext2 :/dev/hda1 + windoze -fstype=smbfs ://windoze/c + removable -fstype=ext2 :/dev/hdd + cd -fstype=iso9660,ro :/dev/hdc + floppy -fstype=auto :/dev/fd0 + server -rw,hard,intr / -ro myserver.me.org:/ \ + /usr myserver.me.org:/usr \ + /home myserver.me.org:/home + '''; + in ''' + /auto file:''${mapConf} + ''' + ''; + description = " + file contents of /etc/auto.master. See man auto.master + see + man auto.master and man 5 autofs + "; + }; + + timeout = mkOption { + default = 600; + description = "Set the global minimum timeout, in seconds, until directories are unmounted"; + }; + + debug = mkOption { + default = false; + description = "pass -d to automount and write log to /var/log/autofs"; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment.etc = singleton + { target = "auto.master"; source = pkgs.writeText "auto.master" cfg.autoMaster; - }]; - }; - - services = { - extraJobs = [ - { - name = "autofs"; - - # kernel module autofs supports kernel protocol v3 - # kernel module autofs4 supports kernel protocol v3, v4, v5 - job = '' - description "automatically mount filesystems" - - start on network-interfaces/started - stop on network-interfaces/stop - - PATH=${pkgs.nfsUtils}/sbin:${modprobe}/sbin - - start script - modprobe autofs4 || true - end script - - script - ${if cfg.debug then "exec &> /var/log/autofs" else ""} - ${pkgs.autofs5}/sbin/automount -f -t ${builtins.toString cfg.timeout} ${if cfg.debug then "-d" else ""} "${pkgs.writeText "auto.master" cfg.autoMaster}" - end script - ''; - } - ]; + }; + + jobAttrs.autofs = + { description = "Filesystem automounter"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + environment = + { PATH = "${pkgs.nfsUtils}/sbin:${config.system.sbin.modprobe}/sbin"; + }; + + preStart = + '' + modprobe autofs4 || true + ''; + + script = + '' + ${if cfg.debug then "exec &> /var/log/autofs" else ""} + ${pkgs.autofs5}/sbin/automount -f -t ${builtins.toString cfg.timeout} ${if cfg.debug then "-d" else ""} "${pkgs.writeText "auto.master" cfg.autoMaster}" + ''; + }; + }; + } diff --git a/modules/services/misc/disnix.nix b/modules/services/misc/disnix.nix index a4568ec78a8..bae74826da1 100644 --- a/modules/services/misc/disnix.nix +++ b/modules/services/misc/disnix.nix @@ -1,62 +1,57 @@ # Disnix server -{config, pkgs, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption; + + cfg = config.services.disnix; + +in + +{ + + ###### interface options = { - services = { - disnix = { - enable = mkOption { - default = false; - description = "Whether to enable Disnix"; - }; - }; - }; - }; -in - -###### implementation -let - cfg = config.services.disnix; - inherit (pkgs.lib) mkIf; - - job = { - name = "disnix"; - - job = '' - description "Disnix server" - - start on dbus - stop on shutdown - - script - export ACTIVATION_SCRIPTS=${pkgs.disnix_activation_scripts}/libexec/disnix/activation-scripts - export PATH=${pkgs.nixUnstable}/bin - export HOME=/root - - ${pkgs.disnix}/bin/disnix-service - end script - ''; - }; -in - -mkIf cfg.enable { - require = [ - #../upstart-jobs/default.nix - #../upstart-jobs/dbus.nix # services.dbus.* - options - ]; - environment.systemPackages = [ pkgs.disnix ]; + services.disnix = { + + enable = mkOption { + default = false; + description = "Whether to enable Disnix"; + }; - services = { - extraJobs = [job]; - - dbus = { - enable = true; - packages = [ pkgs.disnix ]; }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.disnix ]; + + services.dbus.enable = true; + services.dbus.packages = [ pkgs.disnix ]; + + jobAttrs.disnix = + { description = "Disnix server"; + + startOn = "dbus"; + stopOn = "shutdown"; + + script = + '' + export ACTIVATION_SCRIPTS=${pkgs.disnix_activation_scripts}/libexec/disnix/activation-scripts + export PATH=${pkgs.nixUnstable}/bin + export HOME=/root + + ${pkgs.disnix}/bin/disnix-service + ''; + }; + + }; + } diff --git a/modules/services/misc/gpsd.nix b/modules/services/misc/gpsd.nix index 724abbea6cb..b4cc58c3094 100644 --- a/modules/services/misc/gpsd.nix +++ b/modules/services/misc/gpsd.nix @@ -1,108 +1,105 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; uid = config.ids.uids.gpsd; gid = config.ids.gids.gpsd; - - options = { - services = { - gpsd = { - - enable = mkOption { - default = false; - description = '' - Whether to enable `gpsd', a GPS service daemon. - ''; - }; - - device = mkOption { - default = "/dev/ttyUSB0"; - description = '' - A device may be a local serial device for GPS input, or a URL of the form: - [{dgpsip|ntrip}://][user:passwd@]host[:port][/stream] - in which case it specifies an input source for DGPS or ntrip data. - ''; - }; - - readonly = mkOption { - default = true; - description = '' - Whether to enable the broken-device-safety, otherwise - known as read-only mode. Some popular bluetooth and USB - receivers lock up or become totally inaccessible when - probed or reconfigured. This switch prevents gpsd from - writing to a receiver. This means that gpsd cannot - configure the receiver for optimal performance, but it - also means that gpsd cannot break the receiver. A better - solution would be for Bluetooth to not be so fragile. A - platform independent method to identify - serial-over-Bluetooth devices would also be nice. - ''; - }; - - port = mkOption { - default = 2947; - description = '' - The port where to listen for TCP connections. - ''; - }; - - debugLevel = mkOption { - default = 0; - description = '' - The debugging level. - ''; - }; - - }; - }; - }; - + cfg = config.services.gpsd; + in -###### implementation -mkIf config.services.gpsd.enable { - require = [ - options - ]; +{ + + ###### interface + + options = { - users = { - extraUsers = [ + services.gpsd = { + + enable = mkOption { + default = false; + description = '' + Whether to enable `gpsd', a GPS service daemon. + ''; + }; + + device = mkOption { + default = "/dev/ttyUSB0"; + description = '' + A device may be a local serial device for GPS input, or a URL of the form: + [{dgpsip|ntrip}://][user:passwd@]host[:port][/stream] + in which case it specifies an input source for DGPS or ntrip data. + ''; + }; + + readonly = mkOption { + default = true; + description = '' + Whether to enable the broken-device-safety, otherwise + known as read-only mode. Some popular bluetooth and USB + receivers lock up or become totally inaccessible when + probed or reconfigured. This switch prevents gpsd from + writing to a receiver. This means that gpsd cannot + configure the receiver for optimal performance, but it + also means that gpsd cannot break the receiver. A better + solution would be for Bluetooth to not be so fragile. A + platform independent method to identify + serial-over-Bluetooth devices would also be nice. + ''; + }; + + port = mkOption { + default = 2947; + description = '' + The port where to listen for TCP connections. + ''; + }; + + debugLevel = mkOption { + default = 0; + description = '' + The debugging level. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + users.extraUsers = singleton { name = "gpsd"; inherit uid; description = "gpsd daemon user"; home = "/var/empty"; - } - ]; + }; - extraGroups = [ + users.extraGroups = singleton { name = "gpsd"; inherit gid; - } - ]; - }; + }; - services = - let cfg = config.services.gpsd; in { - extraJobs = [{ - name = "gpsd"; + jobAttrs.gpsd = + { description = "GPSD daemon"; - job = - let gpsd = pkgs.gpsd; - in '' - description "GPSD daemon" + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; - start on network-interfaces/started - stop on network-interfaces/stop - - respawn ${gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ - -S "${toString cfg.port}" \ - ${if cfg.readonly then "-b" else ""} \ + exec = + '' + respawn ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ + -S "${toString cfg.port}" \ + ${if cfg.readonly then "-b" else ""} \ "${cfg.device}" ''; - }]; }; + + }; + } diff --git a/modules/services/misc/nixos-manual.nix b/modules/services/misc/nixos-manual.nix index 961dbe2800f..78c120872c8 100644 --- a/modules/services/misc/nixos-manual.nix +++ b/modules/services/misc/nixos-manual.nix @@ -3,12 +3,12 @@ # of the virtual consoles. The latter is useful for the installation # CD. -{pkgs, config, options, ...}: +{ config, pkgs, options, ... }: + +with pkgs.lib; let - inherit (pkgs.lib) mkOption mkIf types; - cfg = config.services.nixosManual; manual = import ../../../doc/manual { @@ -72,18 +72,22 @@ in boot.extraTTYs = mkIf cfg.showManual [cfg.ttyNumber]; - services.extraJobs = mkIf cfg.showManual (pkgs.lib.singleton - { name = "nixos-manual"; + jobAttrs = mkIf cfg.showManual + { nixosManual = + { name = "nixos-manual"; - job = '' - description "NixOS manual" + description = "NixOS manual"; - start on udev - stop on shutdown - respawn ${cfg.browser} ${manual}/share/doc/nixos/manual.html \ - < /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1 - ''; - }); + startOn = "udev"; + stopOn = "shutdown"; + + exec = + '' + ${cfg.browser} ${manual}/share/doc/nixos/manual.html \ + < /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1 + ''; + }; + }; services.ttyBackgrounds.specificThemes = mkIf cfg.showManual [ { tty = cfg.ttyNumber; diff --git a/modules/services/misc/synergy.nix b/modules/services/misc/synergy.nix index 3a1ce34d070..a7df38f239d 100644 --- a/modules/services/misc/synergy.nix +++ b/modules/services/misc/synergy.nix @@ -1,106 +1,108 @@ +{ config, pkgs, ... }: -{pkgs, config, ...}: +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; - options = { - services = { - synergy = { - - client = { - enable = mkOption { - default = false; - description = " - Whether to enable the synergy client (receive keyboard and mouse events from a synergy server) - "; - }; - screenName = mkOption { - default = ""; - description = " - use screen-name instead the hostname to identify - ourselfs to the server. - "; - }; - }; - - server = { - enable = mkOption { - default = false; - description = " - Whether to enable the synergy server (send keyboard and mouse events) - "; - }; - configFile = mkOption { - default = "/etc/synergy-server.conf"; - description = " - The synergy server configuration file. open upstart-jobs/synergy.nix to see an example - "; - }; - screenName = mkOption { - default = ""; - description = " - use screen-name instead the hostname to identify - this screen in the configuration. - "; - }; - address = mkOption { - default = ""; - description = "listen for clients on the given address"; - }; - }; - }; - }; - }; - -###### implementation - - inherit (pkgs.lib) optional; - - cfgC = (config.services.synergy.client); - cfgS = (config.services.synergy.server); - - clientJob = { - name = "synergy-client"; - - job = '' - description "synergy client" - - start on started network-interfaces - stop on stopping network-interfaces - - respawn ${pkgs.synergy}/bin/synergyc ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" } - ''; - }; - - serverJob = { - name = "synergy-server"; - - job = '' - description "synergy server" - - start on started network-interfaces - stop on stopping network-interfaces - - respawn ${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} \ - -f ${if cfgS.address == "" then "" else "-a ${cfgS.address}"} \ - ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" } - ''; - }; + cfgC = config.services.synergy.client; + cfgS = config.services.synergy.server; in - { - require = [ - options - ]; + ###### interface + + options = { + + services.synergy = { + + # !!! All these option descriptions needs to be cleaned up. + + client = { + enable = mkOption { + default = false; + description = " + Whether to enable the synergy client (receive keyboard and mouse events from a synergy server) + "; + }; + screenName = mkOption { + default = ""; + description = " + use screen-name instead the hostname to identify + ourselfs to the server. + "; + }; + }; + + server = { + enable = mkOption { + default = false; + description = " + Whether to enable the synergy server (send keyboard and mouse events) + "; + }; + configFile = mkOption { + default = "/etc/synergy-server.conf"; + description = " + The synergy server configuration file. open upstart-jobs/synergy.nix to see an example + "; + }; + screenName = mkOption { + default = ""; + description = " + use screen-name instead the hostname to identify + this screen in the configuration. + "; + }; + address = mkOption { + default = ""; + description = "listen for clients on the given address"; + }; + }; + }; - services = { - extraJobs = (optional cfgS.enable serverJob) - ++ (optional cfgC.enable clientJob); }; + + + ###### implementation + + config = { + + jobAttrs = + + optionalAttrs cfgC.enable + { synergyClient = + { name = "synergy-client"; + + description = "Synergy client"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stopped"; + + exec = "${pkgs.synergy}/bin/synergyc ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" }"; + }; + } + + // optionalAttrs cfgS.enable + { synergyServer = + { name = "synergy-server"; + + description = "Synergy server"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stopped"; + + exec = + '' + respawn ${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} \ + -f ${if cfgS.address == "" then "" else "-a ${cfgS.address}"} \ + ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" } + ''; + }; + }; + + }; + } /* SYNERGY SERVER example configuration file diff --git a/modules/services/monitoring/nagios/default.nix b/modules/services/monitoring/nagios/default.nix index af309f5043c..dc060e675da 100644 --- a/modules/services/monitoring/nagios/default.nix +++ b/modules/services/monitoring/nagios/default.nix @@ -1,65 +1,11 @@ # Nagios system/network monitoring daemon. -{config, pkgs, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption; - options = { - services = { - nagios = { - - enable = mkOption { - default = false; - description = " - Whether to use Nagios to monitor - your system or network. - "; - }; - - objectDefs = mkOption { - description = " - A list of Nagios object configuration files that must define - the hosts, host groups, services and contacts for the - network that you want Nagios to monitor. - "; - }; - - plugins = mkOption { - default = [pkgs.nagiosPluginsOfficial pkgs.ssmtp]; - description = " - Packages to be added to the Nagios PATH. - Typically used to add plugins, but can be anything. - "; - }; - - enableWebInterface = mkOption { - default = false; - description = " - Whether to enable the Nagios web interface. You should also - enable Apache (). - "; - }; - - urlPath = mkOption { - default = "/nagios"; - description = " - The URL path under which the Nagios web interface appears. - That is, you can access the Nagios web interface through - http://server/urlPath. - "; - }; - - }; - }; - }; -in - -###### implementation -let cfg = config.services.nagios; - inherit (pkgs.lib) mkIf mkThenElse; nagiosUser = "nagios"; nagiosGroup = "nogroup"; @@ -67,146 +13,184 @@ let nagiosState = "/var/lib/nagios"; nagiosLogDir = "/var/log/nagios"; - nagiosObjectDefs = [ - ./timeperiods.cfg - ./host-templates.cfg - ./service-templates.cfg - ./commands.cfg - ] ++ cfg.objectDefs; + nagiosObjectDefs = + [ ./timeperiods.cfg + ./host-templates.cfg + ./service-templates.cfg + ./commands.cfg + ] ++ cfg.objectDefs; nagiosObjectDefsDir = pkgs.runCommand "nagios-objects" {inherit nagiosObjectDefs;} "ensureDir $out; ln -s $nagiosObjectDefs $out/"; - nagiosCfgFile = pkgs.writeText "nagios.cfg" " - - # Paths for state and logs. - log_file=${nagiosLogDir}/current - log_archive_path=${nagiosLogDir}/archive - status_file=${nagiosState}/status.dat - object_cache_file=${nagiosState}/objects.cache - comment_file=${nagiosState}/comment.dat - downtime_file=${nagiosState}/downtime.dat - temp_file=${nagiosState}/nagios.tmp - lock_file=/var/run/nagios.lock # Not used I think. - state_retention_file=${nagiosState}/retention.dat + nagiosCfgFile = pkgs.writeText "nagios.cfg" + '' + # Paths for state and logs. + log_file=${nagiosLogDir}/current + log_archive_path=${nagiosLogDir}/archive + status_file=${nagiosState}/status.dat + object_cache_file=${nagiosState}/objects.cache + comment_file=${nagiosState}/comment.dat + downtime_file=${nagiosState}/downtime.dat + temp_file=${nagiosState}/nagios.tmp + lock_file=/var/run/nagios.lock # Not used I think. + state_retention_file=${nagiosState}/retention.dat - # Configuration files. - #resource_file=resource.cfg - cfg_dir=${nagiosObjectDefsDir} + # Configuration files. + #resource_file=resource.cfg + cfg_dir=${nagiosObjectDefsDir} - # Uid/gid that the daemon runs under. - nagios_user=${nagiosUser} - nagios_group=${nagiosGroup} + # Uid/gid that the daemon runs under. + nagios_user=${nagiosUser} + nagios_group=${nagiosGroup} - # Misc. options. - illegal_macro_output_chars=`~$&|'\"<> - retain_state_information=1 + # Misc. options. + illegal_macro_output_chars=`~$&|'"<> + retain_state_information=1 + ''; # " - "; - # Plain configuration for the Nagios web-interface with no # authentication. - nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf" " - main_config_file=${nagiosCfgFile} - use_authentication=0 - url_html_path=/nagios - "; + nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf" + '' + main_config_file=${nagiosCfgFile} + use_authentication=0 + url_html_path=/nagios + ''; urlPath = cfg.urlPath; - extraHttpdConfig = " - ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin + extraHttpdConfig = + '' + ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin - - Options ExecCGI - AllowOverride None - Order allow,deny - Allow from all - SetEnv NAGIOS_CGI_CONFIG ${nagiosCGICfgFile} - + + Options ExecCGI + AllowOverride None + Order allow,deny + Allow from all + SetEnv NAGIOS_CGI_CONFIG ${nagiosCGICfgFile} + - Alias ${urlPath} ${pkgs.nagios}/share + Alias ${urlPath} ${pkgs.nagios}/share - - Options None - AllowOverride None - Order allow,deny - Allow from all - - "; + + Options None + AllowOverride None + Order allow,deny + Allow from all + + ''; - user = { - name = nagiosUser; - uid = config.ids.uids.nagios; - description = "Nagios monitoring daemon"; - home = nagiosState; - }; - - job = { - name = "nagios"; - - # Run `nagios -v' to check the validity of the configuration file so - # that a nixos-rebuild fails *before* we kill the running Nagios - # daemon. - buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}"; - - job = " - description \"Nagios monitoring daemon\" - - start on network-interfaces/started - stop on network-interfaces/stop - - start script - mkdir -m 0755 -p ${nagiosState} ${nagiosLogDir} - chown ${nagiosUser} ${nagiosState} ${nagiosLogDir} - end script - - respawn - - script - for i in ${toString config.services.nagios.plugins}; do - export PATH=$i/bin:$i/sbin:$i/libexec:$PATH - done - exec ${pkgs.nagios}/bin/nagios ${nagiosCfgFile} - end script - "; - }; in + +{ + ###### interface -mkIf cfg.enable { - require = [ - # ../../upstart-jobs/default.nix # config.services.extraJobs - # ../../system/user.nix # users = { .. } - # ? # config.environment.etc - # ? # config.environment.extraPackages - # ../../upstart-jobs/httpd.nix # config.services.httpd - options - ]; + options = { + + services.nagios = { + + enable = mkOption { + default = false; + description = " + Whether to use Nagios to monitor + your system or network. + "; + }; + + objectDefs = mkOption { + description = " + A list of Nagios object configuration files that must define + the hosts, host groups, services and contacts for the + network that you want Nagios to monitor. + "; + }; + + plugins = mkOption { + default = [pkgs.nagiosPluginsOfficial pkgs.ssmtp]; + description = " + Packages to be added to the Nagios PATH. + Typically used to add plugins, but can be anything. + "; + }; + + enableWebInterface = mkOption { + default = false; + description = " + Whether to enable the Nagios web interface. You should also + enable Apache (). + "; + }; + + urlPath = mkOption { + default = "/nagios"; + description = " + The URL path under which the Nagios web interface appears. + That is, you can access the Nagios web interface through + http://server/urlPath. + "; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + users.extraUsers = singleton + { name = nagiosUser; + uid = config.ids.uids.nagios; + description = "Nagios monitoring daemon"; + home = nagiosState; + }; - environment = { # This isn't needed, it's just so that the user can type "nagiostats # -c /etc/nagios.cfg". - etc = [ + environment.etc = singleton { source = nagiosCfgFile; target = "nagios.cfg"; - } - ]; + }; - systemPackages = [pkgs.nagios]; - }; + environment.systemPackages = [ pkgs.nagios ]; - users = { - extraUsers = [user]; - }; + jobAttrs.nagios = + { # Run `nagios -v' to check the validity of the configuration file so + # that a nixos-rebuild fails *before* we kill the running Nagios + # daemon. + buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}"; - services = { - extraJobs = [job]; + description = "Nagios monitoring daemon"; - httpd = mkIf cfg.enableWebInterface { + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + preStart = + '' + mkdir -m 0755 -p ${nagiosState} ${nagiosLogDir} + chown ${nagiosUser} ${nagiosState} ${nagiosLogDir} + ''; + + script = + '' + for i in ${toString config.services.nagios.plugins}; do + export PATH=$i/bin:$i/sbin:$i/libexec:$PATH + done + exec ${pkgs.nagios}/bin/nagios ${nagiosCfgFile} + ''; + }; + + services.httpd = mkIf cfg.enableWebInterface { extraConfig = mkThenElse { thenPart = extraHttpdConfig; elsePart = ""; }; }; + }; + } diff --git a/modules/services/monitoring/zabbix-agent.nix b/modules/services/monitoring/zabbix-agent.nix index 70e6a73277b..f3559ef8ba4 100644 --- a/modules/services/monitoring/zabbix-agent.nix +++ b/modules/services/monitoring/zabbix-agent.nix @@ -1,35 +1,8 @@ # Zabbix agent daemon. -{config, pkgs, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption; +with pkgs.lib; - options = { - services = { - zabbixAgent = { - - enable = mkOption { - default = false; - description = " - Whether to run the Zabbix monitoring agent on this machine. - It will send monitoring data to a Zabbix server. - "; - }; - - server = mkOption { - default = "127.0.0.1"; - description = '' - The IP address or hostname of the Zabbix server to connect to. - ''; - }; - - }; - }; - }; -in - -###### implementation let cfg = config.services.zabbixAgent; @@ -40,69 +13,87 @@ let pidFile = "${stateDir}/zabbix_agentd.pid"; - configFile = pkgs.writeText "zabbix_agentd.conf" '' - Server = ${cfg.server} + configFile = pkgs.writeText "zabbix_agentd.conf" + '' + Server = ${cfg.server} - LogFile = ${logDir}/zabbix_agentd + LogFile = ${logDir}/zabbix_agentd - PidFile = ${pidFile} + PidFile = ${pidFile} - StartAgents = 5 - ''; - - user = { - name = "zabbix"; - uid = config.ids.uids.zabbix; - description = "Zabbix daemon user"; - }; - - job = { - name = "zabbix-agent"; - - job = '' - start on network-interfaces/started - stop on network-interfaces/stop - - description "Zabbix agent daemon" - - start script - mkdir -m 0755 -p ${stateDir} ${logDir} - chown zabbix ${stateDir} ${logDir} - - export PATH=${pkgs.nettools}/bin:$PATH - ${pkgs.zabbixAgent}/sbin/zabbix_agentd --config ${configFile} - end script - - respawn sleep 100000 - - stop script - # !!! this seems to leave processes behind. - #pid=$(cat ${pidFile}) - #if test -n "$pid"; then - # kill $pid - #fi - - # So instead kill the agent in a brutal fashion. - while ${pkgs.procps}/bin/pkill -u zabbix zabbix_agentd; do true; done - end script + StartAgents = 5 ''; - }; - ifEnable = pkgs.lib.ifEnable cfg.enable; in - + { - require = [ - # ../upstart-jobs/default.nix - # ../system/user.nix # users = { .. } - options - ]; - services = { - extraJobs = ifEnable [job]; + ###### interface + + options = { + + services.zabbixAgent = { + + enable = mkOption { + default = false; + description = '' + Whether to run the Zabbix monitoring agent on this machine. + It will send monitoring data to a Zabbix server. + ''; + }; + + server = mkOption { + default = "127.0.0.1"; + description = '' + The IP address or hostname of the Zabbix server to connect to. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + users.extraUsers = singleton + { name = "zabbix"; + uid = config.ids.uids.zabbix; + description = "Zabbix daemon user"; + }; + + jobAttrs.zabbix_agent = + { #name = "zabbix-agent"; !!! mkIf bug + + description = "Zabbix agent daemon"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + preStart = + '' + mkdir -m 0755 -p ${stateDir} ${logDir} + chown zabbix ${stateDir} ${logDir} + + export PATH=${pkgs.nettools}/bin:$PATH + ${pkgs.zabbixAgent}/sbin/zabbix_agentd --config ${configFile} + ''; + + postStop = + '' + # !!! this seems to leave processes behind. + #pid=$(cat ${pidFile}) + #if test -n "$pid"; then + # kill $pid + #fi + + # So instead kill the agent in a brutal fashion. + while ${pkgs.procps}/bin/pkill -u zabbix zabbix_agentd; do true; done + ''; + }; + }; - users = { - extraUsers = ifEnable [user]; - }; } diff --git a/modules/services/monitoring/zabbix-server.nix b/modules/services/monitoring/zabbix-server.nix index 198b040f10e..c41fc93ac1d 100644 --- a/modules/services/monitoring/zabbix-server.nix +++ b/modules/services/monitoring/zabbix-server.nix @@ -1,25 +1,8 @@ # Zabbix server daemon. -{config, pkgs, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption; +with pkgs.lib; - options = { - services = { - zabbixServer = { - enable = mkOption { - default = false; - description = " - Whether to run the Zabbix server on this machine. - "; - }; - }; - }; - }; -in - -###### implementation let stateDir = "/var/run/zabbix"; @@ -30,72 +13,76 @@ let pidFile = "${stateDir}/zabbix_server.pid"; - configFile = pkgs.writeText "zabbix_server.conf" '' - LogFile = ${logDir}/zabbix_server + configFile = pkgs.writeText "zabbix_server.conf" + '' + LogFile = ${logDir}/zabbix_server - PidFile = ${pidFile} + PidFile = ${pidFile} - DBName = zabbix + DBName = zabbix - DBUser = zabbix - ''; - - user = { - name = "zabbix"; - uid = config.ids.uids.zabbix; - description = "Zabbix daemon user"; - }; - - job = { - name = "zabbix-server"; - - job = '' - description "Zabbix server daemon" - - start on postgresql/started - stop on shutdown - - start script - mkdir -m 0755 -p ${stateDir} ${logDir} ${libDir} - chown zabbix ${stateDir} ${logDir} ${libDir} - - if ! test -e "${libDir}/db-created"; then - ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole zabbix || true - ${pkgs.postgresql}/bin/createdb --owner zabbix zabbix || true - cat ${pkgs.zabbixServer}/share/zabbix/db/schema/postgresql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' - cat ${pkgs.zabbixServer}/share/zabbix/db/data/data.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' - cat ${pkgs.zabbixServer}/share/zabbix/db/data/images_pgsql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' - touch "${libDir}/db-created" - fi - - export PATH=${pkgs.nettools}/bin:$PATH - ${pkgs.zabbixServer}/sbin/zabbix_server --config ${configFile} - end script - - respawn sleep 100000 - - stop script - while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done - end script + DBUser = zabbix ''; - - }; - ifEnable = pkgs.lib.ifEnable config.services.zabbixServer.enable; in - + { - require = [ - # ../upstart-jobs/default.nix - # ../system/user.nix # users = { .. } - options - ]; - services = { - extraJobs = ifEnable [job]; + ###### interface + + options = { + + services.zabbixServer.enable = mkOption { + default = false; + description = '' + Whether to run the Zabbix server on this machine. + ''; + }; + }; - users = { - extraUsers = ifEnable [user]; + ###### implementation + + config = mkIf config.services.zabbixServer.enable { + + users.extraUsers = singleton + { name = "zabbix"; + uid = config.ids.uids.zabbix; + description = "Zabbix daemon user"; + }; + + jobAttrs.zabbix_server = + { #name = "zabbix-server"; !!! mkIf bug + + description = "Zabbix server daemon"; + + startOn = "postgresql"; + stopOn = "shutdown"; + + preStart = + '' + mkdir -m 0755 -p ${stateDir} ${logDir} ${libDir} + chown zabbix ${stateDir} ${logDir} ${libDir} + + if ! test -e "${libDir}/db-created"; then + ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole zabbix || true + ${pkgs.postgresql}/bin/createdb --owner zabbix zabbix || true + cat ${pkgs.zabbixServer}/share/zabbix/db/schema/postgresql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' + cat ${pkgs.zabbixServer}/share/zabbix/db/data/data.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' + cat ${pkgs.zabbixServer}/share/zabbix/db/data/images_pgsql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c 'psql zabbix' + touch "${libDir}/db-created" + fi + + export PATH=${pkgs.nettools}/bin:$PATH + ${pkgs.zabbixServer}/sbin/zabbix_server --config ${configFile} + ''; + + postStop = + '' + while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done + ''; + }; + }; + } diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index d2667e1cd18..624e224fb36 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -1,154 +1,149 @@ +{ config, pkgs, ... }: -{pkgs, config, ...}: +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - nfsKernel = { - - enable = mkOption { - default = false; - description = " - wether to use the kernel nfs functionality to export filesystems. - You should be aware about existing security issues. - requires portmap! - "; - }; - - exports = mkOption { - check = v: v != "/etc/exports"; # this won't work - description = " - the file listing the directories to be exported. - install nfsUtils and run man exports to learn about its format. - The exports setting can either be a file path or the file contents. - Don't use /etc/exports. This won't work as nix will overwrite it. - "; - }; - - hostName = mkOption { - default = null; - description = " - specify a particular hostname (or address) that NFS requests will be accepted on. - Default: all. - See man rpc.nfsd (-H option) - "; - }; - nproc = mkOption { - default = 8; - description = " - specify the number of NFS server threads. (-> man rpc.nfsd). Defaults to recommended value 8 - "; - }; - - createMountPoints = mkOption { - default = false; - description = "Whether to create the mount points in the exports file at startup time."; - }; - }; - }; - }; - -###### implementation inherit (pkgs) writeText openssh; - cfg = (config.services.nfsKernel); + cfg = config.services.nfsKernel; - modprobe = config.system.sbin.modprobe; - - exports = if builtins.pathExists cfg.exports - then cfg.exports else pkgs.writeText "exports" cfg.exports; + exports = + if builtins.pathExists cfg.exports + then cfg.exports + else pkgs.writeText "exports" cfg.exports; in +{ -mkIf config.services.nfsKernel.enable { - require = [ - options - ]; + ###### interface - environment.etc = [ - { source = exports; - target = "exports"; } - ]; + options = { + + services.nfsKernel = { - services = { - extraJobs = [ - { - name = "nfs-kernel-exports"; + enable = mkOption { + default = false; + description = '' + Whether to enable the kernel's NFS server. + ''; + }; - job = '' - description "export filesystems using kernel nfs" + # !!! Why is this a file? Why not a list of export entries? + exports = mkOption { + check = v: v != "/etc/exports"; # this won't work + description = '' + The file listing the directories to be exported. See + exports + 5 for the format. + ''; + }; - start on network-interfaces/started - stop on network-interfaces/stop - - start script - export PATH=${pkgs.nfsUtils}/sbin:$PATH - mkdir -p /var/lib/nfs - ${modprobe}/sbin/modprobe nfsd || true - - ${if cfg.createMountPoints == true then - '' - # create export directories: - # skip comments, take first col which may either be a quoted - # "foo bar" or just foo (-> man export) - sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ - | xargs -d '\n' mkdir -p - '' - else ""} - - # exports file is ${exports} - # keep this comment so that this job is restarted whenever exports changes! - exportfs -ra - end script - - respawn sleep 1000000 - ''; - } - { - name = "nfs-kernel-rpc-nfsd"; - - job = '' - description "export filesystems using kernel nfs" - - start on nfs-kernel-exports/started - stop on nfs-kernel-exports/stop - - respawn ${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} ${builtins.toString cfg.nproc} - ''; - } - { - name = "nfs-kernel-mountd"; - - job = '' - description "export filesystems using kernel nfs" - - start on nfs-kernel-rpc-nfsd/started - stop on nfs-kernel-exports/stop - - respawn ${pkgs.nfsUtils}/sbin/rpc.mountd -F -f ${exports} - ''; - } - { - name = "nfs-kernel-statd"; + hostName = mkOption { + default = null; + description = '' + Hostname or address on which NFS requests will be accepted. + Default is all. See the option in + nfsd + 8. + ''; + }; - job = '' - description "NSM (Network Status Monitor) of the RPC protocol" - - start on nfs-kernel-rpc-nfsd/started - stop on nfs-kernel-exports/stop - - start script - mkdir -p /var/lib/nfs - end script + nproc = mkOption { + default = 8; + description = '' + Number of NFS server threads. Defaults to the recommended value of 8. + ''; + }; + + createMountPoints = mkOption { + default = false; + description = "Whether to create the mount points in the exports file at startup time."; + }; + + }; - respawn ${pkgs.nfsUtils}/sbin/rpc.statd -F - ''; - } - ]; }; + + + ###### implementation + + config = mkIf config.services.nfsKernel.enable { + + environment.etc = singleton + { source = exports; + target = "exports"; + }; + + jobAttrs.nfs_kernel_exports = + { name = "nfs-kernel-exports"; + + description = "Kernel NFS server"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + preStart = + '' + export PATH=${pkgs.nfsUtils}/sbin:$PATH + mkdir -p /var/lib/nfs + ${config.system.sbin.modprobe}/sbin/modprobe nfsd || true + + ${optionalString cfg.createMountPoints + '' + # create export directories: + # skip comments, take first col which may either be a quoted + # "foo bar" or just foo (-> man export) + sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ + | xargs -d '\n' mkdir -p + '' + } + + # exports file is ${exports} + # keep this comment so that this job is restarted whenever exports changes! + exportfs -ra + ''; + }; + + jobAttrs.nfs_kernel_nfsd = + { name = "nfs-kernel-nfsd"; + + description = "Kernel NFS server"; + + startOn = "nfs-kernel-exports/started"; + stopOn = "nfs-kernel-exports/stop"; + + exec = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} ${builtins.toString cfg.nproc}"; + }; + + jobAttrs.nfs_kernel_mountd = + { name = "nfs-kernel-mountd"; + + description = "Kernel NFS server - mount daemon"; + + startOn = "nfs-kernel-nfsd/started"; + stopOn = "nfs-kernel-exports/stop"; + + exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -F -f ${exports}"; + }; + + jobAttrs.nfs_kernel_statd = + { name = "nfs-kernel-statd"; + + description = "Kernel NFS server - Network Status Monitor"; + + startOn = "nfs-kernel-nfsd/started"; + stopOn = "nfs-kernel-exports/stop"; + + preStart = + '' + mkdir -p /var/lib/nfs + ''; + + exec = "${pkgs.nfsUtils}/sbin/rpc.statd -F"; + }; + + }; + } diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix index fcd1393d5c5..177a2f5128e 100644 --- a/modules/services/network-filesystems/samba.nix +++ b/modules/services/network-filesystems/samba.nix @@ -1,118 +1,6 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf mkAlways; - - options = { - services = { - samba = { - - enable = mkOption { - default = false; - description = " - Whether to enable the samba server. (to communicate with, and provide windows shares) - use start / stop samba-control to start/stop all daemons. - smbd and nmbd are not shutdown correctly yet. so just pkill them and restart those jobs. - "; - }; - - syncPasswordsByPam = mkOption { - default = false; - description = " - enabling this will add a line directly after pam_unix.so. - Whenever a password is changed the samba password will be updated as well. - However you still yave to add the samba password once using smbpasswd -a user - If you don't want to maintain an extra pwd database you still can send plain text - passwords which is not secure. - "; - }; - - extraConfig = mkOption { - default = '' - # [global] continuing global section here, section is started by nix to set pids etc - - smb passwd file = /etc/samba/passwd - - # is this useful ? - domain master = auto - - encrypt passwords = Yes - client plaintext auth = No - - # yes: if you use this you probably also want to enable syncPasswordsByPam - # no: You can still use the pam password database. However - # passwords will be sent plain text on network (discouraged) - - workgroup = Users - server string = %h - comment = Samba - log file = /var/log/samba/log.%m - log level = 10 - max log size = 50000 - security = user - - client lanman auth = Yes - dns proxy = no - invalid users = root - passdb backend = tdbsam - passwd program = /usr/bin/passwd %u - - ### end [ global ] section - - - # Un-comment the following (and tweak the other settings below to suit) - # to enable the default home directory shares. This will share each - # user's home directory as \\server\username - ;[homes] - ; comment = Home Directories - ; browseable = no - ; writable = no - - # File creation mask is set to 0700 for security reasons. If you want to - # create files with group=rw permissions, set next parameter to 0775. - ; create mask = 0700 - - # this directory and user is created automatically for you by nixos - ;[default] - ; path = /home/smbd - ; read only = no - ; guest ok = yes - - # this directory and user is created automatically for you by nixos - ;[default] - ; path = /home/smbd - ; read only = no - ; guest ok = yes - - # additional share example - ;[raidbackup] - ; path = /home/raidbackup/files - ; read only = no - ; guest ok = no - ; available = yes - ; browseable = yes - ; public = yes - ; valid users = raidbackup - ; comment = Raid backup Files - ''; - - description = " - additional global section and extra section lines go in here. - "; - }; - - configFile = mkOption { - description = " - internal use to pass filepath to samba pam module - "; - }; - }; - }; - }; -in - -###### implementation +with pkgs.lib; let @@ -121,115 +9,179 @@ let user = "smbguest"; group = "smbguest"; - logDir = "/var/log/samba"; privateDir = "/var/samba/private"; inherit (pkgs) samba; - setupScript = '' - mkdir -p /var/lock + setupScript = + '' + mkdir -p /var/lock - if ! test -d /home/smbd ; then - mkdir -p /home/smbd - chown ${user} /home/smbd - chmod a+rwx /home/smbd - fi + if ! test -d /home/smbd ; then + mkdir -p /home/smbd + chown ${user} /home/smbd + chmod a+rwx /home/smbd + fi - if ! test -d /var/samba ; then - mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd - fi + if ! test -d /var/samba ; then + mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd + fi - passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' /nix/store/nnmrqalldfv2vkwy6qpg340rv7w34lmp-smb.conf)" - if [ -n "$passwdFile" ]; then - echo 'INFO: creating directory containing passwd file' - mkdir -p "$(dirname "$passwdFile")" - fi + passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' /nix/store/nnmrqalldfv2vkwy6qpg340rv7w34lmp-smb.conf)" + if [ -n "$passwdFile" ]; then + echo 'INFO: creating directory containing passwd file' + mkdir -p "$(dirname "$passwdFile")" + fi - mkdir -p ${logDir} - mkdir -p ${privateDir} - ''; + mkdir -p ${logDir} + mkdir -p ${privateDir} - configFile = pkgs.writeText "smb.conf" '' - [ global ] + # The following line is to trigger a restart of the daemons when + # the configuration changes: + # ${configFile} + ''; + + configFile = pkgs.writeText "smb.conf" + '' + [ global ] log file = ${logDir}/log.%m private dir = ${privateDir} + ${optionalString cfg.syncPasswordsByPam "pam password change = true"} - ${if cfg.syncPasswordsByPam then "pam password change = true" else "" /* does this make sense ? */ } + ${cfg.extraConfig} + ''; + daemonJob = appName: args: + { name = "samba-${appName}"; + description = "Samba Service daemon ${appName}"; - ${cfg.extraConfig}"; - ''; + startOn = "samba/started"; + stopOn = "samba-control/stop"; - daemonJob = appName : args : - { - name = "samba-${appName}"; - job = '' - - description "Samba Service daemon ${appName}" - - start on samba-control/started - stop on samba-control/stop - - respawn ${samba}/sbin/${appName} ${args} - ''; + exec = "${samba}/sbin/${appName} ${args}"; }; in +{ -mkIf config.services.samba.enable { - require = [ - options - ]; + ###### interface - users = { - extraUsers = [ + options = { + + # !!! clean up the descriptions. + + services.samba = { + + enable = mkOption { + default = false; + description = " + Whether to enable the samba server. (to communicate with, and provide windows shares) + use start / stop samba-control to start/stop all daemons. + smbd and nmbd are not shutdown correctly yet. so just pkill them and restart those jobs. + "; + }; + + syncPasswordsByPam = mkOption { + default = false; + description = " + enabling this will add a line directly after pam_unix.so. + Whenever a password is changed the samba password will be updated as well. + However you still yave to add the samba password once using smbpasswd -a user + If you don't want to maintain an extra pwd database you still can send plain text + passwords which is not secure. + "; + }; + + extraConfig = mkOption { + # !!! Bad default. + default = '' + # [global] continuing global section here, section is started by nix to set pids etc + + smb passwd file = /etc/samba/passwd + + # is this useful ? + domain master = auto + + encrypt passwords = Yes + client plaintext auth = No + + # yes: if you use this you probably also want to enable syncPasswordsByPam + # no: You can still use the pam password database. However + # passwords will be sent plain text on network (discouraged) + + workgroup = Users + server string = %h + comment = Samba + log file = /var/log/samba/log.%m + log level = 10 + max log size = 50000 + security = user + + client lanman auth = Yes + dns proxy = no + invalid users = root + passdb backend = tdbsam + passwd program = /usr/bin/passwd %u + ''; + + description = " + additional global section and extra section lines go in here. + "; + }; + + configFile = mkOption { + description = " + internal use to pass filepath to samba pam module + "; + }; + }; + + }; + + + ###### implementation + + config = mkIf config.services.samba.enable { + + users.extraUsers = singleton { name = user; description = "Samba service user"; group = group; - } - ]; - - extraGroups = [ + }; + + users.extraGroups = singleton { name = group; - } - ]; - }; - - # always provide a smb.conf to shut up programs like smbclient and smbspool. - environment = { - etc = mkAlways [{ - source = if cfg.enable then configFile else pkgs.writeText "smb-dummy.conf" "# samba is disabled. Purpose see samba expression in nixpkgs"; - target = "samba/smb.conf"; - }]; - }; - - services = { - - extraJobs = [ - { name = "samba-control"; # start this dummy job to start the real samba daemons nmbd, smbd, winbindd - job = '' - description "samba job starting/stopping the real samba jobs"; - - start on network-interfaces/started - stop on network-interfaces/stop - - start script - ${setupScript} - end script - - respawn sleep 1000000 # !!! hack - - # put the store path here so that daemons are restarted when configuration changes - # config is ${configFile} - ''; - } - # add -S to get debugging output on stdout - # config directory is passed by configure at compilation time - ( daemonJob "nmbd" " -i -F" ) # nmbd says "standard input is not a socket, assuming -D option", but using -i makes it stay in foreground (?) - ( daemonJob "smbd" " -i -F" ) # dito - ( daemonJob "winbindd" " -F" ) - ]; + }; + + # always provide a smb.conf to shut up programs like smbclient and smbspool. + environment.etc = mkAlways (singleton + { source = + if cfg.enable then configFile + else pkgs.writeText "smb-dummy.conf" "# Samba is disabled."; + target = "samba/smb.conf"; + }); + + # Dummy job to start the real Samba daemons (nmbd, smbd, winbindd). + jobAttrs.sambaControl = + { name = "samba"; + description = "Samba server"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + preStart = setupScript; + }; + + # nmbd says "standard input is not a socket, assuming -D option", + # but using -i makes it stay in foreground (?) + jobAttrs.nmbd = daemonJob "nmbd" " -i -F"; + + jobAttrs.smbd = daemonJob "smbd" " -i -F"; + + jobAttrs.winbindd = daemonJob "winbindd" " -F"; + }; + } diff --git a/modules/services/networking/avahi-daemon.nix b/modules/services/networking/avahi-daemon.nix index ff01a755f6a..34e2a83754d 100644 --- a/modules/services/networking/avahi-daemon.nix +++ b/modules/services/networking/avahi-daemon.nix @@ -1,86 +1,18 @@ # Avahi daemon. -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption; - options = { - services = { - avahi = { - - enable = mkOption { - default = false; - description = '' - Whether to run the Avahi daemon, which allows Avahi clients - to use Avahi's service discovery facilities and also allows - the local machine to advertise its presence and services - (through the mDNS responder implemented by `avahi-daemon'). - ''; - }; - - hostName = mkOption { - default = config.networking.hostName; - description = ''Host name advertised on the LAN.''; - }; - - browseDomains = mkOption { - default = [ "0pointer.de" "zeroconf.org" ]; - description = '' - List of non-local DNS domains to be browsed. - ''; - }; - - ipv4 = mkOption { - default = true; - description = ''Whether to use IPv4''; - }; - - ipv6 = mkOption { - default = false; - description = ''Whether to use IPv6''; - }; - - wideArea = mkOption { - default = true; - description = ''Whether to enable wide-area service discovery.''; - }; - - publishing = mkOption { - default = true; - description = ''Whether to allow publishing.''; - }; - - nssmdns = mkOption { - default = false; - description = '' - Whether to enable the mDNS NSS (Name Service Switch) plug-in. - Enabling it allows applications to resolve names in the `.local' - domain by transparently querying the Avahi daemon. - - Warning: Currently, enabling this option breaks DNS lookups after - a `nixos-rebuild'. This is because `/etc/nsswitch.conf' is - updated to use `nss-mdns' but `libnss_mdns' is not in - applications' `LD_LIBRARY_PATH'. The next time `/etc/profile' is - sourced, it will set up an appropriate `LD_LIBRARY_PATH', though. - ''; - }; - }; - }; - }; -in - -###### implementation -let cfg = config.services.avahi; - inherit (pkgs.lib) mkIf mkThenElse; - inherit (pkgs) avahi writeText lib; + inherit (pkgs) avahi; - avahiDaemonConf = with cfg; writeText "avahi-daemon.conf" '' + avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" '' [server] host-name=${hostName} - browse-domains=${lib.concatStringsSep ", " browseDomains} + browse-domains=${concatStringsSep ", " browseDomains} use-ipv4=${if ipv4 then "yes" else "no"} use-ipv6=${if ipv6 then "yes" else "no"} @@ -91,69 +23,119 @@ let disable-publishing=${if publishing then "no" else "yes"} ''; - user = { - name = "avahi"; - uid = config.ids.uids.avahi; - description = "`avahi-daemon' privilege separation user"; - home = "/var/empty"; - }; - - group = { - name = "avahi"; - gid = config.ids.gids.avahi; - }; - - job = { - name = "avahi-daemon"; - - job = '' - start on network-interfaces/started - stop on network-interfaces/stop - respawn - script - export PATH="${avahi}/bin:${avahi}/sbin:$PATH" - - # Make NSS modules visible so that `avahi_nss_support ()' can - # return a sensible value. - export LD_LIBRARY_PATH="${config.system.nssModules.path}" - - exec ${avahi}/sbin/avahi-daemon --daemonize -f "${avahiDaemonConf}" - end script - ''; - }; in -mkIf cfg.enable { - require = [ - # ../upstart-jobs/default.nix # config.services.extraJobs - # ../system/? # system.nssModules - # ? # config.environment.etc - # ../system/user.nix # users.* - # ../upstart-jobs/udev.nix # services.udev.* - # ../upstart-jobs/dbus.nix # services.dbus.* - # ? # config.environment.extraPackages - options - ]; +{ - system = { - nssModules = pkgs.lib.optional cfg.nssmdns pkgs.nssmdns; - }; + ###### interface - environment = { - systemPackages = [avahi]; - }; + options = { + + services.avahi = { - users = { - extraUsers = [user]; - extraGroups = [group]; - }; + enable = mkOption { + default = false; + description = '' + Whether to run the Avahi daemon, which allows Avahi clients + to use Avahi's service discovery facilities and also allows + the local machine to advertise its presence and services + (through the mDNS responder implemented by `avahi-daemon'). + ''; + }; - services = { - extraJobs = [job]; + hostName = mkOption { + default = config.networking.hostName; + description = ''Host name advertised on the LAN.''; + }; - dbus = { - enable = true; - packages = [avahi]; + browseDomains = mkOption { + default = [ "0pointer.de" "zeroconf.org" ]; + description = '' + List of non-local DNS domains to be browsed. + ''; + }; + + ipv4 = mkOption { + default = true; + description = ''Whether to use IPv4''; + }; + + ipv6 = mkOption { + default = false; + description = ''Whether to use IPv6''; + }; + + wideArea = mkOption { + default = true; + description = ''Whether to enable wide-area service discovery.''; + }; + + publishing = mkOption { + default = true; + description = ''Whether to allow publishing.''; + }; + + nssmdns = mkOption { + default = false; + description = '' + Whether to enable the mDNS NSS (Name Service Switch) plug-in. + Enabling it allows applications to resolve names in the `.local' + domain by transparently querying the Avahi daemon. + + Warning: Currently, enabling this option breaks DNS lookups after + a `nixos-rebuild'. This is because `/etc/nsswitch.conf' is + updated to use `nss-mdns' but `libnss_mdns' is not in + applications' `LD_LIBRARY_PATH'. The next time `/etc/profile' is + sourced, it will set up an appropriate `LD_LIBRARY_PATH', though. + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + users.extraUsers = singleton + { name = "avahi"; + uid = config.ids.uids.avahi; + description = "`avahi-daemon' privilege separation user"; + home = "/var/empty"; + }; + + users.extraGroups = singleton + { name = "avahi"; + gid = config.ids.gids.avahi; + }; + + system.nssModules = optional cfg.nssmdns pkgs.nssmdns; + + environment.systemPackages = [ avahi ]; + + jobAttrs.avahi_daemon = + { name = "avahi-daemon"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + script = + '' + export PATH="${avahi}/bin:${avahi}/sbin:$PATH" + + # Make NSS modules visible so that `avahi_nss_support ()' can + # return a sensible value. + export LD_LIBRARY_PATH="${config.system.nssModules.path}" + + exec ${avahi}/sbin/avahi-daemon --daemonize -f "${avahiDaemonConf}" + ''; + }; + + services.dbus.enable = true; + services.dbus.packages = [avahi]; + + }; + } diff --git a/modules/services/networking/bind.nix b/modules/services/networking/bind.nix index d216987e573..d1a137f3502 100644 --- a/modules/services/networking/bind.nix +++ b/modules/services/networking/bind.nix @@ -1,123 +1,121 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; + + cfg = config.services.bind; + + confFile = pkgs.writeText "named.conf" + '' + acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} }; + acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} }; + + options { + listen-on {any;}; + listen-on-v6 {any;}; + allow-query { cachenetworks; }; + blackhole { badnetworks; }; + forward first; + forwarders { ${concatMapStrings (entry: " ${entry}; ") config.networking.nameservers} }; + directory "/var/run/named"; + pid-file "/var/run/named/named.pid"; + }; + + ${ concatMapStrings + ({ name, file, master ? true, slaves ? [], masters ? [] }: + '' + zone "${name}" { + type ${if master then "master" else "slave"}; + file "${file}"; + ${ if master then + '' + allow-transfer { + ${concatMapStrings (ip: "${ip};\n") slaves} + }; + '' + else + '' + masters { + ${concatMapStrings (ip: "${ip};\n") masters} + }; + '' + } + allow-query { any; }; + }; + '') + cfg.zones } + ''; + +in + +{ + + ###### interface options = { - services = { - bind = { - enable = mkOption { - default = false; - description = " - Whether to enable BIND domain name server. - "; - }; - cacheNetworks = mkOption { - default = ["127.0.0.0/24"]; - description = " - What networks are allowed to use us as a resolver. - "; - }; - blockedNetworks = mkOption { - default = []; - description = " - What networks are just blocked. - "; - }; - zones = mkOption { - default = []; - description = " - List of zones we claim authority over. - master=false means slave server; slaves means addresses - who may request zone transfer. - "; - example = [{ - name = "example.com"; - master = false; - file = "/var/dns/example.com"; - masters = ["192.168.0.1"]; - slaves = []; - }]; - }; + + services.bind = { + + enable = mkOption { + default = false; + description = " + Whether to enable BIND domain name server. + "; }; - }; - }; -in - -###### implementation - -let - startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; - cfg = config.services.bind; - concatMapStrings = pkgs.lib.concatMapStrings; - - namedConf = - ('' - acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} }; - acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} }; - - options { - listen-on {any;}; - listen-on-v6 {any;}; - allow-query { cachenetworks; }; - blackhole { badnetworks; }; - forward first; - forwarders { ${concatMapStrings (entry: " ${entry}; ") config.networking.nameservers} }; - directory "/var/run/named"; - pid-file "/var/run/named/named.pid"; + + cacheNetworks = mkOption { + default = ["127.0.0.0/24"]; + description = " + What networks are allowed to use us as a resolver. + "; + }; + + blockedNetworks = mkOption { + default = []; + description = " + What networks are just blocked. + "; + }; + + zones = mkOption { + default = []; + description = " + List of zones we claim authority over. + master=false means slave server; slaves means addresses + who may request zone transfer. + "; + example = [{ + name = "example.com"; + master = false; + file = "/var/dns/example.com"; + masters = ["192.168.0.1"]; + slaves = []; + }]; + }; + }; - '') - + - (concatMapStrings - (_entry:let entry={master=true;slaves=[];masters=[];}//_entry; in - '' - zone "${entry.name}" { - type ${if entry.master then "master" else "slave"}; - file "${entry.file}"; - ${ if entry.master then - '' - allow-transfer { - ${concatMapStrings (ip: ip+";\n") entry.slaves} - }; - '' - else - '' - masters { - ${concatMapStrings (ip: ip+";\n") entry.masters} - }; - '' - } - allow-query { any; }; - }; - '' - ) - cfg.zones - ) - ; - - confFile = pkgs.writeText "named.conf" namedConf; - -in - -mkIf config.services.bind.enable { - require = [ - options - ]; - - services = { - extraJobs = [{ - name = "bind"; - job = '' - description "BIND name server job" - - start script - ${pkgs.coreutils}/bin/mkdir -p /var/run/named - end script - - respawn ${pkgs.bind}/sbin/named -c ${confFile} -f - ''; - }]; }; + + + ###### implementation + + config = mkIf config.services.bind.enable { + + jobAttrs.bind = + { description = "BIND name server job"; + + preStart = + '' + ${pkgs.coreutils}/bin/mkdir -p /var/run/named + ''; + + exec = "${pkgs.bind}/sbin/named -c ${confFile} -f"; + }; + + }; + } diff --git a/modules/services/networking/bitlbee.nix b/modules/services/networking/bitlbee.nix index 9e07858f949..c55adb49335 100644 --- a/modules/services/networking/bitlbee.nix +++ b/modules/services/networking/bitlbee.nix @@ -1,91 +1,93 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + bitlbeeUid = config.ids.uids.bitlbee; + + inherit (config.services.bitlbee) portNumber interface; + +in + +{ + + ###### interface options = { - services = { - bitlbee = { - - enable = mkOption { - default = false; - description = '' - Whether to run the BitlBee IRC to other chat network gateway. - Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat - networks via an IRC client. - ''; - }; - - interface = mkOption { - default = "127.0.0.1"; - description = '' - The interface the BitlBee deamon will be listening to. If `127.0.0.1', - only clients on the local host can connect to it; if `0.0.0.0', clients - can access it from any network interface. - ''; - }; - - portNumber = mkOption { - default = 6667; - description = '' - Number of the port BitlBee will be listening to. - ''; - }; + + services.bitlbee = { + enable = mkOption { + default = false; + description = '' + Whether to run the BitlBee IRC to other chat network gateway. + Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat + networks via an IRC client. + ''; }; + + interface = mkOption { + default = "127.0.0.1"; + description = '' + The interface the BitlBee deamon will be listening to. If `127.0.0.1', + only clients on the local host can connect to it; if `0.0.0.0', clients + can access it from any network interface. + ''; + }; + + portNumber = mkOption { + default = 6667; + description = '' + Number of the port BitlBee will be listening to. + ''; + }; + }; + }; -in + -###### implementation + ###### implementation -let - bitlbeeUid = config.ids.uids.bitlbee; - inherit (config.services.bitlbee) portNumber interface; -in + config = mkIf config.services.bitlbee.enable { -mkIf config.services.bitlbee.enable { - - require = options; - - users = { - extraUsers = [ + users.extraUsers = singleton { name = "bitlbee"; uid = bitlbeeUid; description = "BitlBee user"; home = "/var/empty"; - } - ]; + }; - extraGroups = [ + users.extraGroups = singleton { name = "bitlbee"; gid = config.ids.gids.bitlbee; - } - ]; - }; + }; - services.extraJobs = [{ - name = "bitlbee"; + jobAttrs.bitlbee = + { description = "BitlBee IRC to other chat networks gateway"; - job = '' - description "BitlBee IRC to other chat networks gateway" + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; - start on network-interfaces/started - stop on network-interfaces/stop + preStart = + '' + if ! test -d /var/lib/bitlbee + then + mkdir -p /var/lib/bitlbee + chown bitlbee:bitlbee /var/lib/bitlbee + fi + ''; - start script - if ! test -d /var/lib/bitlbee - then - mkdir -p /var/lib/bitlbee - chown bitlbee:bitlbee /var/lib/bitlbee - fi - end script - - respawn ${pkgs.bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \ + exec = + '' + ${pkgs.bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \ -i ${interface} -u bitlbee - ''; - }]; + ''; + }; - environment.systemPackages = [ pkgs.bitlbee ]; + environment.systemPackages = [ pkgs.bitlbee ]; + + }; + } diff --git a/modules/services/networking/dhcpd.nix b/modules/services/networking/dhcpd.nix index 9604dd965b9..5a2d9034dfd 100644 --- a/modules/services/networking/dhcpd.nix +++ b/modules/services/networking/dhcpd.nix @@ -1,79 +1,6 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - dhcpd = { - - enable = mkOption { - default = false; - description = " - Whether to enable the DHCP server. - "; - }; - - extraConfig = mkOption { - default = ""; - example = " - option subnet-mask 255.255.255.0; - option broadcast-address 192.168.1.255; - option routers 192.168.1.5; - option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1; - option domain-name \"example.org\"; - subnet 192.168.1.0 netmask 255.255.255.0 { - range 192.168.1.100 192.168.1.200; - } - "; - description = " - Extra text to be appended to the DHCP server configuration - file. Currently, you almost certainly need to specify - something here, such as the options specifying the subnet - mask, DNS servers, etc. - "; - }; - - configFile = mkOption { - default = null; - description = " - The path of the DHCP server configuration file. If no file - is specified, a file is generated using the other options. - "; - }; - - interfaces = mkOption { - default = ["eth0"]; - description = " - The interfaces on which the DHCP server should listen. - "; - }; - - machines = mkOption { - default = []; - example = [ - { hostName = "foo"; - ethernetAddress = "00:16:76:9a:32:1d"; - ipAddress = "192.168.1.10"; - } - { hostName = "bar"; - ethernetAddress = "00:19:d1:1d:c4:9a"; - ipAddress = "192.168.1.11"; - } - ]; - description = " - A list mapping ethernet addresses to IP addresses for the - DHCP server. - "; - }; - - }; - }; - }; -in - -###### implementation +with pkgs.lib; let @@ -81,43 +8,114 @@ let stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant. - machines = pkgs.lib.concatMapStrings (machine: '' - host ${machine.hostName} { - hardware ethernet ${machine.ethernetAddress}; - fixed-address ${machine.ipAddress}; - } - '') cfg.machines; + configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf" + '' + default-lease-time 600; + max-lease-time 7200; + authoritative; + ddns-update-style ad-hoc; + log-facility local1; # see dhcpd.nix + + ${cfg.extraConfig} - configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf" '' - default-lease-time 600; - max-lease-time 7200; - authoritative; - ddns-update-style ad-hoc; - log-facility local1; # see dhcpd.nix - ${cfg.extraConfig} - ${machines} - ''; + ${pkgs.lib.concatMapStrings + (machine: '' + host ${machine.hostName} { + hardware ethernet ${machine.ethernetAddress}; + fixed-address ${machine.ipAddress}; + } + '') + cfg.machines + } + ''; in +{ -mkIf config.services.dhcpd.enable { - require = [ - options - ]; + ###### interface - services = { - extraJobs = [{ - name = "dhcpd"; - - job = '' - description "DHCP server" + options = { + + services.dhcpd = { - start on network-interfaces/started - stop on network-interfaces/stop + enable = mkOption { + default = false; + description = " + Whether to enable the DHCP server. + "; + }; - script + extraConfig = mkOption { + default = ""; + example = " + option subnet-mask 255.255.255.0; + option broadcast-address 192.168.1.255; + option routers 192.168.1.5; + option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1; + option domain-name \"example.org\"; + subnet 192.168.1.0 netmask 255.255.255.0 { + range 192.168.1.100 192.168.1.200; + } + "; + description = " + Extra text to be appended to the DHCP server configuration + file. Currently, you almost certainly need to specify + something here, such as the options specifying the subnet + mask, DNS servers, etc. + "; + }; + configFile = mkOption { + default = null; + description = " + The path of the DHCP server configuration file. If no file + is specified, a file is generated using the other options. + "; + }; + + interfaces = mkOption { + default = ["eth0"]; + description = " + The interfaces on which the DHCP server should listen. + "; + }; + + machines = mkOption { + default = []; + example = [ + { hostName = "foo"; + ethernetAddress = "00:16:76:9a:32:1d"; + ipAddress = "192.168.1.10"; + } + { hostName = "bar"; + ethernetAddress = "00:19:d1:1d:c4:9a"; + ipAddress = "192.168.1.11"; + } + ]; + description = " + A list mapping ethernet addresses to IP addresses for the + DHCP server. + "; + }; + + }; + + }; + + + ###### implementation + + config = mkIf config.services.dhcpd.enable { + + jobAttrs.dhcpd = + { description = "DHCP server"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + script = + '' mkdir -m 755 -p ${stateDir} touch ${stateDir}/dhcpd.leases @@ -125,9 +123,9 @@ mkIf config.services.dhcpd.enable { exec ${pkgs.dhcp}/sbin/dhcpd -f -cf ${configFile} \ -lf ${stateDir}/dhcpd.leases \ ${toString cfg.interfaces} + ''; + }; - end script - ''; - }]; }; + } diff --git a/modules/services/networking/ejabberd.nix b/modules/services/networking/ejabberd.nix index b1f485cf1c8..8ef910e1262 100644 --- a/modules/services/networking/ejabberd.nix +++ b/modules/services/networking/ejabberd.nix @@ -1,85 +1,83 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + cfg = config.services.ejabberd; + +in + +{ + + ###### interface options = { - services = { - ejabberd = { - enable = mkOption { - default = false; - description = "Whether to enable ejabberd server"; - }; - - spoolDir = mkOption { - default = "/var/lib/ejabberd"; - description = "Location of the spooldir of ejabberd"; - }; - - logsDir = mkOption { - default = "/var/log/ejabberd"; - description = "Location of the logfile directory of ejabberd"; - }; - - confDir = mkOption { - default = "/var/ejabberd"; - description = "Location of the config directory of ejabberd"; - }; - - virtualHosts = mkOption { - default = "\"localhost\""; - description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; - }; + + services.ejabberd = { + + enable = mkOption { + default = false; + description = "Whether to enable ejabberd server"; }; + + spoolDir = mkOption { + default = "/var/lib/ejabberd"; + description = "Location of the spooldir of ejabberd"; + }; + + logsDir = mkOption { + default = "/var/log/ejabberd"; + description = "Location of the logfile directory of ejabberd"; + }; + + confDir = mkOption { + default = "/var/ejabberd"; + description = "Location of the config directory of ejabberd"; + }; + + virtualHosts = mkOption { + default = "\"localhost\""; + description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; + }; + }; + }; -in + -###### implementation + ###### implementation -let + config = mkIf cfg.enable { -cfg = config.services.ejabberd; + jobAttrs.ejabberd = + { description = "EJabberd server"; -in + startOn = "network-interface/started"; + stopOn = "network-interfaces/stop"; -mkIf config.services.ejabberd.enable { + preStart = + '' + # Initialise state data + mkdir -p ${cfg.logsDir} - require = [ - options - ]; + if ! test -d ${cfg.spoolDir} + then + cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib + fi + mkdir -p ${cfg.confDir} + test -f ${cfg.confDir}/ejabberd.cfg || sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg + ''; - services = { - extraJobs = [{ - name = "ejabberd"; - - job = '' - description "EJabberd server" + exec = "${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin:${pkgs.coreutils}/bin:${pkgs.bash}/bin; cd ~; ejabberdctl --logs ${cfg.logsDir} --spool ${cfg.spoolDir} --config ${cfg.confDir}/ejabberd.cfg start; sleep 1d'"; - start on network-interface/started - stop on network-interfaces/stop - - start script - # Initialise state data - mkdir -p ${cfg.logsDir} - - if ! test -d ${cfg.spoolDir} - then - cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib - fi - - mkdir -p ${cfg.confDir} - test -f ${cfg.confDir}/ejabberd.cfg || sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg - end script - - respawn ${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin:${pkgs.coreutils}/bin:${pkgs.bash}/bin; cd ~; ejabberdctl --logs ${cfg.logsDir} --spool ${cfg.spoolDir} --config ${cfg.confDir}/ejabberd.cfg start; sleep 1d' - - stop script + postStop = + '' ${pkgs.ejabberd}/sbin/ejabberdctl stop - end script - ''; - }]; + ''; + }; + }; + } diff --git a/modules/services/networking/gnunet.nix b/modules/services/networking/gnunet.nix index 57e3b3d8c96..05956f74612 100644 --- a/modules/services/networking/gnunet.nix +++ b/modules/services/networking/gnunet.nix @@ -1,218 +1,218 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + cfg = config.services.gnunet; + + configFile = with cfg; pkgs.writeText "gnunetd.conf" + '' + [PATHS] + GNUNETD_HOME = ${home} + + [GNUNETD] + HOSTLISTURL = ${lib.concatStringsSep " " hostLists} + APPLICATIONS = ${lib.concatStringsSep " " applications} + TRANSPORTS = ${lib.concatStringsSep " " transports} + + [LOAD] + MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth} + MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth} + HARDUPLIMIT = ${toString load.hardNetUpBandwidth} + MAXCPULOAD = ${toString load.maxCPULoad} + INTERFACES = ${lib.concatStringsSep " " load.interfaces} + + [FS] + QUOTA = ${toString fileSharing.quota} + ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"} + + [MODULES] + sqstore = sqstore_sqlite + dstore = dstore_sqlite + topology = topology_default + + ${extraOptions} + ''; + +in + +{ + + ###### interface options = { - services = { - gnunet = { + + services.gnunet = { - enable = mkOption { + enable = mkOption { + default = false; + description = '' + Whether to run the GNUnet daemon. GNUnet is GNU's anonymous + peer-to-peer communication and file sharing framework. + ''; + }; + + home = mkOption { + default = "/var/lib/gnunet"; + description = '' + Directory where the GNUnet daemon will store its data. + ''; + }; + + debug = mkOption { + default = false; + description = '' + When true, run in debug mode; gnunetd will not daemonize and + error messages will be written to stderr instead of a + logfile. + ''; + }; + + logLevel = mkOption { + default = "ERROR"; + example = "INFO"; + description = '' + Log level of the deamon (see `gnunetd(1)' for details). + ''; + }; + + hostLists = mkOption { + default = [ + "http://gnunet.org/hostlist.php" + "http://gnunet.mine.nu:8081/hostlist" + "http://vserver1236.vserver-on.de/hostlist-074" + ]; + description = '' + URLs of host lists. + ''; + }; + + applications = mkOption { + default = [ "advertising" "getoption" "fs" "stats" "traffic" ]; + example = [ "chat" "fs" ]; + description = '' + List of GNUnet applications supported by the daemon. Note that + `fs', which means "file sharing", is probably the one you want. + ''; + }; + + transports = mkOption { + default = [ "udp" "tcp" "http" "nat" ]; + example = [ "smtp" "http" ]; + description = '' + List of transport methods used by the server. + ''; + }; + + fileSharing = { + quota = mkOption { + default = 1024; + description = '' + Maximum file system usage (in MiB) for file sharing. + ''; + }; + + activeMigration = mkOption { default = false; description = '' - Whether to run the GNUnet daemon. GNUnet is GNU's anonymous - peer-to-peer communication and file sharing framework. - ''; - }; - - home = mkOption { - default = "/var/lib/gnunet"; - description = '' - Directory where the GNUnet daemon will store its data. - ''; - }; - - debug = mkOption { - default = false; - description = '' - When true, run in debug mode; gnunetd will not daemonize and - error messages will be written to stderr instead of a - logfile. - ''; - }; - - logLevel = mkOption { - default = "ERROR"; - example = "INFO"; - description = '' - Log level of the deamon (see `gnunetd(1)' for details). - ''; - }; - - hostLists = mkOption { - default = [ - "http://gnunet.org/hostlist.php" - "http://gnunet.mine.nu:8081/hostlist" - "http://vserver1236.vserver-on.de/hostlist-074" - ]; - description = '' - URLs of host lists. - ''; - }; - - - applications = mkOption { - default = [ "advertising" "getoption" "fs" "stats" "traffic" ]; - example = [ "chat" "fs" ]; - description = '' - List of GNUnet applications supported by the daemon. Note that - `fs', which means "file sharing", is probably the one you want. - ''; - }; - - transports = mkOption { - default = [ "udp" "tcp" "http" "nat" ]; - example = [ "smtp" "http" ]; - description = '' - List of transport methods used by the server. - ''; - }; - - fileSharing = { - quota = mkOption { - default = 1024; - description = '' - Maximum file system usage (in MiB) for file sharing. - ''; - }; - - activeMigration = mkOption { - default = false; - description = '' - Whether to allow active migration of content originating - from other nodes. - ''; - }; - }; - - load = { - maxNetDownBandwidth = mkOption { - default = 50000; - description = '' - Maximum bandwidth usage (in bits per second) for GNUnet - when downloading data. - ''; - }; - - maxNetUpBandwidth = mkOption { - default = 50000; - description = '' - Maximum bandwidth usage (in bits per second) for GNUnet - when downloading data. - ''; - }; - - hardNetUpBandwidth = mkOption { - default = 0; - description = '' - Hard bandwidth limit (in bits per second) when uploading - data. - ''; - }; - - maxCPULoad = mkOption { - default = 100; - description = '' - Maximum CPU load (percentage) authorized for the GNUnet - daemon. - ''; - }; - - interfaces = mkOption { - default = [ "eth0" ]; - example = [ "wlan0" "eth1" ]; - description = '' - List of network interfaces to use. - ''; - }; - }; - - extraOptions = mkOption { - default = ""; - example = '' - [NETWORK] - INTERFACE = eth3 - ''; - description = '' - Additional options that will be copied verbatim in `gnunetd.conf'. - See `gnunetd.conf(5)' for details. + Whether to allow active migration of content originating + from other nodes. ''; }; }; + + load = { + maxNetDownBandwidth = mkOption { + default = 50000; + description = '' + Maximum bandwidth usage (in bits per second) for GNUnet + when downloading data. + ''; + }; + + maxNetUpBandwidth = mkOption { + default = 50000; + description = '' + Maximum bandwidth usage (in bits per second) for GNUnet + when downloading data. + ''; + }; + + hardNetUpBandwidth = mkOption { + default = 0; + description = '' + Hard bandwidth limit (in bits per second) when uploading + data. + ''; + }; + + maxCPULoad = mkOption { + default = 100; + description = '' + Maximum CPU load (percentage) authorized for the GNUnet + daemon. + ''; + }; + + interfaces = mkOption { + default = [ "eth0" ]; + example = [ "wlan0" "eth1" ]; + description = '' + List of network interfaces to use. + ''; + }; + }; + + extraOptions = mkOption { + default = ""; + example = '' + [NETWORK] + INTERFACE = eth3 + ''; + description = '' + Additional options that will be copied verbatim in `gnunetd.conf'. + See `gnunetd.conf(5)' for details. + ''; + }; }; + }; -in -###### implementation -mkIf config.services.gnunet.enable { - require = [ - options - ]; + ###### implementation - users = { - extraUsers = [ + config = mkIf config.services.gnunet.enable { + + users.extraUsers = singleton { name = "gnunetd"; uid = config.ids.uids.gnunetd; description = "GNUnet Daemon User"; home = "/var/empty"; - } - ]; - }; + }; - services = { - extraJobs = [{ - name = "gnunetd"; + jobAttrs.gnunetd = + { description = "The GNUnet Daemon"; - job = - with config.services.gnunet; - let - inherit (pkgs) lib gnunet; - configFile = pkgs.writeText "gnunetd.conf" '' - [PATHS] - GNUNETD_HOME = ${home} + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; - [GNUNETD] - HOSTLISTURL = ${lib.concatStringsSep " " hostLists} - APPLICATIONS = ${lib.concatStringsSep " " applications} - TRANSPORTS = ${lib.concatStringsSep " " transports} + preStart = + '' + test -d "${cfg.home}" || \ + ( mkdir -m 755 -p "${cfg.home}" && chown -R gnunetd:users "${cfg.home}") + ''; - [LOAD] - MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth} - MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth} - HARDUPLIMIT = ${toString load.hardNetUpBandwidth} - MAXCPULOAD = ${toString load.maxCPULoad} - INTERFACES = ${lib.concatStringsSep " " load.interfaces} - - [FS] - QUOTA = ${toString fileSharing.quota} - ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"} - - [MODULES] - sqstore = sqstore_sqlite - dstore = dstore_sqlite - topology = topology_default - - ${extraOptions} - ''; - in '' - description "The GNUnet Daemon" - - start on network-interfaces/started - stop on network-interfaces/stop - - start script - test -d "${home}" || \ - ( mkdir -m 755 -p "${home}" && chown -R gnunetd:users "${home}") - end script - - respawn ${gnunet}/bin/gnunetd \ + exec = + '' + respawn ${pkgs.gnunet}/bin/gnunetd \ ${if debug then "--debug" else "" } \ --user="gnunetd" \ --config="${configFile}" \ - --log="${logLevel}" - ''; - }]; + --log="${cfg.logLevel}" + ''; + }; + }; + } diff --git a/modules/services/networking/gw6c.nix b/modules/services/networking/gw6c.nix index 502a7b1826e..961940d534a 100644 --- a/modules/services/networking/gw6c.nix +++ b/modules/services/networking/gw6c.nix @@ -1,141 +1,143 @@ -{servicesPath, pkgs, config, ...}: +{ config, pkgs, servicesPath, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + cfg = config.services.gw6c; + + gw6cService = import (servicesPath + /gw6c) { + inherit (pkgs) stdenv gw6c coreutils + procps upstart iputils gnused + gnugrep seccure writeScript; + username = cfg.username; + password = cfg.password; + server = cfg.server; + keepAlive = cfg.keepAlive; + everPing = cfg.everPing; + seccureKeys = config.security.seccureKeys; + waitPingableBroker = cfg.waitPingableBroker; + }; + +in + +{ + + ###### interface options = { - services = { - gw6c = { - enable = mkOption { - default = false; - description = " - Whether to enable Gateway6 client (IPv6 tunnel). - "; - }; - - autorun = mkOption { - default = true; - description = " - Switch to false to create upstart-job and configuration, - but not run it automatically - "; - }; - - username = mkOption { - default = ""; - description = " - Your Gateway6 login name, if any. - "; - }; - - password = mkOption { - default = ""; - description = " - Your Gateway6 password, if any. - "; - }; - - server = mkOption { - default = "anon.freenet6.net"; - example = "broker.freenet6.net"; - description = " - Used Gateway6 server. - "; - }; - - keepAlive = mkOption { - default = "30"; - example = "2"; - description = " - Gateway6 keep-alive period. - "; - }; - - everPing = mkOption { - default = "1000000"; - example = "2"; - description = " - Gateway6 manual ping period. - "; - }; - - waitPingableBroker = mkOption { - default = true; - example = false; - description = " - Whether to wait until tunnel broker returns ICMP echo. - "; - }; + + services.gw6c = { + + enable = mkOption { + default = false; + description = " + Whether to enable Gateway6 client (IPv6 tunnel). + "; }; - }; - security = { - seccureKeys = { - public = mkOption { - default = /var/elliptic-keys/public; - description = " - Public key. Make it path argument, so it is copied into store and - hashed. - The key is used to encrypt Gateway 6 configuration in store, as it - contains a password for external service. Unfortunately, - derivation file should be protected by other means. For example, - nix-http-export.cgi will happily export any non-derivation path, - but not a derivation. - "; - }; - - private = mkOption { - default = "/var/elliptic-keys/private"; - description = " - Private key. Make it string argument, so it is not copied into store. - "; - }; + autorun = mkOption { + default = true; + description = " + Switch to false to create upstart-job and configuration, + but not run it automatically + "; }; + + username = mkOption { + default = ""; + description = " + Your Gateway6 login name, if any. + "; + }; + + password = mkOption { + default = ""; + description = " + Your Gateway6 password, if any. + "; + }; + + server = mkOption { + default = "anon.freenet6.net"; + example = "broker.freenet6.net"; + description = " + Used Gateway6 server. + "; + }; + + keepAlive = mkOption { + default = "30"; + example = "2"; + description = " + Gateway6 keep-alive period. + "; + }; + + everPing = mkOption { + default = "1000000"; + example = "2"; + description = " + Gateway6 manual ping period. + "; + }; + + waitPingableBroker = mkOption { + default = true; + example = false; + description = " + Whether to wait until tunnel broker returns ICMP echo. + "; + }; + }; + + security.seccureKeys = { + + # !!! It's not clear to me (ED) what additional security this + # provides. Passwords shouldn't be in configuration.nix, + # period. You could just place the password in + # /var/blah/password or whatever. + + public = mkOption { + default = /var/elliptic-keys/public; + description = " + Public key. Make it path argument, so it is copied into store and + hashed. + + The key is used to encrypt Gateway 6 configuration in store, as it + contains a password for external service. Unfortunately, + derivation file should be protected by other means. For example, + nix-http-export.cgi will happily export any non-derivation path, + but not a derivation. + "; + }; + + private = mkOption { + default = "/var/elliptic-keys/private"; + description = " + Private key. Make it string argument, so it is not copied into store. + "; + }; + + }; + }; -in + -###### implementation + ###### implementation -let - cfg = config.services.gw6c; - procps = pkgs.procps; - gw6cService = import (servicesPath + /gw6c) { - inherit (pkgs) stdenv gw6c coreutils - procps upstart iputils gnused - gnugrep seccure writeScript; - username = cfg.username; - password = cfg.password; - server = cfg.server; - keepAlive = cfg.keepAlive; - everPing = cfg.everPing; + config = mkIf cfg.enable { - seccureKeys = config.security.seccureKeys; + jobAttrs.gw6c = + { description = "Gateway6 client"; + + startOn = if cfg.autorun then "network-interfaces/started" else ""; + stopOn = "network-interfaces/stop"; - waitPingableBroker = cfg.waitPingableBroker; - }; -in + exec = "${gw6cService}/bin/control start"; + }; - -mkIf config.services.gw6c.enable { - require = [ - options - ]; - - services = { - extraJobs = [{ - name = "gw6c"; - users = []; - groups = []; - job = '' - description \"Gateway6 client\" - - start on ${ if cfg.autorun then "network-interfaces/started" else "never" } - stop on network-interfaces/stop - - respawn ${gw6cService}/bin/control start - ''; - }]; }; + } diff --git a/modules/services/networking/ircd-hybrid.nix b/modules/services/networking/ircd-hybrid.nix index 070abc1ef22..e59f9a8fa4f 100644 --- a/modules/services/networking/ircd-hybrid.nix +++ b/modules/services/networking/ircd-hybrid.nix @@ -1,89 +1,11 @@ -{servicesPath, pkgs, config, ...}: +{ config, pkgs, servicesPath, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - ircdHybrid = { - - enable = mkOption { - default = false; - description = " - Enable IRCD. - "; - }; - - serverName = mkOption { - default = "hades.arpa"; - description = " - IRCD server name. - "; - }; - - sid = mkOption { - default = "0NL"; - description = " - IRCD server unique ID in a net of servers. - "; - }; - - description = mkOption { - default = "Hybrid-7 IRC server."; - description = " - IRCD server description. - "; - }; - - rsaKey = mkOption { - default = null; - example = /root/certificates/irc.key; - description = " - IRCD server RSA key. - "; - }; - - certificate = mkOption { - default = null; - example = /root/certificates/irc.pem; - description = " - IRCD server SSL certificate. There are some limitations - read manual. - "; - }; - - adminEmail = mkOption { - default = ""; - example = ""; - description = " - IRCD server administrator e-mail. - "; - }; - - extraIPs = mkOption { - default = []; - example = ["127.0.0.1"]; - description = " - Extra IP's to bind. - "; - }; - - extraPort = mkOption { - default = "7117"; - description = " - Extra port to avoid filtering. - "; - }; - - }; - }; - }; -in - -###### implementation +with pkgs.lib; let + cfg = config.services.ircdHybrid; + ircdService = import (servicesPath + /ircd-hybrid) { stdenv = pkgs.stdenv; inherit (pkgs) ircdHybrid coreutils @@ -96,35 +18,116 @@ let adminEmail = cfg.adminEmail; extraIPs = cfg.extraIPs; extraPort = cfg.extraPort; - gw6cEnabled = (config.services.gw6c.enable) && - (config.services.gw6c.autorun); + gw6cEnabled = config.services.gw6c.enable && config.services.gw6c.autorun; }; startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; in -mkIf config.services.ircdHybrid.enable { - require = [ - options - ]; +{ - services = { - extraJobs = [{ - name = "ircd-hybrid"; - users = [ { - name = "ircd"; - description = "IRCD owner."; - } ]; - groups = [{name = "ircd";}]; - job = '' - description = "IRCD Hybrid server." + ###### interface - start on ${startingDependency}/started - stop on ${startingDependency}/stop + options = { + + services.ircdHybrid = { + + enable = mkOption { + default = false; + description = " + Enable IRCD. + "; + }; + + serverName = mkOption { + default = "hades.arpa"; + description = " + IRCD server name. + "; + }; + + sid = mkOption { + default = "0NL"; + description = " + IRCD server unique ID in a net of servers. + "; + }; + + description = mkOption { + default = "Hybrid-7 IRC server."; + description = " + IRCD server description. + "; + }; + + rsaKey = mkOption { + default = null; + example = /root/certificates/irc.key; + description = " + IRCD server RSA key. + "; + }; + + certificate = mkOption { + default = null; + example = /root/certificates/irc.pem; + description = " + IRCD server SSL certificate. There are some limitations - read manual. + "; + }; + + adminEmail = mkOption { + default = ""; + example = ""; + description = " + IRCD server administrator e-mail. + "; + }; + + extraIPs = mkOption { + default = []; + example = ["127.0.0.1"]; + description = " + Extra IP's to bind. + "; + }; + + extraPort = mkOption { + default = "7117"; + description = " + Extra port to avoid filtering. + "; + }; + + }; - respawn ${ircdService}/bin/control start - ''; - }]; }; + + + ###### implementation + + config = mkIf config.services.ircdHybrid.enable { + + users.extraUsers = singleton + { name = "ircd"; + description = "IRCD owner"; + }; + + users.extraGroups = singleton + { name = "ircd"; }; + + jobAttrs.ircd_hybrid = + { # name = "ircd-hybrid"; !!! mkIf bug + + description = "IRCD Hybrid server"; + + startOn = "${startingDependency}/started"; + stopOn = "${startingDependency}/stop"; + + exec = "${ircdService}/bin/control start"; + }; + + }; + } diff --git a/modules/services/networking/openfire.nix b/modules/services/networking/openfire.nix index fa51ad173a3..e009498546c 100644 --- a/modules/services/networking/openfire.nix +++ b/modules/services/networking/openfire.nix @@ -1,65 +1,62 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - openfire = { - enable = mkOption { - default = false; - description = " - Whether to enable OpenFire XMPP server. - "; - }; - usePostgreSQL = mkOption { - default = true; - description = " - Whether you use PostgreSQL service for your storage back-end. - "; - }; - }; - }; - }; -in - -###### implementation +with pkgs.lib; let + inherit (pkgs) jre openfire coreutils which gnugrep gawk gnused; - startDependency = if config.services.openfire.usePostgreSQL then - "postgresql" - else - if config.services.gw6c.enable then - "gw6c" - else - "network-interfaces"; + startDependency = + if config.services.openfire.usePostgreSQL then "postgresql" else + if config.services.gw6c.enable then "gw6c" else + "network-interfaces"; + in -mkIf config.services.openfire.enable { +{ - assertions = [ { - assertion = !(config.services.openfire.usePostgreSQL -> config.services.postgresql.enable); - message = "openfire assertion failed"; - } ]; + ###### interface - require = [ - options - ]; + options = { + + services.openfire = { + + enable = mkOption { + default = false; + description = " + Whether to enable OpenFire XMPP server. + "; + }; + + usePostgreSQL = mkOption { + default = true; + description = " + Whether you use PostgreSQL service for your storage back-end. + "; + }; + + }; + + }; - services = { - extraJobs = [{ - name = "openfire"; - job = '' - description "OpenFire XMPP server" + ###### implementation - start on ${startDependency}/started - stop on shutdown + config = mkIf config.services.openfire.enable { - script + assertions = singleton + { assertion = !(config.services.openfire.usePostgreSQL -> config.services.postgresql.enable); + message = "openfire assertion failed"; + }; + + jobAttrs.openfire = + { description = "OpenFire XMPP server"; + + startOn = "${startDependency}/started"; + stopOn = "shutdown"; + + script = + '' export PATH=${jre}/bin:${openfire}/bin:${coreutils}/bin:${which}/bin:${gnugrep}/bin:${gawk}/bin:${gnused}/bin export HOME=/tmp mkdir /var/log/openfire || true @@ -70,8 +67,9 @@ mkIf config.services.openfire.enable { fi done openfire start - end script - ''; - }]; + ''; # */ + }; + }; + } diff --git a/modules/services/networking/openvpn.nix b/modules/services/networking/openvpn.nix index 025a93d20a0..f7a8f51d9b1 100644 --- a/modules/services/networking/openvpn.nix +++ b/modules/services/networking/openvpn.nix @@ -1,83 +1,14 @@ +{ config, pkgs, ... }: -{pkgs, config, ...}: +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - openvpn = { - enable = mkOption { - default = false; - description = " - Whether to enable the Secure Shell daemon, which allows secure - remote logins. - "; - }; - servers = mkOption { - example = [ - { - id = "server-simplest"; - config = '' - # Most simple configuration: http://openvpn.net/index.php/documentation/miscellaneous/static-key-mini-howto.html. - # server : - dev tun - ifconfig 10.8.0.1 10.8.0.2 - secret static.key - ''; - up = "ip route add ..!"; - down = "ip route add ..!"; - } - { - id = "client-simplest"; - config = '' - #client: - #remote myremote.mydomain - #dev tun - #ifconfig 10.8.0.2 10.8.0.1 - #secret static.key - ''; - } - { - id = "server-scalable"; - config = '' - multiple clienst - see example file found in http://openvpn.net/index.php/documentation/howto.html - ''; - } - { - id = "client-scalabe"; - config = '' dito ''; - } - ]; - default = []; - description = '' - openvpn instances to be run. Each will be put into an extra job named openvpn-{id} - - The up and down properties will be added config line up=/nix/store/xxx-up-script - automatically for you. If you define at least one of up/down - "script-security 2" will be prepended to your config. - - Don't forget to check that the all package sizes can be sent. if scp hangs or such you should set - --fragment XXX --mssfix YYY. - ''; - }; - }; - }; - }; - - - modprobe = config.system.sbin.modprobe; - -###### implementation cfg = config.services.openvpn; inherit (pkgs) openvpn; - inherit (builtins) hasAttr; - PATH="${pkgs.iptables}/sbin:${pkgs.coreutils}/bin:${pkgs.iproute}/sbin:${pkgs.nettools}/sbin"; + PATH = "${pkgs.iptables}/sbin:${pkgs.coreutils}/bin:${pkgs.iproute}/sbin:${pkgs.nettools}/sbin"; makeOpenVPNJob = cfg : let @@ -93,42 +24,105 @@ let PATH=${PATH} ${cfg.down} ''; - configFile = pkgs.writeText "openvpn-config-${cfg.id}" '' - ${if hasAttr "up" cfg || hasAttr "down" cfg then "script-security 2" else ""} - ${cfg.config} - ${if hasAttr "up" cfg then "up ${pkgs.writeScript "openvpn-${cfg.id}-up" upScript}" else "" } - ${if hasAttr "down" cfg then "down ${pkgs.writeScript "openvpn-${cfg.id}-down" downScript}" else "" } - ''; + configFile = pkgs.writeText "openvpn-config-${cfg.id}" + '' + ${if cfg ? up || cfg ? down then "script-security 2" else ""} + ${cfg.config} + ${if cfg ? up then "up ${pkgs.writeScript "openvpn-${cfg.id}-up" upScript}" else "" } + ${if cfg ? down then "down ${pkgs.writeScript "openvpn-${cfg.id}-down" downScript}" else "" } + ''; in { - name = "openvpn-${cfg.id}"; + description = "OpenVPN-${cfg.id}"; - job = '' - description "OpenVPN-${cfg.id}" + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; - start on network-interfaces/started - stop on network-interfaces/stop + environment = { PATH = "${pkgs.coreutils}/bin"; }; - - PATH=${pkgs.coreutils}/bin - - respawn - script + script = + '' exec &> /var/log/openvpn-${cfg.id} - ${modprobe} tun || true + ${config.system.sbin.modprobe} tun || true ${openvpn}/sbin/openvpn --config ${configFile} - end script - ''; + ''; }; in + +{ + ###### interface -mkIf cfg.enable { - require = [ - options - ]; + options = { + + services.openvpn = { + + enable = mkOption { + default = false; + description = "Whether to enable OpenVPN."; + }; + + servers = mkOption { + example = [ + { + id = "server-simplest"; + config = '' + # Most simple configuration: http://openvpn.net/index.php/documentation/miscellaneous/static-key-mini-howto.html. + # server : + dev tun + ifconfig 10.8.0.1 10.8.0.2 + secret static.key + ''; + up = "ip route add ..!"; + down = "ip route add ..!"; + } + { + id = "client-simplest"; + config = '' + #client: + #remote myremote.mydomain + #dev tun + #ifconfig 10.8.0.2 10.8.0.1 + #secret static.key + ''; + } + { + id = "server-scalable"; + config = '' + multiple clienst + see example file found in http://openvpn.net/index.php/documentation/howto.html + ''; + } + { + id = "client-scalabe"; + config = '' dito ''; + } + ]; + default = []; + # !!! clean up this description please + description = '' + openvpn instances to be run. Each will be put into an extra job named openvpn-{id} + + The up and down properties will be added config line up=/nix/store/xxx-up-script + automatically for you. If you define at least one of up/down + "script-security 2" will be prepended to your config. + + Don't forget to check that the all package sizes can be sent. if scp hangs or such you should set + --fragment XXX --mssfix YYY. + ''; + }; + + }; - services = { - extraJobs = map makeOpenVPNJob cfg.servers; }; + + + ###### implementation + + config = mkIf cfg.enable { + + jobAttrs = listToAttrs (map (c: nameValuePair "openvpn-${cfg.id}" (makeOpenVPNJob c)) cfg.servers); + + }; + } diff --git a/modules/services/networking/portmap.nix b/modules/services/networking/portmap.nix index 5583108f894..08cd2457bcc 100644 --- a/modules/services/networking/portmap.nix +++ b/modules/services/networking/portmap.nix @@ -1,89 +1,84 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + uid = config.ids.uids.portmap; + gid = config.ids.gids.portmap; + + portmap = pkgs.portmap.override { daemonUID = uid; daemonGID = gid; }; + +in + +{ + + ###### interface options = { - services = { - portmap = { - enable = mkOption { - default = false; - description = '' - Whether to enable `portmap', an ONC RPC directory service - notably used by NFS and NIS, and which can be queried - using the rpcinfo(1) command. - ''; - }; - - verbose = mkOption { - default = false; - description = '' - Whether to enable verbose output. - ''; - }; - - chroot = mkOption { - default = "/var/empty"; - description = '' - If non-empty, a path to change root to. - ''; - }; - + + services.portmap = { + + enable = mkOption { + default = false; + description = '' + Whether to enable `portmap', an ONC RPC directory service + notably used by NFS and NIS, and which can be queried + using the rpcinfo(1) command. + ''; }; + + verbose = mkOption { + default = false; + description = '' + Whether to enable verbose output. + ''; + }; + + chroot = mkOption { + default = "/var/empty"; + description = '' + If non-empty, a path to change root to. + ''; + }; + }; + }; -in + -###### implementation + ###### implementation -let uid = config.ids.uids.portmap; - gid = config.ids.gids.portmap; -in + config = mkIf config.services.portmap.enable { -mkIf config.services.portmap.enable { - - require = [ - options - ]; - - - users = { - extraUsers = [ + users.extraUsers = singleton { name = "portmap"; inherit uid; description = "portmap daemon user"; home = "/var/empty"; - } - ]; + }; - extraGroups = [ + users.extraGroups = singleton { name = "portmap"; inherit gid; - } - ]; - }; + }; - services = { - extraJobs = [{ - name = "portmap"; - + jobAttrs.portmap = + { description = "ONC RPC portmap"; - job = - let portmap = pkgs.portmap.override { daemonUID = uid; daemonGID = gid; }; - in + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + exec = '' - description "ONC RPC portmap" + ${portmap}/sbin/portmap -f \ + ${if config.services.portmap.chroot == "" + then "" + else "-t \"${config.services.portmap.chroot}\""} \ + ${if config.services.portmap.verbose then "-v" else ""} + ''; + }; - start on network-interfaces/started - stop on network-interfaces/stop - - respawn ${portmap}/sbin/portmap -f \ - ${if config.services.portmap.chroot == "" - then "" - else "-t \"${config.services.portmap.chroot}\""} \ - ${if config.services.portmap.verbose then "-v" else ""} - ''; - }]; }; + } diff --git a/modules/services/networking/ssh/lshd.nix b/modules/services/networking/ssh/lshd.nix index c6b529e66ee..35eaa0c743f 100644 --- a/modules/services/networking/ssh/lshd.nix +++ b/modules/services/networking/ssh/lshd.nix @@ -1,138 +1,132 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - lshd = { - - enable = mkOption { - default = false; - description = '' - Whether to enable the GNU lshd SSH2 daemon, which allows - secure remote login. - ''; - }; - - portNumber = mkOption { - default = 22; - description = '' - The port on which to listen for connections. - ''; - }; - - interfaces = mkOption { - default = []; - description = '' - List of network interfaces where listening for connections. - When providing the empty list, `[]', lshd listens on all - network interfaces. - ''; - example = [ "localhost" "1.2.3.4:443" ]; - }; - - hostKey = mkOption { - default = "/etc/lsh/host-key"; - description = '' - Path to the server's private key. Note that this key must - have been created, e.g., using "lsh-keygen --server | - lsh-writekey --server", so that you can run lshd. - ''; - }; - - syslog = mkOption { - default = true; - description = ''Whether to enable syslog output.''; - }; - - passwordAuthentication = mkOption { - default = true; - description = ''Whether to enable password authentication.''; - }; - - publicKeyAuthentication = mkOption { - default = true; - description = ''Whether to enable public key authentication.''; - }; - - rootLogin = mkOption { - default = false; - description = ''Whether to enable remote root login.''; - }; - - loginShell = mkOption { - default = null; - description = '' - If non-null, override the default login shell with the - specified value. - ''; - example = "/nix/store/xyz-bash-10.0/bin/bash10"; - }; - - srpKeyExchange = mkOption { - default = false; - description = '' - Whether to enable SRP key exchange and user authentication. - ''; - }; - - tcpForwarding = mkOption { - default = true; - description = ''Whether to enable TCP/IP forwarding.''; - }; - - x11Forwarding = mkOption { - default = true; - description = ''Whether to enable X11 forwarding.''; - }; - - subsystems = mkOption { - default = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; - description = '' - List of subsystem-path pairs, where the head of the pair - denotes the subsystem name, and the tail denotes the path to - an executable implementing it. - ''; - }; - }; - }; - }; -in - -###### implementation +with pkgs.lib; let inherit (pkgs) lsh; - inherit (pkgs.lib) concatStrings concatStringsSep head tail; - lshdConfig = config.services.lshd; + cfg = config.services.lshd; - nssModules = config.system.nssModules.list; - - nssModulesPath = config.system.nssModules.path; in -mkIf config.services.lshd.enable { - require = [ - options - ]; +{ - services = { - extraJobs = [{ - name = "lshd"; + ###### interface + + options = { + + services.lshd = { + + enable = mkOption { + default = false; + description = '' + Whether to enable the GNU lshd SSH2 daemon, which allows + secure remote login. + ''; + }; + + portNumber = mkOption { + default = 22; + description = '' + The port on which to listen for connections. + ''; + }; + + interfaces = mkOption { + default = []; + description = '' + List of network interfaces where listening for connections. + When providing the empty list, `[]', lshd listens on all + network interfaces. + ''; + example = [ "localhost" "1.2.3.4:443" ]; + }; + + hostKey = mkOption { + default = "/etc/lsh/host-key"; + description = '' + Path to the server's private key. Note that this key must + have been created, e.g., using "lsh-keygen --server | + lsh-writekey --server", so that you can run lshd. + ''; + }; + + syslog = mkOption { + default = true; + description = ''Whether to enable syslog output.''; + }; + + passwordAuthentication = mkOption { + default = true; + description = ''Whether to enable password authentication.''; + }; + + publicKeyAuthentication = mkOption { + default = true; + description = ''Whether to enable public key authentication.''; + }; + + rootLogin = mkOption { + default = false; + description = ''Whether to enable remote root login.''; + }; + + loginShell = mkOption { + default = null; + description = '' + If non-null, override the default login shell with the + specified value. + ''; + example = "/nix/store/xyz-bash-10.0/bin/bash10"; + }; + + srpKeyExchange = mkOption { + default = false; + description = '' + Whether to enable SRP key exchange and user authentication. + ''; + }; + + tcpForwarding = mkOption { + default = true; + description = ''Whether to enable TCP/IP forwarding.''; + }; + + x11Forwarding = mkOption { + default = true; + description = ''Whether to enable X11 forwarding.''; + }; + + subsystems = mkOption { + default = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; + description = '' + List of subsystem-path pairs, where the head of the pair + denotes the subsystem name, and the tail denotes the path to + an executable implementing it. + ''; + }; - job = with lshdConfig; '' - description "GNU lshd SSH2 daemon" + }; - start on network-interfaces/started - stop on network-interfaces/stop + }; - env LD_LIBRARY_PATH=${nssModulesPath} - start script + ###### implementation + + config = mkIf cfg.enable { + + jobAttrs.lshd = + { description = "GNU lshd SSH2 daemon"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + environment = + { LD_LIBRARY_PATH = config.system.nssModules.path; }; + + preStart = + '' test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh @@ -144,35 +138,37 @@ mkIf config.services.lshd.enable { ${lsh}/bin/lsh-make-seed -o /var/spool/lsh/yarrow-seed-file fi - if ! test -f "${hostKey}" + if ! test -f "${cfg.hostKey}" then ${lsh}/bin/lsh-keygen --server | \ - ${lsh}/bin/lsh-writekey --server -o "${hostKey}" + ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}" fi - end script + ''; - respawn ${lsh}/sbin/lshd --daemonic \ - --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ - -p ${toString portNumber} \ - ${if interfaces == [] then "" - else (concatStrings (map (i: "--interface=\"${i}\"") - interfaces))} \ - -h "${hostKey}" \ - ${if !syslog then "--no-syslog" else ""} \ - ${if passwordAuthentication then "--password" else "--no-password" } \ - ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ - ${if rootLogin then "--root-login" else "--no-root-login" } \ - ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \ - ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ - ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ - ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ - --subsystems=${concatStringsSep "," - (map (pair: (head pair) + "=" + - (head (tail pair))) - subsystems)} - ''; + exec = with cfg; + '' + ${lsh}/sbin/lshd --daemonic \ + --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ + -p ${toString portNumber} \ + ${if interfaces == [] then "" + else (concatStrings (map (i: "--interface=\"${i}\"") + interfaces))} \ + -h "${hostKey}" \ + ${if !syslog then "--no-syslog" else ""} \ + ${if passwordAuthentication then "--password" else "--no-password" } \ + ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ + ${if rootLogin then "--root-login" else "--no-root-login" } \ + ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \ + ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ + ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ + ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ + --subsystems=${concatStringsSep "," + (map (pair: (head pair) + "=" + + (head (tail pair))) + subsystems)} + ''; + }; + + }; -} - ]; - }; } diff --git a/modules/services/networking/vsftpd.nix b/modules/services/networking/vsftpd.nix index a0630de77cc..2a567f3ec90 100644 --- a/modules/services/networking/vsftpd.nix +++ b/modules/services/networking/vsftpd.nix @@ -1,92 +1,11 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: -###### interface -let - inherit (pkgs.lib) mkOption mkIf; - - options = { - services = { - vsftpd = { - enable = mkOption { - default = false; - description = " - Whether to enable the vsftpd FTP server. - "; - }; - - anonymousUser = mkOption { - default = false; - description = " - Whether to enable the anonymous FTP user. - "; - }; - - anonymousUserHome = mkOption { - default = "/home/ftp"; - description = " - Path to anonymous user data. - "; - }; - - localUsers = mkOption { - default = false; - description = " - Whether to enable FTP for the local users. - "; - }; - - writeEnable = mkOption { - default = false; - description = " - Whether any write activity is permitted to users. - "; - }; - - anonymousUploadEnable = mkOption { - default = false; - description = " - Whether any uploads are permitted to anonymous users. - "; - }; - - anonymousMkdirEnable = mkOption { - default = false; - description = " - Whether mkdir is permitted to anonymous users. - "; - }; - - chrootlocalUser = mkOption { - default = false; - description = " - Whether u can like out of ur home dir. - "; - }; - - userlistEnable = mkOption { - default = false; - description = " - Whether users are included. - "; - }; - - userlistDeny = mkOption { - default = false; - description = " - Whether users are excluded. - "; - }; - }; - }; - }; -in - -###### implementation +with pkgs.lib; let - inherit (config.services.vsftpd) anonymousUser anonymousUserHome localUsers writeEnable anonymousUploadEnable anonymousMkdirEnable - chrootlocalUser userlistEnable userlistDeny; + cfg = config.services.vsftpd; + inherit (pkgs) vsftpd; yesNoOption = p : name : @@ -94,67 +13,123 @@ let in -mkIf config.services.vsftpd.enable { - require = [ - options - ]; +{ - users = { - extraUsers = [ - { name = "vsftpd"; + ###### interface + + options = { + + services.vsftpd = { + + enable = mkOption { + default = false; + description = "Whether to enable the vsftpd FTP server."; + }; + + anonymousUser = mkOption { + default = false; + description = "Whether to enable the anonymous FTP user."; + }; + + anonymousUserHome = mkOption { + default = "/home/ftp"; + description = "Path to anonymous user data."; + }; + + localUsers = mkOption { + default = false; + description = "Whether to enable FTP for local users."; + }; + + writeEnable = mkOption { + default = false; + description = "Whether any write activity is permitted to users."; + }; + + anonymousUploadEnable = mkOption { + default = false; + description = "Whether any uploads are permitted to anonymous users."; + }; + + anonymousMkdirEnable = mkOption { + default = false; + description = "Whether mkdir is permitted to anonymous users."; + }; + + chrootlocalUser = mkOption { + default = false; + description = "Whether local users are confined to their home directory."; + }; + + userlistEnable = mkOption { + default = false; + description = "Whether users are included."; + }; + + userlistDeny = mkOption { + default = false; + description = "Whether users are excluded."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + users.extraUsers = + [ { name = "vsftpd"; uid = config.ids.uids.vsftpd; description = "VSFTPD user"; home = "/homeless-shelter"; } - ] ++ pkgs.lib.optional anonymousUser + ] ++ pkgs.lib.optional cfg.anonymousUser { name = "ftp"; uid = config.ids.uids.ftp; group = "ftp"; - description = "Anonymous ftp user"; - home = anonymousUserHome; + description = "Anonymous FTP user"; + home = cfg.anonymousUserHome; }; - extraGroups = [ + users.extraGroups = singleton { name = "ftp"; gid = config.ids.gids.ftp; - } - ]; - - }; - - services = { - extraJobs = [{ - name = "vsftpd"; - - job = '' - description "vsftpd server" - - start on network-interfaces/started - stop on network-interfaces/stop - - start script - cat > /etc/vsftpd.conf < /etc/vsftpd.conf < - Order allow,deny - Allow localhost - - - - Order allow,deny - Allow localhost - - - - AuthType Basic - Require user @SYSTEM - Order allow,deny - Allow localhost - + + Order allow,deny + Allow localhost + - - - Require user @OWNER @SYSTEM - Order deny,allow - + + Order allow,deny + Allow localhost + - + AuthType Basic Require user @SYSTEM - Order deny,allow - + Order allow,deny + Allow localhost + - - Require user @OWNER @SYSTEM - Order deny,allow - + + + Require user @OWNER @SYSTEM + Order deny,allow + - - Order deny,allow - - - ''; + + AuthType Basic + Require user @SYSTEM + Order deny,allow + + + + Require user @OWNER @SYSTEM + Order deny,allow + + + + Order deny,allow + + + ''; in +{ -mkIf config.services.printing.enable { - require = [ - options - ]; + ###### interface - environment.systemPackages = [cups]; + options = { + + services.printing = { - environment.etc = - [ # CUPS expects the following files in its ServerRoot. - { source = "${cups}/etc/cups/mime.convs"; - target = "cups/mime.convs"; - } - { source = "${cups}/etc/cups/mime.types"; - target = "cups/mime.types"; - } - ]; + enable = mkOption { + default = false; + description = '' + Whether to enable printing support through the CUPS daemon. + ''; + }; - services.extraJobs = pkgs.lib.singleton - { name = "cupsd"; + bindirCmds = mkOption { + default = ""; + description = '' + Additional commands executed while creating the directory + containing the CUPS server binaries. + ''; + }; - job = '' - description "CUPS printing daemon" + }; - start on network-interfaces/started - stop on network-interfaces/stop + }; - start script + + ###### implementation + + config = mkIf config.services.printing.enable { + + environment.systemPackages = [cups]; + + environment.etc = + [ # CUPS expects the following files in its ServerRoot. + { source = "${cups}/etc/cups/mime.convs"; + target = "cups/mime.convs"; + } + { source = "${cups}/etc/cups/mime.types"; + target = "cups/mime.types"; + } + ]; + + jobAttrs.cupsd = + { description = "CUPS printing daemon"; + + startOn = "network-interfaces/started"; + stopOn = "network-interfaces/stop"; + + preStart = + '' mkdir -m 0755 -p ${logDir} mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/spool/cups # Make USB printers show up. ${modprobe}/sbin/modprobe usblp || true - end script + ''; - respawn ${cups}/sbin/cupsd -c ${cupsdConfig} -F - ''; - }; + exec = "${cups}/sbin/cupsd -c ${cupsdConfig} -F"; + }; + + }; + } diff --git a/modules/services/scheduling/cron.nix b/modules/services/scheduling/cron.nix index 2b4dcc825c5..19ea49619ec 100644 --- a/modules/services/scheduling/cron.nix +++ b/modules/services/scheduling/cron.nix @@ -1,92 +1,82 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption; - options = { - services = { - cron = { - - mailto = mkOption { - default = ""; - description = " The job output will be mailed to this email address. "; - }; - - systemCronJobs = mkOption { - default = []; - example = [ - "* * * * * test ls -l / > /tmp/cronout 2>&1" - "* * * * * eelco echo Hello World > /home/eelco/cronout" - ]; - description = '' - A list of Cron jobs to be appended to the system-wide - crontab. See the manual page for crontab for the expected - format. If you want to get the results mailed you must setuid - sendmail. See - - If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root - will is allowed to have its own crontab file. The /var/cron/cron.deny file - is created automatically for you. So every user can use a crontab. - ''; - }; - - }; - }; - }; -in - -###### implementation -let inherit (config.services) jobsTags; # Put all the system cronjobs together. - systemCronJobs = - config.services.cron.systemCronJobs; - - systemCronJobsFile = pkgs.writeText "system-crontab" '' - SHELL=${pkgs.bash}/bin/sh - PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin:${pkgs.su}/bin - MAILTO="${config.services.cron.mailto}" - ${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)} - ''; + systemCronJobsFile = pkgs.writeText "system-crontab" + '' + SHELL=${pkgs.bash}/bin/sh + PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin:${pkgs.su}/bin + MAILTO="${config.services.cron.mailto}" + ${pkgs.lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)} + ''; + in { - require = [ - # ../upstart-jobs/default.nix # config.services.extraJobs - # ? # config.time.timeZone - # ? # config.environment.etc - # ? # config.environment.extraPackages - options - ]; - environment = { - etc = [ + ###### interface + + options = { + + services.cron = { + + mailto = mkOption { + default = ""; + description = " The job output will be mailed to this email address. "; + }; + + systemCronJobs = mkOption { + default = []; + example = [ + "* * * * * test ls -l / > /tmp/cronout 2>&1" + "* * * * * eelco echo Hello World > /home/eelco/cronout" + ]; + description = '' + A list of Cron jobs to be appended to the system-wide + crontab. See the manual page for crontab for the expected + format. If you want to get the results mailed you must setuid + sendmail. See + + If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root + will is allowed to have its own crontab file. The /var/cron/cron.deny file + is created automatically for you. So every user can use a crontab. + ''; + }; + + }; + + }; + + + ###### implementation + + config = { + + environment.etc = singleton # The system-wide crontab. { source = systemCronJobsFile; target = "crontab"; mode = "0600"; # Cron requires this. - } - ]; + }; - systemPackages = [pkgs.cron]; - }; + environment.systemPackages = [pkgs.cron]; - services = { - extraJobs = [{ - name = "cron"; - - job = '' - description "Cron daemon" - - start on startup - stop on shutdown + jobAttrs.cron = + { description = "Cron daemon"; + startOn = "startup"; + stopOn = "shutdown"; + # Needed to interpret times in the local timezone. - env TZ=${config.time.timeZone} + environment = { TZ = config.time.timeZone; }; - start script + preStart = + '' mkdir -m 710 -p /var/cron # By default, allow all users to create a crontab. This @@ -94,10 +84,11 @@ in if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then touch /var/cron/cron.deny fi - end script + ''; + + exec = "${pkgs.cron}/sbin/cron -n"; + }; - respawn ${pkgs.cron}/sbin/cron -n - ''; - }]; }; + } diff --git a/modules/services/scheduling/fcron.nix b/modules/services/scheduling/fcron.nix index 2764f8fdad0..18b002ef387 100644 --- a/modules/services/scheduling/fcron.nix +++ b/modules/services/scheduling/fcron.nix @@ -1,135 +1,122 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption concatStringsSep; - inherit (pkgs) writeText; - options = { - services = { - fcron = { - enable = mkOption { - default = false; - description = ''Whether to enable the `fcron' daemon. - From its docs: "fcron does both the job of Vixie Cron and anacron, but does even more and better". - It can trigger actions even if the event has passed due to shutdown for example. - TODO: add supoprt for fcron.allow and fcron.deny - Of course on cron daemon is enough.. So if fcron works fine there should be a system option systemCron="fcron or cron" - - There are (or have been) some security issues. - I haven't yet checked wether they have been resolved. - For now you should trust the users registering crontab files. - I think gentoo has them listed. - ''; - }; - allow = mkOption { - default = []; - description = '' - Users allowed to use fcrontab and fcrondyn (one name per line, special name "all" acts for everyone) - nix adds username "root" for you. - ''; - }; - deny = mkOption { - default = []; - description = " same as allow but deny "; - }; - maxSerialJobs = mkOption { - default = 1; - description = "maximum number of serial jobs which can run simultaneously (-m)"; - }; - queuelen = mkOption { - default = ""; - description = "number of jobs the serial queue and the lavg queue can contain - empty to net set this number (-q)"; - }; - systab = mkOption { - default = ""; - description = '' - The "system" crontab contents.. - ''; - }; - }; - }; - }; -in - -###### implementation -let # Put all the system cronjobs together. # TODO allow using fcron only.. #systemCronJobs = # config.services.cron.systemCronJobs; cfg = config.services.fcron; - ifEnabled = if cfg.enable then pkgs.lib.id else (x : []); + queuelen = if cfg.queuelen == "" then "" else "-q ${toString cfg.queuelen}"; # shell is set to /sh in config.. # ${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)} - systemCronJobsFile = pkgs.writeText "fcron-systab" '' - SHELL=${pkgs.bash}/bin/sh - PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin - ''; + systemCronJobsFile = pkgs.writeText "fcron-systab" + '' + SHELL=${pkgs.bash}/bin/sh + PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin + ''; - allowdeny = target: users : { - source = writeText "fcron.${target}" (concatStringsSep "\n" users); - target = "fcron.${target}"; - mode = "600"; # fcron has some security issues.. So I guess this is most safe - }; + allowdeny = target: users: + { source = pkgs.writeText "fcron.${target}" (concatStringsSep "\n" users); + target = "fcron.${target}"; + mode = "600"; # fcron has some security issues.. So I guess this is most safe + }; in { - require = [ - # ../upstart-jobs/default.nix # config.services.extraJobs - # ? # config.time.timeZone - # ? # config.environment.etc - # ? # config.environment.extraPackages - # ? # config.environment.cleanStart - options - ]; - environment = { - etc = ifEnabled [ - (allowdeny "allow" (["root"] ++ cfg.allow)) - (allowdeny "deny" cfg.deny) - # see man 5 fcron.conf - { source = writeText "fcon.conf" '' - fcrontabs = /var/spool/fcron - pidfile = /var/run/fcron.pid - fifofile = /var/run/fcron.fifo - fcronallow = /etc/fcron.allow - fcrondeny = /etc/fcron.deny - shell = /bin/sh - sendmail = /var/setuid-wrappers/sendmail - editor = /var/run/current-system/sw/bin/vi - ''; - target = "fcron.conf"; - mode = "0600"; # max allowed is 644 - } - ]; + ###### interface + + options = { + + services.fcron = { + + enable = mkOption { + default = false; + description = "Whether to enable the `fcron' daemon."; + }; + + allow = mkOption { + default = []; + description = '' + Users allowed to use fcrontab and fcrondyn (one name per line, "all" for everyone). + ''; + }; + + deny = mkOption { + default = []; + description = "Users forbidden from using fcron."; + }; + + maxSerialJobs = mkOption { + default = 1; + description = "Maximum number of serial jobs which can run simultaneously."; + }; + + queuelen = mkOption { + default = ""; + description = "Number of jobs the serial queue and the lavg queue can contain - empty to net set this number (-q)"; + }; + + systab = mkOption { + default = ""; + description = ''The "system" crontab contents.''; + }; + }; - systemPackages = ifEnabled [pkgs.fcron]; }; - services = { - extraJobs = ifEnabled [{ - name = "fcron"; - job = '' - description "fcron daemon" + ###### implementation - start on startup - stop on shutdown + config = mkIf cfg.enable { - env PATH=/var/run/current-system/sw/bin + environment.etc = + [ (allowdeny "allow" (["root"] ++ cfg.allow)) + (allowdeny "deny" cfg.deny) + # see man 5 fcron.conf + { source = pkgs.writeText "fcon.conf" '' + fcrontabs = /var/spool/fcron + pidfile = /var/run/fcron.pid + fifofile = /var/run/fcron.fifo + fcronallow = /etc/fcron.allow + fcrondeny = /etc/fcron.deny + shell = /bin/sh + sendmail = /var/setuid-wrappers/sendmail + editor = /var/run/current-system/sw/bin/vi + ''; + target = "fcron.conf"; + mode = "0600"; # max allowed is 644 + } + ]; - start script + environment.systemPackages = [ pkgs.fcron ]; + + jobAttrs.fcron = + { description = "fcron daemon"; + + startOn = "startup"; + stopOn = "shutdown"; + + environment = + { PATH = "/var/run/current-system/sw/bin"; + }; + + preStart = + '' ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron # load system crontab file - ${pkgs.fcron}/bin/fcrontab -u systab ${writeText "systab" cfg.systab} - end script + ${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab} + ''; + + exec = "${pkgs.fcron}/sbin/fcron -f -m ${toString cfg.maxSerialJobs} ${queuelen}"; + }; - respawn ${pkgs.fcron}/sbin/fcron -f -m ${toString cfg.maxSerialJobs} ${queuelen} - ''; - }]; }; + } diff --git a/modules/services/ttys/gpm.nix b/modules/services/ttys/gpm.nix index 35ecab0083d..fdc1db2878c 100644 --- a/modules/services/ttys/gpm.nix +++ b/modules/services/ttys/gpm.nix @@ -1,58 +1,52 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption; + + cfg = config.services.gpm; + +in + +{ + + ###### interface options = { - services = { - gpm = { - enable = mkOption { - default = false; - description = " - Whether to enable general purpose mouse daemon. - "; - }; - protocol = mkOption { - default = "ps/2"; - description = " - Mouse protocol to use. - "; - }; + + services.gpm = { + + enable = mkOption { + default = false; + description = '' + Whether to enable GPM, the General Purpose Mouse daemon, + which enables mouse support in virtual consoles. + ''; }; + + protocol = mkOption { + default = "ps/2"; + description = "Mouse protocol to use."; + }; + }; + }; -in + -###### implementation -let - cfg = config.services.gpm; - inherit (pkgs.lib) mkIf; + ###### implementation - gpm = pkgs.gpm; - gpmBin = "${gpm}/sbin/gpm"; + config = mkIf cfg.enable { - job = { - name = "gpm"; - job = '' - description = "General purpose mouse" + jobAttrs.gpm = + { description = "General purpose mouse"; - start on udev - stop on shutdown + startOn = "udev"; + stopOn = "shutdown"; + + exec = "${pkgs.gpm}/sbin/gpm -m /dev/input/mice -t ${cfg.protocol} -D &>/dev/null"; + }; - respawn ${gpmBin} -m /dev/input/mice -t ${cfg.protocol} -D &>/dev/null - ''; - }; -in - -mkIf cfg.enable { - require = [ - # ../upstart-jobs/default.nix # config.services.extraJobs - # /etc/security/console.perms (should be generated ?) - options - ]; - - services = { - extraJobs = [job]; }; + } diff --git a/modules/services/web-servers/jboss.nix b/modules/services/web-servers/jboss.nix index 9ead3e11e9b..9d81f75a83d 100644 --- a/modules/services/web-servers/jboss.nix +++ b/modules/services/web-servers/jboss.nix @@ -1,82 +1,81 @@ -{servicesPath, pkgs, config, ...}: +{ config, pkgs, servicesPath, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + cfg = config.services.jboss; + + jbossService = import (servicesPath + /jboss) { + inherit (pkgs) stdenv jboss su; + inherit (cfg) tempDir logDir libUrl deployDir serverDir user useJK; + }; + +in + +{ + + ###### interface options = { - services = { - jboss = { - enable = mkOption { - default = false; - description = "Whether to enable jboss"; - }; - - tempDir = mkOption { - default = "/tmp"; - description = "Location where JBoss stores its temp files"; - }; - - logDir = mkOption { - default = "/var/log/jboss"; - description = "Location of the logfile directory of JBoss"; - }; - - serverDir = mkOption { - description = "Location of the server instance files"; - default = "/var/jboss/server"; - }; - - deployDir = mkOption { - description = "Location of the deployment files"; - default = "/nix/var/nix/profiles/default/server/default/deploy/"; - }; - - libUrl = mkOption { - default = "file:///nix/var/nix/profiles/default/server/default/lib"; - description = "Location where the shared library JARs are stored"; - }; - - user = mkOption { - default = "nobody"; - description = "User account under which jboss runs."; - }; - - useJK = mkOption { - default = false; - description = "Whether to use to connector to the Apache HTTP server"; - }; + + services.jboss = { + + enable = mkOption { + default = false; + description = "Whether to enable jboss"; }; + + tempDir = mkOption { + default = "/tmp"; + description = "Location where JBoss stores its temp files"; + }; + + logDir = mkOption { + default = "/var/log/jboss"; + description = "Location of the logfile directory of JBoss"; + }; + + serverDir = mkOption { + description = "Location of the server instance files"; + default = "/var/jboss/server"; + }; + + deployDir = mkOption { + description = "Location of the deployment files"; + default = "/nix/var/nix/profiles/default/server/default/deploy/"; + }; + + libUrl = mkOption { + default = "file:///nix/var/nix/profiles/default/server/default/lib"; + description = "Location where the shared library JARs are stored"; + }; + + user = mkOption { + default = "nobody"; + description = "User account under which jboss runs."; + }; + + useJK = mkOption { + default = false; + description = "Whether to use to connector to the Apache HTTP server"; + }; + }; + }; -in -###### implementation -let -cfg = config.services.jboss; -jbossService = import (servicesPath + /jboss) { - inherit (pkgs) stdenv jboss su; - inherit (cfg) tempDir logDir libUrl deployDir serverDir user useJK; -}; + ###### implementation -in + config = mkIf config.services.jboss.enable { -mkIf config.services.jboss.enable { - require = [ - options - ]; + jobAttrs.jboss = + { description = "JBoss server"; - services = { - extraJobs = [{ - name = "jboss"; - job = '' - description \"JBoss server\" + exec = "${jbossService}/bin/control start"; + }; - stop on shutdown - - respawn ${jbossService}/bin/control start - ''; - }]; }; + } diff --git a/modules/services/web-servers/tomcat.nix b/modules/services/web-servers/tomcat.nix index b9e1c82a04e..613e1204f50 100644 --- a/modules/services/web-servers/tomcat.nix +++ b/modules/services/web-servers/tomcat.nix @@ -1,114 +1,114 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + cfg = config.services.tomcat; + +in + +{ + + ###### interface options = { - services = { - tomcat = { + + services.tomcat = { + + enable = mkOption { + default = false; + description = "Whether to enable Apache Tomcat"; + }; + + baseDir = mkOption { + default = "/var/tomcat"; + description = "Location where Tomcat stores configuration files, webapplications and logfiles"; + }; + + user = mkOption { + default = "tomcat"; + description = "User account under which Apache Tomcat runs."; + }; + + group = mkOption { + default = "tomcat"; + description = "Group account under which Apache Tomcat runs."; + }; + + javaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; + }; + + catalinaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; + }; + + sharedLibs = mkOption { + default = []; + description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications"; + }; + + commonLibs = mkOption { + default = []; + description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container"; + }; + + webapps = mkOption { + default = [ pkgs.tomcat6 ]; + description = "List containing WAR files or directories with WAR files which are web applications to be deployed on Tomcat"; + }; + + virtualHosts = mkOption { + default = []; + description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host"; + }; + + axis2 = { + enable = mkOption { default = false; - description = "Whether to enable Apache Tomcat"; + description = "Whether to enable an Apache Axis2 container"; }; - - baseDir = mkOption { - default = "/var/tomcat"; - description = "Location where Tomcat stores configuration files, webapplications and logfiles"; - }; - - user = mkOption { - default = "tomcat"; - description = "User account under which Apache Tomcat runs."; - }; - - group = mkOption { - default = "tomcat"; - description = "Group account under which Apache Tomcat runs."; - }; - - javaOpts = mkOption { - default = ""; - description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; - }; - - catalinaOpts = mkOption { - default = ""; - description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; - }; - - sharedLibs = mkOption { + + services = mkOption { default = []; - description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications"; + description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; }; - commonLibs = mkOption { - default = []; - description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container"; - }; - - webapps = mkOption { - default = [ pkgs.tomcat6 ]; - description = "List containing WAR files or directories with WAR files which are web applications to be deployed on Tomcat"; - }; - - virtualHosts = mkOption { - default = []; - description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host"; - }; - - axis2 = { - enable = mkOption { - default = false; - description = "Whether to enable an Apache Axis2 container"; - }; - - services = mkOption { - default = []; - description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; - }; - }; }; + }; + }; -in -###### implementation -let - cfg = config.services.tomcat; -in + ###### implementation -mkIf config.services.tomcat.enable { - require = [ - options - ]; + config = mkIf config.services.tomcat.enable { - services = { - extraJobs = [{ - name = "tomcat"; + users.extraGroups = singleton + { name = "tomcat"; + gid = config.ids.gids.tomcat; + }; - groups = [ - { name = "tomcat"; - gid = config.ids.gids.tomcat; - } - ]; + users.extraUsers = singleton + { name = "tomcat"; + uid = config.ids.uids.tomcat; + description = "Tomcat user"; + home = "/homeless-shelter"; + }; - users = [ - { name = "tomcat"; - uid = config.ids.uids.tomcat; - description = "Tomcat user"; - home = "/homeless-shelter"; - } - ]; - - job = '' - description "Apache Tomcat server" + jobAttrs.tomcat = + { description = "Apache Tomcat server"; - start on network-interface/started - stop on network-interfaces/stop - - start script + startOn = "network-interface/started"; + stopOn = "network-interfaces/stop"; + + preStart = + '' # Create the base directory mkdir -p ${cfg.baseDir} @@ -304,15 +304,21 @@ mkIf config.services.tomcat.enable { done '' else ""} - end script - - respawn ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh; sleep 1000d' - - stop script + ''; # */ + + exec = + '' + ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh; sleep 1000d' + ''; + + postStop = + '' echo "Stopping tomcat..." CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${pkgs.tomcat6}/bin/shutdown.sh - end script - ''; - }]; + ''; + + }; + }; + } diff --git a/modules/services/x11/xfs.nix b/modules/services/x11/xfs.nix index 07f5bac7a9a..4f4d278fadb 100644 --- a/modules/services/x11/xfs.nix +++ b/modules/services/x11/xfs.nix @@ -1,54 +1,54 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; -###### interface let - inherit (pkgs.lib) mkOption mkIf; + + configFile = ./xfs.conf; + + startingDependency = + if config.services.gw6c.enable && config.services.gw6c.autorun + then "gw6c" + else "network-interfaces"; + +in + +{ + + ###### interface options = { - services = { - xfs = { - - enable = mkOption { - default = false; - description = " - Whether to enable the X Font Server. - "; - }; + + services.xfs = { + enable = mkOption { + default = false; + description = "Whether to enable the X Font Server."; }; + }; + }; -in - -###### implementation -let - configFile = ./xfs.conf; - startingDependency = if config.services.gw6c.enable && config.services.gw6c.autorun then "gw6c" else "network-interfaces"; -in + ###### implementation -mkIf config.services.xfs.enable { + config = mkIf config.services.xfs.enable { - assertions = [ { assertion = config.fonts.enableFontDir; message = "Please enable fontDir (fonts.enableFontDir) to use xfs."; } ]; + assertions = singleton + { assertion = config.fonts.enableFontDir; + message = "Please enable fontDir (fonts.enableFontDir) to use xfs."; + }; - require = [ - options - ]; + jobAttrs.xfs = + { description = "X Font Server"; + + startOn = "${startingDependency}/started"; + stopOn = "shutdown"; - services = { + exec = "${pkgs.xorg.xfs}/bin/xfs -config ${configFile}"; + }; - extraJobs = [ (rec { - name = "xfs"; - groups = []; - users = []; - job = '' - description "X Font Server" - start on ${startingDependency}/started - stop on shutdown - - respawn ${pkgs.xorg.xfs}/bin/xfs -config ${configFile} - ''; - })]; }; + } diff --git a/modules/system/upstart-events/ctrl-alt-delete.nix b/modules/system/upstart-events/ctrl-alt-delete.nix index 6f58606b5cd..3fb6c12c25d 100644 --- a/modules/system/upstart-events/ctrl-alt-delete.nix +++ b/modules/system/upstart-events/ctrl-alt-delete.nix @@ -1,20 +1,18 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: ###### implementation { + jobAttrs.ctrl_alt_delete = + { name = "ctrl-alt-delete"; - services = { - extraJobs = [{ - name = "ctrl-alt-delete"; - - job = '' - on ctrlaltdel - - script - shutdown -r now 'Ctrl-Alt-Delete pressed' - end script - ''; - }]; - }; + startOn = "ctrlaltdel"; + + task = true; + + script = + '' + shutdown -r now 'Ctrl-Alt-Delete pressed' + ''; + }; } diff --git a/modules/system/upstart-events/halt.nix b/modules/system/upstart-events/halt.nix index 0713aa70ab7..c7721eb3e28 100644 --- a/modules/system/upstart-events/halt.nix +++ b/modules/system/upstart-events/halt.nix @@ -1,19 +1,20 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; ###### implementation - let inherit (pkgs) bash utillinux; - jobFun = event : { - name = "sys-" + event; - - job = '' - start on ${event} - - script + jobFun = event: + { startOn = event; + + task = true; + + script = + '' set +e # continue in case of errors exec < /dev/tty1 > /dev/tty1 2>&1 @@ -109,16 +110,12 @@ let sleep 1 exec halt -f -p fi - - end script - ''; - }; + ''; + }; in - { - services = { - extraJobs = map jobFun ["reboot" "halt" "system-halt" "power-off"]; - }; + jobAttrs = listToAttrs (map (n: nameValuePair "sys-${n}" (jobFun n)) + [ "reboot" "halt" "system-halt" "power-off" ] ); } diff --git a/modules/system/upstart-events/maintenance-shell.nix b/modules/system/upstart-events/maintenance-shell.nix index 8481f4283f5..6c9d32b625c 100644 --- a/modules/system/upstart-events/maintenance-shell.nix +++ b/modules/system/upstart-events/maintenance-shell.nix @@ -1,24 +1,22 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: ###### implementation { - services = { - extraJobs = [{ - name = "maintenance-shell"; - - job = '' - start on maintenance - start on stalled - - script - exec < /dev/tty1 > /dev/tty1 2>&1 - echo \"\" - echo \"<<< MAINTENANCE SHELL >>>\" - echo \"\" - exec ${pkgs.bash}/bin/sh - end script - ''; - }]; - }; + jobAttrs.maintenance_shell = + { name = "maintenance-shell"; + + startOn = [ "maintenance" "stalled" ]; + + task = true; + + script = + '' + exec < /dev/tty1 > /dev/tty1 2>&1 + echo \ + echo "<<< MAINTENANCE SHELL >>>" + echo "" + exec ${pkgs.bash}/bin/sh + ''; + }; } diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index a87c6e5ee2c..f55c7ddcf3d 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -327,7 +327,7 @@ in } ]; - # see test/test-upstart-job.sh (!!! check whether this still works) + # !!! fix this tests.upstartJobs = { recurseForDerivations = true; } // builtins.listToAttrs (map (job: { name = removePrefix "upstart-" job.name; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index ec9836e09e3..86eaaf0c429 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -1,117 +1,9 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; let -###### interface - inherit (pkgs.lib) mkOption types; - - options = { - - fileSystems = mkOption { - example = [ - { mountPoint = "/"; - device = "/dev/hda1"; - } - { mountPoint = "/data"; - device = "/dev/hda2"; - fsType = "ext3"; - options = "data=journal"; - } - { mountPoint = "/bigdisk"; - label = "bigdisk"; - } - ]; - description = " - The file systems to be mounted. It must include an entry for - the root directory (mountPoint = \"/\"). Each - entry in the list is an attribute set with the following fields: - mountPoint, device, - fsType (a file system type recognised by - mount; defaults to - \"auto\"), and options - (the mount options passed to mount using the - flag; defaults to \"defaults\"). - - Instead of specifying device, you can also - specify a volume label (label) for file - systems that support it, such as ext2/ext3 (see mke2fs - -L). - - autocreate forces mountPoint to be created with - mkdir -p . - "; - type = types.nullOr (types.list types.optionSet); - - options = { - - mountPoint = mkOption { - example = "/mnt/usb"; - type = types.uniq types.string; - description = " - Location of the mounted the file system. - "; - }; - - device = mkOption { - default = null; - example = "/dev/sda"; - type = types.uniq (types.nullOr types.string); - description = " - Location of the device. - "; - }; - - label = mkOption { - default = null; - example = "root-partition"; - type = types.uniq (types.nullOr types.string); - description = " - Label of the device (if any). - "; - }; - - fsType = mkOption { - default = "auto"; - example = "ext3"; - type = types.uniq types.string; - description = " - Type of the file system. - "; - }; - - options = mkOption { - default = "defaults,relatime"; - example = "data=journal"; - type = types.string; - merge = pkgs.lib.concatStringsSep ","; - description = " - Option used to mount the file system. - "; - }; - - autocreate = mkOption { - default = false; - type = types.bool; - description = " - Automatically create the mount point defined in - . - "; - }; - }; - }; - - system.sbin.mount = mkOption { - internal = true; - default = pkgs.utillinuxng; - description = " - Package containing mount and umount. - "; - }; - - }; - -###### implementation - fileSystems = config.fileSystems; mountPoints = map (fs: fs.mountPoint) fileSystems; devices = map (fs: if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fileSystems; @@ -120,12 +12,8 @@ let autocreates = map (fs: fs.autocreate) fileSystems; mount = config.system.sbin.mount; - job = '' - start on startup - start on new-devices - start on ip-up - - script + task = + '' PATH=${pkgs.e2fsprogs}/sbin:${pkgs.utillinuxng}/sbin:$PATH mountPoints=(${toString mountPoints}) @@ -218,25 +106,141 @@ let if ${mount}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint"; then newDevices=1 fi - + done done + ''; - end script - ''; in { - require = [options]; + + ###### interface + + options = { + + fileSystems = mkOption { + example = [ + { mountPoint = "/"; + device = "/dev/hda1"; + } + { mountPoint = "/data"; + device = "/dev/hda2"; + fsType = "ext3"; + options = "data=journal"; + } + { mountPoint = "/bigdisk"; + label = "bigdisk"; + } + ]; + + description = " + The file systems to be mounted. It must include an entry for + the root directory (mountPoint = \"/\"). Each + entry in the list is an attribute set with the following fields: + mountPoint, device, + fsType (a file system type recognised by + mount; defaults to + \"auto\"), and options + (the mount options passed to mount using the + flag; defaults to \"defaults\"). + + Instead of specifying device, you can also + specify a volume label (label) for file + systems that support it, such as ext2/ext3 (see mke2fs + -L). + + autocreate forces mountPoint to be created with + mkdir -p . + "; + + type = types.nullOr (types.list types.optionSet); + + options = { + + mountPoint = mkOption { + example = "/mnt/usb"; + type = types.uniq types.string; + description = " + Location of the mounted the file system. + "; + }; + + device = mkOption { + default = null; + example = "/dev/sda"; + type = types.uniq (types.nullOr types.string); + description = " + Location of the device. + "; + }; + + label = mkOption { + default = null; + example = "root-partition"; + type = types.uniq (types.nullOr types.string); + description = " + Label of the device (if any). + "; + }; + + fsType = mkOption { + default = "auto"; + example = "ext3"; + type = types.uniq types.string; + description = " + Type of the file system. + "; + }; + + options = mkOption { + default = "defaults,relatime"; + example = "data=journal"; + type = types.string; + merge = pkgs.lib.concatStringsSep ","; + description = " + Option used to mount the file system. + "; + }; + + autocreate = mkOption { + default = false; + type = types.bool; + description = " + Automatically create the mount point defined in + . + "; + }; + }; + }; - services = { - extraJobs = [{ - name = "filesystems"; - inherit job; - }]; + system.sbin.mount = mkOption { + internal = true; + default = pkgs.utillinuxng; + description = " + Package containing mount and umount. + "; + }; + + }; + + + ###### implementation + + config = { + + # Add the mount helpers to the system path so that `mount' can find them. + environment.systemPackages = [pkgs.ntfs3g pkgs.mount_cifs pkgs.nfsUtils]; + + jobAttrs.filesystems = + { startOn = [ "startup" "new-devices" "ip-up" ]; + + script = task; + + task = true; + }; + }; - # Add the mount helpers to the system path so that `mount' can find them. - environment.systemPackages = [pkgs.ntfs3g pkgs.mount_cifs pkgs.nfsUtils]; } diff --git a/modules/tasks/lvm.nix b/modules/tasks/lvm.nix index 1d16da59bef..28fb293821a 100644 --- a/modules/tasks/lvm.nix +++ b/modules/tasks/lvm.nix @@ -1,27 +1,18 @@ -{pkgs, config, ...}: - -###### implementation - -let - modprobe = config.system.sbin.modprobe; - -in - +{ config, pkgs, ... }: { - services = { - extraJobs = [{ - name = "lvm"; - - job = '' - start on udev - #start on new-devices + ###### implementation - script + config = { + jobAttrs.lvm = + { startOn = " udev"; # !!! or on new-devices + + script = + '' # Load the device mapper. - ${modprobe}/sbin/modprobe dm_mod || true + ${config.system.sbin.modprobe}/sbin/modprobe dm_mod || true ${pkgs.devicemapper}/sbin/dmsetup mknodes # Scan for block devices that might contain LVM physical volumes @@ -33,9 +24,11 @@ in ${pkgs.lvm2}/sbin/vgchange --available y initctl emit new-devices - - end script - ''; - }]; + ''; + + task = true; + }; + }; + } diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 6c77a40ae5d..713eed22e88 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -132,7 +132,6 @@ in pkgs.wirelesstools ]; - jobs = pkgs.lib.singleton { name = "network-interfaces"; diff --git a/modules/tasks/swraid.nix b/modules/tasks/swraid.nix index a0a25efa354..d9419fadb11 100644 --- a/modules/tasks/swraid.nix +++ b/modules/tasks/swraid.nix @@ -1,4 +1,4 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: ###### implementation @@ -12,16 +12,11 @@ in { - services = { - extraJobs = [{ - name = "swraid"; - - job = '' - start on udev - #start on new-devices - - script + jobAttrs.swraid = + { startOn = "udev"; # !!! or on "new-devices" + script = + '' # Load the necessary RAID personalities. # !!! hm, doesn't the kernel load these automatically? for mod in raid0 raid1 raid5; do @@ -35,10 +30,9 @@ in ${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan initctl emit new-devices - - end script - - ''; - }]; - }; + ''; + + task = true; + }; + }