3495a773f9
longer compares the current configuration to the previous configuration, but instead compares the current Upstart state to the intended state. Thus, if the switch script is interrupted, running nixos-rebuild again will resume starting/stopping Upstart jobs where the previous run left off. We determine if an Upstart job has changed by having the pre-start script of each Upstart job put a symlink to its .conf file in /var/run/upstart-jobs. So if this symlink differs from the target of /etc/init/<job>.conf, then the job has changed. This also prevents multiple restarts of dependent jobs. E.g., if job B has "start on started A" and "stop on stopping A", then restarting A will cause B to be restarted, so B shouldn't B restarted a second time. We only start jobs that are not running if 1) they're tasks that have been previously run (like mountall); or 2) they're jobs that have a "start on" condition. This seems a reasonable heuristic. svn path=/nixos/trunk/; revision=33222
146 lines
3.6 KiB
Nix
146 lines
3.6 KiB
Nix
# generate the script used to activate the configuration.
|
|
{ config, pkgs, ... }:
|
|
|
|
with pkgs.lib;
|
|
|
|
let
|
|
|
|
addAttributeName = mapAttrs (a: v: v // {
|
|
text = ''
|
|
#### Activation script snippet ${a}:
|
|
${v.text}
|
|
'';
|
|
});
|
|
|
|
path =
|
|
[ pkgs.coreutils pkgs.gnugrep pkgs.findutils
|
|
pkgs.glibc # needed for getent
|
|
pkgs.shadow
|
|
pkgs.nettools # needed for hostname
|
|
];
|
|
|
|
in
|
|
|
|
{
|
|
|
|
###### 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.stdenv.shell}
|
|
|
|
systemConfig=@out@
|
|
|
|
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
|
|
'';
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
###### implementation
|
|
|
|
config = {
|
|
|
|
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
|
|
|
|
# Directory holding symlinks to currently running Upstart
|
|
# jobs. Used to determine which jobs need to be restarted
|
|
# when switching to a new configuration.
|
|
mkdir -m 0700 -p /var/run/upstart-jobs
|
|
|
|
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 -m 0755 -p /media
|
|
'';
|
|
|
|
system.activationScripts.usrbinenv =
|
|
''
|
|
mkdir -m 0755 -p /usr/bin
|
|
ln -sfn ${pkgs.coreutils}/bin/env /usr/bin/.env.tmp
|
|
mv /usr/bin/.env.tmp /usr/bin/env # atomically replace /usr/bin/env
|
|
'';
|
|
|
|
};
|
|
|
|
}
|