Add custom impermanence module

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2024-08-08 22:03:15 +03:00
parent 5e57d63a54
commit 22e0150a65
69 changed files with 777 additions and 494 deletions

5
.gitmodules vendored
View File

@@ -7,8 +7,3 @@
path = submodules/home-manager path = submodules/home-manager
url = https://github.com/karaolidis/home-manager.git url = https://github.com/karaolidis/home-manager.git
branch = integration branch = integration
[submodule "submodules/impermanence"]
path = submodules/impermanence
url = https://github.com/karaolidis/impermanence
branch = integration

23
flake.lock generated
View File

@@ -64,11 +64,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1722408750, "lastModified": 1723023714,
"narHash": "sha256-1nKAicPoQVrCcatj84LnAagtCeriztszBlmB2rllnT8=", "narHash": "sha256-AyQvRwyaSvzoknqzKmhKRbDsUpq5Igwl8sUS7syshWg=",
"owner": "karaolidis", "owner": "karaolidis",
"repo": "home-manager", "repo": "home-manager",
"rev": "bd83e8a0c3b6af03eb9d9a22251c9e2145d2974c", "rev": "82b0b4fbd2a54f787f28853f7ef8c99448d8824b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -78,22 +78,6 @@
"type": "github" "type": "github"
} }
}, },
"impermanence": {
"locked": {
"lastModified": 1722433536,
"narHash": "sha256-Bvy4hGg5jgOlyl3KX3X986g5r06aBJKJY79Z+VWP3vg=",
"owner": "karaolidis",
"repo": "impermanence",
"rev": "720ee9a1b00516214d05e2b509e4fe26c2368d90",
"type": "github"
},
"original": {
"owner": "karaolidis",
"ref": "integration",
"repo": "impermanence",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1722433574, "lastModified": 1722433574,
@@ -146,7 +130,6 @@
"ags": "ags", "ags": "ags",
"disko": "disko", "disko": "disko",
"home-manager": "home-manager", "home-manager": "home-manager",
"impermanence": "impermanence",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nur": "nur", "nur": "nur",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",

View File

@@ -31,20 +31,6 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
impermanence = {
# --- Official
# type = "github";
# owner = "nix-community"
# repo = "impermanence";
# --- Fork
type = "github";
owner = "karaolidis";
repo = "impermanence";
ref = "integration";
# --- Local
# url = "git+file:./submodules/impermanence";
};
disko = { disko = {
url = "github:nix-community/disko"; url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";

View File

@@ -1,4 +1,4 @@
{ ... }: { config, ... }:
{ {
hardware.bluetooth = { hardware.bluetooth = {
enable = true; enable = true;
@@ -8,5 +8,8 @@
}; };
}; };
environment.persistence."/persist".directories = [ "/var/lib/bluetooth" ]; environment.persistence."/persist"."/var/lib/bluetooth" = { };
systemd.services.bluetooth.after = [
config.environment.persistence."/persist"."/var/lib/bluetooth".mount
];
} }

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { config, pkgs, ... }:
{ {
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;
@@ -18,7 +18,12 @@
}; };
environment = { environment = {
persistence."/persist".directories = [ "/var/lib/docker" ]; persistence."/persist"."/var/lib/docker" = { };
systemPackages = with pkgs; [ docker-compose ]; systemPackages = with pkgs; [ docker-compose ];
}; };
systemd = {
services.docker.after = [ config.environment.persistence."/persist"."/var/lib/docker".mount ];
sockets.docker.after = [ config.environment.persistence."/persist"."/var/lib/docker".mount ];
};
} }

View File

@@ -1,6 +1,6 @@
{ inputs, pkgs, ... }: { config, pkgs, ... }:
{ {
imports = [ inputs.impermanence.nixosModules.impermanence ]; imports = [ ./options.nix ];
boot.initrd.systemd = boot.initrd.systemd =
let let
@@ -12,35 +12,35 @@
]; ];
in in
{ {
enable = true;
initrdBin = bins; initrdBin = bins;
services.impermanence = { services.impermanence = {
description = "Rollback BTRFS subvolumes to a pristine state"; description = "Rollback BTRFS subvolumes to a pristine state";
serviceConfig.Type = "oneshot";
wantedBy = [ "initrd.target" ]; wantedBy = [ "initrd.target" ];
before = [ "sysroot.mount" ]; before = [ "sysroot.mount" ];
after = [ "cryptsetup.target" ]; after = [ "cryptsetup.target" ];
unitConfig.DefaultDependencies = "no"; unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
path = bins; path = bins;
script = builtins.readFile ./impermanence.sh; script = builtins.readFile ./scripts/wipe.sh;
}; };
}; };
fileSystems = { # https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/administration/systemd-state.section.md
"/persist".neededForBoot = true; # https://github.com/NixOS/nixpkgs/pull/286140/files
"/cache".neededForBoot = true; # https://git.eisfunke.com/config/nixos/-/blob/e65e1dc21d06d07b454005762b177ef151f8bfb6/nixos/machine-id.nix
}; sops.secrets."machineId".mode = "0444";
environment.persistence."/persist" = { environment = {
hideMounts = true; etc."machine-id".source = pkgs.runCommandLocal "machine-id-link" { } ''
directories = [ ln -s ${config.sops.secrets."machineId".path} $out
"/etc/nixos" '';
"/var/lib/nixos"
"/var/lib/systemd/coredump" persistence."/persist" = {
"/var/log" "/etc/nixos" = { };
]; "/var/lib/nixos" = { };
files = [ "/etc/machine-id" ]; "/var/lib/systemd" = { };
"/var/log" = { };
};
}; };
} }

View File

@@ -0,0 +1,247 @@
{
config,
lib,
utils,
...
}:
let
cfg = config.environment.persistence;
# ["/home/user/" "/.screenrc"] -> ["home" "user" ".screenrc"]
splitPath =
paths:
(builtins.filter (s: builtins.typeOf s == "string" && s != "") (
builtins.concatMap (builtins.split "/") paths
));
# ["/home/user/" "/.screenrc"] -> "/home/user/.screenrc"
mergePaths =
paths:
let
prefix = lib.strings.optionalString (lib.strings.hasPrefix "/" (builtins.head paths)) "/";
path = lib.strings.concatStringsSep "/" (splitPath paths);
in
prefix + path;
# "/home/user/.screenrc" -> ["/home", "/home/user"]
parentsOf =
path:
let
prefix = lib.strings.optionalString (lib.strings.hasPrefix "/" path) "/";
split = splitPath [ path ];
parents = lib.lists.take ((lib.lists.length split) - 1) split;
in
lib.lists.foldl' (
state: item:
state
++ [
(mergePaths [
(if state != [ ] then lib.lists.last state else prefix)
item
])
]
) [ ] parents;
in
{
options.environment.persistence =
with lib;
with types;
let
isPathLike = strings.hasPrefix "/";
in
mkOption {
type = (
addCheck (attrsOf (
attrsOf (
submodule (
{ name, config, ... }:
{
options = {
enable = mkOption {
type = bool;
default = true;
description = "Whether to enable the item.";
};
service = mkOption {
type = str;
readOnly = true;
description = ''
Systemd service that prepares and syncs the item.
Can be used as a dependency in other units.
'';
};
mount = mkOption {
type = str;
readOnly = true;
description = ''
Systemd mount that binds the item.
Can be used as a dependency in other units.
'';
};
_path = mkOption {
type = str;
internal = true;
default = name;
};
_sourceRoot = mkOption {
type = str;
internal = true;
};
_source = mkOption {
type = str;
internal = true;
};
_targetRoot = mkOption {
type = str;
internal = true;
};
_target = mkOption {
type = str;
internal = true;
};
};
}
)
)
)) (attrs: lists.all isPathLike (builtins.attrNames attrs))
);
apply =
ps:
builtins.mapAttrs (
persistence: items:
builtins.mapAttrs (
_: config:
let
_path = config._path;
_sourceRoot = persistence;
_source = mergePaths [
_sourceRoot
_path
];
_targetRoot =
let
parents = lists.reverseList (parentsOf _path);
in
lists.foldl' (
acc: parent:
if acc == "/" then
lists.findFirst (
otherPersistence: lists.any (other: parent == other) (builtins.attrNames ps.${otherPersistence})
) "/" (builtins.attrNames ps)
else
acc
) "/" parents;
_target = mergePaths [
_targetRoot
_path
];
in
config
// {
inherit
_sourceRoot
_source
_targetRoot
_target
;
service = "${utils.escapeSystemdPath _target}.service";
mount = "${utils.escapeSystemdPath _target}.mount";
}
) items
) ps;
default = { };
description = "Persistence config.";
};
config =
let
all = lib.lists.flatten (builtins.concatMap builtins.attrValues (builtins.attrValues cfg));
in
{
fileSystems = builtins.mapAttrs (_: _: { neededForBoot = true; }) cfg;
systemd = {
mounts = builtins.map (c: {
description = c._path;
requiredBy = [ "local-fs.target" ];
requires = [ c.service ];
bindsTo = [ c.service ];
after = [ c.service ];
unitConfig = {
ConditionPathExists = [ (lib.strings.escape [ " " ] c._source) ];
RefuseManualStart = "yes";
RefuseManualStop = "yes";
};
what = c._source;
where = c._target;
options = lib.strings.concatStringsSep "," ([
"bind"
"X-fstrim.notrim"
"x-gvfs-hide"
]);
}) all;
services = builtins.listToAttrs (
builtins.map (c: {
name = utils.escapeSystemdPath c._target;
value = {
description = c._path;
after = [ "local-fs-pre.target" ];
requiredBy = [
"local-fs.target"
c.mount
];
before = [
"local-fs.target"
c.mount
"umount.target"
];
conflicts = [ "umount.target" ];
unitConfig.DefaultDependencies = "no";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = "yes";
};
script = ''
source=${lib.strings.escapeShellArg c._sourceRoot}
target=${lib.strings.escapeShellArg c._targetRoot}
path=${lib.strings.escapeShellArg c._path}
${builtins.readFile ./scripts/start.sh}
'';
preStop = ''
source=${lib.strings.escapeShellArg c._sourceRoot}
target=${lib.strings.escapeShellArg c._targetRoot}
path=${lib.strings.escapeShellArg c._path}
${builtins.readFile ./scripts/stop.sh}
'';
};
}) all
);
};
assertions =
let
paths = builtins.map (c: c._path) all;
duplicates = lib.lists.filter (t: lib.lists.count (o: o == t) paths > 1) (lib.lists.unique paths);
in
[
{
assertion = lib.lists.length duplicates == 0;
message = "Each target must be defined under a single persistence. Duplicate targets found: ${lib.concatStringsSep ", " duplicates}";
}
];
};
}

