aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/system/activation/activation-script.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/system/activation/activation-script.nix')
-rw-r--r--nixpkgs/nixos/modules/system/activation/activation-script.nix229
1 files changed, 229 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/system/activation/activation-script.nix b/nixpkgs/nixos/modules/system/activation/activation-script.nix
new file mode 100644
index 00000000000..ddfd1af4a31
--- /dev/null
+++ b/nixpkgs/nixos/modules/system/activation/activation-script.nix
@@ -0,0 +1,229 @@
+# generate the script used to activate the configuration.
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ addAttributeName = mapAttrs (a: v: v // {
+ text = ''
+ #### Activation script snippet ${a}:
+ _localstatus=0
+ ${v.text}
+
+ if (( _localstatus > 0 )); then
+ printf "Activation script snippet '%s' failed (%s)\n" "${a}" "$_localstatus"
+ fi
+ '';
+ });
+
+ path = with pkgs; map getBin
+ [ coreutils
+ gnugrep
+ findutils
+ getent
+ stdenv.cc.libc # nscd in update-users-groups.pl
+ shadow
+ nettools # needed for hostname
+ utillinux # needed for mount and mountpoint
+ ];
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ system.activationScripts = mkOption {
+ default = {};
+
+ example = literalExample ''
+ { 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.runtimeShell}
+
+ systemConfig=@out@
+
+ export PATH=/empty
+ for i in ${toString path}; do
+ PATH=$PATH:$i/bin:$i/sbin
+ done
+
+ _status=0
+ trap "_status=1 _localstatus=\$?" ERR
+
+ # Ensure a consistent umask.
+ umask 0022
+
+ ${
+ let
+ set' = mapAttrs (n: v: if 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
+
+ exit $_status
+ '';
+ };
+ };
+
+ system.userActivationScripts = mkOption {
+ default = {};
+
+ example = literalExample ''
+ { plasmaSetup = {
+ text = '''
+ ${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5"
+ ''';
+ deps = [];
+ };
+ }
+ '';
+
+ description = ''
+ A set of shell script fragments that are executed by a systemd user
+ service when a NixOS system configuration is activated. Examples are
+ rebuilding the .desktop file cache for showing applications in the menu.
+ Since these are executed every time you run
+ <command>nixos-rebuild</command>, it's important that they are
+ idempotent and fast.
+ '';
+
+ type = types.attrsOf types.unspecified;
+
+ apply = set: {
+ script = ''
+ unset PATH
+ for i in ${toString path}; do
+ PATH=$PATH:$i/bin:$i/sbin
+ done
+
+ _status=0
+ trap "_status=1 _localstatus=\$?" ERR
+
+ ${
+ let
+ set' = mapAttrs (n: v: if isString v then noDepEntry v else v) set;
+ withHeadlines = addAttributeName set';
+ in textClosureMap id (withHeadlines) (attrNames withHeadlines)
+ }
+
+ exit $_status
+ '';
+ };
+
+ };
+
+ environment.usrbinenv = mkOption {
+ default = "${pkgs.coreutils}/bin/env";
+ example = literalExample ''
+ "''${pkgs.busybox}/bin/env"
+ '';
+ type = types.nullOr types.path;
+ visible = false;
+ description = ''
+ The env(1) executable that is linked system-wide to
+ <literal>/usr/bin/env</literal>.
+ '';
+ };
+ };
+
+
+ ###### implementation
+
+ config = {
+
+ system.activationScripts.stdio = ""; # obsolete
+
+ system.activationScripts.var =
+ ''
+ # Various log/runtime directories.
+
+ mkdir -m 1777 -p /var/tmp
+
+ # Empty, immutable home directory of many system accounts.
+ mkdir -p /var/empty
+ # Make sure it's really empty
+ ${pkgs.e2fsprogs}/bin/chattr -f -i /var/empty || true
+ find /var/empty -mindepth 1 -delete
+ chmod 0555 /var/empty
+ chown root:root /var/empty
+ ${pkgs.e2fsprogs}/bin/chattr -f +i /var/empty || true
+ '';
+
+ system.activationScripts.usrbinenv = if config.environment.usrbinenv != null
+ then ''
+ mkdir -m 0755 -p /usr/bin
+ ln -sfn ${config.environment.usrbinenv} /usr/bin/.env.tmp
+ mv /usr/bin/.env.tmp /usr/bin/env # atomically replace /usr/bin/env
+ ''
+ else ''
+ rm -f /usr/bin/env
+ rmdir --ignore-fail-on-non-empty /usr/bin /usr
+ '';
+
+ system.activationScripts.specialfs =
+ ''
+ specialMount() {
+ local device="$1"
+ local mountPoint="$2"
+ local options="$3"
+ local fsType="$4"
+
+ if mountpoint -q "$mountPoint"; then
+ local options="remount,$options"
+ else
+ mkdir -m 0755 -p "$mountPoint"
+ fi
+ mount -t "$fsType" -o "$options" "$device" "$mountPoint"
+ }
+ source ${config.system.build.earlyMountScript}
+ '';
+
+ systemd.user = {
+ services.nixos-activation = {
+ description = "Run user-specific NixOS activation";
+ script = config.system.userActivationScripts.script;
+ unitConfig.ConditionUser = "!@system";
+ serviceConfig.Type = "oneshot";
+ };
+ };
+ };
+
+}