at 17.09-beta 4.9 kB view raw
1# generate the script used to activate the configuration. 2{ config, lib, pkgs, ... }: 3 4with lib; 5 6let 7 8 addAttributeName = mapAttrs (a: v: v // { 9 text = '' 10 #### Activation script snippet ${a}: 11 ${v.text} 12 ''; 13 }); 14 15 path = with pkgs; map getBin 16 [ coreutils 17 gnugrep 18 findutils 19 glibc # needed for getent 20 shadow 21 nettools # needed for hostname 22 utillinux # needed for mount and mountpoint 23 ]; 24 25in 26 27{ 28 29 ###### interface 30 31 options = { 32 33 system.activationScripts = mkOption { 34 default = {}; 35 36 example = literalExample '' 37 { stdio = { 38 text = ''' 39 # Needed by some programs. 40 ln -sfn /proc/self/fd /dev/fd 41 ln -sfn /proc/self/fd/0 /dev/stdin 42 ln -sfn /proc/self/fd/1 /dev/stdout 43 ln -sfn /proc/self/fd/2 /dev/stderr 44 '''; 45 deps = []; 46 }; 47 } 48 ''; 49 50 description = '' 51 A set of shell script fragments that are executed when a NixOS 52 system configuration is activated. Examples are updating 53 /etc, creating accounts, and so on. Since these are executed 54 every time you boot the system or run 55 <command>nixos-rebuild</command>, it's important that they are 56 idempotent and fast. 57 ''; 58 59 type = types.attrsOf types.unspecified; # FIXME 60 61 apply = set: { 62 script = 63 '' 64 #! ${pkgs.stdenv.shell} 65 66 systemConfig=@out@ 67 68 export PATH=/empty 69 for i in ${toString path}; do 70 PATH=$PATH:$i/bin:$i/sbin 71 done 72 73 _status=0 74 trap "_status=1" ERR 75 76 # Ensure a consistent umask. 77 umask 0022 78 79 ${ 80 let 81 set' = mapAttrs (n: v: if isString v then noDepEntry v else v) set; 82 withHeadlines = addAttributeName set'; 83 in textClosureMap id (withHeadlines) (attrNames withHeadlines) 84 } 85 86 # Make this configuration the current configuration. 87 # The readlink is there to ensure that when $systemConfig = /system 88 # (which is a symlink to the store), /run/current-system is still 89 # used as a garbage collection root. 90 ln -sfn "$(readlink -f "$systemConfig")" /run/current-system 91 92 # Prevent the current configuration from being garbage-collected. 93 ln -sfn /run/current-system /nix/var/nix/gcroots/current-system 94 95 exit $_status 96 ''; 97 }; 98 99 }; 100 101 environment.usrbinenv = mkOption { 102 default = "${pkgs.coreutils}/bin/env"; 103 example = literalExample '' 104 "''${pkgs.busybox}/bin/env" 105 ''; 106 type = types.nullOr types.path; 107 visible = false; 108 description = '' 109 The env(1) executable that is linked system-wide to 110 <literal>/usr/bin/env</literal>. 111 ''; 112 }; 113 }; 114 115 116 ###### implementation 117 118 config = { 119 120 system.activationScripts.stdio = 121 '' 122 # Needed by some programs. 123 ln -sfn /proc/self/fd /dev/fd 124 ln -sfn /proc/self/fd/0 /dev/stdin 125 ln -sfn /proc/self/fd/1 /dev/stdout 126 ln -sfn /proc/self/fd/2 /dev/stderr 127 ''; 128 129 system.activationScripts.var = 130 '' 131 # Various log/runtime directories. 132 133 mkdir -m 0755 -p /run/nix/current-load # for distributed builds 134 mkdir -m 0700 -p /run/nix/remote-stores 135 136 mkdir -m 0755 -p /var/log 137 138 touch /var/log/wtmp /var/log/lastlog # must exist 139 chmod 644 /var/log/wtmp /var/log/lastlog 140 141 mkdir -m 1777 -p /var/tmp 142 143 # Empty, immutable home directory of many system accounts. 144 mkdir -p /var/empty 145 # Make sure it's really empty 146 ${pkgs.e2fsprogs}/bin/chattr -f -i /var/empty || true 147 find /var/empty -mindepth 1 -delete 148 chmod 0555 /var/empty 149 chown root:root /var/empty 150 ${pkgs.e2fsprogs}/bin/chattr -f +i /var/empty || true 151 ''; 152 153 system.activationScripts.usrbinenv = if config.environment.usrbinenv != null 154 then '' 155 mkdir -m 0755 -p /usr/bin 156 ln -sfn ${config.environment.usrbinenv} /usr/bin/.env.tmp 157 mv /usr/bin/.env.tmp /usr/bin/env # atomically replace /usr/bin/env 158 '' 159 else '' 160 rm -f /usr/bin/env 161 rmdir --ignore-fail-on-non-empty /usr/bin /usr 162 ''; 163 164 system.activationScripts.specialfs = 165 '' 166 specialMount() { 167 local device="$1" 168 local mountPoint="$2" 169 local options="$3" 170 local fsType="$4" 171 172 if mountpoint -q "$mountPoint"; then 173 local options="remount,$options" 174 else 175 mkdir -m 0755 -p "$mountPoint" 176 fi 177 mount -t "$fsType" -o "$options" "$device" "$mountPoint" 178 } 179 source ${config.system.build.earlyMountScript} 180 ''; 181 182 }; 183 184}