diff options
Diffstat (limited to 'users/tazjin/nixos')
23 files changed, 1106 insertions, 175 deletions
diff --git a/users/tazjin/nixos/.gitignore b/users/tazjin/nixos/.gitignore new file mode 100644 index 0000000000..212d3ad270 --- /dev/null +++ b/users/tazjin/nixos/.gitignore @@ -0,0 +1 @@ +local-config.nix diff --git a/users/tazjin/nixos/README.md b/users/tazjin/nixos/README.md index 0093f4ac65..662f2a36ac 100644 --- a/users/tazjin/nixos/README.md +++ b/users/tazjin/nixos/README.md @@ -1,20 +1,17 @@ NixOS configuration =================== -My NixOS configuration! It configures most of the packages I require +My NixOS configurations! It configures most of the packages I require on my systems, sets up Emacs the way I need and does a bunch of other interesting things. -System configuration lives in folders for each machine and a custom -fixed point evaluation (similar to standard NixOS module -configuration) is used to combine configuration together. +System configuration lives in folders, and some of the modules stem +from `//ops/modules`. -Building `ops.nixos.rebuilder` yields a script that will automatically -build and activate the newest configuration based on the current -hostname. +Machines are deployed with the script at `ops.nixos.rebuild-system`. ## Configured hosts: -* `frog` - weapon of mass computation at home -* `camden` - NUC serving tazj.in, tvl.fyi & co -* ~~`urdhva` - T470s~~ (currently with edef) +* `tverskoy` - X13 AMD that's travelling around with me +* `frog` - weapon of mass computation (in storage in London) +* `camden` - NUC formerly serving tazj.in (in storage in London) diff --git a/users/tazjin/nixos/camden/default.nix b/users/tazjin/nixos/camden/default.nix index d8c439b4f4..130b51dd38 100644 --- a/users/tazjin/nixos/camden/default.nix +++ b/users/tazjin/nixos/camden/default.nix @@ -1,11 +1,8 @@ # This file configures camden.tazj.in, my homeserver. { depot, pkgs, lib, ... }: -config: let - nixpkgs = import depot.third_party.nixpkgsSrc { - config.allowUnfree = true; - }; - +config: +let nginxRedirect = { from, to, acmeHost }: { serverName = from; useACMEHost = acmeHost; @@ -13,25 +10,13 @@ config: let extraConfig = "return 301 https://${to}$request_uri;"; }; -in lib.fix(self: { - depot = depot; - - # Disable the current ACME module and use the old one from 19.09 - # instead, until the various regressions have been sorted out. - # TODO(tazjin): Remove this once the new ACME module works. - disabledModules = [ "security/acme.nix" ]; - imports = - let oldChannel = fetchTarball { - # NixOS 19.09 on 2020-10-04 - url = "https://github.com/NixOS/nixpkgs-channels/archive/75f4ba05c63be3f147bcc2f7bd4ba1f029cedcb1.tar.gz"; - sha256 = "157c64220lf825ll4c0cxsdwg7cxqdx4z559fdp7kpz0g6p8fhhr"; - }; - in [ - "${depot.depotPath}/ops/nixos/depot.nix" - "${depot.depotPath}/ops/nixos/quassel.nix" - "${depot.depotPath}/ops/nixos/smtprelay.nix" - "${oldChannel}/nixos/modules/security/acme.nix" - ]; + mod = name: depot.path.origSrc + ("/ops/modules/" + name); +in +lib.fix (self: { + imports = [ + (mod "quassel.nix") + (mod "smtprelay.nix") + ]; # camden is intended to boot unattended, despite having an encrypted # root partition. @@ -44,8 +29,14 @@ in lib.fix(self: { boot = { initrd = { availableKernelModules = [ - "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" - "rtsx_usb_sdmmc" "r8169" + "ahci" + "xhci_pci" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + "rtsx_usb_sdmmc" + "r8169" ]; kernelModules = [ "dm-snapshot" ]; @@ -63,7 +54,7 @@ in lib.fix(self: { efi.canTouchEfiVariables = true; }; - cleanTmpDir = true; + tmp.cleanOnBoot = true; }; fileSystems = { @@ -83,25 +74,17 @@ in lib.fix(self: { }; }; - nix = { - maxJobs = lib.mkDefault 4; - - nixPath = [ - "depot=/home/tazjin/depot" - "nixpkgs=${depot.third_party.nixpkgsSrc}" - ]; - - trustedUsers = [ "root" "tazjin" ]; - - binaryCaches = [ + nix.settings = { + max-jobs = lib.mkDefault 4; + trusted-users = [ "root" "tazjin" ]; + substituters = [ "https://tazjin.cachix.org" ]; - binaryCachePublicKeys = [ + trusted-public-keys = [ "tazjin.cachix.org-1:IZkgLeqfOr1kAZjypItHMg1NoBjm4zX9Zzep8oRSh7U=" ]; }; - nixpkgs.pkgs = nixpkgs; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; @@ -125,7 +108,7 @@ in lib.fix(self: { programs.mosh.enable = true; fonts = { - fonts = [ nixpkgs.jetbrains-mono ]; + packages = [ pkgs.jetbrains-mono ]; fontconfig.defaultFonts.monospace = [ "JetBrains Mono" ]; }; @@ -134,15 +117,14 @@ in lib.fix(self: { (with depot; [ fun.idual.script fun.idual.setAlarm - third_party.pounce ]) ++ # programs from nixpkgs - (with nixpkgs; [ + (with pkgs; [ bat curl direnv - emacs26-nox + emacs28-nox fswebcam git gnupg @@ -162,14 +144,14 @@ in lib.fix(self: { isNormalUser = true; uid = 1000; extraGroups = [ "git" "wheel" "quassel" "video" ]; - shell = nixpkgs.fish; + shell = pkgs.fish; }; # Set up a user & group for general git shenanigans - groups.git = {}; + groups.git = { }; users.git = { group = "git"; - isNormalUser = false; + isSystemUser = true; }; }; @@ -181,13 +163,13 @@ in lib.fix(self: { services.tailscale.enable = true; # Allow sudo-ing via the forwarded SSH agent. - security.pam.enableSSHAgentAuth = true; + security.pam.sshAgentAuth.enable = true; # NixOS 20.03 broke nginx and I can't be bothered to debug it # anymore, all solution attempts have failed, so here's a # brute-force fix. systemd.services.fix-nginx = { - script = "${nixpkgs.coreutils}/bin/chown -R nginx: /var/spool/nginx /var/cache/nginx"; + script = "${pkgs.coreutils}/bin/chown -R nginx: /var/spool/nginx /var/cache/nginx"; serviceConfig = { User = "root"; @@ -205,38 +187,36 @@ in lib.fix(self: { # Provision a TLS certificate outside of nginx to avoid # nixpkgs#38144 security.acme = { - # acceptTerms = true; + acceptTerms = true; certs."tazj.in" = { email = "mail@tazj.in"; - user = "nginx"; group = "nginx"; webroot = "/var/lib/acme/acme-challenge"; - extraDomains = { - "cs.tazj.in" = null; - "git.tazj.in" = null; - "www.tazj.in" = null; + postRun = "systemctl reload nginx"; + + extraDomainNames = [ + "cs.tazj.in" + "git.tazj.in" + "www.tazj.in" # Local domains (for this machine only) - "camden.tazj.in" = null; - }; - postRun = "systemctl reload nginx"; + "camden.tazj.in" + ]; }; certs."quassel.tazj.in" = { email = "mail@tazj.in"; webroot = "/var/lib/acme/challenge-quassel"; - user = "nginx"; # required because of a bug in the ACME module group = "quassel"; - allowKeysForGroup = true; }; }; # Forward logs to Google Cloud Platform services.journaldriver = { - enable = true; - logStream = "home"; - googleCloudProject = "tazjins-infrastructure"; + enable = true; + logStream = "home"; + googleCloudProject = "tazjins-infrastructure"; applicationCredentials = "/etc/gcp/key.json"; }; @@ -249,7 +229,7 @@ in lib.fix(self: { }; services.bitlbee = { - enable = true; + enable = false; portNumber = 2337; # bees }; @@ -257,7 +237,7 @@ in lib.fix(self: { services.nginx = { enable = true; enableReload = true; - package = with nixpkgs; nginx.override { + package = with pkgs; nginx.override { modules = [ nginxModules.rtmp ]; }; diff --git a/users/tazjin/nixos/default.nix b/users/tazjin/nixos/default.nix index d4576bd3c7..8f82c39ea1 100644 --- a/users/tazjin/nixos/default.nix +++ b/users/tazjin/nixos/default.nix @@ -1,46 +1,12 @@ -# TODO(tazjin): Generalise this and move to //ops/nixos { depot, lib, ... }: -let - inherit (builtins) foldl'; - - systemFor = configs: (depot.third_party.nixos { - configuration = lib.fix(config: - foldl' lib.recursiveUpdate {} (map (c: c config) configs) - ); - }).system; - - caseFor = hostname: '' - ${hostname}) - echo "Rebuilding NixOS for //users/tazjin/nixos/${hostname}" - system=$(nix-build -E '(import <depot> {}).users.tazjin.nixos.${hostname}System' --no-out-link) - ;; - ''; - - rebuilder = depot.third_party.writeShellScriptBin "rebuilder" '' - set -ue - if [[ $EUID -ne 0 ]]; then - echo "Oh no! Only root is allowed to rebuild the system!" >&2 - exit 1 - fi - - case $HOSTNAME in - ${caseFor "camden"} - ${caseFor "frog"} - *) - echo "$HOSTNAME is not a known NixOS host!" >&2 - exit 1 - ;; - esac - - nix-env -p /nix/var/nix/profiles/system --set $system - $system/bin/switch-to-configuration switch - ''; -in { - inherit rebuilder; - - camdenSystem = systemFor [ depot.users.tazjin.nixos.camden ]; - frogSystem = systemFor [ depot.users.tazjin.nixos.frog ]; - - meta.targets = [ "camdenSystem" "frogSystem" ]; +let systemFor = sys: (depot.ops.nixos.nixosFor sys).system; +in depot.nix.readTree.drvTargets { + camdenSystem = systemFor depot.users.tazjin.nixos.camden; + frogSystem = systemFor depot.users.tazjin.nixos.frog; + tverskoySystem = systemFor depot.users.tazjin.nixos.tverskoy; + zamalekSystem = systemFor depot.users.tazjin.nixos.zamalek; + koptevoRaw = depot.ops.nixos.nixosFor depot.users.tazjin.nixos.koptevo; + koptevoSystem = systemFor depot.users.tazjin.nixos.koptevo; + khamovnikSystem = systemFor depot.users.tazjin.nixos.khamovnik; } diff --git a/users/tazjin/nixos/frog/default.nix b/users/tazjin/nixos/frog/default.nix index 9765554319..dfb6b46d5a 100644 --- a/users/tazjin/nixos/frog/default.nix +++ b/users/tazjin/nixos/frog/default.nix @@ -1,30 +1,18 @@ -{ depot, lib, ... }: +{ depot, lib, pkgs, ... }: -config: let - nixpkgs = import depot.third_party.nixpkgsSrc { - config.allowUnfree = true; - }; - - lieer = depot.third_party.lieer {}; - - # add google-c-style here because other machines get it from, eh, - # elsewhere. - frogEmacs = (depot.users.tazjin.emacs.overrideEmacs(epkgs: epkgs ++ [ - depot.third_party.emacsPackages.google-c-style - ])); +config: +let + inherit (pkgs) lieer; - quasselClient = depot.third_party.quassel.override { + quasselClient = pkgs.quassel.override { client = true; enableDaemon = false; monolithic = false; }; -in depot.lib.fix(self: { - imports = [ - "${depot.depotPath}/ops/nixos/v4l2loopback.nix" - ]; - +in +lib.fix (self: { boot = { - tmpOnTmpfs = true; + tmp.useTmpfs = true; kernelModules = [ "kvm-amd" ]; loader = { @@ -38,14 +26,16 @@ in depot.lib.fix(self: { kernelModules = [ "dm-snapshot" ]; }; - kernelPackages = nixpkgs.linuxPackages_latest; + kernelPackages = pkgs.linuxPackages_latest; kernel.sysctl = { "kernel.perf_event_paranoid" = -1; }; - kernelPatches = [ - depot.third_party.kernelPatches.trx40_usb_audio - ]; + # Enable this again if frog is put back into use ... + # + # kernelPatches = [ + # depot.third_party.kernelPatches.trx40_usb_audio + # ]; }; hardware = { @@ -59,7 +49,7 @@ in depot.lib.fix(self: { pulseaudio = { enable = true; - package = nixpkgs.pulseaudioFull; + package = pkgs.pulseaudioFull; }; bluetooth = { @@ -67,19 +57,11 @@ in depot.lib.fix(self: { }; }; - nix = { - maxJobs = 48; - nixPath = [ - "depot=/depot" - "nixpkgs=${depot.third_party.nixpkgsSrc}" - ]; - - binaryCaches = ["ssh://nix-ssh@whitby.tvl.fyi"]; - binaryCachePublicKeys = ["cache.tvl.fyi:fd+9d1ceCPvDX/xVhcfv8nAa6njEhAGAEe+oGJDEeoc="]; + nix.settings = { + max-jobs = 48; + substituters = [ "ssh://nix-ssh@whitby.tvl.fyi" ]; }; - nixpkgs.pkgs = nixpkgs; - networking = { hostName = "frog"; useDHCP = true; @@ -96,7 +78,7 @@ in depot.lib.fix(self: { # Generate an immutable /etc/resolv.conf from the nameserver settings # above (otherwise DHCP overwrites it): environment.etc."resolv.conf" = with lib; { - source = depot.third_party.writeText "resolv.conf" '' + source = pkgs.writeText "resolv.conf" '' ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") self.networking.nameservers)} options edns0 ''; @@ -115,7 +97,7 @@ in depot.lib.fix(self: { extraGroups = [ "wheel" "audio" "docker" ]; isNormalUser = true; uid = 1000; - shell = nixpkgs.fish; + shell = pkgs.fish; }; security.sudo = { @@ -124,7 +106,7 @@ in depot.lib.fix(self: { }; fonts = { - fonts = with nixpkgs; [ + packages = with pkgs; [ corefonts dejavu_fonts jetbrains-mono @@ -159,7 +141,7 @@ in depot.lib.fix(self: { # Required for Yubikey usage as smartcard services.pcscd.enable = true; services.udev.packages = [ - nixpkgs.yubikey-personalization + pkgs.yubikey-personalization ]; # Enable Docker for Nixery testing @@ -170,13 +152,13 @@ in depot.lib.fix(self: { services.xserver = { enable = true; - layout = "us"; - xkbOptions = "caps:super"; + xkb.layout = "us"; + xkb.options = "caps:super"; exportConfiguration = true; videoDrivers = [ "amdgpu" ]; displayManager = { # Give EXWM permission to control the session. - sessionCommands = "${nixpkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; + sessionCommands = "${pkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; lightdm.enable = true; lightdm.greeters.gtk.clock-format = "%H·%M"; # TODO(tazjin): TZ? @@ -184,7 +166,7 @@ in depot.lib.fix(self: { windowManager.session = lib.singleton { name = "exwm"; - start = "${frogEmacs}/bin/tazjins-emacs"; + start = "${depot.users.tazjin.emacs}/bin/tazjins-emacs"; }; }; @@ -219,32 +201,28 @@ in depot.lib.fix(self: { environment.systemPackages = # programs from the depot (with depot; [ - frogEmacs fun.idual.script fun.uggc lieer ops.kontemplate quasselClient - third_party.ffmpeg third_party.git - third_party.lutris - third_party.rr tools.nsfv-setup + users.tazjin.emacs ]) ++ # programs from nixpkgs - (with nixpkgs; [ + (with pkgs; [ age bat chromium clang-manpages clang-tools - clang_10 + clang curl direnv dnsutils - emacs26 # mostly for emacsclient - exa + emacs28 # mostly for emacsclient fd file gdb @@ -260,13 +238,12 @@ in depot.lib.fix(self: { jq kubectl linuxPackages.perf - manpages + man-pages miller msmtp nix-prefetch-github notmuch obs-studio - obs-v4l2sink openssh openssl pass @@ -279,10 +256,7 @@ in depot.lib.fix(self: { ripgrep rustup screen - scrot - sourcetrail spotify - steam tokei transmission tree @@ -295,6 +269,10 @@ in depot.lib.fix(self: { yubico-piv-tool yubikey-personalization zoxide + + # Commented out because of interim breakage: + # steam + # lutris ]); # ... and other nonsense. diff --git a/users/tazjin/nixos/khamovnik/default.nix b/users/tazjin/nixos/khamovnik/default.nix new file mode 100644 index 0000000000..8ea925c90d --- /dev/null +++ b/users/tazjin/nixos/khamovnik/default.nix @@ -0,0 +1,133 @@ +# Yandex work laptop +# +# Some of the configuration for this machine is not public. +{ depot, lib, pkgs, ... }: + +config: +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); + private = /arc/junk/tazjin; + + zdevice = device: { + inherit device; + fsType = "zfs"; + }; +in +{ + imports = [ + (usermod "chromium.nix") + (usermod "desktop.nix") + (usermod "fonts.nix") + (usermod "home-config.nix") + (usermod "laptop.nix") + (usermod "physical.nix") + (pkgs.home-manager.src + "/nixos") + ] ++ (if (builtins.pathExists private) then [ + (private + "/nixos/yandex.nix") + (private + "/emacs/module.nix") + ] else [ ]); + + # from hardware-configuration.nix + boot = { + initrd.luks.devices."luks-9c3cd590-a648-450d-ae42-ed3859d4c717".device = + "/dev/disk/by-uuid/9c3cd590-a648-450d-ae42-ed3859d4c717"; + + initrd.availableKernelModules = [ + "xhci_pci" + "thunderbolt" + "ahci" + "nvme" + "usb_storage" + "sd_mod" + "rtsx_pci_sdmmc" + ]; + kernelModules = [ "kvm-intel" ]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/1f783029-c4f9-4192-b893-84f4f0c2a493"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/DD01-2B3E"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ + device = "/dev/disk/by-uuid/9b9049c5-5975-441d-9ac6-2f9150775fd6"; + }]; + + tvl.cache.enable = true; + + networking.hostName = "khamovnik"; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + hardware.opengl.extraPackages = with pkgs; [ + intel-compute-runtime + intel-media-driver + intel-vaapi-driver + ]; + + # from generated configuration.nix + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Setup keyfile + boot.initrd.secrets = { + "/crypto_keyfile.bin" = null; + }; + + # Enable swap on luks + boot.initrd.luks.devices."luks-e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9".device = "/dev/disk/by-uuid/e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9"; + boot.initrd.luks.devices."luks-e9a4b4dc-ade2-45bf-8ed0-0ed5c4c392c9".keyFile = "/crypto_keyfile.bin"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "ru_RU.UTF-8"; + LC_IDENTIFICATION = "ru_RU.UTF-8"; + LC_MEASUREMENT = "ru_RU.UTF-8"; + LC_MONETARY = "ru_RU.UTF-8"; + LC_NAME = "ru_RU.UTF-8"; + LC_NUMERIC = "ru_RU.UTF-8"; + LC_PAPER = "ru_RU.UTF-8"; + LC_TELEPHONE = "ru_RU.UTF-8"; + LC_TIME = "ru_RU.UTF-8"; + }; + + # 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; + }; + + # Try to work around Intel CPU throttling bugs + services.throttled.enable = true; + + virtualisation.docker.enable = true; + + hardware.bluetooth.enable = true; + users.users.tazjin.extraGroups = [ "tss" ]; + + environment.systemPackages = with pkgs; [ + tdesktop + linuxPackages.perf + hotspot + protobuf + ]; + + system.stateVersion = "23.05"; # Did you read the comment? +} diff --git a/users/tazjin/nixos/koptevo/default.nix b/users/tazjin/nixos/koptevo/default.nix new file mode 100644 index 0000000000..ea8dfd4bd8 --- /dev/null +++ b/users/tazjin/nixos/koptevo/default.nix @@ -0,0 +1,187 @@ +# NUC in my closet. +_: # ignore readTree options + +{ config, depot, lib, pkgs, ... }: + +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); +in +{ + imports = [ + (mod "quassel.nix") + (mod "www/base.nix") + (mod "www/tazj.in.nix") + (usermod "airsonic.nix") + (usermod "geesefs.nix") + (usermod "predlozhnik.nix") + (usermod "tgsa.nix") + (usermod "miniflux.nix") + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ]; + kernelModules = [ "kvm-intel" ]; + kernelParams = [ "nomodeset" ]; + }; + + nix.settings.trusted-users = [ "tazjin" ]; + + fileSystems = { + "/" = { + device = "rpool/root"; + fsType = "zfs"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/E214-E6B3"; + fsType = "vfat"; + }; + + "/var" = { + device = "rpool/var"; + fsType = "zfs"; + }; + + "/home" = { + device = "rpool/home"; + fsType = "zfs"; + }; + }; + + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + services.fwupd.enable = true; + + networking = { + hostName = "koptevo"; + hostId = "07bbbf4f"; + domain = "tazj.in"; + useDHCP = true; + firewall.enable = true; + firewall.allowedTCPPorts = [ 22 80 443 ]; + + wireless.enable = true; + wireless.networks."How do I computer fast?" = { + psk = "washyourface"; + }; + }; + + time.timeZone = "UTC"; + + security.acme.acceptTerms = true; + security.acme.defaults.email = lib.mkForce "acme@tazj.in"; + + programs.fish.enable = true; + + users.users.tazjin = { + isNormalUser = true; + extraGroups = [ "wheel" "docker" "systemd-journal" ]; + shell = pkgs.fish; + openssh.authorizedKeys.keys = depot.users.tazjin.keys.all; + }; + + age.secrets = + let + secretFile = name: depot.users.tazjin.secrets."${name}.age"; + in + { + tgsa-yandex.file = secretFile "tgsa-yandex"; + }; + + security.sudo.wheelNeedsPassword = false; + + services.openssh.enable = true; + + services.depot.quassel = { + enable = true; + acmeHost = "koptevo.tazj.in"; + bindAddresses = [ + "0.0.0.0" + ]; + }; + + services.tailscale = { + enable = true; + useRoutingFeatures = "server"; # for exit-node usage + }; + + # Automatically collect garbage from the Nix store. + services.depot.automatic-gc = { + enable = true; + interval = "daily"; + diskThreshold = 15; # GiB + maxFreed = 10; # GiB + preserveGenerations = "14d"; + }; + + services.nginx.virtualHosts."koptevo.tazj.in" = { + addSSL = true; + enableACME = true; + + extraConfig = '' + location = / { + return 302 https://at.tvl.fyi/?q=%2F%2Fusers%2Ftazjin%2Fnixos%2Fkoptevo%2Fdefault.nix; + } + ''; + }; + + # I don't use the podcast nor playlist feature, + # but I *have to* supply podcasts to gonic ... + systemd.tmpfiles.rules = [ + "d /tmp/fake-podcasts 0555 nobody nobody -" + "d /tmp/fake-playlists 0555 nobody nobody -" + ]; + + services.gonic = { + enable = true; + settings = { + listen-addr = "0.0.0.0:4747"; + scan-interval = 5; + scan-at-start-enabled = true; + podcast-path = [ "/tmp/fake-podcasts" ]; + playlists-path = [ "/tmp/fake-playlists" ]; + music-path = [ "/var/lib/geesefs/tazjins-files/music" ]; + }; + }; + + # hack to work around the strict sandboxing of the gonic module + # breaking DNS resolution + systemd.services.gonic.serviceConfig.BindReadOnlyPaths = [ + "-/etc/resolv.conf" + ]; + + # add a hard dependency on the FUSE mount + systemd.services.gonic.requires = [ "geesefs.service" ]; + + services.nginx.virtualHosts."music.tazj.in" = { + addSSL = true; + enableACME = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:4747"; + }; + }; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + curl + htop + jq + nmap + bat + emacs-nox + nano + wget + ]; + + programs.mtr.enable = true; + programs.mosh.enable = true; + zramSwap.enable = true; + + system.stateVersion = "23.05"; +} diff --git a/users/tazjin/nixos/modules/airsonic.nix b/users/tazjin/nixos/modules/airsonic.nix new file mode 100644 index 0000000000..815f183778 --- /dev/null +++ b/users/tazjin/nixos/modules/airsonic.nix @@ -0,0 +1,32 @@ +# airsonic is a decent, web-based player UI for subsonic +{ pkgs, ... }: + +let + env = builtins.toFile "env.js" '' + window.env = { + SERVER_URL: "https://music.tazj.in", + } + ''; + + airsonicDist = pkgs.fetchzip { + name = "airsonic-refix"; + + # from master CI @ f894d5eacebec2f47486f340c8610f446d4f64b3 + # https://github.com/tamland/airsonic-refix/actions/runs/6150155527 + url = "https://storage.yandexcloud.net/tazjin-public/airsonic-refix-f894d5ea.zip"; + sha256 = "02rnh9h7rh22wkghays389yddwbwg7sawmczdxdmjrcnkc7mq2jz"; + + stripRoot = false; + postFetch = "cp ${env} $out/env.js"; + }; +in +{ + services.nginx.virtualHosts."player.tazj.in" = { + enableACME = true; + forceSSL = true; + root = "${airsonicDist}"; + + # deal with SPA routing requirements + locations."/".extraConfig = "try_files $uri /index.html;"; + }; +} diff --git a/users/tazjin/nixos/modules/chromium.nix b/users/tazjin/nixos/modules/chromium.nix new file mode 100644 index 0000000000..22f1c8d362 --- /dev/null +++ b/users/tazjin/nixos/modules/chromium.nix @@ -0,0 +1,30 @@ +# Configure the Chromium browser with various useful things. +{ pkgs, ... }: + +{ + environment.systemPackages = [ + (pkgs.chromium.override { + enableWideVine = true; # DRM support (for Кинопоиск) + }) + ]; + + programs.chromium = { + enable = true; + homepageLocation = "about:blank"; + + extensions = [ + "dbepggeogbaibhgnhhndojpepiihcmeb" # Vimium + "cjpalhdlnbpafiamejdnhcphjbkeiagm" # uBlock Origin + "mohaicophfnifehkkkdbcejkflmgfkof" # nitter redirect + "lhdifindchogekmjooeiolmjdlheilae" # Huruf + ]; + + extraOpts = { + SpellcheckEnabled = true; + SpellcheckLanguage = [ + "ru" + "en-GB" + ]; + }; + }; +} diff --git a/users/tazjin/nixos/modules/default.nix b/users/tazjin/nixos/modules/default.nix new file mode 100644 index 0000000000..d747e8e131 --- /dev/null +++ b/users/tazjin/nixos/modules/default.nix @@ -0,0 +1,2 @@ +# Make readTree happy at this level. +_: { } diff --git a/users/tazjin/nixos/modules/desktop.nix b/users/tazjin/nixos/modules/desktop.nix new file mode 100644 index 0000000000..12a42b8faa --- /dev/null +++ b/users/tazjin/nixos/modules/desktop.nix @@ -0,0 +1,55 @@ +# EXWM and other desktop configuration. +{ config, depot, lib, pkgs, ... }: + +{ + services = { + pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + redshift.enable = true; + blueman.enable = true; + + xserver = { + enable = true; + xkb.layout = "us"; + xkb.options = "caps:super"; + + libinput.enable = true; + + displayManager = { + # Give EXWM permission to control the session. + sessionCommands = "${pkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; + lightdm.enable = true; + # lightdm.greeters.gtk.clock-format = "%H:%M"; # TODO(tazjin): TZ? + }; + + windowManager.session = lib.singleton { + name = "exwm"; + start = "${config.tazjin.emacs}/bin/tazjins-emacs --internal-border=0 --border-width=0"; + }; + }; + }; + + # Set variables to enable EXWM-XIM and other Emacs features. + environment.sessionVariables = { + XMODIFIERS = "@im=exwm-xim"; + GTK_IM_MODULE = "xim"; + QT_IM_MODULE = "xim"; + CLUTTER_IM_MODULE = "xim"; + EDITOR = "emacsclient"; + _JAVA_AWT_WM_NONREPARENTING = "1"; + }; + + # Do not restart the display manager automatically + systemd.services.display-manager.restartIfChanged = lib.mkForce false; + + # If something needs more than 10s to stop it should probably be + # killed. + systemd.extraConfig = '' + DefaultTimeoutStopSec=10s + ''; +} diff --git a/users/tazjin/nixos/modules/fonts.nix b/users/tazjin/nixos/modules/fonts.nix new file mode 100644 index 0000000000..ee1b84e581 --- /dev/null +++ b/users/tazjin/nixos/modules/fonts.nix @@ -0,0 +1,24 @@ +# Attempt at configuring reasonable font-rendering. + +{ pkgs, ... }: + +{ + fonts = { + packages = with pkgs; [ + corefonts + dejavu_fonts + jetbrains-mono + noto-fonts-cjk + noto-fonts-emoji + ]; + + fontconfig = { + hinting.enable = true; + subpixel.lcdfilter = "light"; + + defaultFonts = { + monospace = [ "JetBrains Mono" ]; + }; + }; + }; +} diff --git a/users/tazjin/nixos/modules/geesefs.nix b/users/tazjin/nixos/modules/geesefs.nix new file mode 100644 index 0000000000..c45ee528f6 --- /dev/null +++ b/users/tazjin/nixos/modules/geesefs.nix @@ -0,0 +1,38 @@ +{ depot, pkgs, ... }: + +{ + imports = [ + (depot.third_party.agenix.src + "/modules/age.nix") + ]; + + age.secrets.geesefs-tazjins-files.file = depot.users.tazjin.secrets."geesefs-tazjins-files.age"; + programs.fuse.userAllowOther = true; + + systemd.services.geesefs = { + description = "geesefs @ tazjins-files"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.fuse ]; + + serviceConfig = { + # TODO: can't get fusermount to work for non-root users (e.g. DynamicUser) here, why? + + Restart = "always"; + LoadCredential = "geesefs-tazjins-files:/run/agenix/geesefs-tazjins-files"; + StateDirectory = "geesefs"; + ExecStartPre = "/run/wrappers/bin/umount -a -t fuse.geesefs"; + }; + + script = '' + set -u # bail out if systemd is misconfigured ... + set -x + + mkdir -p $STATE_DIRECTORY/tazjins-files $STATE_DIRECTORY/cache + + ${depot.third_party.geesefs}/bin/geesefs \ + -f -o allow_other \ + --cache $STATE_DIRECTORY/cache \ + --shared-config $CREDENTIALS_DIRECTORY/geesefs-tazjins-files \ + tazjins-files $STATE_DIRECTORY/tazjins-files + ''; + }; +} diff --git a/users/tazjin/nixos/modules/hidpi.nix b/users/tazjin/nixos/modules/hidpi.nix new file mode 100644 index 0000000000..2ff61d499a --- /dev/null +++ b/users/tazjin/nixos/modules/hidpi.nix @@ -0,0 +1,19 @@ +# Configuration for machines with HiDPI displays, which are a total +# mess, of course. +{ ... }: + +{ + # Expose a variable to all programs that might be interested in the + # screen settings to do conditional initialisation (mostly for Emacs). + environment.variables.HIDPI_SCREEN = "true"; + + # TODO(tazjin): this option has been removed and needs to be replaced + # by manual configuration: https://github.com/NixOS/nixpkgs/issues/222805 + # Ensure a larger font size in early boot stage. + # hardware.video.hidpi.enable = true; + + # Bump DPI across the board. + # TODO(tazjin): This should actually be set per monitor, but I + # haven't yet figured out the right interface for doing that. + services.xserver.dpi = 161; +} diff --git a/users/tazjin/nixos/modules/home-config.nix b/users/tazjin/nixos/modules/home-config.nix new file mode 100644 index 0000000000..bda8f7a440 --- /dev/null +++ b/users/tazjin/nixos/modules/home-config.nix @@ -0,0 +1,19 @@ +# Inject the right home-manager config for the machine. + +{ config, depot, pkgs, ... }: + +{ + users.users.tazjin = { + isNormalUser = true; + createHome = true; + extraGroups = [ "wheel" "networkmanager" "video" "adbusers" ]; + uid = 1000; + shell = pkgs.fish; + initialHashedPassword = "$2b$05$1eBPdoIgan/C/L8JFqIHBuVscQyTKw1L/4VBlzlLvLBEf6CXS3EW6"; + }; + + nix.settings.trusted-users = [ "tazjin" ]; + + home-manager.useGlobalPkgs = true; + home-manager.users.tazjin = depot.users.tazjin.home."${config.networking.hostName}"; +} diff --git a/users/tazjin/nixos/modules/laptop.nix b/users/tazjin/nixos/modules/laptop.nix new file mode 100644 index 0000000000..e0d67dc259 --- /dev/null +++ b/users/tazjin/nixos/modules/laptop.nix @@ -0,0 +1,15 @@ +# Configuration specifically for laptops that move around. +{ ... }: + +{ + time.timeZone = "Europe/Moscow"; + + # Automatically detect location for redshift & so on ... + services.geoclue2.enable = true; + location.provider = "geoclue2"; + + # Enable power-saving features. + services.tlp.enable = true; + + programs.light.enable = true; +} diff --git a/users/tazjin/nixos/modules/miniflux.nix b/users/tazjin/nixos/modules/miniflux.nix new file mode 100644 index 0000000000..72089bfb3d --- /dev/null +++ b/users/tazjin/nixos/modules/miniflux.nix @@ -0,0 +1,22 @@ +{ config, depot, lib, pkgs, ... }: + +{ + age.secrets.miniflux.file = depot.users.tazjin.secrets."miniflux.age"; + + services.miniflux = { + enable = true; + adminCredentialsFile = "/run/agenix/miniflux"; + config.LISTEN_ADDR = "127.0.0.1:6359"; + config.BASE_URL = "https://feeds.tazj.in"; + }; + + services.nginx.virtualHosts."feeds" = { + serverName = "feeds.tazj.in"; + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:6359"; + }; + }; +} diff --git a/users/tazjin/nixos/modules/persistence.nix b/users/tazjin/nixos/modules/persistence.nix new file mode 100644 index 0000000000..b864d13a8d --- /dev/null +++ b/users/tazjin/nixos/modules/persistence.nix @@ -0,0 +1,26 @@ +# Configuration for persistent (non-home) data. +{ config, depot, pkgs, lib, ... }: + +{ + imports = [ + (depot.third_party.sources.impermanence + "/nixos.nix") + ]; + + environment.persistence."/persist" = { + directories = [ + "/etc/NetworkManager/system-connections" + "/etc/mullvad-vpn" + "/var/cache/mullvad-vpn" + "/var/lib/bluetooth" + "/var/lib/systemd/coredump" + "/var/lib/tailscale" + "/var/log" + ]; + + files = lib.optional (builtins.isNull config.networking.hostId) [ + "/etc/machine-id" + ]; + }; + + programs.fuse.userAllowOther = true; +} diff --git a/users/tazjin/nixos/modules/physical.nix b/users/tazjin/nixos/modules/physical.nix new file mode 100644 index 0000000000..bb85c6fb98 --- /dev/null +++ b/users/tazjin/nixos/modules/physical.nix @@ -0,0 +1,105 @@ +# Default configuration settings for physical machines that I use. +{ lib, pkgs, config, depot, ... }: + +let + pass-otp = pkgs.pass.withExtensions (e: [ e.pass-otp ]); +in +{ + options = with lib; { + tazjin.emacs = mkOption { + type = types.package; + default = depot.users.tazjin.emacs; + description = '' + Derivation with my Emacs package, with configuration included. + ''; + }; + }; + + config = { + # Install all the default software. + environment.systemPackages = + # programs from the depot + (with depot; [ + users.tazjin.screenLock + users.tazjin.chase-geese + config.tazjin.emacs + third_party.agenix.cli + ]) ++ + + # programs from nixpkgs + (with pkgs; [ + (aspellWithDicts (d: [ d.ru ])) + amber + bat + curl + ddcutil + direnv + dnsutils + electrum + firefox + config.tazjin.emacs.emacs # emacsclient + expect + fd + file + gdb + git + gnupg + gtk3 # for gtk-launch + htop + hyperfine + iftop + imagemagick + josh + jq + lieer + maim + man-pages + moreutils + mosh + msmtp + networkmanagerapplet + nix-prefetch-github + nmap + notmuch + openssh + openssl + pass-otp + pavucontrol + pinentry + pinentry-emacs + pulseaudio # for pactl + pwgen + quasselClient + rink + ripgrep + rustup + screen + tig + tokei + tree + unzip + vlc + volumeicon + whois + xclip + xsecurelock + zoxide + ]); + + # Run services & configure programs for all machines. + services.fwupd.enable = true; + + # Disable the broken NetworkManager-wait-online.service + systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; + + # Disable the thing that prints annoying warnings when trying to + # run manually patchelfed binaries + environment.stub-ld.enable = false; + + programs = { + fish.enable = true; + mosh.enable = true; + ssh.startAgent = true; + }; + }; +} diff --git a/users/tazjin/nixos/modules/predlozhnik.nix b/users/tazjin/nixos/modules/predlozhnik.nix new file mode 100644 index 0000000000..db20963df1 --- /dev/null +++ b/users/tazjin/nixos/modules/predlozhnik.nix @@ -0,0 +1,10 @@ +# Host predlozhnik.ru, serving //users/tazjin/predlozhnik +{ depot, ... }: + +{ + services.nginx.virtualHosts."predlozhnik.ru" = { + root = depot.corp.russian.predlozhnik; + enableACME = true; + forceSSL = true; + }; +} diff --git a/users/tazjin/nixos/modules/tgsa.nix b/users/tazjin/nixos/modules/tgsa.nix new file mode 100644 index 0000000000..e162e0d822 --- /dev/null +++ b/users/tazjin/nixos/modules/tgsa.nix @@ -0,0 +1,29 @@ +{ config, depot, lib, pkgs, ... }: + +{ + systemd.services.tgsa = { + description = "telegram -> SA bbcode thing"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + DynamicUser = true; + Restart = "always"; + LoadCredential = "tgsa-yandex.json:/run/agenix/tgsa-yandex"; + }; + + script = '' + export YANDEX_KEY_FILE="''${CREDENTIALS_DIRECTORY}/tgsa-yandex.json" + ${depot.users.tazjin.tgsa}/bin/tgsa + ''; + }; + + services.nginx.virtualHosts."tgsa" = { + serverName = "tgsa.tazj.in"; + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:8472"; + }; + }; +} diff --git a/users/tazjin/nixos/tverskoy/default.nix b/users/tazjin/nixos/tverskoy/default.nix new file mode 100644 index 0000000000..733929219a --- /dev/null +++ b/users/tazjin/nixos/tverskoy/default.nix @@ -0,0 +1,175 @@ +# tverskoy is my Thinkpad X13 AMD 1st gen +{ depot, lib, pkgs, ... }: + +config: +let + quasselClient = pkgs.quassel.override { + client = true; + enableDaemon = false; + monolithic = false; + }; + + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); +in +lib.fix (self: { + imports = [ + (mod "open_eid.nix") + (usermod "chromium.nix") + (usermod "desktop.nix") + (usermod "fonts.nix") + (usermod "home-config.nix") + (usermod "laptop.nix") + (usermod "persistence.nix") + (usermod "physical.nix") + + (pkgs.home-manager.src + "/nixos") + ] ++ lib.optional (builtins.pathExists ./local-config.nix) ./local-config.nix; + + tvl.cache.enable = true; + + boot = rec { + initrd.availableKernelModules = [ "nvme" "ehci_pci" "xhci_pci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ]; + initrd.kernelModules = [ ]; + + # Restore /home to the blank snapshot, erasing all ephemeral data. + initrd.postDeviceCommands = lib.mkAfter '' + zfs rollback -r zpool/ephemeral/home@tazjin-clean + ''; + + # Install thinkpad modules for TLP + extraModulePackages = [ kernelPackages.acpi_call ]; + + kernelModules = [ "kvm-amd" "i2c_dev" ]; + kernelPackages = pkgs.zfsUnstable.latestCompatibleLinuxPackages; + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + }; + + virtualisation.docker.enable = true; + users.users.tazjin.extraGroups = [ "docker" "vboxusers" "adbusers" ]; + + fileSystems = { + "/" = { + device = "zpool/ephemeral/root"; + fsType = "zfs"; + }; + + "/home" = { + device = "zpool/ephemeral/home"; + fsType = "zfs"; + }; + + "/nix" = { + device = "zpool/local/nix"; + fsType = "zfs"; + }; + + "/depot" = { + device = "zpool/safe/depot"; + fsType = "zfs"; + }; + + "/persist" = { + device = "zpool/safe/persist"; + fsType = "zfs"; + neededForBoot = true; + }; + + # SD card + "/mnt" = { + device = "/dev/disk/by-uuid/c602d703-f1b9-4a44-9e45-94dfe24bdaa8"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/BF4F-388B"; + fsType = "vfat"; + }; + }; + + hardware = { + cpu.amd.updateMicrocode = true; + enableRedistributableFirmware = true; + bluetooth.enable = true; + + opengl = { + enable = true; + driSupport32Bit = true; + + extraPackages = with pkgs; [ + vaapiVdpau + libvdpau-va-gl + ]; + }; + }; + + networking = { + hostName = "tverskoy"; + hostId = "3c91827f"; + domain = "tvl.su"; + useDHCP = false; + networkmanager.enable = true; + firewall.enable = false; + + nameservers = [ + "8.8.8.8" + "8.8.4.4" + ]; + }; + + security.rtkit.enable = true; + + services = { + tailscale.enable = true; + printing.enable = true; + + # expose i2c device as /dev/i2c-amdgpu-dm and make it user-accessible + # this is required for sending control commands to the Dasung screen. + udev.extraRules = '' + SUBSYSTEM=="i2c-dev", ACTION=="add", DEVPATH=="/devices/pci0000:00/0000:00:08.1/0000:06:00.0/i2c-5/i2c-dev/i2c-5", SYMLINK+="i2c-amdgpu-dm", TAG+="uaccess" + ''; + + xserver.videoDrivers = [ "amdgpu" ]; + + # Automatically collect garbage from the Nix store. + depot.automatic-gc = { + enable = true; + interval = "1 hour"; + diskThreshold = 16; # GiB + maxFreed = 10; # GiB + preserveGenerations = "14d"; + }; + }; + + systemd.user.services.lieer-tazjin = { + description = "Synchronise mail@tazj.in via lieer"; + script = "${pkgs.lieer}/bin/gmi sync"; + + serviceConfig = { + WorkingDirectory = "%h/mail/account.tazjin"; + Type = "oneshot"; + }; + }; + + systemd.user.timers.lieer-tazjin = { + wantedBy = [ "timers.target" ]; + + timerConfig = { + OnActiveSec = "1"; + OnUnitActiveSec = "180"; + }; + }; + + # android stuff for hacking on Awful.apk + programs.adb.enable = true; + + # systemd-oomd seems to have been enabled by default around ~ + # December 2022, and it's really into killing my X session as soon + # as I do anything stressful to the machine + systemd.services.systemd-oomd.enable = lib.mkForce false; + + environment.systemPackages = [ pkgs.vulkan-tools ]; + + system.stateVersion = "20.09"; +}) diff --git a/users/tazjin/nixos/zamalek/default.nix b/users/tazjin/nixos/zamalek/default.nix new file mode 100644 index 0000000000..a340e8a3e8 --- /dev/null +++ b/users/tazjin/nixos/zamalek/default.nix @@ -0,0 +1,88 @@ +# zamalek is my Huawei MateBook X (unknown year) +{ depot, lib, pkgs, ... }: + +config: +let + mod = name: depot.path.origSrc + ("/ops/modules/" + name); + usermod = name: depot.path.origSrc + ("/users/tazjin/nixos/modules/" + name); + + zdevice = device: { + inherit device; + fsType = "zfs"; + }; +in +{ + imports = [ + (usermod "chromium.nix") + (usermod "desktop.nix") + (usermod "fonts.nix") + (usermod "hidpi.nix") + (usermod "home-config.nix") + (usermod "laptop.nix") + (usermod "persistence.nix") + (usermod "physical.nix") + + (pkgs.home-manager.src + "/nixos") + ] ++ lib.optional (builtins.pathExists ./local-config.nix) ./local-config.nix; + + tvl.cache.enable = true; + + boot = { + initrd.availableKernelModules = [ "nvme" "xhci_pci" ]; + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + supportedFilesystems = [ "zfs" ]; + zfs.devNodes = "/dev/"; + + extraModprobeConfig = '' + options snd_hda_intel power_save=1 + options iwlwifi power_save=1 + options iwldvm force_cam=0 + options i915 enable_guc=3 enable_fbc=1 + ''; + }; + + fileSystems = { + "/" = zdevice "zpool/ephemeral/root"; + "/home" = zdevice "zpool/ephemeral/home"; + "/persist" = zdevice "zpool/persistent/data" // { neededForBoot = true; }; + "/nix" = zdevice "zpool/persistent/nix"; + "/depot" = zdevice "zpool/persistent/depot"; + + "/boot" = { + device = "/dev/disk/by-uuid/2487-3908"; + fsType = "vfat"; + }; + }; + + networking = { + hostName = "zamalek"; + domain = "tvl.su"; + hostId = "ee399356"; + networkmanager.enable = true; + + extraHosts = '' + 10.101.240.1 wifi.silja.fi + ''; + + nameservers = [ + "8.8.8.8" + "8.8.4.4" + ]; + }; + + hardware = { + cpu.intel.updateMicrocode = true; + bluetooth.enable = true; + enableRedistributableFirmware = true; + opengl.enable = true; + }; + + services.xserver.libinput.touchpad.clickMethod = "clickfinger"; + services.xserver.libinput.touchpad.tapping = false; + services.avahi.enable = true; + services.tailscale.enable = true; + powerManagement.powertop.enable = true; + + system.stateVersion = "21.11"; +} |