diff options
Diffstat (limited to 'nixos/modules/system/activation/activation-script.nix')
-rw-r--r-- | nixos/modules/system/activation/activation-script.nix | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix new file mode 100644 index 000000000000..e012c977164e --- /dev/null +++ b/nixos/modules/system/activation/activation-script.nix @@ -0,0 +1,151 @@ +# 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 = '' + A set of shell script fragments that are executed when a NixOS + system configuration is activated. Examples are updating + /etc, creating accounts, and so on. Since these are executed + every time you boot the system or run + <command>nixos-rebuild</command>, it's important that they are + idempotent and fast. + ''; + + type = types.attrsOf types.unspecified; # FIXME + + 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 + + mkdir -m 0755 -p /var/log + + touch /var/log/wtmp /var/log/lastlog # must exist + chmod 644 /var/log/wtmp /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 + ''; + + }; + +} |