Compare commits
16 commits
edc5ccb848
...
cdf117daa2
Author | SHA1 | Date | |
---|---|---|---|
cdf117daa2 | |||
1346b1ca63 | |||
c3a1eb812c | |||
67d2373cec | |||
7e3d4ebd41 | |||
16c295d7c1 | |||
8bde5c66e6 | |||
ff1c7502a5 | |||
bef143852a | |||
f5aa5e4bbf | |||
e16354b0ef | |||
7aa3204141 | |||
54539758ad | |||
a56408403c | |||
63fc603f07 | |||
de8f54ead2 |
28 changed files with 430 additions and 239 deletions
|
@ -5,19 +5,4 @@
|
|||
];
|
||||
|
||||
custom.hostname = "myeck";
|
||||
|
||||
fileSystems = {
|
||||
"/mnt/external" = {
|
||||
device = "/dev/disk/by-label/external";
|
||||
options = [
|
||||
"noatime"
|
||||
"nofail"
|
||||
"users"
|
||||
"exec"
|
||||
"x-gvfs-show"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = ["z /mnt/external 0755 myned users"];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
./disko.nix
|
||||
./hardware-configuration.nix
|
||||
|
@ -9,6 +9,20 @@
|
|||
width = 3440;
|
||||
height = 1440;
|
||||
refresh = 100;
|
||||
|
||||
settings = {
|
||||
storage.mnt = ["gayme" "myve"];
|
||||
|
||||
vm.passthrough = {
|
||||
enable = true;
|
||||
driver = "amdgpu";
|
||||
guest = "myndows";
|
||||
id = "1002:73df";
|
||||
init = true;
|
||||
intel = true;
|
||||
node = "pci_0000_03_00_0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
boot = {
|
||||
|
@ -32,85 +46,14 @@
|
|||
# `- \`_`"'-
|
||||
#// services.logind.powerKey = "ignore"; # Disable power button
|
||||
|
||||
# Mount external drives on boot
|
||||
fileSystems = {
|
||||
"/mnt/gayme" = {
|
||||
device = "/dev/disk/by-label/gayme";
|
||||
options = [
|
||||
"noatime"
|
||||
"nofail"
|
||||
"users"
|
||||
"exec"
|
||||
"x-gvfs-show"
|
||||
];
|
||||
};
|
||||
|
||||
"/mnt/gaymer" = {
|
||||
device = "/dev/disk/by-label/gaymer";
|
||||
options = [
|
||||
"noatime"
|
||||
"nofail"
|
||||
"users"
|
||||
"exec"
|
||||
"x-gvfs-show"
|
||||
home-manager.users.${config.custom.username} = {
|
||||
# Prevent secondary GPU reset from crashing window manager
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
monitor = [
|
||||
"HDMI-A-1, disable"
|
||||
"HDMI-A-2, disable"
|
||||
"HDMI-A-3, disable"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Set mount directory permissions
|
||||
#?? TYPE PATH MODE USER GROUP AGE ARGUMENT
|
||||
systemd.tmpfiles.rules = [
|
||||
"z /mnt/gayme 0755 myned users"
|
||||
"z /mnt/gaymer 0755 myned users"
|
||||
];
|
||||
|
||||
# BUG: "manual" profile is the same as "auto" with kernel 6.10
|
||||
# TODO: Remove when Linux 6.12 is released
|
||||
# https://gitlab.freedesktop.org/agd5f/linux/-/commit/ec1aab7816b06c32f42935e34ce3a3040c778afb
|
||||
# Work around performance issues with AMD power scaling
|
||||
# https://wiki.archlinux.org/title/AMDGPU#Screen_artifacts_and_frequency_problem
|
||||
# https://wiki.archlinux.org/title/AMDGPU#Power_profiles
|
||||
#!! cardX must match the correct gpu
|
||||
#?? lspci
|
||||
#?? ls -l /dev/dri/by-path/*-card
|
||||
#?? grep '*' /sys/class/drm/card*/device/pp_power_profile_mode
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="drm", KERNEL=="card1", DRIVERS=="amdgpu", ATTR{device/power_dpm_force_performance_level}="manual", ATTR{device/pp_power_profile_mode}="1"
|
||||
'';
|
||||
|
||||
# https://github.com/Zygo/bees
|
||||
# Deduplicate entire filesystem
|
||||
#?? Optimal for ~1TB total disk space
|
||||
# https://github.com/Zygo/bees/blob/master/docs/config.md#hash-table-sizing
|
||||
# services.beesd.filesystems.root = {
|
||||
# spec = "/";
|
||||
# verbosity = "err";
|
||||
# extraOptions = [ "--loadavg-target" "5" ]; # Reduce threads on ~5% total processor load
|
||||
# };
|
||||
|
||||
# Periodically upload current wallpaper to remote server
|
||||
# systemd.user = {
|
||||
# services."wallpaper" = {
|
||||
# path = with pkgs; [
|
||||
# openssh
|
||||
# rsync
|
||||
# tailscale
|
||||
# variety
|
||||
# ];
|
||||
|
||||
# #!! Hostname dependent
|
||||
# script = ''
|
||||
# rsync --chown caddy:caddy "$(variety --current)" root@myne:/srv/static/wallpaper.png
|
||||
# '';
|
||||
# };
|
||||
|
||||
# timers."wallpaper" = {
|
||||
# wantedBy = [ "timers.target" ];
|
||||
|
||||
# timerConfig = {
|
||||
# OnBootSec = "1m";
|
||||
# OnUnitActiveSec = "1m";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
config,
|
||||
inputs,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
|
@ -30,20 +29,6 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
home-manager.users.${config.custom.username} = {
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
exec-once = ["${brightnessctl} set 0%"];
|
||||
|
||||
device = [
|
||||
{
|
||||
name = "pixa3854:00-093a:0274-touchpad";
|
||||
accel_profile = "adaptive";
|
||||
sensitivity = 0.3;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.keyd.keyboards.default.settings.main.rightcontrol = "layer(altgr)"; # No Ctrl_R
|
||||
|
||||
boot = {
|
||||
|
@ -69,4 +54,18 @@ in {
|
|||
#// "amd_pstate=disable"
|
||||
];
|
||||
};
|
||||
|
||||
home-manager.users.${config.custom.username} = {
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
exec-once = ["${brightnessctl} set 0%"];
|
||||
|
||||
device = [
|
||||
{
|
||||
name = "pixa3854:00-093a:0274-touchpad";
|
||||
accel_profile = "adaptive";
|
||||
sensitivity = 0.3;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,10 +38,13 @@ in {
|
|||
# TODO: Use nobody:nogroup instead when docker allows changing mount ownership
|
||||
# HACK: Copy with global read-only permissions in container directory which is assumed to be locked down
|
||||
# https://github.com/moby/moby/issues/2259
|
||||
systemd.tmpfiles.rules = [
|
||||
"C ${config.custom.containers.directory}/coturn/coturn.conf 0444 - - - ${
|
||||
config.age.secrets."${config.custom.profile}/coturn/coturn.conf".path
|
||||
}"
|
||||
];
|
||||
systemd.tmpfiles.settings."10-coturn" = {
|
||||
"${config.custom.containers.directory}/coturn/coturn.conf" = {
|
||||
C = {
|
||||
mode = "0444";
|
||||
argument = "${config.age.secrets."${config.custom.profile}/coturn/coturn.conf".path}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -79,7 +79,16 @@ in {
|
|||
podman-tui
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = ["d /containers 0700 root root"]; # Custom directory for containers
|
||||
systemd.tmpfiles.settings."10-containers" = {
|
||||
"/containers" = {
|
||||
d = {
|
||||
mode = "0700";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${config.custom.username}.extraGroups = [
|
||||
(
|
||||
if cfg.docker
|
||||
|
|
|
@ -81,6 +81,14 @@ in {
|
|||
};
|
||||
|
||||
#!! Required for correct volume permissions
|
||||
systemd.tmpfiles.rules = ["z ${config.custom.containers.directory}/netbox/media 0770 999 root"]; # unit:root
|
||||
systemd.tmpfiles.settings."10-netbox" = {
|
||||
"${config.custom.containers.directory}/netbox/media" = {
|
||||
z = {
|
||||
mode = "0770";
|
||||
user = "999"; # unit
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -272,6 +272,7 @@ in {
|
|||
then "--scale 140"
|
||||
else ""
|
||||
} myndows'')
|
||||
(key "W" "Super+Ctrl+Shift" "exec" virt-manager)
|
||||
(key "W" "Super+Shift" "movetoworkspacesilent" "special:vm")
|
||||
(key "X" "Super" "workspace" "+1")
|
||||
(key "X" "Super+Shift" "movetoworkspacesilent" "+1")
|
||||
|
|
|
@ -29,6 +29,7 @@ in {
|
|||
"plugin:hyprbars:nobar, class:^dev\\.benz\\.walker$"
|
||||
"plugin:hyprbars:nobar, class:^discord$, title:^Discord Updater$"
|
||||
"plugin:hyprbars:nobar, class:^dropdown$"
|
||||
"plugin:hyprbars:nobar, class:^looking-glass-client$"
|
||||
"plugin:hyprbars:nobar, class:^moe\\.launcher\\..+$"
|
||||
"plugin:hyprbars:nobar, class:^org\\.gnome\\.Nautilus$, title:^New Folder$"
|
||||
"plugin:hyprbars:nobar, class:^org\\.gnome\\.NautilusPreviewer$"
|
||||
|
|
|
@ -246,6 +246,7 @@ in {
|
|||
];
|
||||
vm = rules: [
|
||||
(class "(sdl-|wl|x)freerdp" (rules ++ ["nomaxsize" "tile"]))
|
||||
(class "looking-glass-client" rules)
|
||||
(class "org\\.remmina\\.Remmina" (rules ++ ["tile"]))
|
||||
(class "virt-manager" rules)
|
||||
];
|
||||
|
|
|
@ -9,14 +9,17 @@ with lib; let
|
|||
audio = config.home-manager.users.${config.custom.username}.home.file.".local/bin/audio".source;
|
||||
clipse = "${pkgs.clipse}/bin/clipse";
|
||||
firefox-esr = "${config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage}/bin/firefox-esr";
|
||||
grep = "${pkgs.gnugrep}/bin/grep";
|
||||
left = config.home-manager.users.${config.custom.username}.home.file.".local/bin/left".source;
|
||||
loupe = "${pkgs.loupe}/bin/loupe";
|
||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||
nautilus = "${pkgs.nautilus}/bin/nautilus";
|
||||
pkill = "${pkgs.procps}/bin/pkill";
|
||||
rm = "${pkgs.coreutils}/bin/rm";
|
||||
sleep = "${pkgs.coreutils}/bin/sleep";
|
||||
sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit";
|
||||
systemctl = "${pkgs.systemd}/bin/systemctl";
|
||||
virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
|
||||
waybar = "${config.home-manager.users.${config.custom.username}.programs.waybar.package}/bin/waybar";
|
||||
|
||||
cfg = config.custom.desktops.hyprland.settings;
|
||||
|
@ -36,7 +39,7 @@ in {
|
|||
|
||||
# https://wiki.hyprland.org/Configuring/Monitors
|
||||
#?? monitor = NAME, RESOLUTION, POSITION, SCALE
|
||||
monitor = [
|
||||
monitor = mkBefore [
|
||||
", highrr, auto, ${toString config.custom.scale}"
|
||||
|
||||
# HACK: Ensure the fallback output has a sane resolution
|
||||
|
@ -66,8 +69,7 @@ in {
|
|||
|
||||
# https://wiki.hyprland.org/Configuring/Keywords/#executing
|
||||
exec-once =
|
||||
optionals config.custom.wallpaper ["wallpaper"]
|
||||
++ [
|
||||
[
|
||||
sway-audio-idle-inhibit # Inhibit idle while audio is playing
|
||||
"${audio} --init" # Enforce audio profile state
|
||||
"${rm} ~/.cache/walker/clipboard.gob" # Clear clipboard history
|
||||
|
@ -77,6 +79,13 @@ in {
|
|||
# HACK: Launch hidden GTK windows to reduce startup time
|
||||
"[workspace special:hidden silent] ${loupe}"
|
||||
"[workspace special:hidden silent] ${nautilus}"
|
||||
]
|
||||
++ optionals config.custom.wallpaper [
|
||||
"wallpaper"
|
||||
]
|
||||
# HACK: Delay driver initialization to work around reset issues
|
||||
++ optionals config.custom.settings.vm.passthrough.init [
|
||||
"${virsh} list | ${grep} ${config.custom.settings.vm.passthrough.guest} || sudo ${modprobe} ${config.custom.settings.vm.passthrough.driver}"
|
||||
];
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#xwayland
|
||||
|
@ -253,6 +262,10 @@ in {
|
|||
devices = names: attrs: map (name: {inherit name;} // attrs) names;
|
||||
in
|
||||
flatten [
|
||||
(devices ["compx-2.4g-receiver-mouse"] {
|
||||
accel_profile = "custom 1 0 1 10 20";
|
||||
})
|
||||
|
||||
(devices ["kensington-orbit-wireless-tb-mouse" "orbit-bt5.0-mouse"] {
|
||||
accel_profile = "adaptive";
|
||||
left_handed = true;
|
||||
|
@ -270,7 +283,7 @@ in {
|
|||
sensitivity = -0.7;
|
||||
})
|
||||
|
||||
(devices ["razer-razer-viper-ultimate" "razer-razer-viper-ultimate-dongle"] {
|
||||
(devices ["razer-razer-viper-ultimate" "razer-razer-viper-ultimate-dongle" "razer-razer-viper-ultimate-dongle-1"] {
|
||||
sensitivity = -0.7;
|
||||
})
|
||||
|
||||
|
|
|
@ -10,6 +10,14 @@ in {
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
# Set /mnt permissions
|
||||
systemd.tmpfiles.rules = ["z /mnt 0755 root root"];
|
||||
systemd.tmpfiles.settings."10-mnt" = {
|
||||
"/mnt" = {
|
||||
z = {
|
||||
mode = "0755";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,9 +11,20 @@ in {
|
|||
config = mkIf cfg.enable {
|
||||
# https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html
|
||||
# Create NixOS configuration directory and set permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /etc/nixos 0755 myned root"
|
||||
"Z /etc/nixos - myned root" # Recursively set owner
|
||||
];
|
||||
systemd.tmpfiles.settings."10-nixos" = {
|
||||
"/etc/nixos" = {
|
||||
d = {
|
||||
mode = "0755";
|
||||
user = config.custom.username;
|
||||
group = "root";
|
||||
};
|
||||
|
||||
#!! Recursive
|
||||
Z = {
|
||||
user = config.custom.username;
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -214,6 +214,7 @@ in {
|
|||
"browser.search.widget.inNavBar" = locked false;
|
||||
"browser.startup.homepage" = locked "about:home";
|
||||
"browser.startup.page" = locked 3; # Previous session
|
||||
"browser.tabs.allowTabDetach" = locked false;
|
||||
"browser.tabs.closeTabByDblclick" = locked true;
|
||||
"browser.tabs.closeWindowWithLastTab" = locked false;
|
||||
"browser.tabs.insertAfterCurrent" = locked false;
|
||||
|
@ -230,6 +231,7 @@ in {
|
|||
"extensions.formautofill.creditCards.enabled" = locked false;
|
||||
"general.autoScroll" = locked false;
|
||||
"general.smoothScroll" = locked true;
|
||||
"gfx.webrender.software" = locked true;
|
||||
"layers.acceleration.force-enabled" = locked true;
|
||||
"layout.css.always_underline_links" = locked false;
|
||||
"layout.css.backdrop-filter.enabled" = locked true;
|
||||
|
|
107
options/custom/programs/looking-glass.nix
Normal file
107
options/custom/programs/looking-glass.nix
Normal file
|
@ -0,0 +1,107 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.custom.programs.looking-glass;
|
||||
in {
|
||||
options.custom.programs.looking-glass = {
|
||||
enable = mkOption {default = false;};
|
||||
kvmfr = mkOption {default = true;};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
#!! Imperative libvirt xml configuration
|
||||
# https://looking-glass.io/
|
||||
# https://looking-glass.io/docs/B6/install/
|
||||
# BUG: CPU host-passthrough causes error on VM start
|
||||
# https://github.com/tianocore/edk2/discussions/4662
|
||||
#?? <cpu><maxphysaddr mode="passthrough" limit="40"/></cpu>
|
||||
|
||||
# https://looking-glass.io/docs/B6/module/#kernel-module
|
||||
boot = mkIf cfg.kvmfr {
|
||||
extraModulePackages = [config.boot.kernelPackages.kvmfr];
|
||||
extraModprobeConfig = "options kvmfr static_size_mb=128";
|
||||
kernelModules = ["kvmfr"];
|
||||
};
|
||||
|
||||
systemd = {
|
||||
tmpfiles.settings."10-looking-glass" = {
|
||||
${
|
||||
if cfg.kvmfr
|
||||
then "/dev/kvmfr0"
|
||||
else "/dev/shm/looking-glass"
|
||||
} = {
|
||||
${
|
||||
if cfg.kvmfr
|
||||
then "z"
|
||||
else "f"
|
||||
} = {
|
||||
mode = "0660";
|
||||
user = config.custom.username;
|
||||
group = "qemu-libvirtd";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# HACK: Remove exclusion of /dev prefix from service so rules take effect for devices
|
||||
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/boot/systemd/tmpfiles.nix
|
||||
# https://github.com/NixOS/nixpkgs/commit/e6b66f08a53261cf825817df59d3ccd75ed0eead
|
||||
services.systemd-tmpfiles-setup.serviceConfig = {
|
||||
ExecStart = mkForce "systemd-tmpfiles --create --remove --boot --exclude-prefix=/sysroot";
|
||||
};
|
||||
};
|
||||
|
||||
# https://looking-glass.io/docs/B6/module/#libvirt
|
||||
virtualisation.libvirtd.qemu.verbatimConfig = mkIf cfg.kvmfr ''
|
||||
cgroup_device_acl = [
|
||||
"/dev/null", "/dev/full", "/dev/zero",
|
||||
"/dev/random", "/dev/urandom",
|
||||
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
|
||||
"/dev/rtc", "/dev/hpet", "/dev/vfio/vfio",
|
||||
"/dev/kvmfr0"
|
||||
]
|
||||
|
||||
# Default configuration
|
||||
namespaces = []
|
||||
'';
|
||||
|
||||
home-manager.users.${config.custom.username} = {
|
||||
# BUG: Crashes when reconnecting to spice channel
|
||||
programs.looking-glass-client = {
|
||||
enable = true;
|
||||
|
||||
# https://looking-glass.io/docs/B6/usage/#all-command-line-options
|
||||
settings = {
|
||||
app = {
|
||||
shmFile =
|
||||
if cfg.kvmfr
|
||||
then "/dev/kvmfr0"
|
||||
else "/dev/shm/looking-glass";
|
||||
};
|
||||
|
||||
input = {
|
||||
grabKeyboard = false;
|
||||
ignoreWindowsKeys = true;
|
||||
};
|
||||
|
||||
spice = {
|
||||
# BUG: SPICE audio causes disconnections, remove with QEMU >= 9.1.2
|
||||
# https://gitlab.com/qemu-project/qemu/-/commit/8d9c6f6fa9eebd09ad8d0b4b4de4a0ec57e756d1
|
||||
audio = false;
|
||||
};
|
||||
|
||||
win = {
|
||||
borderless = true;
|
||||
fullScreen = true;
|
||||
quickSplash = true;
|
||||
size = "${toString (config.custom.width / 2)}x${toString (config.custom.height / 2)}";
|
||||
uiFont = config.custom.font.monospace;
|
||||
uiSize = 24;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -94,6 +94,11 @@ in {
|
|||
libnotify
|
||||
systemd
|
||||
])
|
||||
(bash "iommu" [
|
||||
coreutils
|
||||
findutils
|
||||
pciutils
|
||||
])
|
||||
(bash "launch" [
|
||||
argc
|
||||
coreutils
|
||||
|
|
12
options/custom/scripts/iommu.sh
Normal file
12
options/custom/scripts/iommu.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#! /usr/bin/env bash
|
||||
|
||||
# https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Ensuring_that_the_groups_are_valid
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
|
||||
echo "IOMMU Group ${g##*/}:"
|
||||
for d in "$g"/devices/*; do
|
||||
echo -e "\t$(lspci -nns "${d##*/}")"
|
||||
done
|
||||
done
|
|
@ -35,10 +35,20 @@ in {
|
|||
};
|
||||
|
||||
# Serve static files
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/static - caddy caddy"
|
||||
"Z /srv/static - caddy caddy"
|
||||
];
|
||||
systemd.tmpfiles.settings."10-caddy" = {
|
||||
"/srv/static" = {
|
||||
d = {
|
||||
user = "caddy";
|
||||
group = "caddy";
|
||||
};
|
||||
|
||||
#!! Recursive
|
||||
Z = {
|
||||
user = "caddy";
|
||||
group = "caddy";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# https://wiki.nixos.org/wiki/Firewall
|
||||
# https://github.com/coturn/coturn/blob/master/docker/coturn/README.md
|
||||
|
|
|
@ -27,6 +27,7 @@ in {
|
|||
SYNC.path = config.custom.sync;
|
||||
|
||||
global = {
|
||||
"acl allow execute always" = "yes"; # Required for execution on Windows
|
||||
"allow insecure wide links" = "yes";
|
||||
"browseable" = "no";
|
||||
"follow symlinks" = "yes";
|
||||
|
|
|
@ -157,7 +157,14 @@ in {
|
|||
|
||||
systemd = {
|
||||
# Ensure creation of config directory
|
||||
tmpfiles.rules = ["d ${cfg.configDir} - ${cfg.user} ${cfg.group}"];
|
||||
tmpfiles.settings."10-syncthing" = {
|
||||
${cfg.configDir} = {
|
||||
d = {
|
||||
user = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#!! Syncthing needs to start after mounting or there is a risk of file deletion
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/networking/syncthing.nix#L646
|
||||
|
|
|
@ -16,7 +16,7 @@ in {
|
|||
kernel = mkOption {
|
||||
default =
|
||||
if config.custom.full
|
||||
then pkgs.linuxPackages_6_11
|
||||
then pkgs.linuxPackages_6_12
|
||||
else pkgs.linuxPackages;
|
||||
};
|
||||
systemd-boot = mkOption {default = config.custom.minimal;};
|
||||
|
|
|
@ -12,6 +12,7 @@ with lib; {
|
|||
networking.enable = true;
|
||||
packages.enable = true;
|
||||
security.enable = true;
|
||||
storage.enable = true;
|
||||
users.enable = true;
|
||||
})
|
||||
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.custom.settings.mounts;
|
||||
in {
|
||||
options.custom.settings.mounts.enable = mkOption {default = false;};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Enforce permissions for mountpoint directory
|
||||
systemd.tmpfiles.rules = ["d /mnt/remote 0755 root root"];
|
||||
|
||||
#!! FUSE does not support remount, sometimes causing activation errors on switch
|
||||
# https://github.com/libfuse/libfuse/issues/717
|
||||
#?? sudo umount /mnt/remote && sudo mount /mnt/remote
|
||||
# https://wiki.nixos.org/wiki/SSHFS
|
||||
# https://man.archlinux.org/man/sshfs.1
|
||||
fileSystems = let
|
||||
#?? "/mnt/PATH" = remote "PATH" UID GID "UMASK"
|
||||
remote = path: uid: gid: umask: {
|
||||
# https://robot.hetzner.com/storage
|
||||
device = "u415778@u415778.your-storagebox.de:/home/${path}";
|
||||
fsType = "sshfs";
|
||||
|
||||
options = [
|
||||
"noatime" # Do not modify access time
|
||||
"reconnect" # Gracefully handle network issues
|
||||
"default_permissions" # Check local permissions
|
||||
"allow_other" # Grant other users access
|
||||
"umask=${umask}" # Set permissions mask
|
||||
"uid=${toString uid}" # Set user id
|
||||
"gid=${toString gid}" # Set group id
|
||||
"idmap=user" # Map local users to remote
|
||||
"transform_symlinks" # Convert absolute symlinks to relative
|
||||
"compression=no" # Save CPU cycles at the cost of transfer speed
|
||||
"port=23"
|
||||
"IdentityFile=/etc/ssh/id_ed25519" # !! SSH key configured imperatively
|
||||
"ServerAliveInterval=15" # Prevent application hangs on reconnect
|
||||
];
|
||||
};
|
||||
in {
|
||||
# Use umask to set sshfs permissions
|
||||
#!! Up to 10 simultaneous connections with Hetzner
|
||||
#?? docker compose exec CONTAINER cat /etc/passwd
|
||||
"/mnt/remote/conduwuit" = remote "conduwuit" 300 300 "0077"; # conduit:conduit @ 0700
|
||||
#// "/mnt/remote/nextcloud" = remote "nextcloud" 33 33 "0007"; # www-data:www-data @ 0700
|
||||
"/mnt/remote/syncthing" = remote "syncthing" 237 237 "0077"; # syncthing:syncthing @ 0700
|
||||
};
|
||||
|
||||
# https://wiki.nixos.org/wiki/Rclone
|
||||
# https://docs.hetzner.com/robot/storage-box/access/access-ssh-rsync-borg/#rclone
|
||||
#!! SSH keys configured imperatively
|
||||
#!! rclone attempts to write to immutable config; need to manually merge changes
|
||||
# https://github.com/rclone/rclone/issues/3655
|
||||
# TODO: Attempt to use rclone after daemon is fixed
|
||||
# https://github.com/rclone/rclone/issues/5664
|
||||
# environment.etc."rclone.conf".text = ''
|
||||
# [remote]
|
||||
# type = sftp
|
||||
# host = u415778.your-storagebox.de
|
||||
# user = u415778
|
||||
# port = 23
|
||||
# key_file = /etc/ssh/id_ed25519
|
||||
# shell_type = unix
|
||||
# '';
|
||||
|
||||
# fileSystems."/mnt/remote" = {
|
||||
# device = "remote:/home";
|
||||
# fsType = "rclone";
|
||||
|
||||
# options = [
|
||||
# "nodev"
|
||||
# "nofail"
|
||||
# "reconnect"
|
||||
# "args2env" # Pass secrets as environment variables
|
||||
# "default_permissions"
|
||||
# "config=/etc/rclone.conf"
|
||||
# ];
|
||||
# };
|
||||
};
|
||||
}
|
|
@ -49,6 +49,9 @@ in {
|
|||
kdiskmark # Must be system package for polkit
|
||||
|
||||
### CLI applications
|
||||
mesa-demos # <glx|vk>gears
|
||||
vulkan-tools # vkcube
|
||||
|
||||
# https://github.com/sonic2kk/steamtinkerlaunch
|
||||
# TODO: Remove when v14 released on nixpkgs
|
||||
# https://github.com/sonic2kk/steamtinkerlaunch/issues/992
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
|
@ -25,5 +26,21 @@ in {
|
|||
'';
|
||||
};
|
||||
};
|
||||
|
||||
environment.shellAliases = {
|
||||
# Sudo confirmation prompt
|
||||
sudo = pkgs.writeShellScript "sudo" ''
|
||||
read -p "Execute as root? [Y/n] "
|
||||
|
||||
case "$REPLY" in
|
||||
"" | [Yy])
|
||||
command sudo "$@"
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
80
options/custom/settings/storage.nix
Normal file
80
options/custom/settings/storage.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.custom.settings.storage;
|
||||
in {
|
||||
options.custom.settings.storage = {
|
||||
enable = mkOption {default = false;};
|
||||
mnt = mkOption {default = [];};
|
||||
remote = mkOption {default = false;};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Enforce permissions for mountpoint directory
|
||||
systemd.tmpfiles.settings."10-storage" = {
|
||||
"/mnt/remote" = {
|
||||
d = {
|
||||
mode = "0755";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#!! FUSE does not support remount, sometimes causing activation errors on switch
|
||||
# https://github.com/libfuse/libfuse/issues/717
|
||||
#?? sudo umount /mnt/remote && sudo mount /mnt/remote
|
||||
# https://wiki.nixos.org/wiki/SSHFS
|
||||
# https://man.archlinux.org/man/sshfs.1
|
||||
fileSystems = let
|
||||
#?? "/mnt/PATH" = remote "PATH" UID GID "UMASK"
|
||||
remote = path: uid: gid: umask: {
|
||||
# https://robot.hetzner.com/storage
|
||||
device = "u415778@u415778.your-storagebox.de:/home/${path}";
|
||||
fsType = "sshfs";
|
||||
|
||||
options = [
|
||||
"noatime" # Do not modify access time
|
||||
"reconnect" # Gracefully handle network issues
|
||||
"default_permissions" # Check local permissions
|
||||
"allow_other" # Grant other users access
|
||||
"umask=${umask}" # Set permissions mask
|
||||
"uid=${toString uid}" # Set user id
|
||||
"gid=${toString gid}" # Set group id
|
||||
"idmap=user" # Map local users to remote
|
||||
"transform_symlinks" # Convert absolute symlinks to relative
|
||||
"compression=no" # Save CPU cycles at the cost of transfer speed
|
||||
"port=23"
|
||||
"IdentityFile=/etc/ssh/id_ed25519" # !! SSH key configured imperatively
|
||||
"ServerAliveInterval=15" # Prevent application hangs on reconnect
|
||||
];
|
||||
};
|
||||
in
|
||||
# Map list of disk labels to /mnt/LABEL with user defaults
|
||||
mergeAttrsList (forEach cfg.mnt (label: {
|
||||
"/mnt/${label}" = {
|
||||
device = "/dev/disk/by-label/${label}";
|
||||
|
||||
options = [
|
||||
"defaults"
|
||||
"noatime"
|
||||
"nofail"
|
||||
"user"
|
||||
"exec"
|
||||
"x-gvfs-show"
|
||||
];
|
||||
};
|
||||
}))
|
||||
// optionalAttrs cfg.remote {
|
||||
# Use umask to set sshfs permissions
|
||||
#!! Up to 10 simultaneous connections with Hetzner
|
||||
#?? docker compose exec CONTAINER cat /etc/passwd
|
||||
#// "/mnt/remote/conduwuit" = remote "conduwuit" 300 300 "0077"; # conduit:conduit @ 0700
|
||||
#// "/mnt/remote/nextcloud" = remote "nextcloud" 33 33 "0007"; # www-data:www-data @ 0700
|
||||
#// "/mnt/remote/syncthing" = remote "syncthing" 237 237 "0077"; # syncthing:syncthing @ 0700
|
||||
};
|
||||
};
|
||||
}
|
|
@ -6,12 +6,24 @@
|
|||
...
|
||||
}:
|
||||
with lib; let
|
||||
virsh = "${config.virtualisation.libvirtd.package}/bin/virsh";
|
||||
|
||||
cfg = config.custom.settings.vm;
|
||||
in {
|
||||
options.custom.settings.vm = {
|
||||
enable = mkOption {default = false;};
|
||||
libvirt = mkOption {default = true;};
|
||||
virtualbox = mkOption {default = false;};
|
||||
|
||||
passthrough = {
|
||||
enable = mkOption {default = false;};
|
||||
driver = mkOption {default = null;}; #?? lspci -k
|
||||
guest = mkOption {default = null;}; #?? virsh list --all
|
||||
id = mkOption {default = null;}; #?? lspci -nn
|
||||
init = mkOption {default = false;};
|
||||
intel = mkOption {default = false;};
|
||||
node = mkOption {default = null;}; #?? virsh nodedev-list
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -23,12 +35,37 @@ in {
|
|||
onBoot = "ignore";
|
||||
onShutdown = "shutdown";
|
||||
|
||||
# https://libvirt.org/hooks.html
|
||||
hooks.qemu = {
|
||||
# Attach/detach GPU for passthrough
|
||||
passthrough = mkIf cfg.passthrough.enable (pkgs.writeShellScript "passthrough" ''
|
||||
if [[ "$1" == "${cfg.passthrough.guest}" ]]; then
|
||||
case "$2" in
|
||||
prepare)
|
||||
${virsh} nodedev-detach ${cfg.passthrough.node}
|
||||
;;
|
||||
release)
|
||||
${virsh} nodedev-reattach ${cfg.passthrough.node}
|
||||
;;
|
||||
*)
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
'');
|
||||
};
|
||||
|
||||
qemu = {
|
||||
swtpm.enable = true; # TPM emulation
|
||||
|
||||
# BUG: Windows requires global mountpoint for some applications (\\.\*: instead of *:)
|
||||
# https://github.com/virtio-win/kvm-guest-drivers-windows/issues/950
|
||||
# https://virtio-win.github.io/Knowledge-Base/Virtiofs:-Shared-file-system
|
||||
#// vhostUserPackages = with pkgs; [virtiofsd]; # virtiofs support
|
||||
|
||||
# Build OVMF with Windows 11 support
|
||||
ovmf.packages = [
|
||||
(pkgs.OVMF.override {
|
||||
ovmf.packages = with pkgs; [
|
||||
(OVMF.override {
|
||||
secureBoot = true;
|
||||
tpmSupport = true;
|
||||
})
|
||||
|
@ -77,24 +114,42 @@ in {
|
|||
++ lib.optionals cfg.virtualbox ["vboxusers"];
|
||||
|
||||
systemd = mkIf cfg.libvirt {
|
||||
# Fix resume messages polluting tty
|
||||
services.libvirt-guests.serviceConfig.StandardOutput = "journal";
|
||||
services = {
|
||||
# Fix resume messages polluting tty
|
||||
libvirt-guests.serviceConfig = {
|
||||
StandardOutput = "journal";
|
||||
};
|
||||
};
|
||||
|
||||
tmpfiles.settings."10-vm" = {
|
||||
# HACK: Manually link image to default directory
|
||||
"/var/lib/libvirt/images/virtio-win.iso" = {
|
||||
"L+" = {
|
||||
argument = "${inputs.virtio-win}";
|
||||
};
|
||||
};
|
||||
|
||||
tmpfiles.rules = let
|
||||
firmware = pkgs.runCommandLocal "qemu-firmware" {} ''
|
||||
mkdir $out
|
||||
cp ${pkgs.qemu}/share/qemu/firmware/*.json $out
|
||||
substituteInPlace $out/*.json --replace ${pkgs.qemu} /run/current-system/sw
|
||||
'';
|
||||
in [
|
||||
# HACK: Fix libvirt not automatically locating firmware
|
||||
# https://github.com/NixOS/nixpkgs/issues/115996#issuecomment-2224296279
|
||||
# https://libvirt.org/formatdomain.html#bios-bootloader
|
||||
"L+ /var/lib/qemu/firmware - - - - ${firmware}"
|
||||
"/var/lib/qemu/firmware" = {
|
||||
"L+" = {
|
||||
argument = "${pkgs.runCommandLocal "qemu-firmware" {} ''
|
||||
mkdir $out
|
||||
cp ${pkgs.qemu}/share/qemu/firmware/*.json $out
|
||||
substituteInPlace $out/*.json --replace ${pkgs.qemu} /run/current-system/sw
|
||||
''}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# HACK: Manually link image to default directory
|
||||
"L+ /var/lib/libvirt/images/virtio-win.iso - - - - ${inputs.virtio-win}"
|
||||
];
|
||||
boot = mkIf cfg.passthrough.enable {
|
||||
# https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Isolating_the_GPU
|
||||
blacklistedKernelModules = mkIf cfg.passthrough.init [cfg.passthrough.driver];
|
||||
|
||||
# https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Enabling_IOMMU
|
||||
kernelParams = mkIf cfg.passthrough.intel ["intel_iommu=on"];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,11 +3,7 @@
|
|||
full = true;
|
||||
profile = "desktop";
|
||||
wallpaper = true;
|
||||
programs.looking-glass.enable = true;
|
||||
services.power-profiles-daemon.enable = true;
|
||||
|
||||
programs.anime-game-launcher = {
|
||||
enable = true;
|
||||
genshin-impact = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
];
|
||||
};
|
||||
|
||||
# TODO: Setup netdata
|
||||
# netdata = {
|
||||
# enable = true;
|
||||
# parent = true;
|
||||
|
@ -59,10 +60,5 @@
|
|||
group = "syncthing";
|
||||
};
|
||||
};
|
||||
|
||||
# settings = {
|
||||
# mounts.enable = true;
|
||||
# #// users.myned.linger = true;
|
||||
# };
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue