diff --git a/flake.nix b/flake.nix index edc71dd..27f97dd 100644 --- a/flake.nix +++ b/flake.nix @@ -236,6 +236,15 @@ ./hosts/nrec-nixos02 ]; }; + media1 = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs self; + }; + modules = commonModules ++ [ + ./hosts/media1 + ]; + }; openstack-template = nixpkgs.lib.nixosSystem { inherit system; specialArgs = { diff --git a/hosts/media1/configuration.nix b/hosts/media1/configuration.nix new file mode 100644 index 0000000..f58bd5e --- /dev/null +++ b/hosts/media1/configuration.nix @@ -0,0 +1,84 @@ +{ + pkgs, + ... +}: + +{ + imports = [ + ./hardware-configuration.nix + ../../system + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "media1"; + networking.domain = "home.2rjus.net"; + networking.useNetworkd = true; + networking.useDHCP = false; + networking.firewall.enable = false; + services.resolved.enable = true; + networking.nameservers = [ + "10.69.13.5" + "10.69.13.6" + ]; + + systemd.network.enable = true; + systemd.network.networks."10-lan" = { + matchConfig.Name = "enp*"; + address = [ + "10.69.31.51/24" + ]; + routes = [ + { Gateway = "10.69.31.1"; } + ]; + linkConfig.RequiredForOnline = "routable"; + }; + + time.timeZone = "Europe/Oslo"; + + homelab.host = { + tier = "prod"; + priority = "low"; + role = "media"; + }; + + # Intel N100 (Alder Lake-N) graphics + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver # VA-API driver for Broadwell+ + ]; + }; + + # NFS for media access + environment.systemPackages = with pkgs; [ + nfs-utils + ]; + services.rpcbind.enable = true; + + systemd.mounts = [ + { + type = "nfs"; + mountConfig = { + Options = "ro,soft,noatime"; + }; + what = "nas.home.2rjus.net:/mnt/hdd-pool/media"; + where = "/mnt/nas/media"; + } + ]; + + systemd.automounts = [ + { + wantedBy = [ "multi-user.target" ]; + automountConfig = { + TimeoutIdleSec = "5min"; + }; + where = "/mnt/nas/media"; + } + ]; + + vault.enable = true; + + system.stateVersion = "25.11"; +} diff --git a/hosts/media1/default.nix b/hosts/media1/default.nix new file mode 100644 index 0000000..7361a6a --- /dev/null +++ b/hosts/media1/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./configuration.nix + ./media-desktop.nix + ]; +} diff --git a/hosts/media1/hardware-configuration.nix b/hosts/media1/hardware-configuration.nix new file mode 100644 index 0000000..a0167aa --- /dev/null +++ b/hosts/media1/hardware-configuration.nix @@ -0,0 +1,33 @@ +# Do not modify this file! It was generated by 'nixos-generate-config' +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/0e1f61fd-18c6-4114-942e-f113a1e4b347"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/03C8-7DFE"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/0871bf99-9db6-4cd7-b307-3cebbb0a4e60"; } + ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/media1/media-desktop.nix b/hosts/media1/media-desktop.nix new file mode 100644 index 0000000..9a7b46e --- /dev/null +++ b/hosts/media1/media-desktop.nix @@ -0,0 +1,114 @@ +{ + pkgs, + lib, + ... +}: + +let + kodiPkg = pkgs.kodi-wayland.withPackages (p: [ + p.jellycon + p.sendtokodi + p.inputstream-adaptive + ]); + + hyprlandConfig = pkgs.writeText "hyprland.conf" '' + # Monitor — auto-detect, native resolution + monitor = , preferred, auto, 1 + + # Launch Kodi and Firefox on login + exec-once = ${lib.getExe' kodiPkg "kodi"} + exec-once = ${lib.getExe pkgs.firefox} + + # Workspace rules — Kodi on 1, Firefox on 2 + windowrulev2 = workspace 1 silent, class:^(kodi)$ + windowrulev2 = workspace 2 silent, class:^(firefox)$ + windowrulev2 = fullscreen, class:^(kodi)$ + windowrulev2 = fullscreen, class:^(firefox)$ + + # Start on workspace 1 (Kodi) + workspace = 1, default:true + + # Switch workspaces with Super+1/2 + bind = SUPER, 1, workspace, 1 + bind = SUPER, 2, workspace, 2 + + # No gaps, no borders — TV setup + general { + gaps_in = 0 + gaps_out = 0 + border_size = 0 + } + + decoration { + rounding = 0 + } + + # Disable animations for snappy switching + animations { + enabled = false + } + + misc { + # Disable Hyprland logo/splash + disable_hyprland_logo = true + disable_splash_rendering = true + } + ''; + + launchHyprland = pkgs.writeShellApplication { + name = "launch-hyprland"; + runtimeInputs = [ pkgs.hyprland ]; + text = '' + export XDG_SESSION_TYPE=wayland + exec Hyprland --config ${hyprlandConfig} + ''; + }; +in +{ + # Hyprland compositor + programs.hyprland.enable = true; + + # greetd for auto-login into Hyprland + services.greetd = { + enable = true; + settings = { + default_session = { + command = lib.getExe launchHyprland; + user = "kodi"; + }; + }; + }; + + # Kodi user + users.users.kodi = { + isNormalUser = true; + home = "/home/kodi"; + group = "kodi"; + extraGroups = [ + "video" + "audio" + "input" + ]; + }; + users.groups.kodi = { }; + + # Packages available on the system + environment.systemPackages = [ + kodiPkg + pkgs.firefox + pkgs.yt-dlp + ]; + + # PipeWire for audio (HDMI passthrough support) + services.pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; + }; + + # Allow VA-API hardware decode in Firefox + environment.sessionVariables = { + MOZ_ENABLE_WAYLAND = "1"; + LIBVA_DRIVER_NAME = "iHD"; + }; +}