View File

@@ -0,0 +1,19 @@
echo "Starting impermanence mount with source: $source, target: $target, path: $path."
source_current="$source"
target_current="$target"
IFS='/' read -ra path_parts <<< "$path"
unset "path_parts[-1]"
for part in "${path_parts[@]}"; do
source_current="$source_current/$part"
target_current="$target_current/$part"
if [ ! -d "$source_current" ]; then
break
fi
read -r mode owner group <<< "$(stat -c '%a %u %g' "$source_current")"
install -d -m "$mode" -o "$owner" -g "$group" "$target_current"
done

View File

@@ -0,0 +1,38 @@
echo "Stopping impermanence mount with source: $source, target: $target, path: $path."
source_current="$source"
target_current="$target"
IFS='/' read -ra path_parts <<< "$path"
unset "path_parts[-1]"
for part in "${path_parts[@]}"; do
source_current="$source_current/$part"
target_current="$target_current/$part"
if [ ! -d "$target_current" ]; then
break
fi
if [ -d "$source_current" ]; then
continue
fi
read -r mode owner group <<< "$(stat -c '%a %u %g' "$target_current")"
install -d -m "$mode" -o "$owner" -g "$group" "$source_current"
done
source=$(realpath -m "$source/$path")
target=$(realpath -m "$target/$path")
if [ ! -e "$target" ] || { [ -d "$target" ] && [ -z "$(ls -A "$target")" ]; } || { [ -f "$target" ] && [ ! -s "$target" ]; }; then
exit 0
fi
if [ -e "$source" ]; then
>&2 echo "Error: Source $source already exists. Cannot move $target to $source."
exit 1
fi
echo "Moving target $target to source $source."
mv "$target" "$source"

View File

@@ -11,7 +11,7 @@ mount /dev/mapper/luks /mnt/btrfs
if [[ -e /mnt/btrfs/@ ]]; then if [[ -e /mnt/btrfs/@ ]]; then
mkdir -p /mnt/btrfs/@.bak mkdir -p /mnt/btrfs/@.bak
timestamp=$(date --date="@$(stat -c %Y /mnt/btrfs/@)" "+%Y-%m-%-d_%H:%M:%S") timestamp=$(date --date="@$(stat -c %Y /mnt/btrfs/@)" "+%Y-%m-%d_%H:%M:%S")
mv /mnt/btrfs/@ "/mnt/btrfs/@.bak/$timestamp" mv /mnt/btrfs/@ "/mnt/btrfs/@.bak/$timestamp"
fi fi

View File

@@ -1,6 +1,9 @@
{ ... }: { config, ... }:
{ {
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
environment.persistence."/persist".directories = [ "/etc/NetworkManager/system-connections" ]; environment.persistence."/persist"."/etc/NetworkManager/system-connections" = { };
systemd.services.NetworkManager.after = [
config.environment.persistence."/persist"."/etc/NetworkManager/system-connections".mount
];
} }

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, config, ... }:
{ {
services = { services = {
printing = { printing = {
@@ -19,7 +19,19 @@
}; };
environment.persistence."/persist" = { environment.persistence."/persist" = {
directories = [ "/var/lib/cups/ppd" ]; "/var/lib/cups/ppd" = { };
files = [ "/var/lib/cups/printers.conf" ]; "/var/lib/cups/printers.conf" = { };
}; };
systemd = {
services.cups.after = [
config.environment.persistence."/persist"."/var/lib/cups/ppd".mount
config.environment.persistence."/persist"."/var/lib/cups/printers.conf".mount
];
sockets.cups.after = [
config.environment.persistence."/persist"."/var/lib/cups/ppd".mount
config.environment.persistence."/persist"."/var/lib/cups/printers.conf".mount
];
};
} }

View File

@@ -3,7 +3,7 @@
imports = [ inputs.sops-nix.nixosModules.sops ]; imports = [ inputs.sops-nix.nixosModules.sops ];
environment = { environment = {
persistence."/persist".files = [ "/etc/ssh/ssh_host_ed25519_key" ]; persistence."/persist"."/etc/ssh/ssh_host_ed25519_key" = { };
systemPackages = with pkgs; [ sops ]; systemPackages = with pkgs; [ sops ];
}; };

View File

@@ -6,7 +6,7 @@
}; };
environment = { environment = {
persistence."/persist".directories = [ "/var/lib/zsh" ]; persistence."/persist"."/var/lib/zsh" = { };
pathsToLink = [ "/share/zsh" ]; pathsToLink = [ "/share/zsh" ];
}; };
} }

View File

