xdg.systemDirs: init module (#1797)
There is a need to manage XDG Base Directory system directory environment variables in Home Manager modules. There is an existing mechanism in `targets.genericLinux.extraXdgDataDirs', but this does not apply to NixOS systems. Furthermore, it is important that `XDG_CONFIG_DIRS' and `XDG_DATA_DIRS' are set in both login shells (to support getty and SSH sessions) as well as the systemd user manager (to propagate them to user services and desktop environments). The first need is addressed by adding the `xdg.systemDirs' module, which configures lists of directory names for both `config' and `data' directories. These are then set in `$XDG_CONFIG_DIR/environment.d/10-home-manager.conf' and picked up by the systemd user manager. To make these, and other variables set in `systemd.user.sessionVariables', available in login shells, an additional step is added to `etc/profile.d/hm-session-vars.sh' which exports the result of `user-environment-generators/30-systemd-environment-d-generator' which is shipped with systemd. The effect of this generator is to print variables set on the systemd user manager such that shells can import these into their environment.
This commit is contained in:
parent
3b799f6ea4
commit
23769994e8
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -34,6 +34,9 @@
|
||||||
|
|
||||||
/modules/misc/xdg-user-dirs.nix @pacien
|
/modules/misc/xdg-user-dirs.nix @pacien
|
||||||
|
|
||||||
|
/modules/misc/xdg-system-dirs.nix @tadfisher
|
||||||
|
/tests/modules/misc/xdg/system-dirs.nix @tadfisher
|
||||||
|
|
||||||
/modules/programs/aria2.nix @JustinLovinger
|
/modules/programs/aria2.nix @JustinLovinger
|
||||||
|
|
||||||
/modules/programs/autojump.nix @evanjs
|
/modules/programs/autojump.nix @evanjs
|
||||||
|
|
|
@ -1980,6 +1980,26 @@ in
|
||||||
A new module is available: 'programs.nix-index'.
|
A new module is available: 'programs.nix-index'.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2021-05-10T18:50:07+00:00";
|
||||||
|
message = ''
|
||||||
|
A new module is available: 'xdg.systemDirs'. Options are:
|
||||||
|
|
||||||
|
- xdg.systemDirs.config
|
||||||
|
|
||||||
|
Extra directory names to add to $XDG_CONFIG_DIRS in the user
|
||||||
|
session.
|
||||||
|
|
||||||
|
- xdg.systemDirs.data
|
||||||
|
|
||||||
|
Extra directory names to add to $XDG_DATA_DIRS in the user
|
||||||
|
session.
|
||||||
|
|
||||||
|
These variables are visible in both systemd user services and
|
||||||
|
login shells.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
49
modules/misc/xdg-system-dirs.nix
Normal file
49
modules/misc/xdg-system-dirs.nix
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg.systemDirs;
|
||||||
|
|
||||||
|
configDirs = concatStringsSep ":" cfg.config;
|
||||||
|
|
||||||
|
dataDirs = concatStringsSep ":" cfg.data;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ tadfisher ];
|
||||||
|
|
||||||
|
options.xdg.systemDirs = {
|
||||||
|
config = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''[ "/etc/xdg" ]'';
|
||||||
|
description = ''
|
||||||
|
Directory names to add to <envar>XDG_CONFIG_DIRS</envar>
|
||||||
|
in the user session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
data = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''[ "/usr/share" "/usr/local/share" ]'';
|
||||||
|
description = ''
|
||||||
|
Directory names to add to <envar>XDG_DATA_DIRS</envar>
|
||||||
|
in the user session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf (cfg.config != [ ]) {
|
||||||
|
systemd.user.sessionVariables.XDG_CONFIG_DIRS =
|
||||||
|
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.data != [ ]) {
|
||||||
|
systemd.user.sessionVariables.XDG_DATA_DIRS =
|
||||||
|
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ let
|
||||||
(loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; })
|
(loadModule ./misc/tmpfiles.nix { condition = hostPlatform.isLinux; })
|
||||||
(loadModule ./misc/version.nix { })
|
(loadModule ./misc/version.nix { })
|
||||||
(loadModule ./misc/vte.nix { })
|
(loadModule ./misc/vte.nix { })
|
||||||
|
(loadModule ./misc/xdg-system-dirs.nix { condition = hostPlatform.isLinux; })
|
||||||
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
|
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
|
||||||
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
||||||
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
||||||
|
|
|
@ -333,6 +333,11 @@ in
|
||||||
unset systemdStatus
|
unset systemdStatus
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Export environment variables in systemd.user.sessionVariables to login shells.
|
||||||
|
home.sessionVariablesExtra = optionalString (cfg.sessionVariables != {}) ''
|
||||||
|
export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)
|
||||||
|
'';
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,19 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
cfg = config.targets.genericLinux;
|
||||||
|
|
||||||
profileDirectory = config.home.profileDirectory;
|
profileDirectory = config.home.profileDirectory;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "targets" "genericLinux" "extraXdgDataDirs" ] [
|
||||||
|
"xdg"
|
||||||
|
"systemDirs"
|
||||||
|
"data"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
options.targets.genericLinux = {
|
options.targets.genericLinux = {
|
||||||
enable = mkEnableOption "" // {
|
enable = mkEnableOption "" // {
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -14,39 +24,20 @@ in {
|
||||||
GNU/Linux distributions other than NixOS.
|
GNU/Linux distributions other than NixOS.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraXdgDataDirs = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
example = [ "/usr/share" "/usr/local/share" ];
|
|
||||||
description = ''
|
|
||||||
List of directory names to add to <envar>XDG_DATA_DIRS</envar>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.targets.genericLinux.enable {
|
config = mkIf cfg.enable {
|
||||||
home.sessionVariables = let
|
xdg.systemDirs.data = [
|
||||||
profiles =
|
# Nix profiles
|
||||||
[ "\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default" profileDirectory ];
|
"\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share"
|
||||||
dataDirs = concatStringsSep ":"
|
"${profileDirectory}/share"
|
||||||
(map (profile: "${profile}/share") profiles
|
|
||||||
++ config.targets.genericLinux.extraXdgDataDirs);
|
|
||||||
|
|
||||||
# https://github.com/archlinux/svntogit-packages/blob/packages/ncurses/trunk/PKGBUILD
|
# Distribution-specific
|
||||||
# https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules
|
"/usr/share/ubuntu"
|
||||||
# https://src.fedoraproject.org/rpms/ncurses/blob/main/f/ncurses.spec
|
"/usr/local/share"
|
||||||
# https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-libs/ncurses/ncurses-6.2-r1.ebuild
|
"/usr/share"
|
||||||
distroTerminfoDirs = concatStringsSep ":" [
|
"/var/lib/snapd/desktop"
|
||||||
"/etc/terminfo" # debian, fedora, gentoo
|
|
||||||
"/lib/terminfo" # debian
|
|
||||||
"/usr/share/terminfo" # package default, all distros
|
|
||||||
];
|
];
|
||||||
in {
|
|
||||||
XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS";
|
|
||||||
TERMINFO_DIRS =
|
|
||||||
"${profileDirectory}/share/terminfo:$TERMINFO_DIRS\${TERMINFO_DIRS:+:}${distroTerminfoDirs}";
|
|
||||||
};
|
|
||||||
|
|
||||||
home.sessionVariablesExtra = ''
|
home.sessionVariablesExtra = ''
|
||||||
. "${pkgs.nix}/etc/profile.d/nix.sh"
|
. "${pkgs.nix}/etc/profile.d/nix.sh"
|
||||||
|
@ -62,8 +53,20 @@ in {
|
||||||
. "${profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
. "${profileDirectory}/etc/profile.d/hm-session-vars.sh"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
systemd.user.sessionVariables = {
|
systemd.user.sessionVariables = let
|
||||||
|
# https://github.com/archlinux/svntogit-packages/blob/packages/ncurses/trunk/PKGBUILD
|
||||||
|
# https://salsa.debian.org/debian/ncurses/-/blob/master/debian/rules
|
||||||
|
# https://src.fedoraproject.org/rpms/ncurses/blob/main/f/ncurses.spec
|
||||||
|
# https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-libs/ncurses/ncurses-6.2-r1.ebuild
|
||||||
|
distroTerminfoDirs = concatStringsSep ":" [
|
||||||
|
"/etc/terminfo" # debian, fedora, gentoo
|
||||||
|
"/lib/terminfo" # debian
|
||||||
|
"/usr/share/terminfo" # package default, all distros
|
||||||
|
];
|
||||||
|
in {
|
||||||
NIX_PATH = "$HOME/.nix-defexpr/channels\${NIX_PATH:+:}$NIX_PATH";
|
NIX_PATH = "$HOME/.nix-defexpr/channels\${NIX_PATH:+:}$NIX_PATH";
|
||||||
|
TERMINFO_DIRS =
|
||||||
|
"${profileDirectory}/share/terminfo:$TERMINFO_DIRS\${TERMINFO_DIRS:+:}${distroTerminfoDirs}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ let
|
||||||
export XDG_CACHE_HOME="/home/hm-user/.cache"
|
export XDG_CACHE_HOME="/home/hm-user/.cache"
|
||||||
export XDG_CONFIG_HOME="/home/hm-user/.config"
|
export XDG_CONFIG_HOME="/home/hm-user/.config"
|
||||||
export XDG_DATA_HOME="/home/hm-user/.local/share"
|
export XDG_DATA_HOME="/home/hm-user/.local/share"
|
||||||
|
export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)
|
||||||
'';
|
'';
|
||||||
|
|
||||||
darwinExpected = ''
|
darwinExpected = ''
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
xdg-mime-apps-basics = ./mime-apps-basics.nix;
|
xdg-mime-apps-basics = ./mime-apps-basics.nix;
|
||||||
xdg-file-attr-names = ./file-attr-names.nix;
|
xdg-file-attr-names = ./file-attr-names.nix;
|
||||||
|
xdg-system-dirs = ./system-dirs.nix;
|
||||||
}
|
}
|
||||||
|
|
25
tests/modules/misc/xdg/system-dirs.nix
Normal file
25
tests/modules/misc/xdg/system-dirs.nix
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
xdg.systemDirs.config = [ "/etc/xdg" "/foo/bar" ];
|
||||||
|
xdg.systemDirs.data = [ "/usr/local/share" "/usr/share" "/baz/quux" ];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
envFile=home-files/.config/environment.d/10-home-manager.conf
|
||||||
|
assertFileExists $envFile
|
||||||
|
assertFileContent $envFile ${
|
||||||
|
pkgs.writeText "expected" ''
|
||||||
|
LOCALE_ARCHIVE_2_27=${pkgs.glibcLocales}/lib/locale/locale-archive
|
||||||
|
XDG_CONFIG_DIRS=/etc/xdg:/foo/bar''${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}
|
||||||
|
XDG_DATA_DIRS=/usr/local/share:/usr/share:/baz/quux''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}
|
||||||
|
''
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh
|
||||||
|
assertFileExists $sessionVarsFile
|
||||||
|
assertFileContains $sessionVarsFile \
|
||||||
|
'export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -15,6 +15,11 @@
|
||||||
V_int=1
|
V_int=1
|
||||||
V_str=2
|
V_str=2
|
||||||
''}
|
''}
|
||||||
|
|
||||||
|
sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh
|
||||||
|
assertFileExists $sessionVarsFile
|
||||||
|
assertFileContains $sessionVarsFile \
|
||||||
|
'export $(${pkgs.systemd}/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)'
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,36 @@
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
{
|
let
|
||||||
|
expectedXdgDataDirs = concatStringsSep ":" [
|
||||||
|
"\${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share"
|
||||||
|
"/home/hm-user/.nix-profile/share"
|
||||||
|
"/usr/share/ubuntu"
|
||||||
|
"/usr/local/share"
|
||||||
|
"/usr/share"
|
||||||
|
"/var/lib/snapd/desktop"
|
||||||
|
"/foo"
|
||||||
|
];
|
||||||
|
|
||||||
|
in {
|
||||||
config = {
|
config = {
|
||||||
targets.genericLinux = {
|
targets.genericLinux.enable = true;
|
||||||
enable = true;
|
|
||||||
extraXdgDataDirs = [ "/foo" ];
|
xdg.systemDirs.data = [ "/foo" ];
|
||||||
};
|
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertFileExists home-path/etc/profile.d/hm-session-vars.sh
|
envFile=home-files/.config/environment.d/10-home-manager.conf
|
||||||
|
assertFileExists $envFile
|
||||||
|
assertFileContains $envFile \
|
||||||
|
'XDG_DATA_DIRS=${expectedXdgDataDirs}''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}'
|
||||||
|
assertFileContains $envFile \
|
||||||
|
'TERMINFO_DIRS=/home/hm-user/.nix-profile/share/terminfo:$TERMINFO_DIRS''${TERMINFO_DIRS:+:}/etc/terminfo:/lib/terminfo:/usr/share/terminfo'
|
||||||
|
|
||||||
assertFileContains \
|
sessionVarsFile=home-path/etc/profile.d/hm-session-vars.sh
|
||||||
home-path/etc/profile.d/hm-session-vars.sh \
|
assertFileExists $sessionVarsFile
|
||||||
'export XDG_DATA_DIRS="''${NIX_STATE_DIR:-/nix/var/nix}/profiles/default/share:/home/hm-user/.nix-profile/share:/foo''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS"'
|
assertFileContains $sessionVarsFile \
|
||||||
assertFileContains \
|
|
||||||
home-path/etc/profile.d/hm-session-vars.sh \
|
|
||||||
'. "${pkgs.nix}/etc/profile.d/nix.sh"'
|
'. "${pkgs.nix}/etc/profile.d/nix.sh"'
|
||||||
|
|
||||||
assertFileContains \
|
|
||||||
home-path/etc/profile.d/hm-session-vars.sh \
|
|
||||||
'export TERMINFO_DIRS="/home/hm-user/.nix-profile/share/terminfo:$TERMINFO_DIRS''${TERMINFO_DIRS:+:}/etc/terminfo:/lib/terminfo:/usr/share/terminfo"'
|
|
||||||
assertFileContains \
|
assertFileContains \
|
||||||
home-path/etc/profile.d/hm-session-vars.sh \
|
home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
'export TERM="$TERM"'
|
'export TERM="$TERM"'
|
||||||
|
|
Loading…
Reference in a new issue