diff --git a/lib/eval-config.nix b/lib/eval-config.nix index e3bccb775aa..7697f44a7e5 100644 --- a/lib/eval-config.nix +++ b/lib/eval-config.nix @@ -11,7 +11,7 @@ , modules }: -let extraArgs_ = extraArgs; pkgs_ = pkgs; in +let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in rec { @@ -39,7 +39,8 @@ rec { # Import Nixpkgs, allowing the NixOS option nixpkgs.config to # specify the Nixpkgs configuration (e.g., to set package options # such as firefox.enableGeckoMediaPlayer, or to apply global - # overrides such as changing GCC throughout the system). This is + # overrides such as changing GCC throughout the system), and the + # option nixpkgs.system to override the platform type. This is # tricky, because we have to prevent an infinite recursion: "pkgs" # is passed as an argument to NixOS modules, but the value of "pkgs" # depends on config.nixpkgs.config, which we get from the modules. @@ -50,12 +51,13 @@ rec { then pkgs_ else import nixpkgs ( let + system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_; nixpkgsOptions = (import ./eval-config.nix { inherit system nixpkgs services extraArgs modules; # For efficiency, leave out most NixOS modules; they don't # define nixpkgs.config, so it's pointless to evaluate them. baseModules = [ ../modules/misc/nixpkgs.nix ]; - pkgs = import nixpkgs { inherit system; config = {}; }; + pkgs = import nixpkgs { system = system_; config = {}; }; }).optionDefinitions.nixpkgs; in { diff --git a/modules/config/fonts.nix b/modules/config/fonts.nix index 8b7ba6fab94..bb75a1e29ab 100644 --- a/modules/config/fonts.nix +++ b/modules/config/fonts.nix @@ -98,7 +98,7 @@ in ###### implementation let - inherit (pkgs) builderDefs ttmkfdir; + inherit (pkgs) builderDefs; inherit (pkgs.xorg) mkfontdir mkfontscale fontalias; fontDirs = config.fonts.fonts; @@ -107,7 +107,7 @@ let localDefs = with builderDefs; builderDefs.passthru.function rec { src = "";/* put a fetchurl here */ - buildInputs = [mkfontdir mkfontscale ttmkfdir]; + buildInputs = [mkfontdir mkfontscale]; configureFlags = []; inherit fontDirs; installPhase = fullDepEntry (" @@ -135,13 +135,6 @@ let rm fonts.alias mkfontdir mkfontscale - mv fonts.scale fonts.scale.old - mv fonts.dir fonts.dir.old - ttmkfdir - cat fonts.scale.old >> fonts.scale - cat fonts.dir.old >> fonts.dir - rm fonts.dir.old - rm fonts.scale.old cat \$( find ${fontalias}/ -name fonts.alias) >fonts.alias ") ["minInit" "addInputs"]; }; diff --git a/modules/installer/tools/nixos-option.sh b/modules/installer/tools/nixos-option.sh index fc4380d00c4..456e2b275d0 100644 --- a/modules/installer/tools/nixos-option.sh +++ b/modules/installer/tools/nixos-option.sh @@ -66,13 +66,14 @@ for arg; do sarg="$arg" while test "$sarg" != "-"; do case $sarg in - --*) longarg=$arg;; + --*) longarg=$arg; sarg="--";; -d*) longarg="$longarg --description";; -v*) longarg="$longarg --value";; -l*) longarg="$longarg --lookup";; -i*) longarg="$longarg --install";; -*) usage;; esac + # remove the first letter option sarg="-${sarg#??}" done ;; diff --git a/modules/misc/deployment.nix b/modules/misc/deployment.nix new file mode 100644 index 00000000000..08559cc2a16 --- /dev/null +++ b/modules/misc/deployment.nix @@ -0,0 +1,23 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + options = { + + deployment = mkOption { + description = '' + This option captures various custom attributes related to the configuration of the system, which + are not directly used for building a system configuration. Usually these attributes + are used by external tooling, such as the nixos-deploy-network tool or the Disnix Avahi + publisher. + ''; + default = {}; + example = { + description = "My production machine"; + hostname = "my.test.org"; + country = "NL"; + }; + }; + }; +} diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index 2db841194e3..f8219c23068 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -57,6 +57,7 @@ in cups = 36; foldingAtHome = 37; sabnzbd = 38; + kdm = 39; # When adding a uid, make sure it doesn't match an existing gid. nixbld = 30000; # start of range of uids diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 2fb61f686f0..154c619bd36 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -13,5 +13,16 @@ ''; }; + nixpkgs.system = pkgs.lib.mkOption { + default = ""; + description = '' + Specifies the Nix platform type for which NixOS should be built. + If unset, it defaults to the platform type of your host system + (${builtins.currentSystem}). + Specifying this option is useful when doing distributed + multi-platform deployment, or when building virtual machines. + ''; + }; + }; } diff --git a/modules/module-list.nix b/modules/module-list.nix index 1364b28182d..8c927aa6142 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -24,6 +24,7 @@ ./installer/tools/tools.nix ./misc/assertions.nix ./misc/check-config.nix + ./misc/deployment.nix ./misc/ids.nix ./misc/locate.nix ./misc/nixpkgs.nix diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 50768635d36..c301ffde73a 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -68,7 +68,7 @@ fi alias ls="ls --color=tty" alias ll="ls -l" alias l="ls -alh" -alias which="type -p" +alias which="type -P" # The "non-interactive" Bash build does not support programmable # completion so check whether it's available. diff --git a/modules/services/backup/mysql-backup.nix b/modules/services/backup/mysql-backup.nix index b6d42b8782a..7c091fcfe26 100644 --- a/modules/services/backup/mysql-backup.nix +++ b/modules/services/backup/mysql-backup.nix @@ -6,10 +6,10 @@ let inherit (pkgs) mysql gzip; - location = config.services.mysqlBackup.location ; - + cfg = config.services.mysqlBackup ; + location = cfg.location ; mysqlBackupCron = db : '' - ${config.services.mysqlBackup.period} ${config.services.mysqlBackup.user} ${mysql}/bin/mysqldump ${db} | ${gzip}/bin/gzip -c > ${location}/${db}.gz + ${cfg.period} ${cfg.user} ${mysql}/bin/mysqldump ${if cfg.singleTransaction then "--single-transaction" else ""} ${db} | ${gzip}/bin/gzip -c > ${location}/${db}.gz ''; in @@ -55,6 +55,13 @@ in Location to put the gzipped MySQL database dumps. ''; }; + + singleTransaction = mkOption { + default = false; + description = '' + Whether to create database dump in a single transaction + ''; + }; }; }; diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index 6d58b757421..56e98e4a3f9 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -9,22 +9,16 @@ let # see description of extraPlugins postgresqlAndPlugins = pg: if cfg.extraPlugins == [] then pg - else pkgs.runCommand "postgresql-and-plugins" { - inherit (pkgs) perl; - inherit pg; - # used by env builder: + else pkgs.buildEnv { + name = "postgresql-and-plugins"; paths = [ pg ] ++ cfg.extraPlugins; - pathsToLink = "/"; - ignoreCollisions = 0; - manifest = null; - } - '' - perlScript=${pkgs.buildEnvScript} - mkdir -p $out/bin - $perl/bin/perl $perlScript - rm $out/bin/{pg_config,postgres,pg_ctl} - cp --target-directory=$out/bin $pg/bin/{postgres,pg_config,pg_ctl} - ''; + postBuild = + '' + mkdir -p $out/bin + rm $out/bin/{pg_config,postgres,pg_ctl} + cp --target-directory=$out/bin ${pg}/bin/{postgres,pg_config,pg_ctl} + ''; + }; postgresql = postgresqlAndPlugins pkgs.postgresql; diff --git a/modules/services/misc/disnix.nix b/modules/services/misc/disnix.nix index 09b9cf8fe08..dee19b0577a 100644 --- a/modules/services/misc/disnix.nix +++ b/modules/services/misc/disnix.nix @@ -6,7 +6,14 @@ with pkgs.lib; let cfg = config.services.disnix; - + + disnix_activation_scripts = pkgs.disnix_activation_scripts.override (origArgs: { + enableApacheWebApplication = config.services.httpd.enable; + enableAxis2WebService = config.services.tomcat.axis2.enable; + enableEjabberdDump = config.services.ejabberd.enable; + enableMySQLDatabase = config.services.mysql.enable; + enableTomcatWebApplication = config.services.tomcat.enable; + }); in { @@ -20,7 +27,17 @@ in enable = mkOption { default = false; description = "Whether to enable Disnix"; - }; + }; + + useWebServiceInterface = mkOption { + default = false; + description = "Whether to enable the DisnixWebService interface running on Apache Tomcat"; + }; + + publishAvahi = mkOption { + default = false; + description = "Whether to publish capabilities/properties as a Disnix service through Avahi"; + }; }; @@ -31,11 +48,19 @@ in config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.disnix ]; + environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService; services.dbus.enable = true; services.dbus.packages = [ pkgs.disnix ]; + services.tomcat.enable = cfg.useWebServiceInterface; + services.tomcat.extraGroups = [ "disnix" ]; + services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} "; + services.tomcat.sharedLibs = [] + ++ optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar" + ++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar"; + services.tomcat.webapps = [] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService; + users.extraGroups = singleton { name = "disnix"; gid = config.ids.gids.disnix; @@ -47,14 +72,37 @@ in startOn = "started dbus"; script = - '' - export PATH=/var/run/current-system/sw/bin:/var/run/current-system/sw/sbin + '' + export PATH=/var/run/current-system/sw/bin:/var/run/current-system/sw/sbin export HOME=/root - - ${pkgs.disnix}/bin/disnix-service --activation-modules-dir=${pkgs.disnix_activation_scripts}/libexec/disnix/activation-scripts + + ${pkgs.disnix}/bin/disnix-service --activation-modules-dir=${disnix_activation_scripts}/libexec/disnix/activation-scripts ''; }; + } // + mkIf cfg.publishAvahi { + + services.avahi.enable = true; + + jobs.disnixAvahi = + { description = "Disnix Avahi publisher"; + + startOn = "started avahi-daemon"; + + exec = + '' + ${pkgs.avahi}/bin/avahi-publish-service disnix-$(${pkgs.nettools}/bin/hostname) _disnix._tcp 22 \ + "hostname=\"$(${pkgs.nettools}/bin/hostname)\"" \ + "system=\"$(uname -m)-linux\"" \ + "mem=$(grep 'MemTotal:' /proc/meminfo | sed -e 's/kB//' -e 's/MemTotal://' -e 's/ //g')" \ + ${optionalString (cfg.useWebServiceInterface) ''"targetEPR=\"http://(${pkgs.nettools}/bin/hostname):8080/DisnixWebService/services/DisnixWebService\""''} \ + ${optionalString (config.services.httpd.enable) ''"documentRoot=\"${config.services.httpd.documentRoot}\""''} \ + ${optionalString (config.services.mysql.enable) ''"mysqlPort=3306"''} \ + ${optionalString (config.services.tomcat.enable) ''"tomcatPort=8080"''} \ + "supportedTypes=[$(for i in ${disnix_activation_scripts}/libexec/disnix/activation-scripts/*; do echo -n " \"$(basename $i)\""; done) ]" \ + ${concatMapStrings (deploymentAttrName: let deploymentAttrValue = getAttr deploymentAttrName (config.deployment); in ''${deploymentAttrName}=\"${deploymentAttrValue}\" '' ) (attrNames (config.deployment))} + ''; + }; }; - } diff --git a/modules/services/monitoring/monit.nix b/modules/services/monitoring/monit.nix index 35f483411b2..40ad8456d7c 100644 --- a/modules/services/monitoring/monit.nix +++ b/modules/services/monitoring/monit.nix @@ -20,7 +20,7 @@ in description = "monit.conf content"; }; startOn = mkOption { - default = "network-interfaces/started"; + default = "started network-interfaces"; description = "What Monit supposes to be already present"; }; }; diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix index 603e63f6005..290622b0997 100644 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ b/modules/services/network-filesystems/nfs-kernel.nix @@ -133,7 +133,15 @@ in startOn = "started nfs-kernel-exports and started nfs-kernel-mountd and started nfs-kernel-statd and started portmap"; stopOn = "stopping nfs-kernel-exports"; - preStart = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} ${builtins.toString cfg.server.nproc}"; + preStart = + '' + # Create a state directory required by NFSv4. + mkdir -p /var/lib/nfs/v4recovery + + ${pkgs.nfsUtils}/sbin/rpc.nfsd \ + ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} \ + ${builtins.toString cfg.server.nproc} + ''; postStop = "${pkgs.nfsUtils}/sbin/rpc.nfsd 0"; }; diff --git a/modules/services/networking/dhclient.nix b/modules/services/networking/dhclient.nix index bd3f781c19a..454bd361b12 100644 --- a/modules/services/networking/dhclient.nix +++ b/modules/services/networking/dhclient.nix @@ -8,7 +8,7 @@ let # Don't start dhclient on explicitly configured interfaces. ignoredInterfaces = - map (i: i.name) (lib.filter (i: i ? ipAddress) config.networking.interfaces); + map (i: i.name) (lib.filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces); stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant. diff --git a/modules/services/web-servers/tomcat.nix b/modules/services/web-servers/tomcat.nix index e63abfb15d2..83b95655011 100644 --- a/modules/services/web-servers/tomcat.nix +++ b/modules/services/web-servers/tomcat.nix @@ -26,6 +26,12 @@ in description = "Location where Tomcat stores configuration files, webapplications and logfiles"; }; + extraGroups = mkOption { + default = []; + example = [ "users" ]; + description = "Defines extra groups to which the tomcat user belongs."; + }; + user = mkOption { default = "tomcat"; description = "User account under which Apache Tomcat runs."; @@ -104,6 +110,7 @@ in uid = config.ids.uids.tomcat; description = "Tomcat user"; home = "/homeless-shelter"; + extraGroups = cfg.extraGroups; }; jobs.tomcat = diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index 1fa5b4f210f..2c5a720f815 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -106,6 +106,13 @@ in security.pam.services = [ { name = "kde"; } ]; + users.extraUsers = singleton + { name = "kdm"; + uid = config.ids.uids.kdm; + description = "kdm user"; + home = "/tmp/kdm"; + }; + }; } diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 562a945d832..640ef0821fc 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -8,6 +8,8 @@ let cfg = config.networking; + ifconfig = "${nettools}/sbin/ifconfig"; + in { @@ -113,6 +115,15 @@ in ''; }; + macAddress = mkOption { + default = ""; + example = "00:11:22:33:44:55"; + type = types.string; + description = '' + MAC address of the interface. Leave empty to use the default. + ''; + }; + }; }; @@ -155,9 +166,19 @@ in export PATH=${config.system.sbin.modprobe}/sbin:$PATH modprobe af_packet || true + ${pkgs.lib.concatMapStrings (i: + if i.macAddress != "" then + '' + echo "Configuring interface ${i.name}..." + ${ifconfig} "${i.name}" down || true + ${ifconfig} "${i.name}" hw ether "${i.macAddress}" || true + '' + else "") cfg.interfaces + } + for i in $(cd /sys/class/net && ls -d *); do echo "Bringing up network device $i..." - ${nettools}/sbin/ifconfig $i up || true + ${ifconfig} $i up || true done # Configure the manually specified interfaces. @@ -169,7 +190,7 @@ in if test -n "${i.subnetMask}"; then extraFlags="$extraFlags netmask ${i.subnetMask}" fi - ${nettools}/sbin/ifconfig "${i.name}" "${i.ipAddress}" $extraFlags || true + ${ifconfig} "${i.name}" "${i.ipAddress}" $extraFlags || true '' else "") cfg.interfaces} @@ -202,7 +223,7 @@ in '' #for i in $(cd /sys/class/net && ls -d *); do # echo "Taking down network device $i..." - # ${nettools}/sbin/ifconfig $i down || true + # ${ifconfig} $i down || true #done ''; }; diff --git a/modules/tasks/tty-backgrounds.nix b/modules/tasks/tty-backgrounds.nix index 8d079edc934..d376c6a4b89 100644 --- a/modules/tasks/tty-backgrounds.nix +++ b/modules/tasks/tty-backgrounds.nix @@ -86,7 +86,8 @@ in assertions = singleton { assertion = kernelPackages.splashutils != null; - message = "kernelPackages.splashutils may not be false"; + message = "The kernelPackages does not provide splashutils, as required by ttyBackgrounds. " + + "Either provide kernelPackages with splashutils, or disable ttyBackgrounds."; }; services.ttyBackgrounds.specificThemes = singleton