1

Compare commits

...

4 Commits

13 changed files with 118 additions and 244 deletions

View File

@ -1,3 +1,3 @@
#!/usr/bin/env fish #!/usr/bin/env fish
grep -E "^bind =" ~/NixFlake/config/hyprland/hyprland.conf | sd "bind = " "" | rofi -dmenu -p " keys " -i cat ~/.config/hypr/keybindings.info | rofi -dmenu -p " keys " -i

View File

@ -1,34 +0,0 @@
#!/usr/bin/env fish
# User chooses service, running services are marked in green
set SERVICES (cat /etc/rofi-containers)
set PROMPT ""
for SERVICE in $SERVICES
set SERVICE_RUNNING "$(systemctl list-units podman-$SERVICE.service | grep podman-$SERVICE.service)"
if test -z $SERVICE_RUNNING
set PROMPT $PROMPT$SERVICE"\n"
else
set PROMPT $PROMPT"<span foreground=\"green\">$SERVICE</span>\n"
end
end
set SERVICE (echo -e $PROMPT | rofi -dmenu -p " pod " -i -markup-rows)
set SERVICE (echo -e $SERVICE | sd "<.*?>" "")
if not contains $SERVICE $SERVICES
exit
end
# User chooses action
set ACTIONS "start" "stop" "restart" "status"
set ACTION (echo -e (string join "\n" $ACTIONS) | rofi -dmenu -p " action " -i)
if not contains $ACTION $ACTIONS
exit
end
# Execute command
set COMMAND "systemctl $ACTION podman-$SERVICE.service"
set EVAL_RESULT "$(eval $COMMAND)"
if test $ACTION = "status" && test -n "$EVAL_RESULT"
# Display result if it exists
rofi -theme ~/NixFlake/config/rofi/rofi.rasi -e "$EVAL_RESULT"
end

View File

@ -33,6 +33,12 @@
mkBind = key: action: "${key}, ${action}"; mkBind = key: action: "${key}, ${action}";
mkBinds = key: actions: builtins.map (mkBind key) actions; mkBinds = key: actions: builtins.map (mkBind key) actions;
# These functions are used to generate the keybindings.info file for Rofi
mkBindHelpKey = key: ''${builtins.replaceStrings ["$mainMod " ", "] ["${cfg.keybindings.main-mod}-" "-"] key}'';
mkBindHelpAction = action: ''${builtins.replaceStrings [","] [""] action}'';
mkBindHelp = key: action: "<${mkBindHelpKey key}>: ${mkBindHelpAction action}";
mkBindsHelp = key: actions: builtins.map (mkBindHelp key) actions;
mkWallpaper = monitor: "${monitor}, ${config.home.homeDirectory}/NixFlake/wallpapers/${cfg.theme}.png"; mkWallpaper = monitor: "${monitor}, ${config.home.homeDirectory}/NixFlake/wallpapers/${cfg.theme}.png";
mkDelayedStart = str: "hyprctl dispatch exec \"sleep 5s && ${str}\""; mkDelayedStart = str: "hyprctl dispatch exec \"sleep 5s && ${str}\"";
@ -164,6 +170,15 @@ in {
libsForQt5.qtwayland libsForQt5.qtwayland
kdePackages.qtwayland kdePackages.qtwayland
]; ];
file = {
".config/hypr/keybindings.info".text = lib.pipe (lib.mergeAttrs cfg.keybindings.bindings always-bind) [
(builtins.mapAttrs mkBindsHelp)
builtins.attrValues
builtins.concatLists
(builtins.concatStringsSep "\n")
];
};
}; };
programs = { programs = {

View File

@ -26,16 +26,19 @@
"--dns=${netdns}" "--dns=${netdns}"
]); ]);
in in
lib.mergeAttrs extraConfig { extraConfig
// {
image = image; image = image;
autoStart = autoStart; autoStart = autoStart;
ports = ports ++ expanded-id-ports; ports = ports ++ expanded-id-ports;
volumes = vols; volumes = vols;
environment = lib.mergeAttrs env { environment =
PUID = "1000"; env
PGID = "1000"; // {
TZ = "Europe/Berlin"; PUID = "1000";
}; PGID = "1000";
TZ = "Europe/Berlin";
};
extraOptions = opts ++ additional-opts; extraOptions = opts ++ additional-opts;
}; };
@ -43,11 +46,12 @@
# Example: podman-stablediffusion = mkOciUserService config.systemd.services.podman-stablediffusion; # Example: podman-stablediffusion = mkOciUserService config.systemd.services.podman-stablediffusion;
# NOTE: This doesn't work, since the cidfile is located in /run, which is not writable for regular users... # NOTE: This doesn't work, since the cidfile is located in /run, which is not writable for regular users...
mkOciUserService = attrs: mkOciUserService = attrs:
lib.mergeAttrs (lib.attrsets.filterAttrs (n: v: (lib.attrsets.filterAttrs (n: v:
!((n == "confinement") !((n == "confinement")
|| (n == "runner") || (n == "runner")
|| (n == "environment"))) || (n == "environment")))
attrs) { attrs)
// {
startLimitIntervalSec = 1; startLimitIntervalSec = 1;
startLimitBurst = 5; startLimitBurst = 5;
}; };

