blob: dc0175632174a2d45fd90761e73d273ffb238c0b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# 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
# Ensure a consistent umask.
umask 0022
${
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), /run/current-system is still
# used as a garbage collection root.
ln -sfn "$(readlink -f "$systemConfig")" /run/current-system
# Prevent the current configuration from being garbage-collected.
ln -sfn /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
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
'';
system.activationScripts.tmpfs =
''
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devSize}" none /dev
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devShmSize}" none /dev/shm
${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.runSize}" none /run
'';
};
}
|