Radically change the way NixOS handles environment variables and make it possible not to use Bash as the default interactive shell.

This change does two things:

* "NixOSizes" environment variables generation. This allows some more
  error-checking and opens possibilities for a modular environment
  configuration. From now on the most of environment variables are
  generated directly by the nix code. Generating sh code that
  generates environment variables is left in a few places where
  nontrivial access to a local environment state is needed.
* By doing the first change this patch untangles bash from the
  environment configuration and makes it trivial to add a support for
  other non bash-compatible shells.

Now to the sad part. This change is quite large (and I'm not sure it's
possible to split it) and yet is not quite complete, it needs some
changes to nixpkgs to be perfect.
See !!! comments in modules/config/shells-environment.nix.

Main principle behind this change is "change environment generation
and nothing else". In particular, shell configuration principles stay
exactly the same as before.
This commit is contained in:
Jan Malakhovski 2013-09-18 03:18:34 +00:00
parent 58e40f84e1
commit b3f4040512
20 changed files with 523 additions and 320 deletions

View File

@ -46,13 +46,10 @@ with pkgs.lib;
</fontconfig>
'';
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 ];

View File

@ -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

View File

@ -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 <option>list</option> 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 <option>value</option> 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
<literal>/bin/sh</literal>. 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 <literal>/bin/sh</literal>
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
'';
};
}

View File

@ -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
'';
};
};
}

View File

@ -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}";

View File

@ -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

View File

@ -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";
};
}

View File

@ -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
<option>users.defaultUserShell</option>,
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 <option>environment.shellAliases</option>
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
<literal>/bin/sh</literal>. 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"
];
};

View File

@ -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@

View File

@ -23,7 +23,7 @@ in
{
environment.interactiveShellInit =
programs.bash.interactiveShellInit =
''
# This function is called whenever a command is not found.
command_not_found_handle() {

View File

@ -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

View File

@ -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)}"
'';
};
}

View File

@ -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;
};
};

View File

@ -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
'';
};
}

View File

@ -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"

View File

@ -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";
};

View File

@ -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

View File

@ -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;

View File

@ -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}";

View File

@ -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";
};