From 6822350a3b067f8887a8658b846a2eb319f9016a Mon Sep 17 00:00:00 2001 From: Joeri Exelmans Date: Tue, 4 Mar 2025 10:55:48 +0100 Subject: [PATCH] init --- .gitignore | 2 + deemz.org/configuration.nix | 342 +++++++++++++++++++++++++++ deemz.org/hardware-configuration.nix | 34 +++ deemz.org/nec-v462-edid-patched.bin | Bin 0 -> 256 bytes deemz.org/pipewire-extra-config.nix | 204 ++++++++++++++++ flake.lock | 44 ++++ flake.nix | 28 +++ t14/configuration.nix | 209 ++++++++++++++++ t14/hardware-configuration.nix | 40 ++++ t14/pipewire-extra-config.nix | 41 ++++ t14/system-packages.nix | 111 +++++++++ 11 files changed, 1055 insertions(+) create mode 100644 .gitignore create mode 100644 deemz.org/configuration.nix create mode 100644 deemz.org/hardware-configuration.nix create mode 100644 deemz.org/nec-v462-edid-patched.bin create mode 100644 deemz.org/pipewire-extra-config.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 t14/configuration.nix create mode 100644 t14/hardware-configuration.nix create mode 100644 t14/pipewire-extra-config.nix create mode 100644 t14/system-packages.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..829d2e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +secrets.nix +t14/eduroam.8021x \ No newline at end of file diff --git a/deemz.org/configuration.nix b/deemz.org/configuration.nix new file mode 100644 index 0000000..0285402 --- /dev/null +++ b/deemz.org/configuration.nix @@ -0,0 +1,342 @@ +# 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, ... }: +let secrets = import ../secrets.nix; in +{ + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + + hardware.firmware = [ + ( + pkgs.runCommand "edid.bin" { } '' + mkdir -p $out/lib/firmware/edid + cp ${./nec-v462-edid-patched.bin} $out/lib/firmware/edid/edid.bin + '' + ) + ]; + + nixpkgs.config.allowUnfree = true; + + # Use the systemd-boot EFI boot loader. + #boot.loader.grub.device = "/dev/sda"; + boot.loader.grub.configurationLimit = 10; + boot.loader.systemd-boot.enable = true; + + time.timeZone = "Europe/Amsterdam"; + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + + services.fwupd.enable = true; + + # Enable the X11 windowing system. + services.xserver.enable = true; + # Enable the GNOME Desktop Environment. + services.xserver.displayManager.gdm.enable = true; + services.xserver.desktopManager.gnome.enable = true; + services.xserver.videoDrivers = [ "modesetting" ]; + services.xserver.deviceSection = '' + Option "TearFree" "true" + ''; + + services.displayManager.autoLogin = { + enable = true; + user= "maestro"; + }; + services.displayManager.preStart = '' + # Enable full range of RGB values in HDMI output + ${pkgs.libdrm.bin}/bin/proptest -M i915 -D /dev/dri/card1 95 connector 97 1 + ''; + # Workaround for GDM crashing on autologin: + # https://github.com/NixOS/nixpkgs/issues/103746 + systemd.services."getty@tty1".enable = false; + systemd.services."autovt@tty1".enable = false; + + services.xserver.xkb.layout = "us"; + services.xserver.xkb.options = "eurosign:e"; + + security.rtkit.enable = true; + services.pulseaudio.enable = false; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + extraConfig = import ./pipewire-extra-config.nix; + }; + + nixpkgs.config.packageOverrides = pkgs: { + vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; + }; + hardware.graphics.enable = true; + hardware.graphics.extraPackages = with pkgs; [ + intel-media-driver + vaapiIntel + intel-compute-runtime # OpenCL filter support + ]; + + # Enable touchpad support (enabled default in most desktopManager). + services.libinput.enable = true; + + + # List packages installed in system profile. To search, run: + environment.systemPackages = with pkgs; [ + vim + firefox + git + pavucontrol + vlc + transmission-remote-gtk + helvum + chromium + kodi + libdrm # proptest + (goaccess.override { + withGeolocation = true; + }) + jq + rygel # UPnP media renderer + ]; + + users.users.maestro = { + isNormalUser = true; + extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + }; + + programs.gnupg.agent = { + enable = true; + # enableSSHSupport = true; + }; + + + networking.hostName = "seedbox"; # Define your hostname. + networking.useDHCP = false; + networking.interfaces.enp1s0 = { + useDHCP = false; + ipv4.addresses = [ + { + address = "192.168.1.60"; + prefixLength = 24; + } + ]; + ipv6.addresses = [ + { + address = "2a02:578:8591:1b00::ffff"; + prefixLength = 64; + } + ]; + }; + networking.enableIPv6 = true; + networking.defaultGateway = "192.168.1.1"; + networking.defaultGateway6 = { + address = "fe80::52d4:f7ff:fe28:9849"; # TP-Link router + interface = "enp1s0"; + }; + networking.nameservers = [ "1.1.1.1" ]; + networking.extraHosts = '' + 192.168.1.60 mstro.duckdns.org + 192.168.1.60 deemz.org + ''; + # 2a02:578:8591:1b00::ffff mstro.duckdns.org + networking.networkmanager.unmanaged = [ "enp1s0" ]; + + # IPv6 is enabled, meaning we're not protected by NAT -> enable firewall + networking.firewall = { + enable = true; + allowedTCPPorts = [ + 22 + #53 + 80 + 443 + 51413 # Transmission + ]; + allowedUDPPorts = [ + #53 + 51413 # Transmission + ]; + # Accept all traffic from local network: + extraCommands = '' + iptables -A nixos-fw -p tcp --source 192.168.1.0/24 -j nixos-fw-accept + iptables -A nixos-fw -p udp --source 192.168.1.0/24 -j nixos-fw-accept + ip6tables -A nixos-fw -p tcp --source 2A02:578:8591:1B00::/64 -j nixos-fw-accept + ip6tables -A nixos-fw -p udp --source 2A02:578:8591:1B00::/64 -j nixos-fw-accept + ''; + }; + + # Users specifically for sending dynamic DNS updates + users.users.duckdns = { + isSystemUser = true; + group = "dyndns"; + }; + users.users.cloudflare-dns = { + isSystemUser = true; + group = "dyndns"; + }; + users.groups.dyndns = {}; # create this user + # Send DNS updates + services.cron = { + enable = true; + systemCronJobs = [ + # Update DuckDNS - use 'journalctl -e' to see logged output (should log 'OK' every 5 minutes) + "*/5 * * * * duckdns curl 'https://www.duckdns.org/update?domains=mstro&token=${duckdns-token}&ip=' | systemd-cat -t 'duckdns'" + # Update CloudFlare DNS + "*/1 * * * * cloudflare-dns curl --request PUT --url https://api.cloudflare.com/client/v4/zones/${secrets.cloudflare_zone_id}/dns_records/${secrets.cloudflare_dns_record_id} --header 'Content-Type: application/json' --header 'Authorization: Bearer ${secrets.cloudflare_api_token}' --data '{ \"comment\": \"Domain verification record\", \"name\": \"@\", \"proxied\": false, \"settings\": {}, \"tags\": [], \"ttl\": 60, \"content\": \"'$(curl https://ipinfo.io/ip)'\", \"type\": \"A\" }' | jq -r '.success' | systemd-cat -t 'cloudflare-dns'" + ]; + }; + + services.openssh.enable = true; + services.openssh.settings.PasswordAuthentication = false; + services.openssh.banner = '' + Howdy, partner! + ''; + + # DNSMasq will override the DNS entry for /etc/hosts entries + services.dnsmasq = { + enable = true; + settings = { + server = [ + "1.1.1.1" # Cloudflare primary + "1.0.0.1" # Cloudflare secondary + "8.8.8.8" # Google primary + "8.8.4.4" # Google secondary + "2606:4700:4700::1111" # Cloudflare primary + "2606:4700:4700::1001" # Cloudflare secondary + "2a02:578:8000:2:212:71:0:33" # Edpnet primary + "2a02:578:1001:3:212:71:8:10" # Edpnet secondary + ]; + listen-address = "::1,2a02:578:8591:1b00::ffff,127.0.0.1,192.168.1.60"; + cache-size = 10000; + }; + }; + + # NGINX + services.nginx = let + userlist = secrets.nginx_userlist; + commonConfig = { + root = "/schijf"; + locations."/" = { + basicAuth = userlist; + extraConfig = '' + autoindex on; + ''; + proxyWebsockets = true; + }; + locations."/public" = { + basicAuth = {}; + extraConfig = '' + autoindex off; + ''; + }; + locations."/plantuml" = { + basicAuth = {}; + extraConfig = '' + autoindex off; + ''; + proxyPass = "http://127.0.0.1:8080/plantuml"; + proxyWebsockets = true; + }; + locations."/transmission/web/" = { + basicAuth = userlist; + proxyPass = "http://127.0.0.1:9091/transmission/web/"; + proxyWebsockets = true; + }; + locations."/transmission/rpc" = { + basicAuth = userlist; + proxyPass = "http://127.0.0.1:9091/transmission/rpc"; + proxyWebsockets = true; + }; + locations."/jellyfin/" = { + #basicAuth = userlist; + proxyPass = "http://127.0.0.1:8096/jellyfin/"; + proxyWebsockets = true; + extraConfig = '' + proxy_buffering off; + ''; + }; + locations."/git/" = { + basicAuth = {}; + proxyPass = "http://127.0.0.1:27365/"; + proxyWebsockets = true; + }; + forceSSL = true; + enableACME = true; + + + extraConfig = '' + charset UTF-8; + disable_symlinks off; + more_set_headers 'Server: nginx on NixOS'; + ''; + }; + in { + enable = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + + # Access from internet: encrypted, authenticated (except '/public') + virtualHosts."mstro.duckdns.org" = commonConfig // { + serverName = "mstro.duckdns.org"; + }; + virtualHosts."deemz.org" = commonConfig // { + serverName = "deemz.org"; + }; + }; + security.acme = { + acceptTerms = true; + certs = { + "mstro.duckdns.org".email = "joeri.exelmans@gmail.com"; + "deemz.org".email = "joeri.exelmans@gmail.com"; + }; + }; + + services.plantuml-server = { + enable = true; + plantumlLimitSize = 40000; + }; + + services.jellyfin.enable = true; + + services.forgejo = { + enable = true; + settings.server.ROOT_URL = "https://deemz.org/git/"; + settings.server.HTTP_PORT = 27365; + settings.service.DISABLE_REGISTRATION = true; + }; + + services.transmission = { + enable = true; + package = pkgs.transmission_3; + settings = { + peer-port = 51413; + rpc-enabled = true; + rpc-authentication-required = false; + rpc-bind-address = "0.0.0.0"; + rpc-whitelist-enabled = false; + rpc-host-whitelist-enabled = false; + }; + home = "/schijf/transmission"; + downloadDirPermissions = "775"; # transmission: read+write+exec, other: read+exec + }; + + + # UPnP media playback (local network only) + services.gnome.rygel.enable = true; + + + # 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. It‘s 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 = "21.11"; # Did you read the comment? +} \ No newline at end of file diff --git a/deemz.org/hardware-configuration.nix b/deemz.org/hardware-configuration.nix new file mode 100644 index 0000000..452d936 --- /dev/null +++ b/deemz.org/hardware-configuration.nix @@ -0,0 +1,34 @@ +# 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" "usbhid" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/cb7a28e2-24d0-4156-8164-19f1e2208985"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/2496-3A5D"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/23382524-af2d-453e-acb4-1cf6a7083319"; } + ]; + + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/deemz.org/nec-v462-edid-patched.bin b/deemz.org/nec-v462-edid-patched.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d895550c3569d78ae47437fea3a1929b6dac6d1 GIT binary patch literal 256 zcmZSh4+abti_J0^85tS%MH!hJ(kv?;y_>r@#Al`&zq{8$PKL$M#)yGIj)8&UFM~m-OpG7{mjW0tFfjaK2s1G=g7Os<7#JA- zGZ;o17#N#aTKG9}DJU?WVq#V}=sSUxMVMJgL|#EriCs*YlbyYpk%1wVnTJ7uflr>H zA&^1Nz@fn$Vv|goV!(z#25AF_0yBt+T$*CoDv%nteq*Qzqilmjp^TV9gpMjiWFDhz V!-XOlF$Dn~)dsMO=P`i582|uXKLG#$ literal 0 HcmV?d00001 diff --git a/deemz.org/pipewire-extra-config.nix b/deemz.org/pipewire-extra-config.nix new file mode 100644 index 0000000..64105e1 --- /dev/null +++ b/deemz.org/pipewire-extra-config.nix @@ -0,0 +1,204 @@ +{ + pipewire = { + "10-downmix-5.1-to-4.0" = { + "context.modules" = [ + { + name = "libpipewire-module-filter-chain"; + args = { + "node.description" = "5.1 surround downmix"; + "media.name" = "5.1 surround downmix"; + "filter.graph" = { + nodes = builtins.concatLists [ + # FC and LFE connect to multiple nodes, so we need to create a 'copy' node for them + (map (name: { name=name; type="builtin"; label="copy"; }) + [ "copyFC" "copyLFE" ]) + + # Each output (FL, FR, RL, RR) is mixed from: + # In 1: their respective inputs (at original level) + # In 2: the center channel (only for FL and FR) + # In 3: the LFE channel (already amplified to match other channels by the decoder (e.g., 10 dB in Dolby spec) divided by 4) + (map (name: { name=name; type="builtin"; label="mixer"; control={"Gain 1"=1; "Gain 2"=0.5; "Gain 3"=0.25;}; }) + [ "mixFL" "mixFR" "mixRL" "mixRR" ]) + ]; + links = [ + # FC goes into FL and FR (at half gain) + { output = "copyFC:Out"; input = "mixFL:In 2"; } + { output = "copyFC:Out"; input = "mixFR:In 2"; } + + # LFE goes into all 4 channels + { output = "copyLFE:Out"; input = "mixFL:In 3"; } + { output = "copyLFE:Out"; input = "mixFR:In 3"; } + { output = "copyLFE:Out"; input = "mixRL:In 3"; } + { output = "copyLFE:Out"; input = "mixRR:In 3"; } + ]; + inputs = [ "mixFL:In 1" "mixFR:In 1" "copyFC:In" "copyLFE:In" "mixRL:In 1" "mixRR:In 1" ]; + outputs = [ "mixFL:Out" "mixFR:Out" "mixRL:Out" "mixRR:Out" ]; + }; + "capture.props" = { + "node.name" = "effect_input.downmix-5.1-to-4.0"; + "media.class" = "Audio/Sink"; + "audio.channels" = 6; + "audio.position" = [ "FL" "FR" "FC" "LFE" "RL" "RR" ]; + }; + "playback.props" = { + "node.name" = "effect_output.downmix-5.1-to-4.0"; + "node.passive" = true; + "audio.channels" = 4; + "audio.position" = [ "FL" "FR" "RL" "RR" ]; + }; + }; + } + ]; + }; + # The following filter is meant for a quadrophonics (4.0) setup with 4 full-range speakers and no dedicated subwoofer. + # It extracts bass from all 4 channels, mixes it, and feeds it back equally to all channels (bass becomes mono). + # The result is more flat bass response in much of the room. + "20-subwoofer-crossover" = let + crossoverFreq = 60; + in { + "context.modules" = [ + { + name = "libpipewire-module-filter-chain"; + args = { + "node.description" = "Subwoofer crossover"; + "media.name" = "Subwoofer crossover"; + "filter.graph" = { + nodes = builtins.concatLists [ + # Create copy nodes for all our inputs + (map (name: { name=name; type="builtin"; label="copy"; }) + [ "copyFL" "copyFR" "copyRL" "copyRR" ]) + + # Each channel is high-passed + (map (name: { name=name; type="builtin"; label="bq_highpass"; }) + [ "highpassFL" "highpassFR" "highpassRL" "highpassRR" ]) + + # Create our 'LFE' channel + # All channels are mixed before being low-passed (for subwoofer channel) + [ + { + name = "mixAll"; + type = "builtin"; + label = "mixer"; + control = { "Gain 1"=0.25; "Gain 2"=0.25; "Gain 3"=0.25; "Gain 4"=0.25; }; + } + { + name = "lowpass"; + type = "builtin"; + label = "bq_lowpass"; + control = { Freq = crossoverFreq; }; + } + # While we're at it, let's add some extra "oomph" + { + name = "oomph"; + type = "builtin"; + label = "bq_peaking"; + control = { Freq = 28; Q = 1; Gain = 6; }; + } + ] + + # Each of the 4 resulting outputs is mixed from (1) the high-passed channel, (2) the low-passed mix of all 4 channels + (map (name: { name=name; type="builtin"; label="mixer"; }) + [ "mixFL" "mixFR" "mixRL" "mixRR" ]) + ]; + links = [ + # All 4 channels are mixed to extract subwoofer channel + { output = "copyFL:Out"; input = "mixAll:In 1"; } + { output = "copyFR:Out"; input = "mixAll:In 2"; } + { output = "copyRL:Out"; input = "mixAll:In 3"; } + { output = "copyRR:Out"; input = "mixAll:In 4"; } + + # All 4 channels are high-passed + { output = "copyFL:Out"; input = "highpassFL:In"; } + { output = "copyFR:Out"; input = "highpassFR:In"; } + { output = "copyRL:Out"; input = "highpassRL:In"; } + { output = "copyRR:Out"; input = "highpassRR:In"; } + + # The mixed channel is low-passed + { output = "mixAll:Out"; input = "lowpass:In"; } + { output = "lowpass:Out"; input = "oomph:In"; } + + # The low-passed signal is mixed into every output channel + { output = "oomph:Out"; input = "mixFL:In 1"; } + { output = "oomph:Out"; input = "mixFR:In 1"; } + { output = "oomph:Out"; input = "mixRL:In 1"; } + { output = "oomph:Out"; input = "mixRR:In 1"; } + + # The high-passed signals are mixed into their respective output channels + { output = "highpassFL:Out"; input = "mixFL:In 2"; } + { output = "highpassFR:Out"; input = "mixFR:In 2"; } + { output = "highpassRL:Out"; input = "mixRL:In 2"; } + { output = "highpassRR:Out"; input = "mixRR:In 2"; } + ]; + inputs = [ "copyFL:In" "copyFR:In" "copyRL:In" "copyRR:In" ]; + outputs = [ "mixFL:Out" "mixFR:Out" "mixRL:Out" "mixRR:Out" ]; + }; + "capture.props" = { + "node.name" = "effect_input.subwoofer-crossover"; + "media.class" = "Audio/Sink"; + "audio.channels" = 4; + "audio.position" = [ "FL" "FR" "RL" "RR" ]; + }; + "playback.props" = { + "node.name" = "effect_output.subwoofer-crossover"; + "node.passive" = true; + "audio.channels" = 4; + "audio.position" = [ "FL" "FR" "RL" "RR" ]; + }; + }; + } + ]; + }; + # Upmixes stereo (2.0) to quadrophonics (4.0). + # The rear speakers get the signal from the front speakers, rotated by 90 degrees, and slightly delayed. + "30-upmix-2.0-to-4.0" = let + #delay = 0.000; # (ms) delay of rear speakers + delay = 0.009; # (ms) delay of rear speakers + in { + "context.modules" = [ + { + name = "libpipewire-module-filter-chain"; + args = { + "node.description" = "Upmix 2.0 -> 4.0"; + "media.name" = "Upmix 2.0 -> 4.0"; + "filter.graph" = { + nodes = builtins.concatLists [ + (map (name: { name=name; type="builtin"; label="copy"; }) + [ "copyFL" "copyFR" "outFL" "outFR" ]) + + (map (name: { name=name; type="builtin"; label="convolver"; config={filename="/hilbert";}; }) + [ "rotateL" "rotateR" ]) + + (map (name: { name=name; type="builtin"; label="delay"; control={"Delay (s)"=delay;}; config={max-delay=delay;}; }) + [ "delayL" "delayR" ]) + ]; + links = [ + # Front channels + { output = "copyFL:Out"; input = "outFL:In"; } + { output = "copyFR:Out"; input = "outFR:In"; } + # Rear channels + { output = "copyFL:Out"; input = "rotateL:In"; } + { output = "copyFR:Out"; input = "rotateR:In"; } + { output = "rotateL:Out"; input = "delayL:In"; } + { output = "rotateR:Out"; input = "delayR:In"; } + ]; + inputs = [ "copyFL:In" "copyFR:In" ]; + outputs = [ "outFL:Out" "outFR:Out" "delayL:Out" "delayR:Out" ]; + }; + "capture.props" = { + "node.name" = "effect_input.upmix-2.0-to-4.0"; + "media.class" = "Audio/Sink"; + "audio.channels" = 2; + "audio.position" = [ "FL" "FR" ]; + }; + "playback.props" = { + "node.name" = "effect_output.upmix-2.0-to-4.0"; + "node.passive" = true; + "audio.channels" = 4; + "audio.position" = [ "FL" "FR" "RL" "RR" ]; + }; + }; + } + ]; + }; + }; +} \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..534ee4f --- /dev/null +++ b/flake.lock @@ -0,0 +1,44 @@ +{ + "nodes": { + "nixpkgs-stable": { + "locked": { + "lastModified": 1740865531, + "narHash": "sha256-h00vGIh/jxcGl8aWdfnVRD74KuLpyY3mZgMFMy7iKIc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5ef6c425980847c78a80d759abc476e941a9bf42", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1740828860, + "narHash": "sha256-cjbHI+zUzK5CPsQZqMhE3npTyYFt9tJ3+ohcfaOF/WM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "303bd8071377433a2d8f76e684ec773d70c5b642", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs-stable": "nixpkgs-stable", + "nixpkgs-unstable": "nixpkgs-unstable" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a4d9e24 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "system config"; + + inputs = { + nixpkgs-stable.url = "github:nixos/nixpkgs?ref=nixos-24.11"; + nixpkgs-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + }; + + outputs = { self, nixpkgs-stable, nixpkgs-unstable }: + let + system = "x86_64-linux"; + in { + nixosConfigurations = { + t14 = nixpkgs-stable.lib.nixosSystem { + specialArgs = { inherit system; }; + modules = [ + ./t14/configuration.nix + ]; + }; + deemz = nixpkgs-unstable.lib.nixosSystem { + specialArgs = { inherit system; }; + modules = [ + ./deemz.org/configuration.nix + ]; + }; + }; + }; +} diff --git a/t14/configuration.nix b/t14/configuration.nix new file mode 100644 index 0000000..e5e9b4d --- /dev/null +++ b/t14/configuration.nix @@ -0,0 +1,209 @@ +# 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, ... }: { + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + nixpkgs.config.allowUnfree = true; + + nixpkgs.config.permittedInsecurePackages = [ + "openssl-1.1.1w" # needed for Sublime Text 4 + ]; + + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.efi.efiSysMountPoint = "/boot/efi"; + + boot.kernelPackages = pkgs.linuxPackages_latest; # use latest kernel - my fancy hardware wasnt supported on default kernel. + + # Example of applying a kernel patch: + # boot.kernelPatches = [{ + # name = "myPatch"; # name doesn't matter + # patch = pkgs.writeTextFile { # file will be written to /nix/store + # name = "myPatch.patch"; # filename doesn't matter + # text = '' + # + # ''; + # }; + # }]; + + boot.resumeDevice = "/dev/disk/by-uuid/a9a63c82-df16-4fde-a794-78ef231c59f6"; + swapDevices = [ + { + device = "/var/lib/swapfile"; + size = 32*1024; + } + ]; + + # Set your time zone. + time.timeZone = "Europe/Brussels"; + #time.timeZone = "Europe/London"; + #time.timeZone = "America/Montreal"; + #time.timeZone = "America/Barbados"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.utf8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "nl_BE.utf8"; + LC_IDENTIFICATION = "nl_BE.utf8"; + LC_MEASUREMENT = "nl_BE.utf8"; + LC_MONETARY = "nl_BE.utf8"; + LC_NAME = "nl_BE.utf8"; + LC_NUMERIC = "nl_BE.utf8"; + LC_PAPER = "nl_BE.utf8"; + LC_TELEPHONE = "nl_BE.utf8"; + LC_TIME = "nl_BE.utf8"; + }; + + networking.hostName = "t14"; + networking.extraHosts = '' + 143.129.75.8 msdl-testing + ''; + networking.networkmanager.enable = true; + networking.networkmanager.wifi.backend = "iwd"; + networking.firewall.enable = false; + + # Enable the X11 windowing system. + services.xserver = { + enable = true; + autoRepeatDelay = 150; + xkb.layout = "us"; # keymap + xkb.variant = ""; # ? + }; + services.libinput.enable = true; + + # T14 Gen3 trackpoint is way too sensitive by default: + hardware.trackpoint = { + enable = true; + device = "TPPS/2 Elan TrackPoint"; + # sensitivity = 90; # default: 128 + speed = 110; # default: 97 + }; + + # Huion tablet: + hardware.opentabletdriver.enable = true; + + # Sound... + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + extraConfig = import ./pipewire-extra-config.nix; + }; + + # Graphics... + hardware.graphics.enable = true; # enable OpenGL + hardware.graphics.enable32Bit = true; # also install 32 bit drivers (in order to run 32 bit apps under Wine) + hardware.graphics.extraPackages = with pkgs; [ + intel-media-driver # hardware accelerated video decoding on Intel + vaapiIntel + ]; + + hardware.bluetooth.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.maestro = { + isNormalUser = true; + description = "Joeri Exelmans"; + extraGroups = [ "networkmanager" "wheel" "vboxusers" "docker" "video" ]; + packages = with pkgs; []; + }; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + pinentryPackage = lib.mkForce pkgs.pinentry-qt; + }; + + # Extra fonts to install + fonts.packages = with pkgs; [ + aileron + liberation_ttf + roboto + roboto-mono + vistafonts + dejavu_fonts + freefont_ttf + gyre-fonts # TrueType substitutes for standard PostScript fonts + unifont + noto-fonts-color-emoji + ]; + + # This seems to fix my buggy PC-LM1E webcam + environment.etc."modprobe.d/uvcvideo.conf".text = pkgs.lib.mkForce '' + options uvcvideo quirks=0x106 + ''; + + # Enable experimental Wayland support in Chromium + # Disabled, because this breaks Chromium on X11 + # nixpkgs.config.chromium.commandLineArgs = "--enable-features=UseOzonePlatform --ozone-platform=wayland"; + + services.pcscd.enable = true; # Belgian eID + + services.locate.enable = true; + services.flatpak.enable = true; + + # Thinkpad power management + services.power-profiles-daemon.enable = false; # conflicts with tlp + services.tlp.enable = true; + services.tlp.settings = { + # Auto-disable wireless networks when Ethernet is connected. + # Not to save power, but to get best performance. + + # Seem broken with iwd: + # DEVICES_TO_DISABLE_ON_LAN_CONNECT = "wifi wwan"; + # DEVICES_TO_ENABLE_ON_LAN_DISCONNECT = "wifi wwan"; + + START_CHARGE_THRESH_BAT0 = 99; # Battery percentage to start charging + STOP_CHARGE_THRESH_BAT0 = 100; # Battery percentage to stop charging + }; + + services.printing.enable = true; + services.printing.drivers = [ + pkgs.hplip # HP LaserJet 4250 + pkgs.gutenprint + pkgs.gutenprintBin + ]; + + #virtualisation.virtualbox.host.enable = true; + # Causes slow-as-fuck re-compilation of kernel module on every software update: + #virtualisation.virtualbox.host.enableExtensionPack = true; + virtualisation.docker.enable = true; + + # KDE config + services.desktopManager.plasma6.enable = true; + services.xserver.desktopManager.xfce.enable = true; + + # firmware updates + services.fwupd.enable = true; + + environment.systemPackages = import ./system-packages.nix { pkgs=pkgs; }; + + environment.sessionVariables = let + # schema = pkgs.gsettings-desktop-schemas; + # datadir = "${schema}/share/gsettings-schemas/${schema.name}"; + in { + # XDG_DATA_DIRS = [ "${datadir}" ]; #:$XDG_DATA_HOME"; + MOZ_ENABLE_WAYLAND = "1"; + MOZ_USE_XINPUT2 = "1"; + GTK_OVERLAY_SCROLLING = 0; + }; + + # 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. It‘s 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 = "22.05"; # Did you read the comment? +} diff --git a/t14/hardware-configuration.nix b/t14/hardware-configuration.nix new file mode 100644 index 0000000..9a7b80a --- /dev/null +++ b/t14/hardware-configuration.nix @@ -0,0 +1,40 @@ +# 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" "thunderbolt" "nvme" "usbhid" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/a9a63c82-df16-4fde-a794-78ef231c59f6"; + fsType = "ext4"; + }; + + fileSystems."/boot/efi" = + { device = "/dev/disk/by-uuid/AC96-E749"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.docker0.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/t14/pipewire-extra-config.nix b/t14/pipewire-extra-config.nix new file mode 100644 index 0000000..979f7c6 --- /dev/null +++ b/t14/pipewire-extra-config.nix @@ -0,0 +1,41 @@ +{ + pipewire = { + "equalizer" = { + "context.modules" = [ + { + name = "libpipewire-module-filter-chain"; + args = { + "node.description" = "equalizer"; + "media.name" = "equalizer"; + "filter.graph" = { + nodes = [ + { name = "eqFL"; type="builtin"; label="bq_peaking"; control = { Freq=24; Q=0.5; Gain=15; }; } + { name = "eqFR"; type="builtin"; label="bq_peaking"; control = { Freq=24; Q=0.5; Gain=15; }; } + { name = "eqFL2"; type="builtin"; label="bq_peaking"; control = { Freq=4000; Q=0.7; Gain=-6; }; } + { name = "eqFR2"; type="builtin"; label="bq_peaking"; control = { Freq=4000; Q=0.7; Gain=-6; }; } + ]; + links = [ + { output="eqFL:Out"; input="eqFL2:In"; } + { output="eqFR:Out"; input="eqFR2:In"; } + ]; + inputs = [ "eqFL:In" "eqFR:In" ]; + outputs = [ "eqFL2:Out" "eqFR2:Out" ]; + }; + "capture.props" = { + "node.name" = "effect_input.equalizer"; + "media.class" = "Audio/Sink"; + "audio.channels" = 2; + "audio.position" = [ "FL" "FR" ]; + }; + "playback.props" = { + "node.name" = "effect_output.equalizer"; + "node.passive" = true; + "audio.channels" = 2; + "audio.position" = [ "FL" "FR" ]; + }; + }; + } + ]; + }; + }; +} diff --git a/t14/system-packages.nix b/t14/system-packages.nix new file mode 100644 index 0000000..5b82491 --- /dev/null +++ b/t14/system-packages.nix @@ -0,0 +1,111 @@ +{ pkgs }: with pkgs; +let + firefoxWithBelgianEid = firefox-wayland.override { pkcs11Modules = [ eid-mw ]; }; + + sublime4Cracked = sublime4.overrideAttrs (finalAttrs: previousAttrs: { + sublime_text = previousAttrs.sublime_text.overrideAttrs (finalAttrs: previousAttrs: + let + pattern = "807905000f94c2"; # hex pattern to look for + replacement = "c6410501b20090"; # replacement + in { + postFixup = '' + # Based on: https://gist.github.com/opastorello/4d494d627ec9012367028c89cb7a1945 + + # Assert that binary contains pattern: + ${xxd}/bin/xxd -p -c 0 $out/sublime_text | sed '/${pattern}/!{q100}' > /dev/null # exit code '100' if pattern not found + + # Patch binary in-place: + ${xxd}/bin/xxd -p -c 0 $out/sublime_text | sed 's/${pattern}/${replacement}/' | ${xxd}/bin/xxd -p -c 0 -r > $out/tmp + mv $out/tmp $out/sublime_text + chmod +x $out/sublime_text + '' + previousAttrs.postFixup; + }); + }); +in [ + # Utility + tree + unzip + killall + nix-index + nix-tree # really useful package for searching, figuring out why something's a dependency, etc. + steam-run + zip + unrar + apg # secure password generator + fuse3 # User space filesystems - need this to run AppImages with steam-run + gnupg + bottles # Wrapper around wine + filelight # Disk space analysis + dconf-editor + gnome-calculator + gnome-disk-utility + file-roller + + # Programming + git + kate + vim + vimPlugins.vim-nix + graphviz + sublime4Cracked + sublime-merge + + # Network thingy + chromium + firefoxWithBelgianEid + thunderbird + signal-desktop + whatsapp-for-linux + tor-browser-bundle-bin + zoom-us + joplin-desktop + transmission-remote-gtk + transmission_3-gtk + dig # DNS debugging + sshfs + teams-for-linux # Unofficial teams client + + # Graphics thingy + gimp + inkscape + xournalpp + drawio + eog + + # Documents thingy + libreoffice + evince + koreader # epub reader + hunspell + hunspellDicts.en-us + hunspellDicts.en-us-large + pdfarranger # useful tool to rearrange / split / merge PDF documents + (texlive.combine { + inherit (texlive) scheme-small + awesomebox fontawesome5; + }) + + # Media thingy + vlc + (wrapOBS { + plugins = with obs-studio-plugins; [ + obs-backgroundremoval + ]; + }) + helvum + pavucontrol + pamixer # command line volume control + audacity + cheese + playerctl # command line media control (play/pause) + + # Belgian eID software and hardware drivers + eid-mw + pcsctools + pcsclite + ccid + acsccid + libacr38u + scmccid + qdigidoc +]