Init nix config

This commit is contained in:
Curt Spark 2024-03-15 11:30:24 +00:00
commit f3faa0350a
13 changed files with 687 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
hardware-configuration.nix

View File

@ -0,0 +1,129 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, lib, inputs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./../../hardware-configuration.nix
./../../modules/cspark-single-gpu-passthru/module.nix
inputs.home-manager.nixosModules.default
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.initrd.luks.devices."luks-9658340a-9d7d-4dbd-be1c-c8c7393ddfc3".device = "/dev/disk/by-uuid/9658340a-9d7d-4dbd-be1c-c8c7393ddfc3";
networking.hostName = "cspark-nixos-desktop"; # Define your hostname.
# Enable networking
networking.networkmanager.enable = true;
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Enable the X11 windowing system.
services.xserver.enable = true;
# Enable the KDE Plasma Desktop Environment.
services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# GTK themes are not applied in Wayland applications / Window Decorations missing / Cursor looks different
programs.dconf.enable = true;
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
};
# My audio interface has issues after coming out from suspend/hibernate, this will reset it to fix it when necessary.
systemd.services.audiointerface-reset = {
description = "Resets audio interface to clear up any issues";
wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
path = with pkgs; [ bash coreutils kmod ];
enable = true;
serviceConfig = {
User = "root";
Group = "root";
ExecStart =
let
script = pkgs.writeShellScript "audiointerface-reset"
''
# Unbind audio interface
echo 3-3 > /sys/bus/usb/drivers/usb/unbind
# Remove snd_usb_audio once no longer in use
while ! modprobe -r snd_usb_audio; do
sleep 1
done
modprobe snd_usb_audio
# Rebind audio interface
echo 3-3 > /sys/bus/usb/drivers/usb/bind
'';
in
"${script}";
};
};
# Home Manager Configuration
home-manager = {
extraSpecialArgs = { inherit inputs; };
users = {
"cspark" = import ./home.nix;
};
};
# Steam Game Platform
programs.steam = {
enable = true;
# remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
# dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
gamescopeSession.enable = true;
};
# Single GPU Passthru Configuration
cspark-single-gpu-passthru.enable = true;
cspark-single-gpu-passthru.vmName = "win11";
cspark-single-gpu-passthru.gpuPCI = "0000:08:00.0";
cspark-single-gpu-passthru.gpuAudioPCI = "0000:08:00.1";
# Waydroid Android Emulation
virtualisation.waydroid.enable = true;
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
git
vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
cifs-utils
neofetch
appimage-run
wl-clipboard
python3
usbutils
nvtop-amd
];
}

View File

