diff options
| author | Daiderd Jordan <daiderd@gmail.com> | 2016-11-05 22:47:09 +0100 |
|---|---|---|
| committer | Daiderd Jordan <daiderd@gmail.com> | 2016-11-05 22:47:09 +0100 |
| commit | cd49cc1ab3cfad373ef2b5c57b99b1cfb5761828 (patch) | |
| tree | 08cd7640a66bcfa03cc25a58a3b9e6c89b48f20b /modules/system | |
| parent | 380bdd293bbcd10ffa8f632572ec34e6f1314cfb (diff) | |
generalized module for write-text
- use custom etc activation script
Diffstat (limited to 'modules/system')
| -rw-r--r-- | modules/system/activation-scripts.nix | 63 | ||||
| -rw-r--r-- | modules/system/etc.nix | 63 | ||||
| -rw-r--r-- | modules/system/write-text.nix | 56 |
3 files changed, 182 insertions, 0 deletions
diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix new file mode 100644 index 0000000..1efe201 --- /dev/null +++ b/modules/system/activation-scripts.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.system; + + script = import ./write-text.nix { + inherit lib; + mkTextDerivation = name: text: pkgs.writeScript "activate-${name}" text; + }; + +in + +{ + options = { + + system.activationScripts = mkOption { + internal = true; + type = types.attrsOf (types.submodule script); + default = {}; + 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. + ''; + }; + + }; + + config = { + + system.activationScripts.script.text = '' + #! ${pkgs.stdenv.shell} + + systemConfig=@out@ + + _status=0 + trap "_status=1" ERR + + # Ensure a consistent umask. + umask 0022 + + # 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 + + ${cfg.activationScripts.etc.text} + + exit $_status + ''; + + }; +} diff --git a/modules/system/etc.nix b/modules/system/etc.nix new file mode 100644 index 0000000..9999c1e --- /dev/null +++ b/modules/system/etc.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + text = import ./write-text.nix { + inherit lib; + mkTextDerivation = name: text: pkgs.writeText "etc-${name}" text; + }; + + etc = filter (f: f.enable) (attrValues config.environment.etc); + +in + +{ + options = { + + environment.etc = mkOption { + type = types.loaOf (types.submodule text); + default = {}; + description = '' + Set of files that have to be linked in <filename>/etc</filename>. + ''; + }; + + }; + + config = { + + system.build.etc = pkgs.runCommand "etc" {} '' + mkdir -p $out/etc + cd $out/etc + ${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") etc} + ''; + + system.activationScripts.etc.text = '' + # Set up the statically computed bits of /etc. + echo "setting up /etc..." + + ln -sfn "$(readlink -f $systemConfig/etc)" /etc/static + + for link in $(ls /etc/static/); do + if [ -e "/etc/$link" ]; then + if [ ! -L "/etc/$link" ]; then + echo "warning: /etc/$link is a file, skipping..." >&2 + fi + else + ln -sfn "/etc/static/$link" "/etc/$link" + fi + done + + for link in $(find /etc/ -maxdepth 1 -type l); do + if [[ "$(readlink $link)" == /etc/static/* ]]; then + if [ ! -e "$(readlink -f $link)" ]; then + rm $link + fi + fi + done + ''; + + }; +} diff --git a/modules/system/write-text.nix b/modules/system/write-text.nix new file mode 100644 index 0000000..f15fedd --- /dev/null +++ b/modules/system/write-text.nix @@ -0,0 +1,56 @@ +{ lib, mkTextDerivation }: + +with lib; + +{ config, name, ... }: +let + + sourceDrv = mkTextDerivation name config.text; + +in + +{ + options = { + + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether this /etc file should be generated. This + option allows specific /etc files to be disabled. + ''; + }; + + text = mkOption { + default = null; + type = types.nullOr types.lines; + description = '' + Text of the file. + ''; + }; + + target = mkOption { + type = types.str; + default = name; + description = '' + Name of symlink (relative to + <filename>/etc</filename>). Defaults to the attribute + name. + ''; + }; + + source = mkOption { + type = types.path; + description = '' + Path of the source file. + ''; + }; + + }; + + config = { + + source = mkIf (config.text != null) (mkDefault sourceDrv); + + }; +} |