@@ -1,10 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, pkgs, ... }: { config, pkgs, ... }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
nixpkgs.overlays = [ nixpkgs.overlays = [
(final: prev: { (final: prev: {
@@ -17,12 +15,12 @@ in
programs.adb.enable = true; programs.adb.enable = true;
services.gvfs.enable = true; services.gvfs.enable = true;
users.users.${username}.extraGroups = [ "adbusers" ]; users.users.${user}.extraGroups = [ "adbusers" ];
environment.persistence."/persist".users.${username}.files = [ environment.persistence."/persist" = {
"${hmConfig.xdg.relativeDataHome}/android/adbkey" "${home}/.local/share/android/adbkey" = { };
"${hmConfig.xdg.relativeDataHome}/android/adbkey.pub" "${home}/.local/share/android/adbkey.pub" = { };
]; };
home-manager.users.${username}.home.sessionVariables.ANDROID_USER_HOME = "${hmConfig.xdg.dataHome}/android"; home-manager.users.${user}.home.sessionVariables.ANDROID_USER_HOME = "${home}/.local/share/android";
} }

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,7 +9,7 @@
... ...
}: }:
{ {
home-manager.users.${username}.systemd.user.services.mpris-proxy = { home-manager.users.${user}.systemd.user.services.mpris-proxy = {
Unit = { Unit = {
Description = "MPRIS proxy"; Description = "MPRIS proxy";
Requires = [ "sound.target" ]; Requires = [ "sound.target" ];

View File

@@ -1,12 +1,13 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ lib, pkgs, ... }: { lib, pkgs, ... }:
{ {
users.users.${username}.extraGroups = [ users.users.${user}.extraGroups = [
"video" "video"
"inputs" "inputs"
]; ];
home-manager.users.${username}.home.packages = with pkgs; [ brightnessctl ]; home-manager.users.${user}.home.packages = with pkgs; [ brightnessctl ];
} }

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username}.programs.btop = { home-manager.users.${user}.programs.btop = {
enable = true; enable = true;
settings = { settings = {
theme_background = false; theme_background = false;

View File

@@ -1,15 +1,14 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
inputs, inputs,
utils,
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
virtualisation.docker.rootless = { virtualisation.docker.rootless = {
enable = true; enable = true;
@@ -29,9 +28,16 @@ in
}; };
}; };
environment.persistence."/persist".users.${username}.directories = [ environment.persistence."/persist"."${home}/.local/share/docker" = { };
"${hmConfig.xdg.relativeDataHome}/docker"
];
home-manager.users.${username}.home.packages = with pkgs; [ docker-compose ]; systemd.user = {
services.docker.after = [
config.environment.persistence."/persist"."${home}/.local/share/docker".mount
];
sockets.docker.after = [
config.environment.persistence."/persist"."${home}/.local/share/docker".mount
];
};
home-manager.users.${user}.home.packages = with pkgs; [ docker-compose ];
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username}.programs.fastfetch.enable = true; home-manager.users.${user}.programs.fastfetch.enable = true;
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username}.home.packages = with pkgs; [ ffmpeg ]; home-manager.users.${user}.home.packages = with pkgs; [ ffmpeg ];
} }

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,11 +9,10 @@
... ...
}: }:
let let
userConfig = config.users.users.${username}; userConfig = config.users.users.${user};
hmConfig = config.home-manager.users.${username};
in in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
programs.git = { programs.git = {
enable = true; enable = true;
lfs.enable = true; lfs.enable = true;
@@ -30,7 +30,7 @@ in
core.fsmonitor = true; core.fsmonitor = true;
feature.manyFiles = true; feature.manyFiles = true;
fetch.writeCommitGraph = true; fetch.writeCommitGraph = true;
http.cookiefile = "${hmConfig.xdg.configHome}/git/cookies"; http.cookiefile = "${home}/.config/git/cookies";
}; };
hooks = { hooks = {
@@ -45,8 +45,8 @@ in
}; };
sops.secrets = { sops.secrets = {
"git/credentials".path = "${hmConfig.xdg.configHome}/git/credentials"; "git/credentials".path = "${home}/.config/git/credentials";
"git/cookies".path = "${hmConfig.xdg.configHome}/git/cookies"; "git/cookies".path = "${home}/.config/git/cookies";
}; };
}; };
} }

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,16 +8,11 @@
pkgs, pkgs,
... ...
}: }:
let
userConfig = config.users.users.${username};
hmConfig = config.home-manager.users.${username};
gpgPath = "${hmConfig.xdg.dataHome}/gnupg";
in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
programs.gpg = { programs.gpg = {
enable = true; enable = true;
homedir = gpgPath; homedir = "${home}/.local/share/gnupg";
}; };
services.gpg-agent = { services.gpg-agent = {
@@ -37,8 +33,8 @@ in
gnupg gnupg
]; ];
runtimeEnv = { runtimeEnv = {
GNUPGHOME = gpgPath; GNUPGHOME = "${home}/.local/share/gnupg";
HOME = userConfig.home; HOME = home;
}; };
text = builtins.readFile ./import-gpg-keys.sh; text = builtins.readFile ./import-gpg-keys.sh;
} }
@@ -67,7 +63,7 @@ in
Install.WantedBy = [ "default.target" ]; Install.WantedBy = [ "default.target" ];
}; };
tmpfiles.rules = [ "d ${gpgPath} 0700 ${username} users -" ]; tmpfiles.rules = [ "d ${home}/.local/share/gnupg 0700 ${user} users -" ];
}; };
sops.secrets = { sops.secrets = {

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, inputs, ... }: { config, inputs, ... }:
{ {
@@ -15,7 +16,7 @@
useUserPackages = true; useUserPackages = true;
useGlobalPkgs = true; useGlobalPkgs = true;
users.${username} = { users.${user} = {
home.stateVersion = "24.11"; home.stateVersion = "24.11";
systemd.user.startServices = true; systemd.user.startServices = true;
nix.settings = config.nix.settings; nix.settings = config.nix.settings;

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username}.home.packages = with pkgs; [ imagemagick ]; home-manager.users.${user}.home.packages = with pkgs; [ imagemagick ];
} }

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ ncdu ]; home.packages = with pkgs; [ ncdu ];
xdg.configFile."ncdu/config".text = '' xdg.configFile."ncdu/config".text = ''

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username}.programs.neovim = { home-manager.users.${user}.programs.neovim = {
enable = true; enable = true;
defaultEditor = true; defaultEditor = true;
viAlias = true; viAlias = true;

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ inputs, ... }: { inputs, ... }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ inputs.nur.hmModules.nur ]; imports = [ inputs.nur.hmModules.nur ];
}; };
} }

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ home.packages = with pkgs; [
wireplumber wireplumber
playerctl playerctl

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username}.programs.ranger.enable = true; home-manager.users.${user}.programs.ranger.enable = true;
} }

View File

@@ -1,24 +1,18 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, inputs, ... }:
{ {
config, environment.persistence."/persist"."${home}/.config/sops-nix/key.txt" = { };
inputs,
lib,
...
}:
let
userConfig = config.users.users.${username};
hmConfig = config.home-manager.users.${username};
sopsKeyPath = "${hmConfig.xdg.relativeConfigHome}/sops-nix/key.txt";
in
{
environment.persistence."/persist".users.${username}.files = [ sopsKeyPath ];
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ inputs.sops-nix.homeManagerModules.sops ]; imports = [ inputs.sops-nix.homeManagerModules.sops ];
sops.age.keyFile = "${userConfig.home}/${sopsKeyPath}"; sops.age.keyFile = "${home}/.config/sops-nix/key.txt";
home.sessionVariables.SOPS_AGE_KEY_FILE = "${userConfig.home}/${sopsKeyPath}"; home.sessionVariables.SOPS_AGE_KEY_FILE = "${home}/.config/sops-nix/key.txt";
systemd.user.services.sops-nix.Unit.After = [
config.environment.persistence."/persist"."${home}/.config/sops-nix/key.txt".mount
];
}; };
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, ... }: { config, utils, ... }:
{ {
networking.firewall = { networking.firewall = {
allowedTCPPorts = [ 22000 ]; allowedTCPPorts = [ 22000 ];
@@ -14,17 +15,17 @@
sops.secrets = { sops.secrets = {
# openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:3072 # openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:3072
"syncthing/key" = { "syncthing/key" = {
owner = username; owner = user;
group = "users"; group = "users";
}; };
# openssl req -new -x509 -key key.pem -out cert.pem -days 9999 -subj "/CN=syncthing" # openssl req -new -x509 -key key.pem -out cert.pem -days 9999 -subj "/CN=syncthing"
"syncthing/cert" = { "syncthing/cert" = {
owner = username; owner = user;
group = "users"; group = "users";
}; };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
services.syncthing = { services.syncthing = {
enable = true; enable = true;
key = config.sops.secrets."syncthing/key".path; key = config.sops.secrets."syncthing/key".path;
@@ -40,6 +41,9 @@
}; };
}; };
systemd.user.services.syncthing.Unit.After = [ "sops-nix.service" ]; systemd.user.services.syncthing.Unit.After = [
"sops-nix.service"
"local-fs.target"
];
}; };
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username}.programs.tmux.enable = true; home-manager.users.${user}.programs.tmux.enable = true;
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username}.home.packages = with pkgs; [ tree ]; home-manager.users.${user}.home.packages = with pkgs; [ tree ];
} }

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username}.home.packages = with pkgs; [ wget ]; home-manager.users.${user}.home.packages = with pkgs; [ wget ];
} }

View File

