Files
nixos-config/home/xdg-compat.nix
T
jory cba6b18914 Harden server and add Nix-native CI + self-hosted Gitea Actions
- caddy: security headers (X-Content-Type-Options/X-XSS-Protection/
  X-Frame-Options) on all vhosts + baseline CSP; strip SnappyMail
  upstream copies via header_down on mail.severijnse.eu
- tlsa-updater: compute TLSA 3 1 1 from cert SPKI (SHA-256), sync
  _25/_465/_993, fail-safe placeholders; coredns zone updated
- pre-commit: wire cachix/git-hooks.nix (alejandra, statix, actionlint,
  ...); CI pre-commit job over x86_64 + aarch64 matrix
- gitea: enable Gitea Actions + self-hosted runner (native:host,
  aarch64 via binfmt); add .gitea/workflows/ci.yml and local hook
- fix statix warnings (merge repeated systemd/database/configFile keys,
  inherit, bool-compare guards); add missing trailing newlines
2026-07-12 01:48:46 +02:00

175 lines
4.6 KiB
Nix

{
config,
lib,
pkgs,
...
}: let
cfg = config.xdg;
username = "someone";
fileType = lib.types.submodule {
options = {
text = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
};
source = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
};
mutable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "If true, copy the file instead of symlinking, allowing the application to modify it";
};
};
};
userOpts = _: {
options = {
configFiles = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
cacheFiles = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
dataFiles = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
stateFiles = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
homeFiles = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
};
};
mkLinkScript = baseDir: name: file: let
target =
if file.text != null
then pkgs.writeText name file.text
else file.source;
fullPath = "${baseDir}/${name}";
parentDir = builtins.dirOf fullPath;
in
if file.mutable
then ''
mkdir -p "${parentDir}"
if [ -L "${fullPath}" ]; then
# Replace symlink with a copy
rm -f "${fullPath}"
cp "${target}" "${fullPath}"
chmod +w "${fullPath}"
elif [ -e "${fullPath}" ]; then
:
else
cp "${target}" "${fullPath}"
chmod +w "${fullPath}"
fi
''
else ''
mkdir -p "${parentDir}"
if [ -L "${fullPath}" ]; then
current_target=$(readlink "${fullPath}")
if [ "$current_target" != "${target}" ]; then
rm -f "${fullPath}"
ln -s "${target}" "${fullPath}"
fi
elif [ -e "${fullPath}" ]; then
rm -f "${fullPath}"
ln -s "${target}" "${fullPath}"
else
ln -s "${target}" "${fullPath}"
fi
'';
in {
options = {
users.users = lib.mkOption {type = lib.types.attrsOf (lib.types.submodule userOpts);};
home = {
homeDirectory = lib.mkOption {
type = lib.types.path;
default = "/home/${username}";
};
file = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
};
xdg = {
configHome = lib.mkOption {
type = lib.types.path;
default = "/home/${username}/.config";
};
cacheHome = lib.mkOption {
type = lib.types.path;
default = "/home/${username}/.cache";
};
dataHome = lib.mkOption {
type = lib.types.path;
default = "/home/${username}/.local/share";
};
stateHome = lib.mkOption {
type = lib.types.path;
default = "/home/${username}/.local/state";
};
runtimeDir = lib.mkOption {
type = lib.types.str;
default = "/run/user/1000";
};
configFile = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
cacheFile = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
dataFile = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
stateFile = lib.mkOption {
type = lib.types.attrsOf fileType;
default = {};
};
};
};
config = {
users.users.${username} = {
configFiles = cfg.configFile;
cacheFiles = cfg.cacheFile;
dataFiles = cfg.dataFile;
stateFiles = cfg.stateFile;
homeFiles = config.home.file;
};
environment.sessionVariables = {
XDG_CONFIG_HOME = cfg.configHome;
XDG_CACHE_HOME = cfg.cacheHome;
XDG_DATA_HOME = cfg.dataHome;
XDG_STATE_HOME = cfg.stateHome;
};
system.activationScripts.xdgUserFiles = lib.stringAfter ["users"] ''
${lib.concatStringsSep "\n" (
lib.flatten (
lib.mapAttrsToList (
_user: userCfg:
(lib.mapAttrsToList (mkLinkScript cfg.configHome) userCfg.configFiles)
++ (lib.mapAttrsToList (mkLinkScript cfg.cacheHome) userCfg.cacheFiles)
++ (lib.mapAttrsToList (mkLinkScript cfg.dataHome) userCfg.dataFiles)
++ (lib.mapAttrsToList (mkLinkScript cfg.stateHome) userCfg.stateFiles)
++ (lib.mapAttrsToList (mkLinkScript config.home.homeDirectory) userCfg.homeFiles)
)
config.users.users
)
)}
'';
};
}