Add xdg settings, cache, cleanup script

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2024-06-21 23:39:18 +03:00
parent ce37f320c2
commit 48f391e3ad
22 changed files with 245 additions and 51 deletions

View File

@@ -4,5 +4,8 @@
histFile = "/var/lib/zsh/history";
};
environment.persistence."/persist".directories = [ "/var/lib/zsh" ];
environment = {
persistence."/persist".directories = [ "/var/lib/zsh" ];
pathsToLink = [ "/share/zsh" ];
};
}

View File

@@ -12,6 +12,7 @@
./configs/nix-ld
./configs/git
./configs/gpg-agent
./scripts/cleanup
];
boot = {
@@ -63,8 +64,13 @@
};
nix = {
settings.experimental-features = [ "nix-command" "flakes" ];
settings = {
use-xdg-base-directories = true;
experimental-features = [ "nix-command" "flakes" ];
};
gc.automatic = true;
optimise.automatic = true;
};
nixpkgs.config.allowUnfree = true;

View File

@@ -0,0 +1,34 @@
set -e
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run as root or with sudo privileges."
exit 1
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/mnt/btrfs/$i"
done
btrfs subvolume delete "$1"
}
if [[ -e /mnt/btrfs && $(mountpoint -q /mnt/btrfs) ]]; then
echo "/mnt/btrfs is already mounted. Exiting."
exit 1
fi
mkdir -p /mnt/btrfs
mount /dev/mapper/luks /mnt/btrfs
if [[ -e /mnt/btrfs/root.bak ]]; then
for i in /mnt/btrfs/root.bak/*; do
delete_subvolume_recursively "$i"
done
fi
umount /mnt/btrfs
rmdir /mnt/btrfs
nix-collect-garbage -d
nix-store --gc -v

View File

@@ -0,0 +1,5 @@
{ pkgs, ... }:
{
environment.systemPackages = [ (pkgs.writeShellScriptBin "nix-cleanup" (builtins.readFile ./cleanup.sh)) ];
}

View File

@@ -11,7 +11,6 @@
networking.hostName = "eirene";
# https://github.com/NixOS/nixos-hardware/tree/master/lenovo/legion/16achg6
hardware = {
cpu.amd.updateMicrocode = true;

View File

@@ -58,6 +58,10 @@
mountpoint = "/nix";
mountOptions = ["subvol=nix" "compress=zstd" "noatime"];
};
"/cache" = {
mountpoint = "/cache";
mountOptions = ["subvol=cache" "compress=zstd" "noatime"];
};
};
};
};

View File

@@ -6,25 +6,20 @@ in {
programs.fuse.userAllowOther = lib.mkIf (users != [ ]) true;
systemd.tmpfiles.rules = lib.mkIf (users != [ ]) (
[ "d /persist/home 0755 root root -" ] ++
lib.attrsets.mapAttrsToList (user: config: "d /persist${config.home} 0700 ${user} users -") users
[
"d /persist/home 0755 root root -"
"d /cache/home 0755 root root -"
] ++
lib.attrsets.mapAttrsToList (user: config: "d /persist${config.home} 0700 ${user} users -") users ++
lib.attrsets.mapAttrsToList (user: config: "d /cache${config.home} 0700 ${user} users -") users
);
home-manager.users = lib.attrsets.mapAttrs (user: config: ({
imports = [ inputs.impermanence.nixosModules.home-manager.impermanence ];
home.persistence."/persist${config.home}" = {
allowOther = true;
directories = [
"Documents"
"Downloads"
"Music"
"Pictures"
"Videos"
"Templates"
"VMs"
"git"
];
home.persistence = {
"/persist${config.home}".allowOther = true;
"/cache${config.home}".allowOther = true;
};
})) users;
}

View File

@@ -0,0 +1,44 @@
{ config, lib, ... }:
let
users = lib.attrsets.filterAttrs (name: config: config.isNormalUser) config.users.users;
in {
home-manager.users = lib.attrsets.mapAttrs (user: cfg: (let
cacheHome = "${cfg.home}/.cache";
configHome = "${cfg.home}/.config";
dataHome = "${cfg.home}/.local/share";
stateHome = "${cfg.home}/.local/state";
xdgVmDir = "${cfg.home}/VMs";
xdgGitDir = "${cfg.home}/git";
in {
xdg = {
enable = true;
mimeApps.enable = true;
inherit cacheHome;
inherit configHome;
inherit dataHome;
inherit stateHome;
userDirs = {
enable = true;
extraConfig = {
XDG_VM_DIR = xdgVmDir;
XDG_GIT_DIR = xdgGitDir;
};
};
};
home.persistence."/persist${cfg.home}".directories = [
"Desktop" # userDirs.desktop
"Documents" # userDirs.documents
"Downloads" # userDirs.download
"Music" # userDirs.music
"Pictures" # userDirs.pictures
"Templates" # userDirs.templates
"Videos" # userDirs.videos
"VMs" # xdgVmDir
"git" # xdgGitDir
];
})) users;
}

View File

@@ -1,4 +1,4 @@
{ inputs, ... }:
{ config, inputs, ... }:
{
imports = [
@@ -6,6 +6,7 @@
./options.nix
./configs/persist
./configs/sops
./configs/xdg
];
home-manager = {
@@ -15,6 +16,7 @@
sharedModules = [{
home.stateVersion = "24.05";
systemd.user.startServices = "sd-switch";
nix.settings = config.nix.settings;
}];
};

View File

@@ -88,6 +88,9 @@
};
};
home.persistence."/persist${user.home}".directories = [ ".mozilla" ];
home.persistence = {
"/persist${user.home}".directories = [ ".mozilla" ];
"/cache${user.home}".directories = [ ".cache/mozilla" ];
};
};
}

View File

@@ -1,6 +1,8 @@
{ user ? throw "user argument is required" }: { pkgs, ... }:
{ user ? throw "user argument is required" }: { config, pkgs, ... }:
{
let
hmConfig = config.home-manager.users."${user.name}";
in {
home-manager.users."${user.name}" = {
programs.git = {
enable = true;
@@ -14,7 +16,7 @@
extraConfig.credential.helper = "store";
hooks = let
commit-msg-hook = pkgs.writeShellScriptBin "git-commit-msg" ''
git interpret-trailers --if-exists doNothing --trailer \
${pkgs.git}/bin/git interpret-trailers --if-exists doNothing --trailer \
"Signed-off-by: $(git config user.name) <$(git config user.email)>" \
--in-place "$1"
'';
@@ -22,5 +24,7 @@
commit-msg = "${commit-msg-hook}/bin/git-commit-msg";
};
};
sops.secrets."git".path = "${hmConfig.xdg.configHome}/git/credentials";
};
}

View File

@@ -1,7 +1,16 @@
{ user ? throw "user argument is required" }: { pkgs, ... }:
{ user ? throw "user argument is required" }: { config, lib, pkgs, ... }:
let
hmConfig = config.home-manager.users."${user.name}";
gpgPath = "${hmConfig.xdg.dataHome}/gnupg";
in
{
home-manager.users."${user.name}" = {
programs.gpg = {
enable = true;
homedir = gpgPath;
};
services.gpg-agent = {
enable = true;
defaultCacheTtl = 31536000;
@@ -11,22 +20,24 @@
systemd.user = {
services.gpg-agent-import = let
init = pkgs.writeShellScriptBin "import-gpg-keys" ''
export GNUPGHOME=${gpgPath}
for keyfile in "${user.home}"/.config/sops-nix/secrets/gpg-agent/*.key; do
passfile="''${keyfile%.key}.pass"
if [ -f "$passfile" ]; then
gpg --batch --yes --pinentry-mode loopback --passphrase-file "$passfile" --import "$keyfile"
${pkgs.gnupg}/bin/gpg2 --batch --yes --pinentry-mode loopback --passphrase-file "$passfile" --import "$keyfile"
else
gpg --batch --yes --import "$keyfile"
${pkgs.gnupg}/bin/gpg2 --batch --yes --import "$keyfile"
fi
gpg --with-colons --import-options show-only --import "$keyfile" | grep '^fpr' | cut -d: -f10 | while read -r KEY_ID; do
echo "$KEY_ID:6:" >> "${user.home}"/.gnupg/otrust.txt
${pkgs.gnupg}/bin/gpg2 --with-colons --import-options show-only --import "$keyfile" | grep '^fpr' | cut -d: -f10 | while read -r KEY_ID; do
echo "$KEY_ID:6:" >> "${gpgPath}"/otrust.txt
done
done
gpg --import-ownertrust "${user.home}"/.gnupg/otrust.txt
rm "${user.home}"/.gnupg/otrust.txt
${pkgs.gnupg}/bin/gpg2 --import-ownertrust "${gpgPath}"/otrust.txt
rm "${gpgPath}"/otrust.txt
'';
in {
Unit = {
@@ -43,7 +54,12 @@
Install = { WantedBy = [ "default.target" ]; };
};
tmpfiles.rules = [ "d ${user.home}/.gnupg 0700 ${user.name} users -" ];
tmpfiles.rules = [ "d ${hmConfig.xdg.dataHome}/gnupg 0700 ${user.name} users -" ];
};
sops.secrets = {
"gpg-agent/pgp.key" = { };
"gpg-agent/pgp.pass" = { };
};
};
}

View File

@@ -0,0 +1,10 @@
{ user ? throw "user argument is required" }: { config, ... }:
let
hmConfig = config.home-manager.users."${user.name}";
in
{
home-manager.users."${user.name}" = {
gtk.gtk2.configLocation = "${hmConfig.xdg.configHome}/gtk-2.0/gtkrc";
};
}

View File

@@ -1,5 +1,8 @@
{ user ? throw "user argument is required" }: { lib, pkgs, ... }:
{ user ? throw "user argument is required" }: { config, lib, pkgs, ... }:
let
hmConfig = config.home-manager.users."${user.name}";
in
{
programs.hyprland.enable = true;
@@ -8,12 +11,12 @@
enable = true;
settings = {
"$mod" = "SUPER";
"$term" = "kitty";
"$term" = "${pkgs.kitty}/bin/kitty";
bind = [
"$mod, Return, exec, $term"
"$mod, r, exec, rofi -show drun"
"$mod, b, exec, firefox"
"$mod, r, exec, ${pkgs.rofi-wayland}/bin/rofi -cache-dir ${hmConfig.xdg.cacheHome}/rofi -show drun"
"$mod, b, exec, ${pkgs.firefox}/bin/firefox"
"$mod, 1, workspace, 1"
"$mod, 2, workspace, 2"
@@ -116,9 +119,8 @@
home = {
sessionVariables.NIXOS_OZONE_WL = "1";
packages = with pkgs; [
swww
rofi-wayland
pavucontrol
];
};

View File

@@ -8,5 +8,7 @@
confirm_os_window_close 0
'';
};
home.persistence."/cache${user.home}".directories = [ ".cache/kitty" ];
};
}

View File

@@ -0,0 +1,10 @@
{ user ? throw "user argument is required" }: { pkgs, ... }:
{
home-manager.users."${user.name}" = {
home = {
packages = with pkgs; [ rofi-wayland ];
persistence."/cache${user.home}".directories = [ ".cache/rofi" ];
};
};
}

View File

@@ -0,0 +1,10 @@
{ user ? throw "user argument is required" }: { pkgs, ... }:
{
home-manager.users."${user.name}" = {
home = {
packages = with pkgs; [ swww ];
persistence."/cache${user.home}".directories = [ ".cache/swww" ];
};
};
}

View File

@@ -1,6 +1,22 @@
{ user ? throw "user argument is required" }: { pkgs, ... }:
{ user ? throw "user argument is required" }: { inputs, lib, pkgs, ... }:
{
let
configDir = ".config/Code";
cacheDirs = [
".config/Code/Cache"
".config/Code/CachedConfigurations"
".config/Code/CachedData"
".config/Code/CachedExtensionVSIXs"
".config/Code/CachedExtensions"
".config/Code/CachedProfilesData"
".config/Code/Code Cache"
".config/Code/DawnCache"
".config/Code/GPUCache"
".config/Code/Service Worker/CacheStorage"
".config/Code/Service Worker/ScriptCache"
];
inherit (pkgs.callPackage "${inputs.impermanence}/lib.nix" { }) sanitizeName concatPaths;
in {
home-manager.users."${user.name}" = {
programs.vscode = {
enable = true;
@@ -59,6 +75,28 @@
./langs/nix.nix
];
home.persistence."/persist${user.home}".directories = [ ".config/Code" ];
home.persistence = {
"/persist${user.home}".directories = [ configDir ];
# Bastard: https://github.com/microsoft/vscode/issues/3884
"/cache${user.home}".directories = cacheDirs;
};
# Some filthy fucking shit below, be warned.
# Microsoft stores cache under .config/Code instead of .cache/Code like normal people.
# Sometimes a race condition is caused if the cache bind mounts are created before the config one.
# So we do this. Sorry.
# https://github.com/nix-community/impermanence/blob/27979f1c3a0d3b9617a3563e2839114ba7d48d3f/home-manager.nix#L238
systemd.user.services = let
configDirService = "bindMount-${sanitizeName (lib.strings.escapeShellArg (concatPaths [ "/persist${user.home}" configDir ]))}.service";
in
builtins.listToAttrs (builtins.map (dir: {
name = "bindMount-${sanitizeName (lib.strings.escapeShellArg (concatPaths [ "/cache${user.home}" dir ]))}";
value = {
Unit = {
Requires = [ configDirService ];
After = [ configDirService ];
};
};
}) cacheDirs);
};
}

View File

@@ -0,0 +1,10 @@
{ user ? throw "user argument is required" }: { config, ... }:
let
hmConfig = config.home-manager.users."${user.name}";
in
{
home-manager.users."${user.name}" = {
xresources.path = "${hmConfig.xdg.configHome}/X11/xresources";
};
}

View File

@@ -4,6 +4,7 @@
home-manager.users."${user.name}" = {
programs.zsh = {
enable = true;
dotDir = ".config/zsh";
autocd = true;
history = {
path = "${user.home}/.local/share/zsh/history";

View File

@@ -8,8 +8,12 @@ in
./nogui.nix
(import ../configs/firefox { inherit user; })
(import ../configs/hyprland { inherit user; })
(import ../configs/rofi { inherit user; })
(import ../configs/swww { inherit user; })
(import ../configs/kitty { inherit user; })
(import ../configs/vscode { inherit user; })
(import ../configs/gtk { inherit user; })
(import ../configs/x { inherit user; })
(import ../configs/stylix { inherit user; })
];

View File

@@ -2,8 +2,7 @@
let
user = config.users.users.nick;
in
{
in {
imports = [
../common
(import ../configs/zsh { inherit user; })
@@ -23,7 +22,7 @@ in
home = "/home/nick";
email = "nick@karaolidis.com";
fullName = "Nikolaos Karaolidis";
description = config.users.users.nick.fullName;
description = user.fullName;
hashedPasswordFile = config.sops.secrets.nick-password.path;
extraGroups = [ "wheel" ];
linger = true;
@@ -31,14 +30,7 @@ in
};
home-manager.users.nick = {
home.homeDirectory = config.users.users.nick.home;
sops = {
defaultSopsFile = ./secrets/secrets.yaml;
secrets = {
"git" = { path = "/home/nick/.git-credentials"; };
"gpg-agent/pgp.key" = { };
"gpg-agent/pgp.pass" = { };
};
};
home.homeDirectory = user.home;
sops.defaultSopsFile = ./secrets/secrets.yaml;
};
}