@@ -1,26 +1,23 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, pkgs, ... }: { config, pkgs, ... }:
let
userConfig = config.users.users.${username};
hmConfig = config.home-manager.users.${username};
in
{ {
environment.persistence."/persist".users.${username}.directories = with hmConfig.xdg.userDirs; [ environment.persistence."/persist" = {
relativeDesktop "${home}/Desktop" = { };
relativeDocuments "${home}/Documents" = { };
relativeDownload "${home}/Downloads" = { };
relativeMusic "${home}/Music" = { };
relativePictures "${home}/Pictures" = { };
relativeTemplates "${home}/Templates" = { };
relativeVideos "${home}/Videos" = { };
"VMs" "${home}/VMs" = { };
"git" "${home}/git" = { };
]; };
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ ./options.nix ]; imports = [ (import ./options.nix { inherit home; }) ];
xdg = { xdg = {
enable = true; enable = true;
@@ -34,8 +31,8 @@ in
userDirs = { userDirs = {
enable = true; enable = true;
extraConfig = { extraConfig = {
XDG_VM_DIR = "${userConfig.home}/VMs"; XDG_VM_DIR = "${home}/VMs";
XDG_GIT_DIR = "${userConfig.home}/git"; XDG_GIT_DIR = "${home}/git";
}; };
}; };
}; };

View File

@@ -1,3 +1,6 @@
{
home ? throw "home argument is required",
}:
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.xdg; cfg = config.xdg;
@@ -87,20 +90,23 @@ in
}; };
}; };
config.xdg = with lib; { config.xdg =
cacheHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeCacheHome}"; with lib;
configHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeConfigHome}"; with cfg;
dataHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeDataHome}"; {
stateHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeStateHome}"; cacheHome = mkDefault "${home}/${relativeCacheHome}";
configHome = mkDefault "${home}/${relativeConfigHome}";
dataHome = mkDefault "${home}/${relativeDataHome}";
stateHome = mkDefault "${home}/${relativeStateHome}";
userDirs = { userDirs = with userDirs; {
desktop = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDesktop}"; desktop = mkDefault "${home}/${relativeDesktop}";
documents = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDocuments}"; documents = mkDefault "${home}/${relativeDocuments}";
download = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDownload}"; download = mkDefault "${home}/${relativeDownload}";
music = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeMusic}"; music = mkDefault "${home}/${relativeMusic}";
pictures = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativePictures}"; pictures = mkDefault "${home}/${relativePictures}";
templates = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeTemplates}"; templates = mkDefault "${home}/${relativeTemplates}";
videos = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeVideos}"; videos = mkDefault "${home}/${relativeVideos}";
};
}; };
};
} }

View File

