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