@ -0,0 +1,81 @@
{ config, pkgs, ... }:
{
imports =
[
# Global Config, always to be included
./../../global-home.nix
];
# KDE Connect
services.kdeconnect.enable = true;
services.kdeconnect.indicator = true;
# Home Manager is pretty good at managing dotfiles. The primary way to manage
# plain files is through 'home.file'.
home.file = {
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
# # symlink to the Nix store copy.
# ".screenrc".source = dotfiles/screenrc;
# # You can also set the file content immediately.
# ".gradle/gradle.properties".text = ''
# org.gradle.console=verbose
# org.gradle.daemon.idletimeout=3600000
# '';
".local/share/applications/ncmpcpp.desktop".text = ''
[Desktop Entry]
Name=NCMPCPP
Comment=Run ncurses music player CPP
Categories=Other;
Icon=konsole
Type=Application
Exec=konsole -e ncmpcpp
Terminal=false
'';
};
# Roblox Curl Service
systemd.user.services.roblox-curl = {
Unit = {
Description = "Check what roblox users are online";
};
Service = {
ExecStart = "%h/Documents/RobloxCurlOnline.sh";
};
};
systemd.user.timers.roblox-curl = {
Unit = {
Description = "Check what roblox users are online - hourly";
};
Timer = {
OnCalendar = "hourly";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
# VRChat Curl Service
systemd.user.services.vrchat-curl = {
Unit = {
Description = "Check what vrchat users are online";
};
Service = {
ExecStart = "%h/Documents/VRChatCurlOnline.sh";
};
};
systemd.user.timers.vrchat-curl = {
Unit = {
Description = "Check what vrchat users are online - hourly";
};
Timer = {
OnCalendar = "hourly";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
}

48
flake.lock Normal file
View File

@ -0,0 +1,48 @@
{
"nodes": {
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1710452332,
"narHash": "sha256-+lKOoQ89fD6iz6Ro7Adml4Sx6SqQcTWII4t1rvVtdjs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "096d9c04b3e9438855aa65e24129b97a998bd3d9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1710272261,
"narHash": "sha256-g0bDwXFmTE7uGDOs9HcJsfLFhH7fOsASbAuOzDC+fhQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "0ad13a6833440b8e238947e47bea7f11071dc2b2",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

24
flake.nix Normal file
View File

@ -0,0 +1,24 @@
{
description = "Nixos config flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, ... }@inputs: {
nixosConfigurations = {
desktop = nixpkgs.lib.nixosSystem {
specialArgs = {inherit inputs;};
modules = [
./global.nix
./configurations/desktop/configuration.nix
];
};
};
};
}

124
global-home.nix Normal file
View File

@ -0,0 +1,124 @@
{ config, pkgs, ... }:
let
homedir = "/home/cspark";
in
{
# Home Manager needs a bit of information about you and the paths it should
# manage.
home.username = "cspark";
home.homeDirectory = "${homedir}";
# This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release
# introduces backwards incompatible changes.
#
# You should not change this value, even if you update Home Manager. If you do
# want to update the value, then make sure to first check the Home Manager
# release notes.
home.stateVersion = "23.11"; # Please read the comment before changing.
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# The home.packages option allows you to install Nix packages into your
# environment.
home.packages = with pkgs; [
# # Adds the 'hello' command to your environment. It prints a friendly
# # "Hello, world!" when run.
# pkgs.hello
# # It is sometimes useful to fine-tune packages, for example, by applying
# # overrides. You can do that directly here, just don't forget the
# # parentheses. Maybe you want to install Nerd Fonts with a limited number of
# # fonts?
# (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
# # You can also create simple shell scripts directly inside your
# # configuration. For example, this adds a command 'my-hello' to your
# # environment:
# (pkgs.writeShellScriptBin "my-hello" ''
# echo "Hello, ${config.home.username}!"
# '')
# wineWowPackages.full
# native wayland support (unstable)
wineWowPackages.waylandFull
firefox
librewolf
ungoogled-chromium
emacs
telegram-desktop
discord
lutris
protonup-qt
qpwgraph
ardour
lsp-plugins
yabridge
yabridgectl
kdenlive
vlc
pass-wayland
thunderbird
# Just for utils
pulseaudio
# For curl scripts
jq
libnotify
];
services.mpd = {
enable = true;
musicDirectory = "${homedir}/Spool2_Secret/Music/Flac";
network.startWhenNeeded = true;
extraConfig = ''
audio_output {
type "pipewire"
name "PipeWire Output"
}
'';
};
services.mpd-discord-rpc.enable = true;
programs.ncmpcpp.enable = true;
# Home Manager can also manage your environment variables through
# 'home.sessionVariables'. If you don't want to manage your shell through Home
# Manager then you have to manually source 'hm-session-vars.sh' located at
# either
#
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# /etc/profiles/per-user/cspark/etc/profile.d/hm-session-vars.sh
#
home.sessionVariables = {
EDITOR = "emacs -nw";
};
programs.bash = {
enable = true;
enableCompletion = true;
bashrcExtra = "neofetch";
initExtra = ''
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
'';
};
programs.git = {
enable = true;
userName = "cspark";
userEmail = "git@cspark.dev";
};
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}

92
global.nix Normal file
View File

@ -0,0 +1,92 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, lib, inputs, ... }:
{
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Set your time zone.
time.timeZone = "Europe/London";
# Select internationalisation properties.
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
# Configure keymap in X11
services.xserver.xkb = {
layout = "gb";
variant = "";
};
# Configure console keymap
console.keyMap = "uk";
# Define a user account. Don't forget to set a password with passwd.
users.users.cspark = {
isNormalUser = true;
description = "Curt Spark";
extraGroups = [ "networkmanager" "wheel" "libvirtd" "libvirt" "kvm" "input" ];
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# Due to NixOS not using FHS paths, many DAWs will not know where to look for VSTs and other plugins. You can solve this by setting
environment.variables = let
makePluginPath = format:
(lib.strings.makeSearchPath format [
"$HOME/.nix-profile/lib"
"/run/current-system/sw/lib"
"/etc/profiles/per-user/$USER/lib"
])
+ ":$HOME/.${format}";
in {
DSSI_PATH = makePluginPath "dssi";
LADSPA_PATH = makePluginPath "ladspa";
LV2_PATH = makePluginPath "lv2";
LXVST_PATH = makePluginPath "lxvst";
VST_PATH = makePluginPath "vst";
VST3_PATH = makePluginPath "vst3";
};
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
}

View File

@ -0,0 +1,112 @@
{ lib, config, pkgs, modulesPath, ... }:
let
cfg = config.cspark-single-gpu-passthru;
in
{
options.cspark-single-gpu-passthru = {
enable
= lib.mkEnableOption "Enable Single GPU Passthrough Setup";
vmName = lib.mkOption {
default = "win11";
description = ''
Name of the virtual machine
'';
};
gpuPCI = lib.mkOption {
default = "0000:08:00.0";
description = ''
PCI ID of GPU VGA
'';
};
gpuAudioPCI = lib.mkOption {
default = "0000:08:00.1";
description = ''
PCI ID of GPU Audio
'';
};
};
config = lib.mkIf cfg.enable {
# Virtualisation, Virt Manager and Waydroid
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
swtpm.enable = true;
ovmf = {
enable = true;
packages = [(pkgs.OVMF.override {
secureBoot = true;
tpmSupport = true;
}).fd];
};
};
};
programs.virt-manager.enable = true;
systemd.services.libvirtd = {
# Add binaries to path so that hooks can use it
path = let
env = pkgs.buildEnv {
name = "qemu-hook-env";
paths = with pkgs; [
bash
libvirt
kmod
systemd
ripgrep
sd
procps
gawk
];
};
in
[ env ];
preStart = let
qemuscript_source = builtins.readFile ./resources/libvirt/hooks/qemu;
startscript_source = builtins.readFile ./resources/libvirt/hooks/qemu.d/vm/prepare/begin/start.sh;
revertscript_source = builtins.readFile ./resources/libvirt/hooks/qemu.d/vm/release/end/revert.sh;
qemuscript = pkgs.writeShellScript "cspark-single-gpu-passthru-qemu" revertscript_source;
startscript = pkgs.writeShellScript "cspark-single-gpu-passthru-start.sh" startscript_source;
revertscript = pkgs.writeShellScript "cspark-single-gpu-passthru-revert.sh" revertscript_source;
gpuvbios = ./resources/libvirt/vgabios/gpuvbios.rom;
in
''
mkdir -p /var/lib/libvirt/hooks
mkdir -p /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/prepare/begin
mkdir -p /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/release/end
mkdir -p /var/lib/libvirt/vgabios
ln -sf ${qemuscript} /var/lib/libvirt/hooks/qemu
ln -sf ${startscript} /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/prepare/begin/start.sh
ln -sf ${revertscript} /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/release/end/revert.sh
ln -sf ${gpuvbios} /var/lib/libvirt/vgabios/gpuvbios.rom
# chmod +x /var/lib/libvirt/hooks/qemu
# chmod +x /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/prepare/begin/start.sh
# chmod +x /var/lib/libvirt/hooks/qemu.d/${cfg.vmName}/release/end/revert.sh
'';
};
# Vendor Reset Patches for Single GPU Passthrough - https://github.com/gnif/vendor-reset
boot.extraModulePackages = with config.boot.kernelPackages; [ vendor-reset ];
# Ensures GPU is configured to use vendor reset module
systemd.services.vendor-reset-config = {
description = "Ensures GPU is configured to use vendor reset module";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.coreutils ];
enable = true;
serviceConfig = {
User = "root";
Group = "root";
};
script = ''echo device_specific > "/sys/bus/pci/devices/${cfg.gpuPCI}/reset_method"'';
};
hardware.opengl.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
};
}

View File

@ -0,0 +1,13 @@
sudo cp ~/libvirt/hooks/qemu /var/lib/libvirt/hooks/qemu
sudo chmod +x /var/lib/libvirt/hooks/qemu
sudo mkdir -p /var/lib/libvirt/hooks/qemu.d/win11/prepare/begin
sudo cp ~/libvirt/hooks/qemu.d/win11/prepare/begin/start.sh /var/lib/libvirt/hooks/qemu.d/win11/prepare/begin/start.sh
sudo chmod +x /var/lib/libvirt/hooks/qemu.d/win11/prepare/begin/start.sh
sudo mkdir -p /var/lib/libvirt/hooks/qemu.d/win11/release/end
sudo cp ~/libvirt/hooks/qemu.d/win11/release/end/stop.sh /var/lib/libvirt/hooks/qemu.d/win11/release/end/stop.sh
sudo chmod +x /var/lib/libvirt/hooks/qemu.d/win11/release/end/stop.sh
sudo mkdir -p /var/lib/libvirt/vgabios
sudo cp ~/libvirt/vgabios/gpuvbios.rom /var/lib/libvirt/vgabios/gpuvbios.rom

View File

@ -0,0 +1,19 @@
#!/run/current-system/sw/bin/bash
GUEST_NAME="$1"
HOOK_NAME="$2"
STATE_NAME="$3"
MISC="${@:4}"
BASEDIR="$(dirname $0)"
HOOKPATH="$BASEDIR/qemu.d/$GUEST_NAME/$HOOK_NAME/$STATE_NAME"
set -e # If a script exits with an error, we should as well.
if [ -f "$HOOKPATH" ]; then
eval \""$HOOKPATH"\" "$@"
elif [ -d "$HOOKPATH" ]; then
while read file; do
eval \""$file"\" "$@"
done <<< "$(find -L "$HOOKPATH" -maxdepth 1 -type f -executable -print;)"
fi

View File

@ -0,0 +1,25 @@
set -x
# Stop desktop environment and display manager
pkill kwin_wayland
systemctl --user -M cspark stop plasma*
systemctl stop display-manager
pkill sddm
pkill sddm-helper
# Log out of session
session=`loginctl session-status | awk 'NR==1{print $1}'`
loginctl terminate-session $session
# My audio interface has issues after coming out from a suspended type state, this will reset it to fix it when necessary.
# Unbind audio interface
echo 3-3 > /sys/bus/usb/drivers/usb/unbind
# Remove snd_usb_audio once no longer in use
while ! modprobe -r snd_usb_audio; do
sleep 1
done
# Remove amdgpu once no longer in use
while ! modprobe -r amdgpu; do
sleep 1
done

View File

@ -0,0 +1,19 @@
set -x
# My audio interface has issues after coming out from a suspended type state, this will reset it to fix it when necessary.
modprobe snd_usb_audio
# Rebind audio interface
echo 3-3 > /sys/bus/usb/drivers/usb/bind
# Remove vfio modules
modprobe -r vfio_pci
modprobe -r vfio
# Re-add amdgpu
modprobe amdgpu
# Avoid race condition whilst re-initalising amdgpu driver
sleep 5
# Restart Display Manager
systemctl start display-manager