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:
parent
58e40f84e1
commit
b3f4040512
@ -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
|
||||
'';
|
||||
environment.variables.FONTCONFIG_FILE.value = "/etc/fonts/fonts.conf";
|
||||
|
||||
environment.systemPackages = [ pkgs.fontconfig ];
|
||||
|
||||
|
@ -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
|
||||
|
202
modules/config/shells-environment.nix
Normal file
202
modules/config/shells-environment.nix
Normal 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
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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}";
|
||||
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -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,7 +38,55 @@ in
|
||||
{
|
||||
options = {
|
||||
|
||||
environment.promptInit = mkOption {
|
||||
programs.bash = {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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"
|
||||
@ -47,106 +97,113 @@ in
|
||||
fi
|
||||
'';
|
||||
description = ''
|
||||
Shell script code used to initialise the shell prompt.
|
||||
Shell script code used to initialise the bash prompt.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
environment.shellInit = mkOption {
|
||||
default = "";
|
||||
example = ''export PATH=/godi/bin/:$PATH'';
|
||||
description = ''
|
||||
Shell script code called during login shell initialisation.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
environment.interactiveShellInit = mkOption {
|
||||
default = "";
|
||||
example = ''export PATH=/godi/bin/:$PATH'';
|
||||
description = ''
|
||||
Shell script code called during interactive shell initialisation.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
environment.enableBashCompletion = mkOption {
|
||||
enableCompletion = mkOption {
|
||||
default = false;
|
||||
description = "Enable Bash completion for all interactive shells.";
|
||||
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 {
|
||||
|
||||
programs.bash = {
|
||||
|
||||
shellInit = ''
|
||||
. /etc/environment
|
||||
|
||||
${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.
|
||||
|
||||
config = {
|
||||
# Only execute this file once per shell.
|
||||
if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi
|
||||
__ETC_PROFILE_SOURCED=1
|
||||
|
||||
# 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;
|
||||
};
|
||||
if [ -z "$__BASH_SHELL_INIT_DONE" ]; then
|
||||
__BASH_SHELL_INIT_DONE=1
|
||||
${cfg.shellInit}
|
||||
fi
|
||||
|
||||
# /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;
|
||||
};
|
||||
${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"
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -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@
|
@ -23,7 +23,7 @@ in
|
||||
|
||||
{
|
||||
|
||||
environment.interactiveShellInit =
|
||||
programs.bash.interactiveShellInit =
|
||||
''
|
||||
# This function is called whenever a command is not found.
|
||||
command_not_found_handle() {
|
||||
|
@ -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
|
79
modules/programs/environment.nix
Normal file
79
modules/programs/environment.nix
Normal 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)}"
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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";
|
||||
|
||||
};
|
||||
|
||||
|
@ -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)}
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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}";
|
||||
|
@ -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";
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user