View File

@ -10,7 +10,6 @@
nixos = import ./nixos.nix {inherit inputs pkgs lib;}; nixos = import ./nixos.nix {inherit inputs pkgs lib;};
modules = import ./modules.nix {inherit inputs pkgs lib;}; modules = import ./modules.nix {inherit inputs pkgs lib;};
networking = import ./networking.nix {inherit inputs pkgs lib;}; networking = import ./networking.nix {inherit inputs pkgs lib;};
virtualisation = import ./virtualisation.nix {inherit inputs pkgs lib;};
rofi = import ./rofi.nix {inherit inputs pkgs lib;}; rofi = import ./rofi.nix {inherit inputs pkgs lib;};
generators = import ./generators.nix {inherit inputs pkgs lib;}; generators = import ./generators.nix {inherit inputs pkgs lib;};
} }

View File

@ -113,6 +113,11 @@ with mylib.networking; {
protectKernelImage = true; protectKernelImage = true;
rtkit.enable = true; rtkit.enable = true;
pam.services = {
# Allow Hyprlock to unlock the system
hyprlock = {};
};
# TODO: Replace with polkit # TODO: Replace with polkit
sudo.enable = true; sudo.enable = true;
sudo.extraRules = [ sudo.extraRules = [

View File

@ -0,0 +1,76 @@
# TODO: Generate file with names for rofi
{
config,
nixosConfig,
lib,
mylib,
pkgs,
...
}:
with lib;
with mylib.virtualisation;
with mylib.modules; let
cfg = config.modules.containers;
in {
options.modules.containers = import ./options.nix {inherit lib mylib;};
# TODO: These need config options exposed through the module,
# e.g. to set paths/volumes/binds differently per system...
config = mkIf cfg.enable rec {
virtualisation.oci-containers.containers = {
# Examples how to use the mkOciContainer function:
# stablediffusion = mkIf cfg.stablediffusion.enable (mkOciContainer {
# image = "rocm/pytorch:rocm5.5_ubuntu20.04_py3.8_pytorch_1.13.1";
# vols = [
# "/home/christoph/NoSync/StableDiffusionWebUI:/webui-data"
# ];
# opts = [
# "--network=host"
# "--device=/dev/kfd"
# "--device=/dev/dri"
# "--group-add=video"
# "--ipc=host"
# "--cap-add=SYS_PTRACE"
# "--security-opt=seccomp=unconfined"
# ];
# extraConfig = {
# entrypoint = "/webui-data/launch.sh";
# };
# });
# sonarr = mkIf cfg.sonarr.enable (mkOciContainer {
# image = "linuxserver/sonarr:3.0.10";
# id-ports = [8989];
# vols = [
# "sonarr-config:/config:Z"
# "/media/Shows:/media/Shows"
# "/media/Usenet:/media/Usenet"
# ];
# netns = "wg0-de-115";
# netdns = "10.2.0.1";
# });
};
# Allow start/stop containers without root password
modules.polkit.allowed-system-services = let
container-services = lib.pipe virtualisation.oci-containers.containers [
builtins.attrNames
(builtins.filter (c: cfg.${c}.enable))
(builtins.map (c: "podman-${c}.service"))
];
in
container-services;
# Generate list of containers for rofi menu
environment.etc."rofi-containers".text = let
containers = lib.pipe virtualisation.oci-containers.containers [
builtins.attrNames
(builtins.filter (c: cfg.${c}.enable))
(builtins.concatStringsSep "\n")
];
in
containers;
};
}

View File

@ -1,148 +0,0 @@
# TODO: Generate file with names for rofi
{
config,
nixosConfig,
lib,
mylib,
pkgs,
...
}:
with lib;
with mylib.virtualisation;
with mylib.modules; let
cfg = config.modules.containers;
in {
options.modules.containers = import ./options.nix {inherit lib mylib;};
# TODO: These need config options exposed through the module,
# e.g. to set paths/volumes/binds differently per system...
config = mkIf cfg.enable rec {
virtualisation.oci-containers.containers = {
# Home Automation
homeassistant = mkIf cfg.homeassistant.enable (mkOciContainer {
image = "homeassistant/home-assistant:2023:5";
id-ports = [8123];
vols = [
"homeassistant-config:/config:Z"
];
});
# Development
# NOTE: PyTorch ROCM image is 36 GB large...
# NOTE: This requires to setup the PodmanROCM direcory beforehand, as described here:
# https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs#running-inside-docker
# NOTE: This requires to manually link the launch.sh, since this is a system module (can't use home.file)
stablediffusion = mkIf cfg.stablediffusion.enable (mkOciContainer {
image = "rocm/pytorch:rocm5.5_ubuntu20.04_py3.8_pytorch_1.13.1";
vols = [
"/home/christoph/NoSync/StableDiffusionWebUI:/webui-data"
];
opts = [
"--network=host"
"--device=/dev/kfd"
"--device=/dev/dri"
"--group-add=video"
"--ipc=host"
"--cap-add=SYS_PTRACE"
"--security-opt=seccomp=unconfined"
];
extraConfig = {
entrypoint = "/webui-data/launch.sh";
};
});
# Multimedia
jellyfin = mkIf cfg.jellyfin.enable (mkOciContainer {
image = "linuxserver/jellyfin:10.8.10";
id-ports = [8096];
autoStart = true;
vols = [
"jellyfin-cache:/cache:Z"
"jellyfin-config:/config:Z"
"/media/Picture:/media/Picture"
"/media/Video:/media/Video"
];
});
fileflows = mkIf cfg.fileflows.enable (mkOciContainer {
image = "revenz/fileflows";
id-ports = [5000];
vols = [
"fileflows-cache:/temp:Z"
"fileflows-data:/app/Data:Z"
"/media/Shows:/media/Shows"
"/media/Movies:/media/Movies"
"/media/Video:/media/Video"
];
});
# Errr...
sonarr = mkIf cfg.sonarr.enable (mkOciContainer {
image = "linuxserver/sonarr:3.0.10";
id-ports = [8989];
vols = [
"sonarr-config:/config:Z"
"/media/Shows:/media/Shows"
"/media/Usenet:/media/Usenet"
];
netns = "wg0-de-115";
netdns = "10.2.0.1";
});
radarr = mkIf cfg.radarr.enable (mkOciContainer {
image = "linuxserver/radarr:4.4.4";
id-ports = [7878];
vols = [
"radarr-config:/config:Z"
"/media/Movies:/media/Movies"
"/media/Usenet:/media/Usenet"
];
netns = "wg0-de-115";
netdns = "10.2.0.1";
});
hydra = mkIf cfg.hydra.enable (mkOciContainer {
image = "linuxserver/nzbhydra2:5.1.8";
id-ports = [5076];
vols = [
"hydra-config:/config:Z"
"/media/Usenet:/media/Usenet"
];
netns = "wg0-de-115";
netdns = "10.2.0.1";
});
sabnzbd = mkIf cfg.sabnzbd.enable (mkOciContainer {
image = "linuxserver/sabnzbd:4.0.1";
id-ports = [8080];
vols = [
"sabnzbd-config:/config:Z"
"/media/Usenet:/media/Usenet"
];
netns = "wg0-de-115";
netdns = "10.2.0.1";
});
};
# Allow start/stop containers without root password
modules.polkit.allowed-system-services = let
container-services = lib.pipe virtualisation.oci-containers.containers [
builtins.attrNames
(builtins.filter (c: cfg.${c}.enable))
(builtins.map (c: "podman-${c}.service"))
];
in
container-services;
# Generate list of containers for rofi menu
environment.etc."rofi-containers".text = let
containers = lib.pipe virtualisation.oci-containers.containers [
builtins.attrNames
(builtins.filter (c: cfg.${c}.enable))
(builtins.concatStringsSep "\n")
];
in
containers;
};
}

View File

@ -1,14 +1,5 @@
{ {...}: {
inputs,
config,
nixosConfig,
lib,
pkgs,
mylib,
...
}: {
imports = [ imports = [
./containers
./polkit ./polkit
./systemd-networkd ./systemd-networkd
]; ];

View File

@ -1,9 +1,8 @@
{ {
config, config,
nixosConfig,
lib, lib,
mylib, mylib,
pkgs, username,
... ...
}: }:
with lib; with lib;
@ -15,9 +14,8 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
security.polkit.enable = true; security.polkit.enable = true;
# TODO: Don't hardcode subject.user == "christoph"
security.polkit.extraConfig = let security.polkit.extraConfig = let
# Stuff that is non-negotiable # Stuff that should always get a rule
always-predicates = []; always-predicates = [];
mkServicePredicate = service: "action.lookup(\"unit\") == \"${service}\""; mkServicePredicate = service: "action.lookup(\"unit\") == \"${service}\"";
@ -27,7 +25,7 @@ in {
]; ];
in '' in ''
polkit.addRule(function(action, subject) { polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" && subject.user == "christoph" && ( if (action.id == "org.freedesktop.systemd1.manage-units" && subject.user == "${username}" && (
${predicates} ${predicates}
)) { )) {
return polkit.Result.YES; return polkit.Result.YES;

View File

@ -2,11 +2,9 @@
# TODO: Need to set permissions through polkit module # TODO: Need to set permissions through polkit module
# TODO: Setup Wireless (IWD/Networkd?) # TODO: Setup Wireless (IWD/Networkd?)
{ {
inputs,
config, config,
lib, lib,
mylib, mylib,
pkgs,
... ...
}: }:
with lib; with lib;

View File

@ -6,25 +6,11 @@
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
../modules
# inputs.musnix.nixosModules.musnix ../modules
]; ];
modules = { modules = {
containers = {
enable = true;
homeassistant.enable = false;
stablediffusion.enable = true;
jellyfin.enable = false;
fileflows.enable = false;
sonarr.enable = false;
radarr.enable = false;
hydra.enable = false;
sabnzbd.enable = false;
};
systemd-networkd = { systemd-networkd = {
networks = { networks = {
# This should override the default network 50-ether # This should override the default network 50-ether
@ -38,17 +24,9 @@
# "10-ether-1G" = mylib.networking.mkStaticSystemdNetwork {...}; # "10-ether-1G" = mylib.networking.mkStaticSystemdNetwork {...};
}; };
allowedTCPPorts = [ allowedTCPPorts = [];
# AvaTalk ports
7777
12777
];
allowedUDPPorts = [ allowedUDPPorts = [];
# AvaTalk ports
7777
12777
];
wireguard-tunnels = { wireguard-tunnels = {
wg0-de-115 = wg0-de-115 =
@ -82,12 +60,6 @@
}; };
}; };
# Low latency audio
# musnix = {
# enable = true;
# # musnix.soundcardPciId = ;
# };
boot = { boot = {
kernelPackages = pkgs.linuxPackages_zen; kernelPackages = pkgs.linuxPackages_zen;
}; };
@ -98,12 +70,10 @@
xkb.variant = "altgr-intl"; xkb.variant = "altgr-intl";
videoDrivers = ["nvidia"]; # NVIDIA videoDrivers = ["nvidia"]; # NVIDIA
# videoDrivers = ["amdgpu"];
}; };
# NOTE: This has been relocated here from the default config, because it forces en-US keyboard layout. # This has been relocated here from the default config,
# The laptop needs de-DE... # because it forces en-US keyboard layout.
# Chinese Input
i18n.inputMethod = { i18n.inputMethod = {
enable = true; enable = true;
type = "fcitx5"; type = "fcitx5";