@@ -1,23 +1,21 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, ... }: { config, ... }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
environment = { environment = {
sessionVariables.ZDOTDIR = "$HOME/.config/zsh"; sessionVariables.ZDOTDIR = "$HOME/.config/zsh";
persistence."/persist".users.${username}.directories = [ "${hmConfig.xdg.relativeDataHome}/zsh" ]; persistence."/persist"."${home}/.local/share/zsh" = { };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
programs.zsh = { programs.zsh = {
enable = true; enable = true;
dotDir = "${hmConfig.xdg.relativeConfigHome}/zsh"; dotDir = ".config/zsh";
autocd = true; autocd = true;
history = { history = {
path = "${hmConfig.xdg.dataHome}/zsh/history"; path = "${home}/.local/share/zsh/history";
expireDuplicatesFirst = true; expireDuplicatesFirst = true;
}; };
historySubstringSearch.enable = true; historySubstringSearch.enable = true;

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -9,16 +10,15 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username};
agsConfig = import ./config { inherit pkgs; }; agsConfig = import ./config { inherit pkgs; };
in in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ inputs.ags.homeManagerModules.default ]; imports = [ inputs.ags.homeManagerModules.default ];
programs.ags.enable = true; programs.ags.enable = true;
xdg.configFile."ags/config.js".source = "${agsConfig}/share/config.js"; xdg.configFile."ags/config.js".source = "${agsConfig}/share/config.js";
theme.templates."${hmConfig.xdg.configHome}/ags/theme.sass".source = ./theme.sass; theme.templates."${home}/.config/ags/theme.sass".source = ./theme.sass;
systemd.user = { systemd.user = {
targets.tray.Unit = { targets.tray.Unit = {

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -10,7 +11,7 @@
{ {
services.blueman.enable = true; services.blueman.enable = true;
home-manager.users.${username} = { home-manager.users.${user} = {
services.blueman-applet.enable = true; services.blueman-applet.enable = true;
systemd.user.services.blueman-applet.Unit.After = [ "graphical-session.target" ]; systemd.user.services.blueman-applet.Unit.After = [ "graphical-session.target" ];
}; };

View File

@@ -1,14 +1,15 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ lib, pkgs, ... }: { lib, pkgs, ... }:
{ {
users.users.${username}.extraGroups = [ users.users.${user}.extraGroups = [
"video" "video"
"inputs" "inputs"
]; ];
home-manager.users.${username}.wayland.windowManager.hyprland.settings.bindle = home-manager.users.${user}.wayland.windowManager.hyprland.settings.bindle =
let let
brightnessctl = lib.meta.getExe pkgs.brightnessctl; brightnessctl = lib.meta.getExe pkgs.brightnessctl;
in in

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,15 +8,12 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
programs.btop.settings.color_theme = "matugen"; programs.btop.settings.color_theme = "matugen";
theme = { theme = {
templates."${hmConfig.xdg.configHome}/btop/themes/matugen.theme".source = ./theme.theme; templates."${home}/.config/btop/themes/matugen.theme".source = ./theme.theme;
extraConfig = "${ extraConfig = "${
lib.meta.getExe ( lib.meta.getExe (

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,7 +9,7 @@
... ...
}: }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
services.cbatticon = { services.cbatticon = {
enable = true; enable = true;
lowLevelPercent = 20; lowLevelPercent = 20;

View File

@@ -1,10 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, ... }: { config, ... }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
programs.chromium = { programs.chromium = {
enable = true; enable = true;
@@ -22,11 +20,11 @@ in
}; };
environment.persistence = { environment.persistence = {
"/persist".users.${username}.directories = [ "${hmConfig.xdg.relativeConfigHome}/chromium" ]; "/persist"."${home}/.config/chromium" = { };
"/cache".users.${username}.directories = [ "${hmConfig.xdg.relativeCacheHome}/chromium" ]; "/cache"."${home}/.cache/chromium" = { };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
programs.chromium = { programs.chromium = {
enable = true; enable = true;

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,15 +8,10 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
environment.persistence."/cache".users.${username}.directories = [ environment.persistence."/cache"."${home}/.cache/cliphist" = { };
"${hmConfig.xdg.relativeCacheHome}/cliphist"
];
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ home.packages = with pkgs; [
wl-clipboard wl-clipboard
cliphist cliphist
@@ -26,7 +22,10 @@ in
Unit = { Unit = {
Description = "Clipboard manager"; Description = "Clipboard manager";
BindsTo = [ "graphical-session.target" ]; BindsTo = [ "graphical-session.target" ];
After = [ "graphical-session.target" ]; After = [
"graphical-session.target"
config.environment.persistence."/cache"."${home}/.cache/cliphist".mount
];
}; };
Service.ExecStart = lib.meta.getExe ( Service.ExecStart = lib.meta.getExe (
@@ -47,7 +46,10 @@ in
Unit = { Unit = {
Description = "Clipboard manager (images)"; Description = "Clipboard manager (images)";
BindsTo = [ "graphical-session.target" ]; BindsTo = [ "graphical-session.target" ];
After = [ "graphical-session.target" ]; After = [
"graphical-session.target"
config.environment.persistence."/cache"."${home}/.cache/cliphist".mount
];
}; };
Service.ExecStart = lib.meta.getExe ( Service.ExecStart = lib.meta.getExe (
@@ -72,8 +74,8 @@ in
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy"; wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
in in
[ [
"$mod, v, exec, ${cliphist} list | ${rofi} -cache-dir ${hmConfig.xdg.cacheHome}/rofi -dmenu -display-columns 2 | ${cliphist} decode | ${wl-copy}" "$mod, v, exec, ${cliphist} list | ${rofi} -cache-dir ${home}/.cache/rofi -dmenu -display-columns 2 | ${cliphist} decode | ${wl-copy}"
"$mod_Ctrl, v, exec, ${cliphist} list | ${rofi} -cache-dir ${hmConfig.xdg.cacheHome}/rofi -dmenu -display-columns 2 | ${cliphist} delete" "$mod_Ctrl, v, exec, ${cliphist} list | ${rofi} -cache-dir ${home}/.cache/rofi -dmenu -display-columns 2 | ${cliphist} delete"
"$mod_Ctrl_Shift, v, exec, ${cliphist} wipe" "$mod_Ctrl_Shift, v, exec, ${cliphist} wipe"
]; ];
}; };

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,16 +8,13 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
environment.persistence = { environment.persistence = {
"/persist".users.${username}.directories = [ ".mozilla" ]; "/persist"."${home}/.mozilla" = { };
"/cache".users.${username}.directories = [ "${hmConfig.xdg.relativeCacheHome}/mozilla" ]; "/cache"."${home}/.cache/mozilla" = { };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
programs.firefox = { programs.firefox = {
enable = true; enable = true;

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,10 +9,10 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
in in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
gtk = { gtk = {
enable = true; enable = true;
@@ -31,7 +32,7 @@ in
package = builtins.head hmConfig.theme.icon.packages; package = builtins.head hmConfig.theme.icon.packages;
}; };
gtk2.configLocation = "${hmConfig.xdg.configHome}/gtk-2.0/gtkrc"; gtk2.configLocation = "${home}/.config/gtk-2.0/gtkrc";
gtk3.extraCss = "@import './theme.css';"; gtk3.extraCss = "@import './theme.css';";
gtk4.extraCss = "@import './theme.css';"; gtk4.extraCss = "@import './theme.css';";
}; };
@@ -52,8 +53,8 @@ in
}; };
theme.templates = { theme.templates = {
"${hmConfig.xdg.configHome}/gtk-3.0/theme.css".source = ./theme.css; "${home}/.config/gtk-3.0/theme.css".source = ./theme.css;
"${hmConfig.xdg.configHome}/gtk-4.0/theme.css".source = ./theme.css; "${home}/.config/gtk-4.0/theme.css".source = ./theme.css;
}; };
theme.extraConfig = "${ theme.extraConfig = "${

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,13 +8,10 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
programs.hyprland.enable = true; programs.hyprland.enable = true;
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ ./options.nix ]; imports = [ ./options.nix ];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
@@ -138,7 +136,7 @@ in
''; '';
theme = { theme = {
templates."${hmConfig.xdg.configHome}/hypr/theme.conf".source = ./theme.conf; templates."${home}/.config/hypr/theme.conf".source = ./theme.conf;
extraConfig = "${ extraConfig = "${
lib.meta.getExe ( lib.meta.getExe (

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,17 +8,14 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
home = { home = {
packages = with pkgs; [ packages = with pkgs; [
hyprshot hyprshot
swappy swappy
]; ];
sessionVariables.HYPRSHOT_DIR = "${hmConfig.xdg.userDirs.pictures}/screenshots"; sessionVariables.HYPRSHOT_DIR = "Pictures/screenshots";
}; };
wayland.windowManager.hyprland.settings.bind = wayland.windowManager.hyprland.settings.bind =

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,14 +9,12 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
in in
{ {
environment.persistence."/cache".users.${username}.directories = [ environment.persistence."/cache"."${home}/.cache/kitty" = { };
"${hmConfig.xdg.relativeCacheHome}/kitty"
];
home-manager.users.${username} = { home-manager.users.${user} = {
programs.kitty = { programs.kitty = {
enable = true; enable = true;
@@ -32,7 +31,7 @@ in
}; };
theme = { theme = {
templates."${hmConfig.xdg.configHome}/kitty/theme.conf".source = ./theme.conf; templates."${home}/.config/kitty/theme.conf".source = ./theme.conf;
extraConfig = "${ extraConfig = "${
lib.meta.getExe ( lib.meta.getExe (

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,20 +8,13 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
environment.persistence = { environment.persistence = {
"/persist".users.${username}.directories = [ "/persist"."${home}/.config/libreoffice/4/user" = { };
"${hmConfig.xdg.relativeConfigHome}/libreoffice/4/user" "/cache"."${home}/.config/libreoffice/4/cache" = { };
];
"/cache".users.${username}.directories = [
"${hmConfig.xdg.relativeConfigHome}/libreoffice/4/cache"
];
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ home.packages = with pkgs; [
libreoffice-fresh libreoffice-fresh
hunspell hunspell

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ ... }: { ... }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
services.network-manager-applet.enable = true; services.network-manager-applet.enable = true;
systemd.user.services.network-manager-applet.Unit.After = [ "graphical-session.target" ]; systemd.user.services.network-manager-applet.Unit.After = [ "graphical-session.target" ];
}; };

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,14 +9,12 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
in in
{ {
environment.persistence."/cache".users.${username}.directories = [ environment.persistence."/cache"."${home}/.config/obsidian" = { };
"${hmConfig.xdg.relativeConfigHome}/obsidian"
];
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ ./options.nix ]; imports = [ ./options.nix ];
programs.obsidian = { programs.obsidian = {

View File

@@ -45,40 +45,6 @@ in
with lib; with lib;
with types; with types;
let let
checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path;
cssSnippetsOptions =
{ config, ... }:
{
options = {
enable = mkOption {
type = bool;
default = true;
description = "Whether to enable the snippet.";
};
name = mkOption {
type = str;
defaultText = literalExpression "lib.strings.removeSuffix \".css\" (builtins.baseNameOf source)";
description = "Name of the snippet.";
};
source = mkOption {
type = nullOr (addCheck path checkCssPath);
description = "Path of the source file.";
default = null;
};
text = mkOption {
type = nullOr str;
description = "Text of the file.";
default = null;
};
};
config.name = mkDefault (toCssName config.source);
};
corePluginsOptions = corePluginsOptions =
{ config, ... }: { config, ... }:
{ {
@@ -125,6 +91,40 @@ in
}; };
}; };
checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path;
cssSnippetsOptions =
{ config, ... }:
{
options = {
enable = mkOption {
type = bool;
default = true;
description = "Whether to enable the snippet.";
};
name = mkOption {
type = str;
defaultText = literalExpression "lib.strings.removeSuffix \".css\" (builtins.baseNameOf source)";
description = "Name of the snippet.";
};
source = mkOption {
type = nullOr (addCheck path checkCssPath);
description = "Path of the source file.";
default = null;
};
text = mkOption {
type = nullOr str;
description = "Text of the file.";
default = null;
};
};
config.name = mkDefault (toCssName config.source);
};
themesOptions = themesOptions =
{ config, ... }: { config, ... }:
{ {
@@ -292,25 +292,27 @@ in
corePlugins = mkOption { corePlugins = mkOption {
description = "Core plugins to activate."; description = "Core plugins to activate.";
type = listOf (either (enum corePlugins) (submodule corePluginsOptions)); type = listOf (coercedTo (enum corePlugins) (p: { name = p; }) (submodule corePluginsOptions));
default = cfg.sharedSettings.corePlugins; default = cfg.sharedSettings.corePlugins;
}; };
communityPlugins = mkOption { communityPlugins = mkOption {
description = "Community plugins to install and activate."; description = "Community plugins to install and activate.";
type = listOf (either package (submodule communityPluginsOptions)); type = listOf (coercedTo package (p: { pkg = p; }) (submodule communityPluginsOptions));
default = cfg.sharedSettings.communityPlugins; default = cfg.sharedSettings.communityPlugins;
}; };
cssSnippets = mkOption { cssSnippets = mkOption {
description = "CSS snippets to install."; description = "CSS snippets to install.";
type = listOf (either (addCheck path checkCssPath) (submodule cssSnippetsOptions)); type = listOf (
coercedTo (addCheck path checkCssPath) (p: { source = p; }) (submodule cssSnippetsOptions)
);
default = cfg.sharedSettings.cssSnippets; default = cfg.sharedSettings.cssSnippets;
}; };
themes = mkOption { themes = mkOption {
description = "Themes to install."; description = "Themes to install.";
type = listOf (either package (submodule themesOptions)); type = listOf (coercedTo package (p: { pkg = p; }) (submodule themesOptions));
default = cfg.sharedSettings.themes; default = cfg.sharedSettings.themes;
}; };
@@ -339,15 +341,10 @@ in
config = config =
let let
vaults = builtins.filter (vault: vault.enable == true) (builtins.attrValues cfg.vaults); vaults = builtins.filter (vault: vault.enable == true) (builtins.attrValues cfg.vaults);
toName = item: if item ? name then item.name else item;
toPkg = item: if item ? pkg then item.pkg else item;
isEnabled = item: if item ? enable then item.enable else true;
hasOptions = item: item ? options;
getCssName = item: if builtins.isAttrs item then item.name else toCssName item;
getManifest = getManifest =
item: item:
let let
manifest = builtins.fromJSON (builtins.readFile "${toPkg item}/manifest.json"); manifest = builtins.fromJSON (builtins.readFile "${item.pkg}/manifest.json");
in in
manifest.id or manifest.name; manifest.id or manifest.name;
in in
@@ -366,16 +363,16 @@ in
name = "${vault.target}/.obsidian/appearance.json"; name = "${vault.target}/.obsidian/appearance.json";
value = value =
let let
enabledCssSnippets = builtins.filter isEnabled vault.settings.cssSnippets; enabledCssSnippets = builtins.filter (snippet: snippet.enable) vault.settings.cssSnippets;
activeTheme = activeTheme = lib.lists.findSingle (
lib.lists.findSingle isEnabled null (throw "Only one theme can be enabled at a time.") theme: theme.enable
vault.settings.themes; ) null (throw "Only one theme can be enabled at a time.") vault.settings.themes;
in in
{ {
source = (pkgs.formats.json { }).generate "appearance.json" ( source = (pkgs.formats.json { }).generate "appearance.json" (
vault.settings.appearance vault.settings.appearance
// { // {
enabledCssSnippets = builtins.map getCssName enabledCssSnippets; enabledCssSnippets = builtins.map (snippet: snippet.name) enabledCssSnippets;
} }
// lib.attrsets.optionalAttrs (activeTheme != null) { cssTheme = getManifest activeTheme; } // lib.attrsets.optionalAttrs (activeTheme != null) { cssTheme = getManifest activeTheme; }
); );
@@ -388,7 +385,7 @@ in
{ {
name = "${vault.target}/.obsidian/core-plugins.json"; name = "${vault.target}/.obsidian/core-plugins.json";
value.source = (pkgs.formats.json { }).generate "core-plugins.json" ( value.source = (pkgs.formats.json { }).generate "core-plugins.json" (
builtins.map toName vault.settings.corePlugins builtins.map (plugin: plugin.name) vault.settings.corePlugins
); );
} }
{ {
@@ -397,9 +394,7 @@ in
builtins.listToAttrs ( builtins.listToAttrs (
builtins.map (name: { builtins.map (name: {
inherit name; inherit name;
value = builtins.any ( value = builtins.any (plugin: name == plugin.name && plugin.enable) vault.settings.corePlugins;
plugin: name == (toName plugin) && isEnabled plugin
) vault.settings.corePlugins;
}) corePlugins }) corePlugins
) )
); );
@@ -408,7 +403,7 @@ in
++ builtins.map (plugin: { ++ builtins.map (plugin: {
name = "${vault.target}/.obsidian/${plugin.name}.json"; name = "${vault.target}/.obsidian/${plugin.name}.json";
value.source = (pkgs.formats.json { }).generate "${plugin.name}.json" plugin.options; value.source = (pkgs.formats.json { }).generate "${plugin.name}.json" plugin.options;
}) (builtins.filter hasOptions vault.settings.corePlugins); }) (builtins.filter (plugin: plugin.options != { }) vault.settings.corePlugins);
mkCommunityPlugins = mkCommunityPlugins =
vault: vault:
@@ -416,38 +411,35 @@ in
{ {
name = "${vault.target}/.obsidian/community-plugins.json"; name = "${vault.target}/.obsidian/community-plugins.json";
value.source = (pkgs.formats.json { }).generate "community-plugins.json" ( value.source = (pkgs.formats.json { }).generate "community-plugins.json" (
builtins.map getManifest (builtins.filter isEnabled vault.settings.communityPlugins) builtins.map getManifest (builtins.filter (plugin: plugin.enable) vault.settings.communityPlugins)
); );
} }
] ]
++ builtins.map (plugin: { ++ builtins.map (plugin: {
name = "${vault.target}/.obsidian/plugins/${getManifest plugin}"; name = "${vault.target}/.obsidian/plugins/${getManifest plugin}";
value = { value = {
source = toPkg plugin; source = plugin.pkg;
recursive = true; recursive = true;
}; };
}) vault.settings.communityPlugins }) vault.settings.communityPlugins
++ builtins.map (plugin: { ++ builtins.map (plugin: {
name = "${vault.target}/.obsidian/plugins/${getManifest plugin}/data.json"; name = "${vault.target}/.obsidian/plugins/${getManifest plugin}/data.json";
value.source = (pkgs.formats.json { }).generate "data.json" plugin.options; value.source = (pkgs.formats.json { }).generate "data.json" plugin.options;
}) (builtins.filter hasOptions vault.settings.communityPlugins); }) (builtins.filter (plugin: plugin.options != { }) vault.settings.communityPlugins);
mkCssSnippets = mkCssSnippets =
vault: vault:
builtins.map (snippet: { builtins.map (snippet: {
name = "${vault.target}/.obsidian/snippets/${getCssName snippet}.css"; name = "${vault.target}/.obsidian/snippets/${snippet.name}.css";
value = value =
if snippet ? source || snippet ? text then if snippet.source != null then { inherit (snippet) source; } else { inherit (snippet) text; };
if snippet.source != null then { inherit (snippet) source; } else { inherit (snippet) text; }
else
{ source = snippet; };
}) vault.settings.cssSnippets; }) vault.settings.cssSnippets;
mkThemes = mkThemes =
vault: vault:
builtins.map (theme: { builtins.map (theme: {
name = "${vault.target}/.obsidian/themes/${getManifest theme}"; name = "${vault.target}/.obsidian/themes/${getManifest theme}";
value.source = toPkg theme; value.source = theme.pkg;
}) vault.settings.themes; }) vault.settings.themes;
mkHotkeys = vault: { mkHotkeys = vault: {
@@ -494,9 +486,7 @@ in
{ {
assertion = builtins.all ( assertion = builtins.all (
vault: vault:
builtins.all ( builtins.all (snippet: snippet.source == null || snippet.text == null) vault.settings.cssSnippets
snippet: (!snippet ? source && !snippet ? text) || (snippet.source == null || snippet.text == null)
) vault.settings.cssSnippets
) (builtins.attrValues cfg.vaults); ) (builtins.attrValues cfg.vaults);
message = "Only one of `source` and `text` must be set"; message = "Only one of `source` and `text` must be set";
} }

View File

@@ -1,9 +1,10 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ lib, pkgs, ... }: { lib, pkgs, ... }:
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ pavucontrol ]; home.packages = with pkgs; [ pavucontrol ];
wayland.windowManager.hyprland.settings = wayland.windowManager.hyprland.settings =

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
lib, lib,
@@ -7,9 +8,6 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
nixpkgs.overlays = [ nixpkgs.overlays = [
(final: prev: { (final: prev: {
@@ -19,11 +17,9 @@ in
}) })
]; ];
environment.persistence."/cache".users.${username}.files = [ environment.persistence."/cache"."${home}/.config/qalculate/qalculate-gtk.history" = { };
"${hmConfig.xdg.relativeConfigHome}/qalculate/qalculate-gtk.history"
];
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ qalculate-gtk ]; home.packages = with pkgs; [ qalculate-gtk ];
xdg.configFile."qalculate/qalculate-gtk.cfg".source = xdg.configFile."qalculate/qalculate-gtk.cfg".source =

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,11 +8,8 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
qt = { qt = {
enable = true; enable = true;
platformTheme.name = "qtct"; platformTheme.name = "qtct";
@@ -28,9 +26,9 @@ in
theme.templates = { theme.templates = {
# https://github.com/GabePoel/KvLibadwaita/blob/main/src/KvLibadwaita/KvLibadwaita.kvconfig # https://github.com/GabePoel/KvLibadwaita/blob/main/src/KvLibadwaita/KvLibadwaita.kvconfig
"${hmConfig.xdg.configHome}/Kvantum/KvAdwQt/KvAdwQt.kvconfig".source = ./KvAdwQt/KvAdwQt.kvconfig; "${home}/.config/Kvantum/KvAdwQt/KvAdwQt.kvconfig".source = ./KvAdwQt/KvAdwQt.kvconfig;
# https://github.com/GabePoel/KvLibadwaita/blob/main/src/KvLibadwaita/KvLibadwaita.svg # https://github.com/GabePoel/KvLibadwaita/blob/main/src/KvLibadwaita/KvLibadwaita.svg
"${hmConfig.xdg.configHome}/Kvantum/KvAdwQt/KvAdwQt.svg".source = ./KvAdwQt/KvAdwQt.svg; "${home}/.config/Kvantum/KvAdwQt/KvAdwQt.svg".source = ./KvAdwQt/KvAdwQt.svg;
}; };
xdg.configFile = xdg.configFile =

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,14 +9,12 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
in in
{ {
environment.persistence."/cache".users.${username}.directories = [ environment.persistence."/cache"."${home}/.cache/rofi" = { };
"${hmConfig.xdg.relativeCacheHome}/rofi"
];
home-manager.users.${username} = { home-manager.users.${user} = {
programs.rofi = { programs.rofi = {
enable = true; enable = true;
package = pkgs.rofi-wayland; package = pkgs.rofi-wayland;
@@ -23,7 +22,7 @@ in
}; };
wayland.windowManager.hyprland.settings.bind = [ wayland.windowManager.hyprland.settings.bind = [
"$mod, r, exec, ${lib.meta.getExe pkgs.rofi-wayland} -cache-dir ${hmConfig.xdg.cacheHome}/rofi -show drun" "$mod, r, exec, ${lib.meta.getExe pkgs.rofi-wayland} -cache-dir ${home}/.cache/rofi -show drun"
]; ];
}; };
} }

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -7,9 +8,6 @@
pkgs, pkgs,
... ...
}: }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
networking.firewall = { networking.firewall = {
allowedTCPPorts = [ 57621 ]; allowedTCPPorts = [ 57621 ];
@@ -17,11 +15,11 @@ in
}; };
environment.persistence = { environment.persistence = {
"/persist".users.${username}.directories = [ "${hmConfig.xdg.relativeConfigHome}/spotify" ]; "/persist"."${home}/.config/spotify" = { };
"/cache".users.${username}.directories = [ "${hmConfig.xdg.relativeCacheHome}/spotify" ]; "/cache"."${home}/.cache/spotify" = { };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ inputs.spicetify-nix.homeManagerModules.default ]; imports = [ inputs.spicetify-nix.homeManagerModules.default ];
programs.spicetify = programs.spicetify =
@@ -37,7 +35,7 @@ in
theme = spicePkgs.themes.sleek // { theme = spicePkgs.themes.sleek // {
extraCommands = '' extraCommands = ''
export COLORS_CSS_PATH="${hmConfig.xdg.configHome}/spotify/colors.css" export COLORS_CSS_PATH="${home}/.config/spotify/colors.css"
''; '';
additionalCss = '' additionalCss = ''
@@ -60,6 +58,6 @@ in
]; ];
}; };
theme.templates."${hmConfig.xdg.configHome}/spotify/colors.css".source = ./colors.css; theme.templates."${home}/.config/spotify/colors.css".source = ./colors.css;
}; };
} }

View File

@@ -1,14 +1,16 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
lib, lib,
utils,
pkgs, pkgs,
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
themeSwww = lib.meta.getExe ( themeSwww = lib.meta.getExe (
pkgs.writeShellApplication { pkgs.writeShellApplication {
name = "theme-swww"; name = "theme-swww";
@@ -21,18 +23,19 @@ let
); );
in in
{ {
environment.persistence."/cache".users.${username}.directories = [ environment.persistence."/cache"."${home}/.cache/swww" = { };
"${hmConfig.xdg.relativeCacheHome}/swww"
];
home-manager.users.${username} = { home-manager.users.${user} = {
home.packages = with pkgs; [ swww ]; home.packages = with pkgs; [ swww ];
systemd.user.services.swww = { systemd.user.services.swww = {
Unit = { Unit = {
Description = "Wallpaper daemon"; Description = "Wallpaper daemon";
BindsTo = [ "graphical-session.target" ]; BindsTo = [ "graphical-session.target" ];
After = [ "graphical-session.target" ]; After = [
"graphical-session.target"
config.environment.persistence."/cache"."${home}/.cache/swww".mount
];
}; };
Service = { Service = {

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -9,15 +10,13 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
themeBin = lib.meta.getExe hmConfig.theme.pkg; themeBin = lib.meta.getExe hmConfig.theme.pkg;
in in
{ {
environment.persistence."/persist".users.${username}.directories = [ environment.persistence."/persist"."${home}/.config/theme" = { };
"${hmConfig.xdg.relativeConfigHome}/theme"
];
home-manager.users.${username} = { home-manager.users.${user} = {
imports = [ ./options.nix ]; imports = [ ./options.nix ];
theme.enable = true; theme.enable = true;

View File

@@ -1,5 +1,6 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ {
config, config,
@@ -8,28 +9,28 @@
... ...
}: }:
let let
hmConfig = config.home-manager.users.${username}; hmConfig = config.home-manager.users.${user};
in in
{ {
environment.persistence = { environment.persistence = {
"/persist".users.${username}.directories = [ "${hmConfig.xdg.relativeConfigHome}/Code" ]; "/persist"."${home}/.config/Code" = { };
# Bastard: https://github.com/microsoft/vscode/issues/3884 # Bastard: https://github.com/microsoft/vscode/issues/3884
"/cache".users.${username}.directories = [ "/cache" = {
"${hmConfig.xdg.relativeConfigHome}/Code/Cache" "${home}/.config/Code/Cache" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/CachedConfigurations" "${home}/.config/Code/CachedConfigurations" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/CachedData" "${home}/.config/Code/CachedData" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/CachedExtensionVSIXs" "${home}/.config/Code/CachedExtensionVSIXs" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/CachedExtensions" "${home}/.config/Code/CachedExtensions" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/CachedProfilesData" "${home}/.config/Code/CachedProfilesData" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/Code Cache" "${home}/.config/Code/Code Cache" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/DawnCache" "${home}/.config/Code/DawnCache" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/GPUCache" "${home}/.config/Code/GPUCache" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/Service Worker/CacheStorage" "${home}/.config/Code/Service Worker/CacheStorage" = { };
"${hmConfig.xdg.relativeConfigHome}/Code/Service Worker/ScriptCache" "${home}/.config/Code/Service Worker/ScriptCache" = { };
]; };
}; };
home-manager.users.${username} = { home-manager.users.${user} = {
programs.vscode = { programs.vscode = {
enable = true; enable = true;

View File

@@ -1,7 +1,8 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ pkgs, ... }: { pkgs, ... }:
{ {
home-manager.users.${username}.home.packages = with pkgs; [ wev ]; home-manager.users.${user}.home.packages = with pkgs; [ wev ];
} }

View File

@@ -1,13 +1,11 @@
{ {
username ? throw "username argument is required", user ? throw "user argument is required",
home ? throw "home argument is required",
}: }:
{ config, ... }: { config, ... }:
let
hmConfig = config.home-manager.users.${username};
in
{ {
home-manager.users.${username} = { home-manager.users.${user} = {
home.pointerCursor.x11.enable = true; home.pointerCursor.x11.enable = true;
xresources.path = "${hmConfig.xdg.configHome}/X11/xresources"; xresources.path = "${home}/.config/X11/xresources";
}; };
} }

View File

@@ -23,6 +23,7 @@
type = "filesystem"; type = "filesystem";
format = "vfat"; format = "vfat";
mountpoint = "/boot"; mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
}; };
}; };
swap = { swap = {

View File

@@ -1,92 +1,97 @@
{ config, ... }: { config, ... }:
let let
username = "nick"; # https://github.com/NixOS/nixpkgs/issues/24570
userConfig = config.users.users.${username}; # https://github.com/NixOS/nixpkgs/issues/305643
hmConfig = config.home-manager.users.${username}; user = "nick";
home = "/home/nick";
in in
{ {
imports = [ imports = [
../common/user/configs/options.nix ../common/user/configs/options.nix
(import ../common/user/configs/console/android { inherit username; }) (import ../common/user/configs/console/android { inherit user home; })
(import ../common/user/configs/console/bluetooth { inherit username; }) (import ../common/user/configs/console/bluetooth { inherit user home; })
(import ../common/user/configs/console/brightnessctl { inherit username; }) (import ../common/user/configs/console/brightnessctl { inherit user home; })
(import ../common/user/configs/console/btop { inherit username; }) (import ../common/user/configs/console/btop { inherit user home; })
(import ../common/user/configs/console/docker { inherit username; }) (import ../common/user/configs/console/docker { inherit user home; })
(import ../common/user/configs/console/fastfetch { inherit username; }) (import ../common/user/configs/console/fastfetch { inherit user home; })
(import ../common/user/configs/console/ffmpeg { inherit username; }) (import ../common/user/configs/console/ffmpeg { inherit user home; })
(import ../common/user/configs/console/git { inherit username; }) (import ../common/user/configs/console/git { inherit user home; })
(import ../common/user/configs/console/gpg-agent { inherit username; }) (import ../common/user/configs/console/gpg-agent { inherit user home; })
(import ../common/user/configs/console/home-manager { inherit username; }) (import ../common/user/configs/console/home-manager { inherit user home; })
(import ../common/user/configs/console/imagemagick { inherit username; }) (import ../common/user/configs/console/imagemagick { inherit user home; })
(import ../common/user/configs/console/ncdu { inherit username; }) (import ../common/user/configs/console/ncdu { inherit user home; })
(import ../common/user/configs/console/neovim { inherit username; }) (import ../common/user/configs/console/neovim { inherit user home; })
(import ../common/user/configs/console/nixpkgs { inherit username; }) (import ../common/user/configs/console/nixpkgs { inherit user home; })
(import ../common/user/configs/console/pipewire { inherit username; }) (import ../common/user/configs/console/pipewire { inherit user home; })
(import ../common/user/configs/console/ranger { inherit username; }) (import ../common/user/configs/console/ranger { inherit user home; })
(import ../common/user/configs/console/sops { inherit username; }) (import ../common/user/configs/console/sops { inherit user home; })
(import ../common/user/configs/console/syncthing { inherit username; }) (import ../common/user/configs/console/syncthing { inherit user home; })
(import ../common/user/configs/console/tmux { inherit username; }) (import ../common/user/configs/console/tmux { inherit user home; })
(import ../common/user/configs/console/tree { inherit username; }) (import ../common/user/configs/console/tree { inherit user home; })
(import ../common/user/configs/console/wget { inherit username; }) (import ../common/user/configs/console/wget { inherit user home; })
(import ../common/user/configs/console/xdg { inherit username; }) (import ../common/user/configs/console/xdg { inherit user home; })
(import ../common/user/configs/console/zsh { inherit username; }) (import ../common/user/configs/console/zsh { inherit user home; })
(import ../common/user/configs/gui/ags { inherit username; }) (import ../common/user/configs/gui/ags { inherit user home; })
(import ../common/user/configs/gui/bluetooth { inherit username; }) (import ../common/user/configs/gui/bluetooth { inherit user home; })
(import ../common/user/configs/gui/brightnessctl { inherit username; }) (import ../common/user/configs/gui/brightnessctl { inherit user home; })
(import ../common/user/configs/gui/btop { inherit username; }) (import ../common/user/configs/gui/btop { inherit user home; })
# (import ../common/user/configs/gui/cbatticon { inherit username; }) (import ../common/user/configs/gui/chromium { inherit user home; })
(import ../common/user/configs/gui/chromium { inherit username; }) (import ../common/user/configs/gui/cliphist { inherit user home; })
(import ../common/user/configs/gui/cliphist { inherit username; }) (import ../common/user/configs/gui/firefox { inherit user home; })
(import ../common/user/configs/gui/firefox { inherit username; }) (import ../common/user/configs/gui/gtk { inherit user home; })
(import ../common/user/configs/gui/gtk { inherit username; }) (import ../common/user/configs/gui/hyprland { inherit user home; })
(import ../common/user/configs/gui/hyprland { inherit username; }) (import ../common/user/configs/gui/hyprshot { inherit user home; })
(import ../common/user/configs/gui/hyprshot { inherit username; }) (import ../common/user/configs/gui/kitty { inherit user home; })
(import ../common/user/configs/gui/kitty { inherit username; }) (import ../common/user/configs/gui/libreoffice { inherit user home; })
(import ../common/user/configs/gui/libreoffice { inherit username; }) (import ../common/user/configs/gui/networking { inherit user home; })
(import ../common/user/configs/gui/networking { inherit username; }) (import ../common/user/configs/gui/obsidian { inherit user home; })
(import ../common/user/configs/gui/obsidian { inherit username; }) (import ../common/user/configs/gui/pipewire { inherit user home; })
(import ../common/user/configs/gui/pipewire { inherit username; }) (import ../common/user/configs/gui/qalculate { inherit user home; })
(import ../common/user/configs/gui/qalculate { inherit username; }) (import ../common/user/configs/gui/qt { inherit user home; })
(import ../common/user/configs/gui/qt { inherit username; }) (import ../common/user/configs/gui/rofi { inherit user home; })
(import ../common/user/configs/gui/rofi { inherit username; }) (import ../common/user/configs/gui/spicetify { inherit user home; })
(import ../common/user/configs/gui/spicetify { inherit username; }) (import ../common/user/configs/gui/swww { inherit user home; })
(import ../common/user/configs/gui/swww { inherit username; }) (import ../common/user/configs/gui/theme { inherit user home; })
(import ../common/user/configs/gui/theme { inherit username; }) (import ../common/user/configs/gui/vscode { inherit user home; })
(import ../common/user/configs/gui/vscode { inherit username; }) (import ../common/user/configs/gui/wev { inherit user home; })
(import ../common/user/configs/gui/wev { inherit username; }) (import ../common/user/configs/gui/x11 { inherit user home; })
(import ../common/user/configs/gui/x11 { inherit username; })
]; ];
sops.secrets."${username}-password" = { sops.secrets."${user}-password" = {
sopsFile = ../../users/${username}/secrets/secrets.yaml; sopsFile = ../../users/${user}/secrets/secrets.yaml;
key = "password"; key = "password";
neededForUsers = true; neededForUsers = true;
}; };
users.users.${username} = { users.users.${user} = {
inherit home;
isNormalUser = true; isNormalUser = true;
email = "nick@karaolidis.com"; email = "nick@karaolidis.com";
fullName = "Nikolaos Karaolidis"; fullName = "Nikolaos Karaolidis";
description = userConfig.fullName; description = "Nikolaos Karaolidis";
hashedPasswordFile = config.sops.secrets."${username}-password".path; hashedPasswordFile = config.sops.secrets."${user}-password".path;
extraGroups = [ "wheel" ]; extraGroups = [ "wheel" ];
linger = true; linger = true;
uid = 1000; uid = 1000;
}; };
services.getty.autologinUser = userConfig.name; services.getty.autologinUser = user;
home-manager.users.${username} = { home-manager.users.${user} = {
home.homeDirectory = userConfig.home; home = {
sops.defaultSopsFile = ../../users/${username}/secrets/secrets.yaml; username = user;
theme.wallpaper = ../../users/${username}/secrets/wallpapers/clouds.png; homeDirectory = home;
};
programs.obsidian.vaults."${hmConfig.xdg.userDirs.relativeDocuments}/Obsidian/master".enable = true; sops.defaultSopsFile = ../../users/${user}/secrets/secrets.yaml;
theme.wallpaper = ../../users/${user}/secrets/wallpapers/clouds.png;
programs.obsidian.vaults."Documents/Obsidian/master".enable = true;
services.syncthing.settings.folders = { services.syncthing.settings.folders = {
obsidian = { obsidian = {
label = "Obsidian"; label = "Obsidian";
path = "${hmConfig.xdg.userDirs.documents}/Obsidian"; path = "Documents/Obsidian";
devices = [ devices = [
"amalthea" "amalthea"
"ganymede" "ganymede"
@@ -94,7 +99,7 @@ in
}; };
official = { official = {
label = "Official"; label = "Official";
path = "${hmConfig.xdg.userDirs.documents}/Official"; path = "Documents/Official";
devices = [ devices = [
"amalthea" "amalthea"
"ganymede" "ganymede"
@@ -102,6 +107,6 @@ in
}; };
}; };
home.file."${hmConfig.xdg.userDirs.documents}/Obsidian/.stignore".source = ../common/user/configs/gui/obsidian/config/.stignore; home.file."Documents/Obsidian/.stignore".source = ../common/user/configs/gui/obsidian/config/.stignore;
}; };
} }