diff --git a/modules/config/fonts/fontconfig.nix b/modules/config/fonts/fontconfig.nix index d0478083ed3..88643b41d83 100644 --- a/modules/config/fonts/fontconfig.nix +++ b/modules/config/fonts/fontconfig.nix @@ -46,13 +46,10 @@ with pkgs.lib; ''; - environment.shellInit = - '' - # FIXME: This variable is no longer needed, but we'll keep it - # around for a while for applications linked against old - # fontconfig builds. - export FONTCONFIG_FILE=/etc/fonts/fonts.conf - ''; + # FIXME: This variable is no longer needed, but we'll keep it + # around for a while for applications linked against old + # fontconfig builds. + environment.variables.FONTCONFIG_FILE.value = "/etc/fonts/fonts.conf"; environment.systemPackages = [ pkgs.fontconfig ]; diff --git a/modules/config/i18n.nix b/modules/config/i18n.nix index 62b01c2221e..15df0b3a12a 100644 --- a/modules/config/i18n.nix +++ b/modules/config/i18n.nix @@ -69,10 +69,7 @@ in environment.systemPackages = [ glibcLocales ]; - environment.shellInit = - '' - export LANG=${config.i18n.defaultLocale} - ''; + environment.variables.LANG.value = config.i18n.defaultLocale; # ‘/etc/locale.conf’ is used by systemd. environment.etc = singleton diff --git a/modules/config/shells-environment.nix b/modules/config/shells-environment.nix new file mode 100644 index 00000000000..116c5f11e1f --- /dev/null +++ b/modules/config/shells-environment.nix @@ -0,0 +1,202 @@ +# This module defines a global environment configuration and +# a common configuration for all shells. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.environment; + + environOpts = { name, config, ... }: { + + options = { + + value = mkOption { + example = "/foo/bin"; + description = + '' + Variable value. + Exactly one of this or must be set. + ''; + type = types.uniq types.string; + }; + + list = mkOption { + default = null; + example = [ "/foo/bin" "/bar/bin" ]; + description = + '' + Variable value. + Exactly one of this or must be set. + ''; + type = types.nullOr (types.listOf types.string); + }; + + }; + + config = { + value = mkIf (config.list != null) + (concatStringsSep ":" config.list); + }; + + }; + +in + +{ + + options = { + + environment.variables = mkOption { + default = {}; + description = '' + A set of environment variables used in the global environment. + ''; + type = types.attrsOf types.optionSet; + options = [ environOpts ]; + }; + + environment.profiles = mkOption { + default = []; + description = '' + A list of profiles used to setup the global environment. + ''; + type = types.listOf types.string; + }; + + environment.profileVariables = mkOption { + default = (p: {}); + description = '' + A function which given a profile path should give back + a set of environment variables for that profile. + ''; + # !!! this should be of the following type: + #type = types.functionTo (types.attrsOf (types.optionSet envVar)); + # and envVar should be changed to something more like environOpts. + # Having unique `value' _or_ multiple `list' is much more useful + # than just sticking everything together with ':' unconditionally. + # Anyway, to have this type mentioned above + # types.optionSet needs to be transformed into a type constructor + # (it has a !!! mark on that in nixpkgs) + # for now we hack all this to be + type = types.functionTo (types.attrsOf (types.listOf types.string)); + }; + + # !!! isn't there a better way? + environment.extraInit = mkOption { + default = ""; + description = '' + Shell script code called during global environment initialisation + after all variables and profileVariables have been set. + This code is asumed to be shell-independent, which means you should + stick to pure sh without sh word split. + ''; + type = types.lines; + }; + + environment.shellInit = mkOption { + default = ""; + description = '' + Shell script code called during shell initialisation. + This code is asumed to be shell-independent, which means you should + stick to pure sh without sh word split. + ''; + type = types.lines; + }; + + environment.loginShellInit = mkOption { + default = ""; + description = '' + Shell script code called during login shell initialisation. + This code is asumed to be shell-independent, which means you should + stick to pure sh without sh word split. + ''; + type = types.lines; + }; + + environment.interactiveShellInit = mkOption { + default = ""; + description = '' + Shell script code called during interactive shell initialisation. + This code is asumed to be shell-independent, which means you should + stick to pure sh without sh word split. + ''; + type = types.lines; + }; + + environment.shellAliases = mkOption { + default = {}; + example = { ll = "ls -l"; }; + description = '' + An attribute set that maps aliases (the top level attribute names in + this option) to command strings or directly to build outputs. The + aliases are added to all users' shells. + ''; + type = types.attrs; # types.attrsOf types.stringOrPath; + }; + + environment.binsh = mkOption { + default = "${config.system.build.binsh}/bin/sh"; + example = "\${pkgs.dash}/bin/dash"; + type = with pkgs.lib.types; path; + description = '' + The shell executable that is linked system-wide to + /bin/sh. Please note that NixOS assumes all + over the place that shell to be Bash, so override the default + setting only if you know exactly what you're doing. + ''; + }; + + environment.shells = mkOption { + default = []; + example = [ "/run/current-system/sw/bin/zsh" ]; + description = '' + A list of permissible login shells for user accounts. + No need to mention /bin/sh + here, it is placed into this list implicitly. + ''; + type = types.listOf types.path; + }; + + }; + + config = { + + system.build.binsh = pkgs.bashInteractive; + + environment.etc."shells".text = + '' + ${concatStringsSep "\n" cfg.shells} + /bin/sh + ''; + + environment.etc."environment".text = + '' + ${concatStringsSep "\n" ( + (mapAttrsToList (n: v: ''export ${n}="${concatStringsSep ":" v}"'') + # This line is a kind of a hack because of !!! note above + (fold (mergeAttrsWithFunc concat) {} ([ (mapAttrs (n: v: [ v.value ]) cfg.variables) ] ++ map cfg.profileVariables cfg.profiles))))} + + ${cfg.extraInit} + + # The setuid wrappers override other bin directories. + export PATH="${config.security.wrapperDir}:$PATH" + + # ~/bin if it exists overrides other bin directories. + export PATH="$HOME/bin:$PATH" + ''; + + system.activationScripts.binsh = stringAfter [ "stdio" ] + '' + # Create the required /bin/sh symlink; otherwise lots of things + # (notably the system() function) won't work. + mkdir -m 0755 -p /bin + ln -sfn "${cfg.binsh}" /bin/.sh.tmp + mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh + ''; + + }; + +} diff --git a/modules/config/shells.nix b/modules/config/shells.nix deleted file mode 100644 index b0a946a8e6e..00000000000 --- a/modules/config/shells.nix +++ /dev/null @@ -1,24 +0,0 @@ -# This module creates /etc/shells, the file that defines the list of -# permissible login shells for user accounts. - -{ config, pkgs, ... }: - -with pkgs.lib; - -{ - - config = { - - environment.etc = singleton - { target = "shells"; - source = pkgs.writeText "shells" - '' - /run/current-system/sw/bin/bash - /var/run/current-system/sw/bin/bash - /bin/sh - ''; - }; - - }; - -} diff --git a/modules/config/timezone.nix b/modules/config/timezone.nix index 81536725501..68b785601fa 100644 --- a/modules/config/timezone.nix +++ b/modules/config/timezone.nix @@ -24,11 +24,8 @@ with pkgs.lib; config = { - environment.shellInit = - '' - export TZDIR=/etc/zoneinfo - export TZ=${config.time.timeZone} - ''; + environment.variables.TZDIR.value = "/etc/zoneinfo"; + environment.variables.TZ.value = config.time.timeZone; environment.etc.localtime.source = "${pkgs.tzdata}/share/zoneinfo/${config.time.timeZone}"; diff --git a/modules/module-list.nix b/modules/module-list.nix index 08acd213355..3a7ede02396 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -13,7 +13,7 @@ ./config/nsswitch.nix ./config/power-management.nix ./config/pulseaudio.nix - ./config/shells.nix + ./config/shells-environment.nix ./config/swap.nix ./config/sysctl.nix ./config/system-path.nix @@ -45,6 +45,7 @@ ./programs/bash/bash.nix ./programs/bash/command-not-found.nix ./programs/blcr.nix + ./programs/environment.nix ./programs/info.nix ./programs/shadow.nix ./programs/shell.nix diff --git a/modules/profiles/installation-device.nix b/modules/profiles/installation-device.nix index 5a92789e5d9..cfb2eb3f9cb 100644 --- a/modules/profiles/installation-device.nix +++ b/modules/profiles/installation-device.nix @@ -50,9 +50,7 @@ with pkgs.lib; # Tell the Nix evaluator to garbage collect more aggressively. # This is desirable in memory-constrained environments that don't # (yet) have swap set up. - environment.shellInit = - '' - export GC_INITIAL_HEAP_SIZE=100000 - ''; + environment.variables.GC_INITIAL_HEAP_SIZE.value = "100000"; + }; } diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 0d751d1d0d3..2324164316d 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -7,9 +7,11 @@ with pkgs.lib; let - cfg = config.environment; + cfge = config.environment; - initBashCompletion = optionalString cfg.enableBashCompletion '' + cfg = config.programs.bash; + + bashCompletion = optionalString cfg.enableCompletion '' # Check whether we're running a version of Bash that has support for # programmable completion. If we do, enable all modules installed in # the system (and user profile). @@ -27,7 +29,7 @@ let fi ''; - shellAliases = concatStringsSep "\n" ( + bashAliases = concatStringsSep "\n" ( mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases ); @@ -36,118 +38,173 @@ in { options = { - environment.promptInit = mkOption { - default = '' - # Provide a nice prompt. - PROMPT_COLOR="1;31m" - let $UID && PROMPT_COLOR="1;32m" - PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " - if test "$TERM" = "xterm"; then - PS1="\[\033]2;\h:\u:\w\007\]$PS1" - fi - ''; - description = '' - Shell script code used to initialise the shell prompt. - ''; - type = types.lines; - }; + programs.bash = { - environment.shellInit = mkOption { - default = ""; - example = ''export PATH=/godi/bin/:$PATH''; - description = '' - Shell script code called during login shell initialisation. - ''; - type = types.lines; - }; + enable = mkOption { + default = true; + description = '' + Whenever to configure Bash as an interactive shell. + Note that this tries to make Bash the default + , + which in turn means that you might need to explicitly + set this variable if you have another shell configured + with NixOS. + ''; + type = types.bool; + }; - environment.interactiveShellInit = mkOption { - default = ""; - example = ''export PATH=/godi/bin/:$PATH''; - description = '' - Shell script code called during interactive shell initialisation. - ''; - type = types.lines; - }; + shellAliases = mkOption { + default = config.environment.shellAliases // { which = "type -P"; }; + description = '' + Set of aliases for bash shell. See + for an option format description. + ''; + type = types.attrs; # types.attrsOf types.stringOrPath; + }; - environment.enableBashCompletion = mkOption { - default = false; - description = "Enable Bash completion for all interactive shells."; - type = types.bool; - }; + shellInit = mkOption { + default = ""; + description = '' + Shell script code called during bash shell initialisation. + ''; + type = types.lines; + }; + + loginShellInit = mkOption { + default = ""; + description = '' + Shell script code called during login bash shell initialisation. + ''; + type = types.lines; + }; + + interactiveShellInit = mkOption { + default = ""; + description = '' + Shell script code called during interactive bash shell initialisation. + ''; + type = types.lines; + }; + + promptInit = mkOption { + default = '' + # Provide a nice prompt. + PROMPT_COLOR="1;31m" + let $UID && PROMPT_COLOR="1;32m" + PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " + if test "$TERM" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi + ''; + description = '' + Shell script code used to initialise the bash prompt. + ''; + type = types.lines; + }; + + enableCompletion = mkOption { + default = false; + description = '' + Enable Bash completion for all interactive bash shells. + ''; + type = types.bool; + }; - environment.binsh = mkOption { - default = "${config.system.build.binsh}/bin/sh"; - example = "\${pkgs.dash}/bin/dash"; - type = types.path; - description = '' - Select the shell executable that is linked system-wide to - /bin/sh. Please note that NixOS assumes all - over the place that shell to be Bash, so override the default - setting only if you know exactly what you're doing. - ''; }; }; + config = mkIf cfg.enable { - config = { + programs.bash = { - # Script executed when the shell starts as a login shell. - environment.etc."profile".source = - pkgs.substituteAll { - src = ./profile.sh; - wrapperDir = config.security.wrapperDir; - inherit (cfg) shellInit; - }; + shellInit = '' + . /etc/environment - # /etc/bashrc: executed every time an interactive bash - # starts. Sources /etc/profile to ensure that the system - # environment is configured properly. - environment.etc."bashrc".source = - pkgs.substituteAll { - src = ./bashrc.sh; - inherit (cfg) interactiveShellInit; - }; + ${cfge.shellInit} + ''; + + loginShellInit = cfge.loginShellInit; + + interactiveShellInit = '' + ${cfge.interactiveShellInit} + + # Check the window size after every command. + shopt -s checkwinsize + + # Disable hashing (i.e. caching) of command lookups. + set +h + + ${cfg.promptInit} + ${bashCompletion} + ${bashAliases} + ''; + + }; + + environment.etc."profile".text = + '' + # /etc/profile: DO NOT EDIT -- this file has been generated automatically. + # This file is read for login shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi + __ETC_PROFILE_SOURCED=1 + + if [ -z "$__BASH_SHELL_INIT_DONE" ]; then + __BASH_SHELL_INIT_DONE=1 + ${cfg.shellInit} + fi + + ${cfg.loginShellInit} + + # Read system-wide modifications. + if test -f /etc/profile.local; then + . /etc/profile.local + fi + + if [ -n "''${BASH_VERSION:-}" ]; then + . /etc/bashrc + fi + ''; + + environment.etc."bashrc".text = + '' + # /etc/bashrc: DO NOT EDIT -- this file has been generated automatically. + + # Only execute this file once per shell. + if [ -n "$__ETC_BASHRC_SOURCED" -o -n "$NOSYSBASHRC" ]; then return; fi + __ETC_BASHRC_SOURCED=1 + + if [ -z "$__BASH_SHELL_INIT_DONE" ]; then + __BASH_SHELL_INIT_DONE=1 + ${cfg.shellInit} + fi + + # We are not always an interactive shell. + if [ -n "$PS1" ]; then + ${cfg.interactiveShellInit} + fi + + # Read system-wide modifications. + if test -f /etc/bashrc.local; then + . /etc/bashrc.local + fi + ''; # Configuration for readline in bash. environment.etc."inputrc".source = ./inputrc; - environment.shellAliases = - { ls = "ls --color=tty"; - ll = "ls -l"; - l = "ls -alh"; - which = "type -P"; - }; + users.defaultUserShell = mkDefault "/run/current-system/sw/bin/bash"; - environment.interactiveShellInit = - '' - # Check the window size after every command. - shopt -s checkwinsize - - ${cfg.promptInit} - ${initBashCompletion} - ${shellAliases} - - # Disable hashing (i.e. caching) of command lookups. - set +h - ''; - - system.build.binsh = pkgs.bashInteractive; - - system.activationScripts.binsh = stringAfter [ "stdio" ] - '' - # Create the required /bin/sh symlink; otherwise lots of things - # (notably the system() function) won't work. - mkdir -m 0755 -p /bin - ln -sfn "${cfg.binsh}" /bin/.sh.tmp - mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh - ''; - - environment.pathsToLink = optionals cfg.enableBashCompletion [ - "/etc/bash_completion.d" - "/share/bash-completion" - ]; + environment.shells = + [ "/run/current-system/sw/bin/bash" + "/var/run/current-system/sw/bin/bash" + "/run/current-system/sw/bin/sh" + "/var/run/current-system/sw/bin/sh" + "${pkgs.bashInteractive}/bin/bash" + "${pkgs.bashInteractive}/bin/sh" + ]; }; diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh deleted file mode 100644 index 98b0907a06b..00000000000 --- a/modules/programs/bash/bashrc.sh +++ /dev/null @@ -1,19 +0,0 @@ -# /etc/bashrc: DO NOT EDIT -- this file has been generated automatically. - -# This file is read for interactive non-login shells. - -# Only execute this file once per shell. -if [ -n "$__ETC_BASHRC_SOURCED" -o -n "$NOSYSBASHRC" ]; then return; fi -__ETC_BASHRC_SOURCED=1 - -# If the profile was not loaded in a parent process, source it. But -# otherwise don't do it because we don't want to clobber overridden -# values of $PATH, etc. -if [ -z "$__ETC_PROFILE_DONE" ]; then - . /etc/profile -fi - -# We are not always an interactive shell. -if [ -z "$PS1" ]; then return; fi - -@interactiveShellInit@ diff --git a/modules/programs/bash/command-not-found.nix b/modules/programs/bash/command-not-found.nix index 6549ba86810..502320446a3 100644 --- a/modules/programs/bash/command-not-found.nix +++ b/modules/programs/bash/command-not-found.nix @@ -23,7 +23,7 @@ in { - environment.interactiveShellInit = + programs.bash.interactiveShellInit = '' # This function is called whenever a command is not found. command_not_found_handle() { diff --git a/modules/programs/bash/profile.sh b/modules/programs/bash/profile.sh deleted file mode 100644 index 92fb0658189..00000000000 --- a/modules/programs/bash/profile.sh +++ /dev/null @@ -1,119 +0,0 @@ -# /etc/profile: DO NOT EDIT -- this file has been generated automatically. - -# This file is read for (interactive) login shells. Any -# initialisation specific to interactive shells should be put in -# /etc/bashrc, which is sourced from here. - -# Only execute this file once per shell. -if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi -__ETC_PROFILE_SOURCED=1 - -# Prevent this file from being sourced by interactive non-login child shells. -export __ETC_PROFILE_DONE=1 - -# Initialise a bunch of environment variables. -export LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive -export LD_LIBRARY_PATH=/run/opengl-driver/lib:/run/opengl-driver-32/lib # !!! only set if needed -export NIXPKGS_CONFIG=/etc/nix/nixpkgs-config.nix -export NIX_PATH=/nix/var/nix/profiles/per-user/root/channels/nixos:nixpkgs=/etc/nixos/nixpkgs:nixos=/etc/nixos/nixos:nixos-config=/etc/nixos/configuration.nix:services=/etc/nixos/services -export PAGER="less -R" -export EDITOR=nano -export LOCATE_PATH=/var/cache/locatedb - -# Include the various profiles in the appropriate environment variables. -export NIX_USER_PROFILE_DIR=/nix/var/nix/profiles/per-user/$USER -export NIX_PROFILES="/run/current-system/sw /nix/var/nix/profiles/default $HOME/.nix-profile" - -unset PATH INFOPATH PKG_CONFIG_PATH PERL5LIB ALSA_PLUGIN_DIRS GST_PLUGIN_PATH KDEDIRS -unset QT_PLUGIN_PATH QTWEBKIT_PLUGIN_PATH STRIGI_PLUGIN_PATH XDG_CONFIG_DIRS XDG_DATA_DIRS -unset MOZ_PLUGIN_PATH TERMINFO_DIRS - -for i in $NIX_PROFILES; do # !!! reverse - # We have to care not leaving an empty PATH element, because that means '.' to Linux - export PATH=$i/bin:$i/sbin:$i/lib/kde4/libexec${PATH:+:}$PATH - export INFOPATH=$i/info:$i/share/info${INFOPATH:+:}$INFOPATH - export PKG_CONFIG_PATH="$i/lib/pkgconfig${PKG_CONFIG_PATH:+:}$PKG_CONFIG_PATH" - - # terminfo and reset TERM with new TERMINFO available - export TERMINFO_DIRS=$i/share/terminfo${TERMINFO_DIRS:+:}$TERMINFO_DIRS - export TERM=$TERM - - export PERL5LIB="$i/lib/perl5/site_perl${PERL5LIB:+:}$PERL5LIB" - - # ALSA plugins - export ALSA_PLUGIN_DIRS="$i/lib/alsa-lib${ALSA_PLUGIN_DIRS:+:}$ALSA_PLUGIN_DIRS" - - # GStreamer. - export GST_PLUGIN_PATH="$i/lib/gstreamer-0.10${GST_PLUGIN_PATH:+:}$GST_PLUGIN_PATH" - - # KDE/Gnome stuff. - export KDEDIRS=$i${KDEDIRS:+:}$KDEDIRS - export STRIGI_PLUGIN_PATH=$i/lib/strigi/${STRIGI_PLUGIN_PATH:+:}$STRIGI_PLUGIN_PATH - export QT_PLUGIN_PATH=$i/lib/qt4/plugins:$i/lib/kde4/plugins${QT_PLUGIN_PATH:+:}:$QT_PLUGIN_PATH - export QTWEBKIT_PLUGIN_PATH=$i/lib/mozilla/plugins/${QTWEBKIT_PLUGIN_PATH:+:}$QTWEBKIT_PLUGIN_PATH - export XDG_CONFIG_DIRS=$i/etc/xdg${XDG_CONFIG_DIRS:+:}$XDG_CONFIG_DIRS - export XDG_DATA_DIRS=$i/share${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS - - # Mozilla plugins. - export MOZ_PLUGIN_PATH=$i/lib/mozilla/plugins${MOZ_PLUGIN_PATH:+:}$MOZ_PLUGIN_PATH - - # Search directory for Aspell dictionaries. - if [ -d "$i/lib/aspell" ]; then - export ASPELL_CONF="dict-dir $i/lib/aspell" - fi -done - -# The setuid wrappers override other bin directories. -export PATH=@wrapperDir@:$PATH - -# ~/bin if it exists overrides other bin directories. -export PATH=$HOME/bin:$PATH - -# Set up the per-user profile. -mkdir -m 0755 -p $NIX_USER_PROFILE_DIR -if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then - echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2 -fi - -if ! test -L $HOME/.nix-profile; then - echo "creating $HOME/.nix-profile" >&2 - if test "$USER" != root; then - ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile - else - # Root installs in the system-wide profile by default. - ln -s /nix/var/nix/profiles/default $HOME/.nix-profile - fi -fi - -# Subscribe the root user to the NixOS channel by default. -if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then - echo "http://nixos.org/channels/nixos-unstable nixos" > $HOME/.nix-channels -fi - -# Create the per-user garbage collector roots directory. -NIX_USER_GCROOTS_DIR=/nix/var/nix/gcroots/per-user/$USER -mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR -if test "$(stat --printf '%u' $NIX_USER_GCROOTS_DIR)" != "$(id -u)"; then - echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2 -fi - -# Set up a default Nix expression from which to install stuff. -if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then - echo "creating $HOME/.nix-defexpr" >&2 - rm -f $HOME/.nix-defexpr - mkdir $HOME/.nix-defexpr - if [ "$USER" != root ]; then - ln -s /nix/var/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root - fi -fi - -@shellInit@ - -# Read system-wide modifications. -if test -f /etc/profile.local; then - . /etc/profile.local -fi - -if [ -n "${BASH_VERSION:-}" ]; then - . /etc/bashrc -fi diff --git a/modules/programs/environment.nix b/modules/programs/environment.nix new file mode 100644 index 00000000000..8f2df7e4a53 --- /dev/null +++ b/modules/programs/environment.nix @@ -0,0 +1,79 @@ +# This module defines a standard configuration for NixOS global environment. + +# Most of the stuff here should probably be moved elsewhere sometime. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.environment; + +in + +{ + + config = { + + environment.variables = + { LOCALE_ARCHIVE.value = "/run/current-system/sw/lib/locale/locale-archive"; + LOCATE_PATH.value = "/var/cache/locatedb"; + NIXPKGS_CONFIG.value = "/etc/nix/nixpkgs-config.nix"; + NIX_PATH.list = + [ "/nix/var/nix/profiles/per-user/root/channels/nixos" + "nixpkgs=/etc/nixos/nixpkgs" + "nixos=/etc/nixos/nixos" + "nixos-config=/etc/nixos/configuration.nix" + "services=/etc/nixos/services" + ]; + PAGER.value = "less -R"; + EDITOR.value = "nano"; + }; + + environment.profiles = + [ "$HOME/.nix-profile" + "/nix/var/nix/profiles/default" + "/run/current-system/sw" + ]; + + # !!! fix environment.profileVariables definition and then move + # most of these elsewhere + environment.profileVariables = (i: + { PATH = [ "${i}/bin" "${i}/sbin" "${i}/lib/kde4/libexec" ]; + MANPATH = [ "${i}/man" "${i}/share/man" ]; + INFOPATH = [ "${i}/info" "${i}/share/info" ]; + PKG_CONFIG_PATH = [ "${i}/lib/pkgconfig" ]; + TERMINFO_DIRS = [ "${i}/share/terminfo" ]; + PERL5LIB = [ "${i}/lib/perl5/site_perl" ]; + ALSA_PLUGIN_DIRS = [ "${i}/lib/alsa-lib" ]; + GST_PLUGIN_PATH = [ "${i}/lib/gstreamer-0.10" ]; + KDEDIRS = [ "${i}" ]; + STRIGI_PLUGIN_PATH = [ "${i}/lib/strigi/" ]; + QT_PLUGIN_PATH = [ "${i}/lib/qt4/plugins" "${i}/lib/kde4/plugins" ]; + QTWEBKIT_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins/" ]; + GTK_PATH = [ "${i}/lib/gtk-2.0" ]; + XDG_CONFIG_DIRS = [ "${i}/etc/xdg" ]; + XDG_DATA_DIRS = [ "${i}/share" ]; + MOZ_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins" ]; + }); + + environment.extraInit = + '' + # reset TERM with new TERMINFO available (if any) + export TERM=$TERM + + unset ASPELL_CONF + for i in ${concatStringsSep " " (reverseList cfg.profiles)} ; do + if [ -d "$i/lib/aspell" ]; then + export ASPELL_CONF="dict-dir $i/lib/aspell" + fi + done + + export NIX_USER_PROFILE_DIR="/nix/var/nix/profiles/per-user/$USER" + export NIX_PROFILES="${concatStringsSep " " (reverseList cfg.profiles)}" + ''; + + }; + +} diff --git a/modules/programs/shadow.nix b/modules/programs/shadow.nix index 39359ac4293..9f62e62beb1 100644 --- a/modules/programs/shadow.nix +++ b/modules/programs/shadow.nix @@ -2,6 +2,8 @@ { config, pkgs, ... }: +with pkgs.lib; + let loginDefs = @@ -39,7 +41,6 @@ in options = { users.defaultUserShell = pkgs.lib.mkOption { - default = "/run/current-system/sw/bin/bash"; description = '' This option defines the default shell assigned to user accounts. This must not be a store path, since the path is @@ -47,6 +48,7 @@ in Rather, it should be the path of a symlink that points to the actual shell in the Nix store. ''; + type = types.uniq types.path; }; }; diff --git a/modules/programs/shell.nix b/modules/programs/shell.nix index 8348c4c25a1..d5f43a86a94 100644 --- a/modules/programs/shell.nix +++ b/modules/programs/shell.nix @@ -1,25 +1,67 @@ -# This module defines global configuration for the shells. +# This module defines a standard configuration for NixOS shells. { config, pkgs, ... }: with pkgs.lib; +let + + cfg = config.environment; + +in + { - options = { - environment.shellAliases = mkOption { - type = types.attrs; # types.attrsOf types.stringOrPath; - default = {}; - example = { - ll = "ls -lh"; - }; - description = '' - An attribute set that maps aliases (the top level attribute names in - this option) to command strings or directly to build outputs. The - aliases are added to all users' shells. - ''; - }; - }; config = { + + environment.shellAliases = + { ls = "ls --color=tty"; + ll = "ls -l"; + l = "ls -alh"; + }; + + environment.shellInit = + '' + # Set up the per-user profile. + mkdir -m 0755 -p $NIX_USER_PROFILE_DIR + if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2 + fi + + if ! test -L $HOME/.nix-profile; then + echo "creating $HOME/.nix-profile" >&2 + if test "$USER" != root; then + ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile + else + # Root installs in the system-wide profile by default. + ln -s /nix/var/nix/profiles/default $HOME/.nix-profile + fi + fi + + # Subscribe the root user to the NixOS channel by default. + if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then + echo "creating $HOME/.nix-channels with nixos-unstable subscription" >&2 + echo "http://nixos.org/channels/nixos-unstable nixos" > $HOME/.nix-channels + fi + + # Create the per-user garbage collector roots directory. + NIX_USER_GCROOTS_DIR=/nix/var/nix/gcroots/per-user/$USER + mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR + if test "$(stat --printf '%u' $NIX_USER_GCROOTS_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2 + fi + + # Set up a default Nix expression from which to install stuff. + if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then + echo "creating $HOME/.nix-defexpr" >&2 + rm -f $HOME/.nix-defexpr + mkdir $HOME/.nix-defexpr + if [ "$USER" != root ]; then + ln -s /nix/var/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root + fi + fi + ''; + }; + } diff --git a/modules/rename.nix b/modules/rename.nix index bc0ebf1f091..ef86befe9e7 100644 --- a/modules/rename.nix +++ b/modules/rename.nix @@ -66,6 +66,7 @@ in zipModules ([] # usage example: # ++ rename alias "services.xserver.slim.theme" "services.xserver.displayManager.slim.theme" ++ rename obsolete "environment.extraPackages" "environment.systemPackages" +++ rename obsolete "environment.enableBashCompletion" "programs.bash.enableCompletion" ++ rename obsolete "security.extraSetuidPrograms" "security.setuidPrograms" ++ rename obsolete "networking.enableWLAN" "networking.wireless.enable" diff --git a/modules/security/ca.nix b/modules/security/ca.nix index e42f5ffe3b8..f0897630eac 100644 --- a/modules/security/ca.nix +++ b/modules/security/ca.nix @@ -17,13 +17,9 @@ with pkgs.lib; } ]; - environment.shellInit = - '' - export OPENSSL_X509_CERT_FILE=/etc/ssl/certs/ca-bundle.crt - - export CURL_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt - export GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt - ''; + environment.variables.OPENSSL_X509_CERT_FILE.value = "/etc/ssl/certs/ca-bundle.crt"; + environment.variables.CURL_CA_BUNDLE.value = "/etc/ssl/certs/ca-bundle.crt"; + environment.variables.GIT_SSL_CAINFO.value = "/etc/ssl/certs/ca-bundle.crt"; }; diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 6ae96028979..9dd58fbab20 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -198,8 +198,7 @@ in example = "http://127.0.0.1:3128"; }; - # Environment variables for running Nix. !!! Misnomer - it's - # actually a shell script. + # Environment variables for running Nix. envVars = mkOption { internal = true; default = {}; @@ -328,11 +327,11 @@ in ftp_proxy = cfg.proxy; }; - environment.shellInit = - '' - # Set up the environment variables for running Nix. - ${concatMapStrings (n: "export ${n}=\"${getAttr n cfg.envVars}\"\n") (attrNames cfg.envVars)} + # Set up the environment variables for running Nix. + environment.variables = mapAttrs (n: v: { value = v; }) cfg.envVars; + environment.extraInit = + '' # Set up secure multi-user builds: non-root users build through the # Nix daemon. if test "$USER" != root; then diff --git a/modules/services/x11/desktop-managers/xfce.nix b/modules/services/x11/desktop-managers/xfce.nix index e22e6a12130..6197a7e10aa 100644 --- a/modules/services/x11/desktop-managers/xfce.nix +++ b/modules/services/x11/desktop-managers/xfce.nix @@ -79,10 +79,7 @@ in environment.pathsToLink = [ "/share/xfce4" "/share/themes" "/share/mime" "/share/desktop-directories" "/share/gtksourceview-2.0" ]; - environment.shellInit = - '' - export GIO_EXTRA_MODULES=${pkgs.xfce.gvfs}/lib/gio/modules - ''; + environment.variables.GIO_EXTRA_MODULES.value = "${pkgs.xfce.gvfs}/lib/gio/modules"; # Enable helpful DBus services. services.udisks2.enable = true; diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 40da6a74389..2c76361ea4b 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -409,6 +409,9 @@ in boot.blacklistedKernelModules = optionals (elem "nvidia" driverNames) [ "nouveau" "nvidiafb" ]; + environment.variables.LD_LIBRARY_PATH.list = + [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]; + environment.etc = (optionals cfg.exportConfiguration [ { source = "${configFile}"; diff --git a/modules/system/boot/modprobe.nix b/modules/system/boot/modprobe.nix index 62ac3009d10..c1c65bed64f 100644 --- a/modules/system/boot/modprobe.nix +++ b/modules/system/boot/modprobe.nix @@ -105,10 +105,7 @@ with pkgs.lib; echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe ''; - environment.shellInit = - '' - export MODULE_DIR=/run/current-system/kernel-modules/lib/modules - ''; + environment.variables.MODULE_DIR.value = "/run/current-system/kernel-modules/lib/modules"; };