From f729f12e4e8f03540e33aaf07292934747417787 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Sep 2010 15:41:38 +0000 Subject: [PATCH] Some cleanups in the activation script: * Moved some scriptlets to the appropriate modules. * Put the scriptlet that sets the default path at the start, since it never makes sense not to have it there. It no longer needs to be declared as a dependency. * If a scriptlet has no dependencies, it can be denoted as a plain string (i.e., `noDepEntry' is not needed anymore). svn path=/nixos/trunk/; revision=23762 --- modules/config/users-groups.nix | 24 +- modules/programs/bash/bash.nix | 17 +- modules/security/policykit.nix | 4 +- modules/security/polkit.nix | 18 +- modules/security/setuid-wrappers.nix | 4 +- modules/services/backup/mysql-backup.nix | 21 +- modules/services/backup/postgresql-backup.nix | 25 +- modules/services/backup/sitecopy-backup.nix | 75 ++-- modules/services/misc/nix-daemon.nix | 29 +- modules/services/monitoring/systemhealth.nix | 57 +-- .../system/activation/activation-script.nix | 324 +++++++----------- modules/system/boot/modprobe.nix | 9 + modules/system/etc/etc.nix | 81 ++--- modules/tasks/network-interfaces.nix | 15 +- modules/virtualisation/xen.nix | 2 +- 15 files changed, 346 insertions(+), 359 deletions(-) diff --git a/modules/config/users-groups.nix b/modules/config/users-groups.nix index 447dc96f818f..6d57209a4ac8 100644 --- a/modules/config/users-groups.nix +++ b/modules/config/users-groups.nix @@ -156,7 +156,23 @@ in config = { - system.activationScripts.users = fullDepEntry + system.activationScripts.rootPasswd = stringAfter [ "etc" ] + '' + # If there is no password file yet, create a root account with an + # empty password. + if ! test -e /etc/passwd; then + rootHome=/root + touch /etc/passwd; chmod 0644 /etc/passwd + touch /etc/group; chmod 0644 /etc/group + touch /etc/shadow; chmod 0600 /etc/shadow + # Can't use useradd, since it complains that it doesn't know us + # (bootstrap problem!). + echo "root:x:0:0:System administrator:$rootHome:${config.users.defaultUserShell}" >> /etc/passwd + echo "root::::::::" >> /etc/shadow + fi + ''; + + system.activationScripts.users = stringAfter [ "groups" ] '' echo "updating users..." @@ -206,9 +222,9 @@ in fi done - '' [ "groups" ]; + ''; - system.activationScripts.groups = fullDepEntry + system.activationScripts.groups = stringAfter [ "rootPasswd" "binsh" "etc" "var" ] '' echo "updating groups..." @@ -231,7 +247,7 @@ in done < ${location}/${db}.gz - ''; + postgresqlBackupCron = db: + '' + ${config.services.postgresqlBackup.period} root ${postgresql}/bin/pg_dump ${db} | ${gzip}/bin/gzip -c > ${location}/${db}.gz + ''; in @@ -52,14 +54,13 @@ in }; config = mkIf config.services.postgresqlBackup.enable { - services.cron = { - systemCronJobs = map postgresqlBackupCron config.services.postgresqlBackup.databases; - }; + services.cron.systemCronJobs = map postgresqlBackupCron config.services.postgresqlBackup.databases; - system.activationScripts.postgresqlBackup = pkgs.stringsWithDeps.fullDepEntry '' - mkdir -m 0700 -p ${config.services.postgresqlBackup.location} - chown root ${config.services.postgresqlBackup.location} - '' [ "stdio" "defaultPath" "systemConfig" "users" ]; + system.activationScripts.postgresqlBackup = stringAfter [ "stdio" "defaultPath" "systemConfig" "users" ] + '' + mkdir -m 0700 -p ${config.services.postgresqlBackup.location} + chown root ${config.services.postgresqlBackup.location} + ''; }; } diff --git a/modules/services/backup/sitecopy-backup.nix b/modules/services/backup/sitecopy-backup.nix index 310a5e78b080..f30002b6ee86 100644 --- a/modules/services/backup/sitecopy-backup.nix +++ b/modules/services/backup/sitecopy-backup.nix @@ -1,7 +1,8 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; let - inherit (pkgs.lib) mkOption mkIf singleton concatStrings; inherit (pkgs) sitecopy; stateDir = "/var/spool/sitecopy"; @@ -63,45 +64,41 @@ in config = mkIf config.services.sitecopy.enable { environment.systemPackages = [ sitecopy ]; - services.cron = { - systemCronJobs = map sitecopyCron config.services.sitecopy.backups; - }; + services.cron.systemCronJobs = map sitecopyCron config.services.sitecopy.backups; + system.activationScripts.sitecopyBackup = stringAfter [ "stdio" "systemConfig" "users" ] + '' + mkdir -m 0700 -p ${stateDir} + chown root ${stateDir} + touch ${stateDir}/sitecopy.secrets + chown root ${stateDir}/sitecopy.secrets - system.activationScripts.sitecopyBackup = - pkgs.stringsWithDeps.fullDepEntry '' - mkdir -m 0700 -p ${stateDir} - chown root ${stateDir} - touch ${stateDir}/sitecopy.secrets - chown root ${stateDir}/sitecopy.secrets - - ${pkgs.lib.concatStrings (map ( b: '' - unset secrets - unset secret - secrets=`grep '^${b.server}' ${stateDir}/sitecopy.secrets | head -1` - secret=($secrets) - cat > ${stateDir}/${b.name}.conf << EOF - site ${b.name} - server ${b.server} - protocol ${b.protocol} - username ''${secret[1]} - password ''${secret[2]} - local ${b.local} - remote ${b.remote} - symlinks ${b.symlinks} - ${if b.https then "http secure" else ""} - EOF - chmod 0600 ${stateDir}/${b.name}.conf - if ! test -e ${stateDir}/${b.name} ; then - echo " * Initializing sitecopy '${b.name}'" - ${sitecopy}/bin/sitecopy --storepath=${stateDir} --rcfile=${stateDir}/${b.name}.conf --initialize ${b.name} - else - echo " * Sitecopy '${b.name}' already initialized" - fi - '' ) config.services.sitecopy.backups - )} - - '' [ "stdio" "defaultPath" "systemConfig" "users" ] ; + ${pkgs.lib.concatStrings (map ( b: '' + unset secrets + unset secret + secrets=`grep '^${b.server}' ${stateDir}/sitecopy.secrets | head -1` + secret=($secrets) + cat > ${stateDir}/${b.name}.conf << EOF + site ${b.name} + server ${b.server} + protocol ${b.protocol} + username ''${secret[1]} + password ''${secret[2]} + local ${b.local} + remote ${b.remote} + symlinks ${b.symlinks} + ${if b.https then "http secure" else ""} + EOF + chmod 0600 ${stateDir}/${b.name}.conf + if ! test -e ${stateDir}/${b.name} ; then + echo " * Initializing sitecopy '${b.name}'" + ${sitecopy}/bin/sitecopy --storepath=${stateDir} --rcfile=${stateDir}/${b.name}.conf --initialize ${b.name} + else + echo " * Sitecopy '${b.name}' already initialized" + fi + '' ) config.services.sitecopy.backups + )} + ''; }; } diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index a9a0bc70f1ec..2be7789cc5fa 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -277,7 +277,7 @@ in # do this, mount the remote file system on a subdirectory of # /var/run/nix/remote-stores. export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix - '' + '' # */ + optionalString config.nix.distributedBuilds '' export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl export NIX_REMOTE_SYSTEMS=/etc/nix.machines @@ -292,6 +292,33 @@ in users.extraUsers = map makeNixBuildUser (pkgs.lib.range 1 config.nix.nrBuildUsers); + system.activationScripts.nix = stringAfter [ "etc" "users" ] + '' + # Set up Nix. + mkdir -p /nix/etc/nix + ln -sfn /etc/nix.conf /nix/etc/nix/nix.conf + chown root.nixbld /nix/store + chmod 1775 /nix/store + + # Nix initialisation. + mkdir -m 0755 -p \ + /nix/var/nix/gcroots \ + /nix/var/nix/temproots \ + /nix/var/nix/manifests \ + /nix/var/nix/userpool \ + /nix/var/nix/profiles \ + /nix/var/nix/db \ + /nix/var/log/nix/drvs \ + /nix/var/nix/channel-cache \ + /nix/var/nix/chroots + mkdir -m 1777 -p /nix/var/nix/gcroots/per-user + mkdir -m 1777 -p /nix/var/nix/profiles/per-user + mkdir -m 1777 -p /nix/var/nix/gcroots/tmp + + ln -sf /nix/var/nix/profiles /nix/var/nix/gcroots/ + ln -sf /nix/var/nix/manifests /nix/var/nix/gcroots/ + ''; + }; } diff --git a/modules/services/monitoring/systemhealth.nix b/modules/services/monitoring/systemhealth.nix index 8d531b526f3a..85f297cfb71b 100644 --- a/modules/services/monitoring/systemhealth.nix +++ b/modules/services/monitoring/systemhealth.nix @@ -75,43 +75,44 @@ in config = mkIf cfg.enable { services.cron.systemCronJobs = [ cronJob ]; - system.activationScripts.systemhealth = fullDepEntry '' - mkdir -p ${rrdDir} ${htmlDir} - chown wwwrun.wwwrun ${rrdDir} ${htmlDir} + system.activationScripts.systemhealth = stringAfter [ "var" ] + '' + mkdir -p ${rrdDir} ${htmlDir} + chown wwwrun.wwwrun ${rrdDir} ${htmlDir} - cat >${configFile} << EOF - [paths] - rrdtool = ${pkgs.rrdtool}/bin/rrdtool - loadavg_rrd = loadavg - ps = /var/run/current-system/sw/bin/ps - df = /var/run/current-system/sw/bin/df - meminfo_rrd = meminfo - uptime_rrd = uptime - rrd_path = ${rrdDir} - png_path = ${htmlDir} + cat >${configFile} << EOF + [paths] + rrdtool = ${pkgs.rrdtool}/bin/rrdtool + loadavg_rrd = loadavg + ps = /var/run/current-system/sw/bin/ps + df = /var/run/current-system/sw/bin/df + meminfo_rrd = meminfo + uptime_rrd = uptime + rrd_path = ${rrdDir} + png_path = ${htmlDir} - [processes] + [processes] - [interfaces] - ${interfacesSection} + [interfaces] + ${interfacesSection} - [drives] - ${drivesSection} + [drives] + ${drivesSection} - [graphs] - width = 400 - time = ['-3hours', '-32hours', '-8days', '-5weeks', '-13months'] - height = 100 + [graphs] + width = 400 + time = ['-3hours', '-32hours', '-8days', '-5weeks', '-13months'] + height = 100 - [external] + [external] - EOF + EOF - chown wwwrun.wwwrun ${configFile} + chown wwwrun.wwwrun ${configFile} - ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --check" wwwrun - ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --html" wwwrun - '' [ "var" ]; + ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --check" wwwrun + ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --html" wwwrun + ''; services.httpd.extraSubservices = [ { function = f: { diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix index 8924041ae600..222addb58d27 100644 --- a/modules/system/activation/activation-script.nix +++ b/modules/system/activation/activation-script.nix @@ -1,220 +1,140 @@ # generate the script used to activate the configuration. -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; let - inherit (pkgs.lib) mkOption mergeTypedOption mergeAttrs - mapAttrs addErrorContext fold id filter textClosureMap noDepEntry - fullDepEntry; - inherit (builtins) attrNames; addAttributeName = mapAttrs (a: v: v // { - text = '' - #### actionScripts snippet ${a} : - # ======================================== - ${v.text} - ''; - }); - - defaultScripts = { - - systemConfig = noDepEntry '' - systemConfig="$1" - if test -z "$systemConfig"; then - systemConfig="/system" # for the installation CD - fi + text = '' + #### Activation script snippet ${a}: + ${v.text} ''; + }); - defaultPath = - let path = [ - pkgs.coreutils pkgs.gnugrep pkgs.findutils - pkgs.glibc # needed for getent - pkgs.shadow - pkgs.nettools # needed for hostname - ]; in noDepEntry '' - export PATH=/empty - for i in ${toString path}; do - PATH=$PATH:$i/bin:$i/sbin; - done - ''; - - stdio = fullDepEntry '' - # Needed by some programs. - ln -sfn /proc/self/fd /dev/fd - ln -sfn /proc/self/fd/0 /dev/stdin - ln -sfn /proc/self/fd/1 /dev/stdout - ln -sfn /proc/self/fd/2 /dev/stderr - '' [ - "defaultPath" # path to ln + path = + [ pkgs.coreutils pkgs.gnugrep pkgs.findutils + pkgs.glibc # needed for getent + pkgs.shadow + pkgs.nettools # needed for hostname ]; - - binsh = fullDepEntry '' - # Create the required /bin/sh symlink; otherwise lots of things - # (notably the system() function) won't work. - mkdir -m 0755 -p $mountPoint/bin - ln -sfn ${config.system.build.binsh}/bin/sh $mountPoint/bin/sh - '' [ - "defaultPath" # path to ln & mkdir - "stdio" # ? - ]; - - modprobe = fullDepEntry '' - # Allow the kernel to find our wrapped modprobe (which searches - # in the right location in the Nix store for kernel modules). - # We need this when the kernel (or some module) auto-loads a - # module. - echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe - '' [ - # ? - ]; - - var = fullDepEntry '' - # Various log/runtime directories. - - touch /var/run/utmp # must exist - chgrp ${toString config.ids.gids.utmp} /var/run/utmp - chmod 664 /var/run/utmp - - mkdir -m 0755 -p /var/run/nix/current-load # for distributed builds - mkdir -m 0700 -p /var/run/nix/remote-stores - - mkdir -m 0755 -p /var/log - mkdir -m 0755 -p /var/log/upstart - - touch /var/log/wtmp # must exist - chmod 644 /var/log/wtmp - - touch /var/log/lastlog - chmod 644 /var/log/lastlog - - mkdir -m 1777 -p /var/tmp - - # Empty, read-only home directory of many system accounts. - mkdir -m 0555 -p /var/empty - '' [ - "defaultPath" # path to mkdir & touch & chmod - ]; - - rootPasswd = fullDepEntry '' - # If there is no password file yet, create a root account with an - # empty password. - if ! test -e /etc/passwd; then - rootHome=/root - touch /etc/passwd; chmod 0644 /etc/passwd - touch /etc/group; chmod 0644 /etc/group - touch /etc/shadow; chmod 0600 /etc/shadow - # Can't use useradd, since it complains that it doesn't know us - # (bootstrap problem!). - echo "root:x:0:0:System administrator:$rootHome:${config.users.defaultUserShell}" >> /etc/passwd - echo "root::::::::" >> /etc/shadow - fi - '' [ - "defaultPath" # path to touch & passwd - "etc" # for /etc - # ? - ]; - - nix = fullDepEntry '' - # Set up Nix. - mkdir -p /nix/etc/nix - ln -sfn /etc/nix.conf /nix/etc/nix/nix.conf - chown root.nixbld /nix/store - chmod 1775 /nix/store - - # Nix initialisation. - mkdir -m 0755 -p \ - /nix/var/nix/gcroots \ - /nix/var/nix/temproots \ - /nix/var/nix/manifests \ - /nix/var/nix/userpool \ - /nix/var/nix/profiles \ - /nix/var/nix/db \ - /nix/var/log/nix/drvs \ - /nix/var/nix/channel-cache \ - /nix/var/nix/chroots - mkdir -m 1777 -p /nix/var/nix/gcroots/per-user - mkdir -m 1777 -p /nix/var/nix/profiles/per-user - mkdir -m 1777 -p /nix/var/nix/gcroots/tmp - - ln -sf /nix/var/nix/profiles /nix/var/nix/gcroots/ - ln -sf /nix/var/nix/manifests /nix/var/nix/gcroots/ - '' [ - "defaultPath" - "etc" # /etc/nix.conf - "users" # nixbld group - ]; - - hostname = fullDepEntry '' - # Set the host name. Don't clear it if it's not configured in the - # NixOS configuration, since it may have been set by dhclient in the - # meantime. - ${if config.networking.hostName != "" then - ''hostname "${config.networking.hostName}"'' - else '' - # dhclient won't do anything if the hostname isn't empty. - if test "$(hostname)" = "(none)"; then - hostname "" - fi - ''} - '' [ "defaultPath" ]; - - # The activation has to be done at the end. This is forced at the apply - # function of activationScripts option - activate = noDepEntry '' - # Make this configuration the current configuration. - # The readlink is there to ensure that when $systemConfig = /system - # (which is a symlink to the store), /var/run/current-system is still - # used as a garbage collection root. - ln -sfn "$(readlink -f "$systemConfig")" /var/run/current-system - - # Prevent the current configuration from being garbage-collected. - ln -sfn /var/run/current-system /nix/var/nix/gcroots/current-system - ''; - - media = noDepEntry '' - mkdir -p /media - ''; - - }; - in { - require = { - system = { - activationScripts = mkOption { - default = []; - example = { - stdio = { - text = " - # Needed by some programs. - ln -sfn /proc/self/fd /dev/fd - ln -sfn /proc/self/fd/0 /dev/stdin - ln -sfn /proc/self/fd/1 /dev/stdout - ln -sfn /proc/self/fd/2 /dev/stderr - "; - deps = []; - }; - }; - description = '' - Activate the new configuration (i.e., update /etc, make accounts, - and so on). - ''; - merge = mergeTypedOption "script" builtins.isAttrs (fold mergeAttrs {}); - apply = set: - let withHeadlines = addAttributeName set; - activateLib = removeAttrs withHeadlines ["activate"]; - activateLibNames = attrNames activateLib; - in { - script = pkgs.writeScript "nixos-activation-script" - ("#! ${pkgs.stdenv.shell}\n" - + textClosureMap id activateLib activateLibNames + "\n" - # make sure that the activate snippet is added last. - + withHeadlines.activate.text); + + ###### interface + + options = { + + system.activationScripts = mkOption { + default = {}; + + example = { + stdio = { + text = '' + # Needed by some programs. + ln -sfn /proc/self/fd /dev/fd + ln -sfn /proc/self/fd/0 /dev/stdin + ln -sfn /proc/self/fd/1 /dev/stdout + ln -sfn /proc/self/fd/2 /dev/stderr + ''; + deps = []; }; }; + + description = '' + Activate the new configuration (i.e., update /etc, make accounts, + and so on). + ''; + + merge = mergeTypedOption "script" builtins.isAttrs (fold mergeAttrs {}); + + apply = set: { + script = pkgs.writeScript "nixos-activation-script" + '' + #! ${pkgs.stdenv.shell} + + export PATH=/empty + for i in ${toString path}; do + PATH=$PATH:$i/bin:$i/sbin; + done + + ${ + let + set' = mapAttrs (n: v: if builtins.isString v then noDepEntry v else v) set; + withHeadlines = addAttributeName set'; + in textClosureMap id (withHeadlines) (attrNames withHeadlines) + } + + # Make this configuration the current configuration. + # The readlink is there to ensure that when $systemConfig = /system + # (which is a symlink to the store), /var/run/current-system is still + # used as a garbage collection root. + ln -sfn "$(readlink -f "$systemConfig")" /var/run/current-system + + # Prevent the current configuration from being garbage-collected. + ln -sfn /var/run/current-system /nix/var/nix/gcroots/current-system + ''; + }; + }; + }; - system.activationScripts = defaultScripts; + + ###### implementation + + config = { + + system.activationScripts.systemConfig = + '' + systemConfig="$1" + if test -z "$systemConfig"; then + systemConfig="/system" # for the installation CD + fi + ''; + + system.activationScripts.stdio = + '' + # Needed by some programs. + ln -sfn /proc/self/fd /dev/fd + ln -sfn /proc/self/fd/0 /dev/stdin + ln -sfn /proc/self/fd/1 /dev/stdout + ln -sfn /proc/self/fd/2 /dev/stderr + ''; + + system.activationScripts.var = + '' + # Various log/runtime directories. + + touch /var/run/utmp # must exist + chgrp ${toString config.ids.gids.utmp} /var/run/utmp + chmod 664 /var/run/utmp + + mkdir -m 0755 -p /var/run/nix/current-load # for distributed builds + mkdir -m 0700 -p /var/run/nix/remote-stores + + mkdir -m 0755 -p /var/log + mkdir -m 0755 -p /var/log/upstart + + touch /var/log/wtmp # must exist + chmod 644 /var/log/wtmp + + touch /var/log/lastlog + chmod 644 /var/log/lastlog + + mkdir -m 1777 -p /var/tmp + + # Empty, read-only home directory of many system accounts. + mkdir -m 0555 -p /var/empty + ''; + + system.activationScripts.media = + '' + mkdir -p /media + ''; + + }; + } diff --git a/modules/system/boot/modprobe.nix b/modules/system/boot/modprobe.nix index 65b3f6fd292a..aa4d023a9f43 100644 --- a/modules/system/boot/modprobe.nix +++ b/modules/system/boot/modprobe.nix @@ -88,6 +88,15 @@ with pkgs.lib; # too? ]; + system.activationScripts.modprobe = + '' + # Allow the kernel to find our wrapped modprobe (which searches + # in the right location in the Nix store for kernel modules). + # We need this when the kernel (or some module) auto-loads a + # module. + echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe + ''; + }; } diff --git a/modules/system/etc/etc.nix b/modules/system/etc/etc.nix index 4ae420017a57..0a2f6665be04 100644 --- a/modules/system/etc/etc.nix +++ b/modules/system/etc/etc.nix @@ -1,9 +1,10 @@ -# produce a script to generate /etc -{config, pkgs, ...}: +# Produce a script to generate /etc. +{ config, pkgs, ... }: + +with pkgs.lib; ###### interface let - inherit (pkgs.lib) mkOption; option = { environment.etc = mkOption { @@ -52,47 +53,39 @@ in { require = [option]; - system = { - build = { - etc = makeEtc; - }; + system.build.etc = makeEtc; - activationScripts = { - etc = pkgs.lib.fullDepEntry '' - # Set up the statically computed bits of /etc. - echo "setting up /etc..." - staticEtc=/etc/static - rm -f $staticEtc - ln -s ${makeEtc}/etc $staticEtc - for i in $(cd $staticEtc && find * -type l); do - mkdir -p /etc/$(dirname $i) - rm -f /etc/$i - if test -e "$staticEtc/$i.mode"; then - # Create a regular file in /etc. - cp $staticEtc/$i /etc/$i - chown 0.0 /etc/$i - chmod "$(cat "$staticEtc/$i.mode")" /etc/$i - else - # Create a symlink in /etc. - ln -s $staticEtc/$i /etc/$i - fi - done + system.activationScripts.etc = stringAfter [ "systemConfig" "stdio" ] + '' + # Set up the statically computed bits of /etc. + echo "setting up /etc..." + staticEtc=/etc/static + rm -f $staticEtc + ln -s ${makeEtc}/etc $staticEtc + for i in $(cd $staticEtc && find * -type l); do + mkdir -p /etc/$(dirname $i) + rm -f /etc/$i + if test -e "$staticEtc/$i.mode"; then + # Create a regular file in /etc. + cp $staticEtc/$i /etc/$i + chown 0.0 /etc/$i + chmod "$(cat "$staticEtc/$i.mode")" /etc/$i + else + # Create a symlink in /etc. + ln -s $staticEtc/$i /etc/$i + fi + done + + # Remove dangling symlinks that point to /etc/static. These are + # configuration files that existed in a previous configuration but not + # in the current one. For efficiency, don't look under /etc/nixos + # (where all the NixOS sources live). + for i in $(find /etc/ \( -path /etc/nixos -prune \) -o -type l); do + target=$(readlink "$i") + if test "''${target:0:''${#staticEtc}}" = "$staticEtc" -a ! -e "$i"; then + rm -f "$i" + fi + done + ''; - # Remove dangling symlinks that point to /etc/static. These are - # configuration files that existed in a previous configuration but not - # in the current one. For efficiency, don't look under /etc/nixos - # (where all the NixOS sources live). - for i in $(find /etc/ \( -path /etc/nixos -prune \) -o -type l); do - target=$(readlink "$i") - if test "''${target:0:''${#staticEtc}}" = "$staticEtc" -a ! -e "$i"; then - rm -f "$i" - fi - done - '' [ - "systemConfig" - "defaultPath" # path to cp, chmod, chown - "stdio" - ]; - }; - }; } diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 8c419810c573..2e1514a82cfd 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -205,7 +205,20 @@ in # ${nettools}/sbin/ifconfig $i down || true #done ''; - }; + }; + + # Set the host name in the activation script. Don't clear it if + # it's not configured in the NixOS configuration, since it may + # have been set by dhclient in the meantime. + system.activationScripts.hostname = + (if config.networking.hostName != "" then '' + hostname "${config.networking.hostName}" + '' else '' + # dhclient won't do anything if the hostname isn't empty. + if test "$(hostname)" = "(none)"; then + hostname "" + fi + ''); }; diff --git a/modules/virtualisation/xen.nix b/modules/virtualisation/xen.nix index b2218fb3fddd..f0ac5944e42a 100644 --- a/modules/virtualisation/xen.nix +++ b/modules/virtualisation/xen.nix @@ -72,7 +72,7 @@ let cfg = config.virtualisation.xen; in ''; # Mount the /proc/xen pseudo-filesystem. - system.activationScripts.xen = noDepEntry + system.activationScripts.xen = '' if [ -d /proc/xen ]; then ${pkgs.sysvtools}/bin/mountpoint -q /proc/xen || \