From 268729083eb80c93aa402883085c37e32c8a08cf Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 13 Jun 2020 21:52:20 +0100 Subject: refactor(ops/nixos): Move my NixOS configurations to //users/tazjin NixOS modules move one level up because it's unlikely that //ops/nixos will contain actual systems at this point (they're user-specific). This is the first users folder, so it is also added to the root readTree invocation for the repository. Change-Id: I546c701145fa204b7ba7518a8a56a783588629e0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/244 Reviewed-by: tazjin --- bin/__dispatch.sh | 2 +- ci-builds.nix | 9 +- default.nix | 1 + ops/nixos/.skip-subtree | 1 + ops/nixos/README.md | 23 +- ops/nixos/camden/default.nix | 464 ------------------------------ ops/nixos/default.nix | 47 --- ops/nixos/depot.nix | 16 ++ ops/nixos/dotfiles/config.fish | 40 --- ops/nixos/dotfiles/msmtprc | 16 -- ops/nixos/dotfiles/notmuch-config | 21 -- ops/nixos/dotfiles/offlineimaprc | 39 --- ops/nixos/frog/default.nix | 254 ---------------- ops/nixos/hound.nix | 62 ++++ ops/nixos/mail.nix | 77 ----- ops/nixos/modules/.skip-subtree | 1 - ops/nixos/modules/depot.nix | 16 -- ops/nixos/modules/hound.nix | 62 ---- ops/nixos/modules/monorepo-gerrit.nix | 105 ------- ops/nixos/modules/smtprelay.nix | 52 ---- ops/nixos/modules/tvl-slapd/contents.ldif | 92 ------ ops/nixos/modules/tvl-slapd/default.nix | 30 -- ops/nixos/modules/tvl-slapd/genpasswd.rb | 5 - ops/nixos/modules/v4l2loopback.nix | 12 - ops/nixos/monorepo-gerrit.nix | 105 +++++++ ops/nixos/nugget/default.nix | 280 ------------------ ops/nixos/smtprelay.nix | 52 ++++ ops/nixos/tvl-slapd/contents.ldif | 92 ++++++ ops/nixos/tvl-slapd/default.nix | 30 ++ ops/nixos/tvl-slapd/genpasswd.rb | 5 + ops/nixos/v4l2loopback.nix | 12 + users/tazjin/dotfiles/config.fish | 40 +++ users/tazjin/dotfiles/msmtprc | 16 ++ users/tazjin/dotfiles/notmuch-config | 21 ++ users/tazjin/dotfiles/offlineimaprc | 39 +++ users/tazjin/nixos/README.md | 20 ++ users/tazjin/nixos/camden/default.nix | 464 ++++++++++++++++++++++++++++++ users/tazjin/nixos/default.nix | 46 +++ users/tazjin/nixos/frog/default.nix | 254 ++++++++++++++++ users/tazjin/nixos/nugget/default.nix | 280 ++++++++++++++++++ 40 files changed, 1565 insertions(+), 1638 deletions(-) create mode 100644 ops/nixos/.skip-subtree delete mode 100644 ops/nixos/camden/default.nix delete mode 100644 ops/nixos/default.nix create mode 100644 ops/nixos/depot.nix delete mode 100644 ops/nixos/dotfiles/config.fish delete mode 100644 ops/nixos/dotfiles/msmtprc delete mode 100644 ops/nixos/dotfiles/notmuch-config delete mode 100644 ops/nixos/dotfiles/offlineimaprc delete mode 100644 ops/nixos/frog/default.nix create mode 100644 ops/nixos/hound.nix delete mode 100644 ops/nixos/mail.nix delete mode 100644 ops/nixos/modules/.skip-subtree delete mode 100644 ops/nixos/modules/depot.nix delete mode 100644 ops/nixos/modules/hound.nix delete mode 100644 ops/nixos/modules/monorepo-gerrit.nix delete mode 100644 ops/nixos/modules/smtprelay.nix delete mode 100644 ops/nixos/modules/tvl-slapd/contents.ldif delete mode 100644 ops/nixos/modules/tvl-slapd/default.nix delete mode 100644 ops/nixos/modules/tvl-slapd/genpasswd.rb delete mode 100644 ops/nixos/modules/v4l2loopback.nix create mode 100644 ops/nixos/monorepo-gerrit.nix delete mode 100644 ops/nixos/nugget/default.nix create mode 100644 ops/nixos/smtprelay.nix create mode 100644 ops/nixos/tvl-slapd/contents.ldif create mode 100644 ops/nixos/tvl-slapd/default.nix create mode 100644 ops/nixos/tvl-slapd/genpasswd.rb create mode 100644 ops/nixos/v4l2loopback.nix create mode 100644 users/tazjin/dotfiles/config.fish create mode 100644 users/tazjin/dotfiles/msmtprc create mode 100644 users/tazjin/dotfiles/notmuch-config create mode 100644 users/tazjin/dotfiles/offlineimaprc create mode 100644 users/tazjin/nixos/README.md create mode 100644 users/tazjin/nixos/camden/default.nix create mode 100644 users/tazjin/nixos/default.nix create mode 100644 users/tazjin/nixos/frog/default.nix create mode 100644 users/tazjin/nixos/nugget/default.nix diff --git a/bin/__dispatch.sh b/bin/__dispatch.sh index 7a18b8b834a7..dce1cc41cd0b 100755 --- a/bin/__dispatch.sh +++ b/bin/__dispatch.sh @@ -36,7 +36,7 @@ case "${TARGET_TOOL}" in attr="third_party.age" ;; rebuilder) - attr="ops.nixos.rebuilder" + attr="users.tazjin.nixos.rebuilder" ;; meson) attr="third_party.meson" diff --git a/ci-builds.nix b/ci-builds.nix index 35f5eb967afb..01f014da49cf 100644 --- a/ci-builds.nix +++ b/ci-builds.nix @@ -19,8 +19,6 @@ with (import ./default.nix {}); [ ops.kms_pass ops.kontemplate ops.mq_cli - ops.nixos.camdenSystem - ops.nixos.frogSystem third_party.cgit third_party.git third_party.lisp # will build all third-party libraries @@ -31,8 +29,7 @@ with (import ./default.nix {}); [ web.cgit-taz web.tvl - # Nugget is not currently built because it depends on various things - # (such as chromium-vaapi) that don't work in CI. - # - # ops.nixos.nuggetSystem + # tazjin's personal things + users.tazjin.nixos.camdenSystem + users.tazjin.nixos.frogSystem ] diff --git a/default.nix b/default.nix index 054b25b9201a..e34734dc9e33 100644 --- a/default.nix +++ b/default.nix @@ -41,6 +41,7 @@ let presentations = readTree ./presentations; third_party = readTree ./third_party; tools = readTree ./tools; + users = readTree ./users; web = readTree ./web; }; in fix(self: { diff --git a/ops/nixos/.skip-subtree b/ops/nixos/.skip-subtree new file mode 100644 index 000000000000..09520f8c831f --- /dev/null +++ b/ops/nixos/.skip-subtree @@ -0,0 +1 @@ +NixOS modules are not readTree compatible. diff --git a/ops/nixos/README.md b/ops/nixos/README.md index fc90cb4b4301..595b4c3344c6 100644 --- a/ops/nixos/README.md +++ b/ops/nixos/README.md @@ -1,20 +1,7 @@ -NixOS configuration -=================== +NixOS modules +============= -My NixOS configuration! 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. +This folder contains various NixOS modules shared by our NixOS +configurations. -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. - -Building `ops.nixos.rebuilder` yields a script that will automatically -build and activate the newest configuration based on the current -hostname. - -## Configured hosts: - -* `frog` - weapon of mass computation at home -* `nugget` - desktop computer at home -* ~~`urdhva` - T470s~~ (currently with edef) +It is not read by `readTree`. diff --git a/ops/nixos/camden/default.nix b/ops/nixos/camden/default.nix deleted file mode 100644 index 32d75147b7a1..000000000000 --- a/ops/nixos/camden/default.nix +++ /dev/null @@ -1,464 +0,0 @@ -# This file configures camden.tazj.in, my homeserver. -{ depot, pkgs, lib, ... }: - -config: let - nixpkgs = import depot.third_party.nixpkgsSrc { - config.allowUnfree = true; - }; - - nginxRedirect = { from, to, acmeHost }: { - serverName = from; - useACMEHost = acmeHost; - forceSSL = true; - - extraConfig = "return 301 https://${to}$request_uri;"; - }; -in lib.fix(self: { - imports = [ - ../modules/depot.nix - ../modules/hound.nix - ../modules/monorepo-gerrit.nix - ../modules/smtprelay.nix - ../modules/tvl-slapd/default.nix - "${pkgs.nixpkgsSrc}/nixos/modules/services/web-apps/gerrit.nix" - ]; - depot = depot; - - # camden is intended to boot unattended, despite having an encrypted - # root partition. - # - # The below configuration uses an externally connected USB drive - # that contains a LUKS key file to unlock the disk automatically at - # boot. - # - # TODO(tazjin): Configure LUKS unlocking via SSH instead. - boot = { - initrd = { - availableKernelModules = [ - "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" - "rtsx_usb_sdmmc" "r8169" - ]; - - kernelModules = [ "dm-snapshot" ]; - - luks.devices.camden-crypt = { - fallbackToPassword = true; - device = "/dev/disk/by-label/camden-crypt"; - keyFile = "/dev/sdb"; - keyFileSize = 4096; - }; - }; - - loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; - }; - - cleanTmpDir = true; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/camden-root"; - fsType = "ext4"; - }; - - "/home" = { - device = "/dev/disk/by-label/camden-home"; - fsType = "ext4"; - }; - - "/boot" = { - device = "/dev/disk/by-label/BOOT"; - fsType = "vfat"; - }; - }; - - nix = { - maxJobs = lib.mkDefault 4; - - nixPath = [ - "depot=/home/tazjin/depot" - "nixpkgs=${depot.third_party.nixpkgsSrc}" - ]; - - trustedUsers = [ "root" "tazjin" ]; - - binaryCaches = [ - "https://tazjin.cachix.org" - ]; - - binaryCachePublicKeys = [ - "tazjin.cachix.org-1:IZkgLeqfOr1kAZjypItHMg1NoBjm4zX9Zzep8oRSh7U=" - ]; - }; - nixpkgs.pkgs = nixpkgs; - - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; - - networking = { - hostName = "camden"; - interfaces.enp1s0.useDHCP = true; - interfaces.enp1s0.ipv6.addresses = [ - { - address = "2a01:4b00:821a:ce02::5"; - prefixLength = 64; - } - ]; - - firewall.enable = false; - }; - - time.timeZone = "UTC"; - - # System-wide application setup - programs.fish.enable = true; - programs.mosh.enable = true; - - environment.systemPackages = - # programs from the depot - (with depot; [ - fun.idual.script - fun.idual.setAlarm - third_party.pounce - ]) ++ - - # programs from nixpkgs - (with nixpkgs; [ - bat - curl - direnv - emacs26-nox - gnupg - git - htop - jq - pass - pciutils - ripgrep - ]); - - users = { - # Set up my own user for logging in and doing things ... - users.tazjin = { - isNormalUser = true; - uid = 1000; - extraGroups = [ "git" "wheel" ]; - shell = nixpkgs.fish; - }; - - # Set up a user & group for general git shenanigans - groups.git = {}; - users.git = { - group = "git"; - isNormalUser = false; - }; - }; - - # Services setup - services.openssh.enable = true; - services.haveged.enable = true; - - # Join Tailscale into home network - services.tailscale.enable = true; - - # Allow sudo-ing via the forwarded SSH agent. - security.pam.enableSSHAgentAuth = true; - - # Run cgit for the depot. The onion here is nginx(thttpd(cgit)). - systemd.services.cgit = { - wantedBy = [ "multi-user.target" ]; - script = "${depot.web.cgit-taz}/bin/cgit-launch"; - - serviceConfig = { - Restart = "on-failure"; - User = "git"; - Group = "git"; - }; - }; - - # Run honk as the ActivityPub server, using all the fancy systemd - # magic. - systemd.services.honk = { - wantedBy = [ "multi-user.target" ]; - script = lib.concatStringsSep " " [ - "${depot.third_party.honk}/bin/honk" - "-datadir /var/lib/honk" - "-viewdir ${depot.third_party.honk.src}" - ]; - - serviceConfig = { - Restart = "always"; - DynamicUser = true; - StateDirectory = "honk"; - WorkingDirectory = "/var/lib/honk"; - }; - }; - - # 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"; - - serviceConfig = { - User = "root"; - Type = "oneshot"; - }; - }; - - systemd.timers.fix-nginx = { - wantedBy = [ "multi-user.target" ]; - timerConfig = { - OnCalendar = "minutely"; - }; - }; - - # Provision a TLS certificate outside of nginx to avoid - # nixpkgs#38144 - security.acme = { - acceptTerms = true; - email = "mail@tazj.in"; - - certs."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; - - # Local domains (for this machine only) - "camden.tazj.in" = null; - }; - postRun = "systemctl reload nginx"; - }; - - certs."tvl.fyi" = { - user = "nginx"; - group = "nginx"; - webroot = "/var/lib/acme/acme-challenge"; - postRun = "systemctl reload nginx"; - extraDomains = { - "cl.tvl.fyi" = null; - "code.tvl.fyi" = null; - "cs.tvl.fyi" = null; - }; - }; - }; - - # Forward logs to Google Cloud Platform - services.journaldriver = { - enable = true; - logStream = "home"; - googleCloudProject = "tazjins-infrastructure"; - applicationCredentials = "/etc/gcp/key.json"; - }; - - # Serve a code search (hound) instance - services.depot.hound = { - enable = true; - title = "tazjin's depot"; - repos.depot = { - url = "file:///var/lib/gerrit/git/depot.git"; - vcs = "git"; - url-pattern = { - base-url = "https://code.tvl.fyi/tree/{path}{anchor}"; - anchor = "#n{line}"; - }; - }; - repos.nixpkgs = { - url = "file:///var/git/nixpkgs"; - vcs = "git"; - url-pattern = { - base-url = "https://github.com/NixOS/nixpkgs/blob/${pkgs.nixpkgsCommit}/{path}{anchor}"; - anchor = "#L{line}"; - }; - }; - }; - - # Start a local SMTP relay to Gmail (used by gerrit) - services.depot.smtprelay = { - enable = true; - args = { - listen = ":2525"; - remote_host = "smtp.gmail.com:587"; - remote_auth = "plain"; - remote_user = "tvlbot@tazj.in"; - }; - }; - - # serve my website(s) - services.nginx = { - enable = true; - enableReload = true; - package = with nixpkgs; nginx.override { - modules = [ nginxModules.rtmp ]; - }; - - recommendedTlsSettings = true; - recommendedGzipSettings = true; - recommendedProxySettings = true; - - - appendConfig = '' - rtmp_auto_push on; - rtmp { - server { - listen 1935; - chunk_size 4000; - - application tvl { - live on; - - allow publish 88.98.195.213; - allow publish 10.0.1.0/24; - deny publish all; - - allow play all; - } - } - } - ''; - - commonHttpConfig = '' - log_format json_combined escape=json - '{' - '"remote_addr":"$remote_addr",' - '"method":"$request_method",' - '"uri":"$request_uri",' - '"status":$status,' - '"request_size":$request_length,' - '"response_size":$body_bytes_sent,' - '"response_time":$request_time,' - '"referrer":"$http_referer",' - '"user_agent":"$http_user_agent"' - '}'; - - access_log syslog:server=unix:/dev/log,nohostname json_combined; - ''; - - virtualHosts.homepage = { - serverName = "tazj.in"; - serverAliases = [ "camden.tazj.in" ]; - default = true; - useACMEHost = "tazj.in"; - root = depot.web.homepage; - forceSSL = true; - - extraConfig = '' - ${depot.web.blog.oldRedirects} - - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - - location ~* \.(webp|woff2)$ { - add_header Cache-Control "public, max-age=31536000"; - } - - location /blog/ { - alias ${depot.web.blog.rendered}/; - - if ($request_uri ~ ^/(.*)\.html$) { - return 302 /$1; - } - - try_files $uri $uri.html $uri/ =404; - } - - location /blobs/ { - alias /var/www/blobs/; - } - ''; - }; - - virtualHosts.tvl = { - serverName = "tvl.fyi"; - useACMEHost = "tvl.fyi"; - root = depot.web.tvl; - forceSSL = true; - - extraConfig = '' - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - - rewrite ^/builds/?$ https://builds.sr.ht/~tazjin/depot last; - rewrite ^/meet/?$ https://meet.google.com/mng-biyw-xbb last; - - rewrite ^/monorepo-doc/?$ https://docs.google.com/document/d/1nnyByXcH0F6GOmEezNOUa2RFelpeRpDToBLYD_CtjWE/edit?usp=sharing last; - - rewrite ^/irc/?$ ircs://chat.freenode.net:6697/##tvl last; - - location ~* \.(webp|woff2)$ { - add_header Cache-Control "public, max-age=31536000"; - } - ''; - }; - - virtualHosts.cgit = { - serverName = "code.tvl.fyi"; - useACMEHost = "tvl.fyi"; - forceSSL = true; - - extraConfig = '' - # Static assets must always hit the root. - location ~ ^/(favicon\.ico|cgit\.(css|png))$ { - proxy_pass http://localhost:2448; - } - - # Everything else hits the depot directly. - location / { - proxy_pass http://localhost:2448/cgit.cgi/depot/; - } - ''; - }; - - virtualHosts.hound = { - serverName = "cs.tvl.fyi"; - useACMEHost = "tvl.fyi"; - forceSSL = true; - - extraConfig = '' - location / { - proxy_pass http://localhost:6080; - } - ''; - }; - - virtualHosts.gerrit = { - serverName = "cl.tvl.fyi"; - useACMEHost = "tvl.fyi"; - forceSSL = true; - - extraConfig = '' - location / { - proxy_pass http://localhost:4778; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - } - ''; - }; - - virtualHosts.cgit-old = nginxRedirect { - from = "git.tazj.in"; - to = "code.tvl.fyi"; - acmeHost = "tazj.in"; - }; - - virtualHosts.cs-old = nginxRedirect { - from = "cs.tazj.in"; - to = "cs.tvl.fyi"; - acmeHost = "tazj.in"; - }; - }; - - # Timer units that can be started with systemd-run to set my alarm. - systemd.user.services.light-alarm = { - script = "${depot.fun.idual.script}/bin/idualctl wakey"; - postStart = "${pkgs.systemd}/bin/systemctl --user stop light-alarm.timer"; - serviceConfig = { - Type = "oneshot"; - }; - }; - - system.stateVersion = "19.09"; -}) diff --git a/ops/nixos/default.nix b/ops/nixos/default.nix deleted file mode 100644 index 6f0655f34e08..000000000000 --- a/ops/nixos/default.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ 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; - - 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 - nugget) - echo "Rebuilding NixOS for //ops/nixos/nugget" - system=$(nix-build -E '(import {}).ops.nixos.nuggetSystem' --no-out-link) - ;; - camden) - echo "Rebuilding NixOS for //ops/nixos/camden" - system=$(nix-build -E '(import {}).ops.nixos.camdenSystem' --no-out-link) - ;; - frog) - echo "Rebuilding NixOS for //ops/nixos/frog" - system=$(nix-build -E '(import {}).ops.nixos.frogSystem' --no-out-link) - ;; - *) - 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; - - nuggetSystem = systemFor [ depot.ops.nixos.nugget ]; - camdenSystem = systemFor [ depot.ops.nixos.camden ]; - frogSystem = systemFor [ depot.ops.nixos.frog ]; -} diff --git a/ops/nixos/depot.nix b/ops/nixos/depot.nix new file mode 100644 index 000000000000..2c1b71a2da9b --- /dev/null +++ b/ops/nixos/depot.nix @@ -0,0 +1,16 @@ +# This module makes it possible to get at the depot from "proper" +# NixOS modules. +# +# It needs to be included and configured in each system like this: +# +# { +# imports = [ "${depot.depotPath}/ops/nixos/depot.nix" ]; +# inherit depot; +# } +{ lib, ... }: + +{ + options.depot = with lib; mkOption { + description = "tazjin's imported monorepo"; + }; +} diff --git a/ops/nixos/dotfiles/config.fish b/ops/nixos/dotfiles/config.fish deleted file mode 100644 index de2c99ae6007..000000000000 --- a/ops/nixos/dotfiles/config.fish +++ /dev/null @@ -1,40 +0,0 @@ -# Configure classic prompt -set fish_color_user --bold blue -set fish_color_cwd --bold white - -# Enable colour hints in VCS prompt: -set __fish_git_prompt_showcolorhints yes -set __fish_git_prompt_color_prefix purple -set __fish_git_prompt_color_suffix purple - -# Fish configuration -set fish_greeting "" -set PATH $HOME/.local/bin $HOME/.cargo/bin $PATH - -# Editor configuration -set -gx EDITOR "emacsclient" -set -gx ALTERNATE_EDITOR "emacs -q -nw" -set -gx VISUAL "emacsclient" - -# Miscellaneous -eval (direnv hook fish) - -# Useful command aliases -alias gpr 'git pull --rebase' -alias gco 'git checkout' -alias gf 'git fetch' -alias gap 'git add -p' -alias pbcopy 'xclip -selection clipboard' -alias edit 'emacsclient -n' -alias servedir 'nix-shell -p haskellPackages.wai-app-static --run warp' - -# Old habits die hard (also ls is just easier to type): -alias ls 'exa' - -# Fix up nix-env & friends for Nix 2.0 -export NIX_REMOTE=daemon - -# Fix display of fish in emacs' term-mode: -function fish_title - true -end diff --git a/ops/nixos/dotfiles/msmtprc b/ops/nixos/dotfiles/msmtprc deleted file mode 100644 index 624b6a77fc4b..000000000000 --- a/ops/nixos/dotfiles/msmtprc +++ /dev/null @@ -1,16 +0,0 @@ -defaults - -port 587 -tls on -tls_trust_file /etc/ssl/certs/ca-certificates.crt - -# Runbox mail -account runbox -from mail@tazj.in -host mail.runbox.com -auth on -user mail@tazj.in -passwordeval pass show general/runbox-tazjin - -# Use Runbox as default -account default : runbox diff --git a/ops/nixos/dotfiles/notmuch-config b/ops/nixos/dotfiles/notmuch-config deleted file mode 100644 index a490774e635f..000000000000 --- a/ops/nixos/dotfiles/notmuch-config +++ /dev/null @@ -1,21 +0,0 @@ -# .notmuch-config - Configuration file for the notmuch mail system -# -# For more information about notmuch, see https://notmuchmail.org - -[database] -path=/home/vincent/mail - -[user] -name=Vincent Ambo -primary_email=mail@tazj.in -other_email=tazjin@gmail.com; - -[new] -tags=unread;inbox; -ignore= - -[search] -exclude_tags=deleted;spam;draft; - -[maildir] -synchronize_flags=true diff --git a/ops/nixos/dotfiles/offlineimaprc b/ops/nixos/dotfiles/offlineimaprc deleted file mode 100644 index 78315447e4bd..000000000000 --- a/ops/nixos/dotfiles/offlineimaprc +++ /dev/null @@ -1,39 +0,0 @@ -[general] -accounts = tazjin, gmail - -[DEFAULT] -ssl = yes -sslcacertfile = /etc/ssl/certs/ca-certificates.crt - -# Private GMail account (old): -[Account gmail] -maxage = 90 -localrepository = gmail-local -remoterepository = gmail-remote -synclabels = yes - -[Repository gmail-local] -type = GmailMaildir -localfolders = ~/mail/gmail - -[Repository gmail-remote] -type = Gmail -remoteuser = tazjin@gmail.com -remotepassfile = ~/.config/mail/gmail-pass -folderfilter = lambda folder: folder == 'INBOX' - -# Main private account: -[Account tazjin] -localrepository = tazjin-local -remoterepository = tazjin-remote - -[Repository tazjin-local] -type = Maildir -localfolders = ~/mail/tazjin - -[Repository tazjin-remote] -type = IMAP -remotehost = mail.runbox.com -remoteuser = mail@tazj.in -remotepassfile = ~/.config/mail/tazjin-pass -auth_mechanisms = LOGIN diff --git a/ops/nixos/frog/default.nix b/ops/nixos/frog/default.nix deleted file mode 100644 index 72b1c9ed3612..000000000000 --- a/ops/nixos/frog/default.nix +++ /dev/null @@ -1,254 +0,0 @@ -{ depot, lib, ... }: - -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.tools.emacs.overrideEmacs(epkgs: epkgs ++ [ - depot.third_party.emacsPackages.google-c-style - ])); -in depot.lib.fix(self: { - # TODO(tazjin): v4l2loopback - - boot = { - tmpOnTmpfs = true; - kernelModules = [ "kvm-amd" ]; - - loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; - }; - - initrd = { - luks.devices.frog-crypt.device = "/dev/disk/by-label/frog-crypt"; - availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ]; - kernelModules = [ "dm-snapshot" ]; - }; - - kernelPackages = nixpkgs.linuxPackages_latest; - kernel.sysctl = { - "kernel.perf_event_paranoid" = 1; - }; - }; - - hardware = { - cpu.amd.updateMicrocode = true; - enableRedistributableFirmware = true; - pulseaudio.enable = true; - u2f.enable = true; - opengl = { - enable = true; - driSupport = true; - }; - }; - - nix = { - maxJobs = 48; - nixPath = [ - "depot=/depot" - "nixpkgs=${depot.third_party.nixpkgsSrc}" - ]; - }; - - nixpkgs.pkgs = nixpkgs; - - networking = { - hostName = "frog"; - useDHCP = false; - interfaces.enp67s0.useDHCP = true; - - # Don't use ISP's DNS servers: - nameservers = [ - "8.8.8.8" - "8.8.4.4" - ]; - - firewall.enable = false; - }; - - # 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" '' - ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") self.networking.nameservers)} - options edns0 - ''; - }; - - time.timeZone = "Europe/London"; - - fileSystems = { - "/".device = "/dev/disk/by-label/frog-root"; - "/boot".device = "/dev/disk/by-label/BOOT"; - "/home".device = "/dev/disk/by-label/frog-home"; - }; - - # Configure user account - users.extraUsers.tazjin = { - extraGroups = [ "wheel" "audio" ]; - isNormalUser = true; - uid = 1000; - shell = nixpkgs.fish; - }; - - security.sudo = { - enable = true; - extraConfig = "wheel ALL=(ALL:ALL) SETENV: ALL"; - }; - - fonts = { - fonts = with nixpkgs; [ - corefonts - dejavu_fonts - jetbrains-mono - noto-fonts-cjk - noto-fonts-emoji - ]; - - fontconfig = { - hinting.enable = true; - subpixel.lcdfilter = "light"; - - defaultFonts = { - monospace = [ "JetBrains Mono" ]; - }; - }; - }; - - # Configure location (Vauxhall, London) for services that need it. - location = { - latitude = 51.4819109; - longitude = -0.1252998; - }; - - programs.fish.enable = true; - programs.ssh.startAgent = true; - - services.redshift.enable = true; - services.openssh.enable = true; - services.fstrim.enable = true; - - # Required for Yubikey usage as smartcard - services.pcscd.enable = true; - services.udev.packages = [ - nixpkgs.yubikey-personalization - ]; - - services.xserver = { - enable = true; - layout = "us"; - xkbOptions = "caps:super"; - exportConfiguration = true; - displayManager = { - # Give EXWM permission to control the session. - sessionCommands = "${nixpkgs.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 = "${frogEmacs}/bin/tazjins-emacs"; - }; - }; - - # Do not restart the display manager automatically - systemd.services.display-manager.restartIfChanged = lib.mkForce false; - - # clangd needs more than ~2GB in the runtime directory to start up - services.logind.extraConfig = '' - RuntimeDirectorySize=16G - ''; - - # Configure email setup - systemd.user.services.lieer-tazjin = { - description = "Synchronise mail@tazj.in via lieer"; - script = "${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"; - }; - }; - - environment.systemPackages = - # programs from the depot - (with depot; [ - fun.idual.script - lieer - frogEmacs - ops.kontemplate - third_party.ffmpeg - third_party.git - ]) ++ - - # programs from nixpkgs - (with nixpkgs; [ - age - bat - chromium - clang-manpages - clang-tools - clang_10 - curl - direnv - dnsutils - emacs26 # mostly for emacsclient - exa - fd - gnupg - go - google-chrome - google-cloud-sdk - htop - hyperfine - i3lock - imagemagick - jq - kubectl - linuxPackages.perf - miller - msmtp - nix-prefetch-github - notmuch - openssh - openssl - pass - pavucontrol - pinentry - pinentry-emacs - pwgen - ripgrep - rr - rustup - scrot - spotify - steam - tokei - tree - unzip - vlc - xclip - yubico-piv-tool - yubikey-personalization - zoxide - ]); - - # ... and other nonsense. - system.stateVersion = "20.03"; -}) diff --git a/ops/nixos/hound.nix b/ops/nixos/hound.nix new file mode 100644 index 000000000000..690055bde3b6 --- /dev/null +++ b/ops/nixos/hound.nix @@ -0,0 +1,62 @@ +# This module serves hound. +# +# https://github.com/hound-search/hound +{ pkgs, config, lib, ... }: + +let + cfg = config.services.depot.hound; + configJson = with builtins; toFile "config.json" (toJSON { + inherit (cfg) title repos; + max-concurrent-indexers = cfg.maxConcurrentIndexers; + dbpath = "/var/lib/hound"; + health-check-uri = "/healthz"; + }); +in { + options.services.depot.hound = with lib; { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the hound code search engine to forward + journald logs to Stackdriver Logging. + ''; + }; + + repos = mkOption { + type = lib.types.attrs; + description = "Repository configuration for hound."; + }; + + port = mkOption { + type = lib.types.int; + default = 6080; + description = "The port hound should listen on."; + }; + + title = mkOption { + type = lib.types.str; + description = "Page title for this hound instance"; + }; + + maxConcurrentIndexers = mkOption { + type = lib.types.int; + default = 2; + }; + }; + + config = { + systemd.services.hound = { + description = "Code search engine"; + script = "${config.depot.third_party.hound}/bin/houndd -addr ':${toString cfg.port}' -conf '${configJson}'"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.git ]; + + serviceConfig = { + Restart = "always"; + DynamicUser = true; + StateDirectory = "hound"; + SupplementaryGroups = "git"; + }; + }; + }; +} diff --git a/ops/nixos/mail.nix b/ops/nixos/mail.nix deleted file mode 100644 index ba4ebfa06026..000000000000 --- a/ops/nixos/mail.nix +++ /dev/null @@ -1,77 +0,0 @@ -# This file configures offlineimap, notmuch and MSMTP. -# -# Some manual configuration is required the first time this is -# applied: -# -# 1. Credential setup. -# 2. Linking of MSMTP config (ln -s /etc/msmtprc ~/.msmtprc) -# 3. Linking of notmuch config (ln -s /etc/notmuch-config ~/.notmuch-config) - -{ config, lib, pkgs, ... }: - -let offlineImapConfig = pkgs.writeText "offlineimaprc" - (builtins.readFile ./dotfiles/offlineimaprc); - -msmtpConfig = pkgs.writeText "msmtprc" - (builtins.readFile ./dotfiles/msmtprc); - -notmuchConfig = pkgs.writeText "notmuch-config" - (builtins.readFile ./dotfiles/notmuch-config); - -tagConfig = pkgs.writeText "notmuch-tags" '' - # Tag emacs-devel mailing list: - -inbox +emacs-devel -- to:emacs-devel@gnu.org OR cc:emacs-devel@gnu.org - - # Tag nix-devel mailing list & discourse: - -inbox +nix-devel -- to:nix-devel@googlegroups.com OR from:nixos1@discoursemail.com - - # Tag my own mail (from other devices) as sent: - -inbox +sent -- from:mail@tazj.in - - # Drafts are always read, duh. - -unread -- tag:draft -''; - -notmuchIndex = pkgs.writeShellScriptBin "notmuch-index" '' - echo "Indexing new mails in notmuch" - - # Index new mail - ${pkgs.notmuch}/bin/notmuch new - - # Apply tags - cat ${tagConfig} | ${pkgs.notmuch}/bin/notmuch tag --batch - - echo "Done indexing new mails" -''; -in { - # Enable OfflineIMAP timer & service: - systemd.user.timers.offlineimap = { - description = "OfflineIMAP timer"; - wantedBy = [ "timers.target" ]; - - timerConfig = { - Unit = "offlineimap.service"; - OnCalendar = "*:0/2"; # every 2 minutes - Persistent = "true"; # persist timer state after reboots - }; - }; - - systemd.user.services.offlineimap = { - description = "OfflineIMAP service"; - path = with pkgs; [ pass notmuch ]; - - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.offlineimap}/bin/offlineimap -u syslog -o -c ${offlineImapConfig}"; - ExecStartPost = "${notmuchIndex}/bin/notmuch-index"; - TimeoutStartSec = "2min"; - }; - }; - - # Link configuration files to /etc/ (from where they will be linked - # further): - environment.etc = { - "msmtprc".source = msmtpConfig; - "notmuch-config".source = notmuchConfig; - }; -} diff --git a/ops/nixos/modules/.skip-subtree b/ops/nixos/modules/.skip-subtree deleted file mode 100644 index 80d92f2eb485..000000000000 --- a/ops/nixos/modules/.skip-subtree +++ /dev/null @@ -1 +0,0 @@ -The files in this folder are NixOS modules, not readTree-importables. diff --git a/ops/nixos/modules/depot.nix b/ops/nixos/modules/depot.nix deleted file mode 100644 index 20220e9f57fe..000000000000 --- a/ops/nixos/modules/depot.nix +++ /dev/null @@ -1,16 +0,0 @@ -# This module makes it possible to get at the depot from "proper" -# NixOS modules. -# -# It needs to be included and configured in each system like this: -# -# { -# imports = [ ../modules/depot.nix ]; -# inherit depot; -# } -{ lib, ... }: - -{ - options.depot = with lib; mkOption { - description = "tazjin's imported monorepo"; - }; -} diff --git a/ops/nixos/modules/hound.nix b/ops/nixos/modules/hound.nix deleted file mode 100644 index 690055bde3b6..000000000000 --- a/ops/nixos/modules/hound.nix +++ /dev/null @@ -1,62 +0,0 @@ -# This module serves hound. -# -# https://github.com/hound-search/hound -{ pkgs, config, lib, ... }: - -let - cfg = config.services.depot.hound; - configJson = with builtins; toFile "config.json" (toJSON { - inherit (cfg) title repos; - max-concurrent-indexers = cfg.maxConcurrentIndexers; - dbpath = "/var/lib/hound"; - health-check-uri = "/healthz"; - }); -in { - options.services.depot.hound = with lib; { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable the hound code search engine to forward - journald logs to Stackdriver Logging. - ''; - }; - - repos = mkOption { - type = lib.types.attrs; - description = "Repository configuration for hound."; - }; - - port = mkOption { - type = lib.types.int; - default = 6080; - description = "The port hound should listen on."; - }; - - title = mkOption { - type = lib.types.str; - description = "Page title for this hound instance"; - }; - - maxConcurrentIndexers = mkOption { - type = lib.types.int; - default = 2; - }; - }; - - config = { - systemd.services.hound = { - description = "Code search engine"; - script = "${config.depot.third_party.hound}/bin/houndd -addr ':${toString cfg.port}' -conf '${configJson}'"; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.git ]; - - serviceConfig = { - Restart = "always"; - DynamicUser = true; - StateDirectory = "hound"; - SupplementaryGroups = "git"; - }; - }; - }; -} diff --git a/ops/nixos/modules/monorepo-gerrit.nix b/ops/nixos/modules/monorepo-gerrit.nix deleted file mode 100644 index 58fbb8d206ac..000000000000 --- a/ops/nixos/modules/monorepo-gerrit.nix +++ /dev/null @@ -1,105 +0,0 @@ -# Gerrit configuration for the TVL monorepo -{ pkgs, config, lib, ... }: - -let - cfg = config.services.gerrit; - gerritHooks = pkgs.runCommandNoCC "gerrit-hooks" {} '' - mkdir -p $out - ln -s ${config.depot.ops.besadii}/bin/besadii $out/ref-updated - ''; -in { - services.gerrit = { - enable = true; - listenAddress = "[::]:4778"; # 4778 - grrt - serverId = "4fdfa107-4df9-4596-8e0a-1d2bbdd96e36"; - builtinPlugins = [ - "download-commands" - "hooks" - ]; - - plugins = with config.depot.third_party.gerrit_plugins; [ - owners - owners-autoassign - ]; - - settings = { - core.packedGitLimit = "100m"; - log.jsonLogging = true; - log.textLogging = false; - sshd.advertisedAddress = "code.tvl.fyi:29418"; - hooks.path = "${gerritHooks}"; - - # Configures gerrit for being reverse-proxied by nginx as per - # https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html - gerrit.canonicalWebUrl = "https://cl.tvl.fyi"; - httpd.listenUrl = "proxy-https://${cfg.listenAddress}"; - - download.command = [ - "checkout" - "cherry_pick" - "format_patch" - "pull" - ]; - - # Configure for cgit. - gitweb = { - type = "custom"; - url = "https://code.tvl.fyi"; - project = "/"; - revision = "/commit/?id=\${commit}"; - branch = "/log/?h=\${branch}"; - tag = "/tag/?h=\${tag}"; - roottree = "/tree/?h=\${commit}"; - file = "/tree/\${file}?h=\${commit}"; - filehistory = "/log/\${file}?h=\${branch}"; - linkname = "cgit"; - }; - - # Configures integration with the locally running OpenLDAP - auth.type = "LDAP"; - ldap = { - server = "ldap://localhost"; - accountBase = "ou=users,dc=tvl,dc=fyi"; - accountPattern = "(&(objectClass=organizationalPerson)(cn=\${username}))"; - accountFullName = "cn"; - accountEmailAddress = "mail"; - accountSshUserName = "cn"; - groupBase = "ou=groups,dc=tvl,dc=fyi"; - - # TODO(tazjin): Assuming this is what we'll be doing ... - groupMemberPattern = "(&(objectClass=group)(member=\${dn}))"; - }; - - # Email sending (emails are relayed via the tazj.in domain's - # GSuite currently). - # - # Note that sendemail.smtpPass is stored in - # $site_path/etc/secure.config and is *not* controlled by Nix. - # - # Receiving email is not currently supported. - sendemail = { - enable = true; - html = false; - connectTimeout = "10sec"; - from = "TVL Code Review "; - includeDiff = true; - smtpEncryption = "none"; - smtpServer = "localhost"; - smtpServerPort = 2525; - }; - }; - }; - - systemd.services.gerrit = { - serviceConfig = { - # There seems to be no easy way to get `DynamicUser` to play - # well with other services (e.g. by using SupplementaryGroups, - # which seem to have no effect) so we force the DynamicUser - # setting for the Gerrit service to be disabled and reuse the - # existing 'git' user. - DynamicUser = lib.mkForce false; - User = "git"; - Group = "git"; - }; - }; -} diff --git a/ops/nixos/modules/smtprelay.nix b/ops/nixos/modules/smtprelay.nix deleted file mode 100644 index ca960f5190a8..000000000000 --- a/ops/nixos/modules/smtprelay.nix +++ /dev/null @@ -1,52 +0,0 @@ -# NixOS module for configuring the simple SMTP relay. -{ pkgs, config, lib, ... }: - -let - inherit (builtins) attrValues mapAttrs; - inherit (lib) - concatStringsSep - mkEnableOption - mkOption - types -; - - cfg = config.services.depot.smtprelay; - description = "Simple SMTP relay"; - - # Configuration values that are always overridden. In particular, - # `config` is specified to always load $StateDirectory/secure.config - # (so that passwords can be loaded from there) and logging is pinned - # to stdout for journald compatibility. - overrideArgs = { - logfile = ""; - config = "/var/lib/smtprelay/secure.config"; - }; - - # Creates the command line argument string for the service. - prepareArgs = args: - concatStringsSep " " - (attrValues (mapAttrs (key: value: "-${key} '${toString value}'") - (args // overrideArgs))); -in { - options.services.depot.smtprelay = { - enable = mkEnableOption description; - args = mkOption { - type = types.attrsOf types.str; - description = "Key value pairs for command line arguments"; - }; - }; - - config = { - systemd.services.smtprelay = { - inherit description; - script = "${config.depot.third_party.smtprelay}/bin/smtprelay ${prepareArgs cfg.args}"; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - Restart = "always"; - StateDirectory = "smtprelay"; - DynamicUser = true; - }; - }; - }; -} diff --git a/ops/nixos/modules/tvl-slapd/contents.ldif b/ops/nixos/modules/tvl-slapd/contents.ldif deleted file mode 100644 index 4ac5bcecdf01..000000000000 --- a/ops/nixos/modules/tvl-slapd/contents.ldif +++ /dev/null @@ -1,92 +0,0 @@ -dn: dc=tvl,dc=fyi -dc: tvl -o: TVL LDAP server -description: Root entry for tvl.fyi -objectClass: top -objectClass: dcObject -objectClass: organization - -dn: ou=users,dc=tvl,dc=fyi -ou: users -description: All users in TVL -objectClass: top -objectClass: organizationalUnit - -dn: ou=groups,dc=tvl,dc=fyi -ou: groups -description: All groups in TVL -objectClass: top -objectClass: organizationalUnit - -# Users in tvl.fyi -dn: cn=edef,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: edef -sn: edef -title: edef -mail: edef@edef.eu -userPassword: {SSHA}7w2XC6xxuhlUX2KvBpK4fD/X7ZCpfN/E - -dn: cn=eta,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: eta -sn: eta -title: eta -mail: eta@theta.eu.org -userPassword: {SSHA}sOR5xzi7Lfv376XGQA8Hf6jyhTvo0XYc - -dn: cn=isomer,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: isomer -sn: isomer -title: isomer -mail: isomer@tvl.fyi -userPassword: {SSHA}OhWQkPJgH1rRJqYIaMUbbKC4iLEzvCev - -dn: cn=lukegb,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: lukegb -sn: lukegb -title: lukegb -mail: lukegb@tvl.fyi -userPassword: {SSHA}7a85VNhpFElFw+N5xcjgGmt4HnBsaGp4 - -dn: cn=nyanotech,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: nyanotech -sn: nyanotech -title: nyanotech -mail: nyanotechnology@gmail.com -userPassword: {SSHA}NIJ2RCRb1+Q4Bs63cyE91VZyiN47DG6y - -dn: cn=q3k,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: q3k -sn: q3k -title: q3k -mail: q3k@q3k.org -userPassword: {SSHA}BEccJdtnhVLDzOn+pxNfayNi3QFcEABE - -dn: cn=riking,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: riking -sn: Kane York -title: riking -mail: rikingcoding@gmail.com -userPassword: {SSHA}6rPxMOofHMGNTEYdyBOYbza7NT/RmiGz - -dn: cn=tazjin,ou=users,dc=tvl,dc=fyi -objectClass: organizationalPerson -objectClass: inetOrgPerson -cn: tazjin -sn: tazjin -title: tazjin -mail: mail@tazj.in -userPassword: {SSHA}67H341jRfAFBDz/R9+T3fHQiPfjwTbpQ diff --git a/ops/nixos/modules/tvl-slapd/default.nix b/ops/nixos/modules/tvl-slapd/default.nix deleted file mode 100644 index 294a6636d719..000000000000 --- a/ops/nixos/modules/tvl-slapd/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -# Configures an OpenLDAP instance for TVL -# -# TODO(tazjin): Configure ldaps:// -{ pkgs, config, ... }: - -{ - services.openldap = { - enable = true; - dataDir = "/var/lib/openldap"; - suffix = "dc=tvl,dc=fyi"; - rootdn = "cn=admin,dc=tvl,dc=fyi"; - rootpw = "{SSHA}yEEO6Ol2W3ritdiJzPSsjOtyPGxWF2JW"; - - # Contents are immutable at runtime, and adding user accounts etc. - # is done statically in the LDIF-formatted contents in this folder. - declarativeContents = builtins.readFile ./contents.ldif; - - # ACL configuration - extraDatabaseConfig = '' - # Allow users to change their own password - access to attrs=userPassword - by self write - by anonymous auth - by users none - - # Allow default read access to other directory elements - access to * by * read - ''; - }; -} diff --git a/ops/nixos/modules/tvl-slapd/genpasswd.rb b/ops/nixos/modules/tvl-slapd/genpasswd.rb deleted file mode 100644 index 8f6f8d75842e..000000000000 --- a/ops/nixos/modules/tvl-slapd/genpasswd.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'securerandom' - -passwd = SecureRandom.urlsafe_base64(15) - -puts "your password: [[#{passwd}]]" diff --git a/ops/nixos/modules/v4l2loopback.nix b/ops/nixos/modules/v4l2loopback.nix deleted file mode 100644 index 636b2ff6cf27..000000000000 --- a/ops/nixos/modules/v4l2loopback.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - boot = { - extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; - kernelModules = [ "v4l2loopback" ]; - extraModprobeConfig = '' - options v4l2loopback exclusive_caps=1 - ''; - }; -} - diff --git a/ops/nixos/monorepo-gerrit.nix b/ops/nixos/monorepo-gerrit.nix new file mode 100644 index 000000000000..58fbb8d206ac --- /dev/null +++ b/ops/nixos/monorepo-gerrit.nix @@ -0,0 +1,105 @@ +# Gerrit configuration for the TVL monorepo +{ pkgs, config, lib, ... }: + +let + cfg = config.services.gerrit; + gerritHooks = pkgs.runCommandNoCC "gerrit-hooks" {} '' + mkdir -p $out + ln -s ${config.depot.ops.besadii}/bin/besadii $out/ref-updated + ''; +in { + services.gerrit = { + enable = true; + listenAddress = "[::]:4778"; # 4778 - grrt + serverId = "4fdfa107-4df9-4596-8e0a-1d2bbdd96e36"; + builtinPlugins = [ + "download-commands" + "hooks" + ]; + + plugins = with config.depot.third_party.gerrit_plugins; [ + owners + owners-autoassign + ]; + + settings = { + core.packedGitLimit = "100m"; + log.jsonLogging = true; + log.textLogging = false; + sshd.advertisedAddress = "code.tvl.fyi:29418"; + hooks.path = "${gerritHooks}"; + + # Configures gerrit for being reverse-proxied by nginx as per + # https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html + gerrit.canonicalWebUrl = "https://cl.tvl.fyi"; + httpd.listenUrl = "proxy-https://${cfg.listenAddress}"; + + download.command = [ + "checkout" + "cherry_pick" + "format_patch" + "pull" + ]; + + # Configure for cgit. + gitweb = { + type = "custom"; + url = "https://code.tvl.fyi"; + project = "/"; + revision = "/commit/?id=\${commit}"; + branch = "/log/?h=\${branch}"; + tag = "/tag/?h=\${tag}"; + roottree = "/tree/?h=\${commit}"; + file = "/tree/\${file}?h=\${commit}"; + filehistory = "/log/\${file}?h=\${branch}"; + linkname = "cgit"; + }; + + # Configures integration with the locally running OpenLDAP + auth.type = "LDAP"; + ldap = { + server = "ldap://localhost"; + accountBase = "ou=users,dc=tvl,dc=fyi"; + accountPattern = "(&(objectClass=organizationalPerson)(cn=\${username}))"; + accountFullName = "cn"; + accountEmailAddress = "mail"; + accountSshUserName = "cn"; + groupBase = "ou=groups,dc=tvl,dc=fyi"; + + # TODO(tazjin): Assuming this is what we'll be doing ... + groupMemberPattern = "(&(objectClass=group)(member=\${dn}))"; + }; + + # Email sending (emails are relayed via the tazj.in domain's + # GSuite currently). + # + # Note that sendemail.smtpPass is stored in + # $site_path/etc/secure.config and is *not* controlled by Nix. + # + # Receiving email is not currently supported. + sendemail = { + enable = true; + html = false; + connectTimeout = "10sec"; + from = "TVL Code Review "; + includeDiff = true; + smtpEncryption = "none"; + smtpServer = "localhost"; + smtpServerPort = 2525; + }; + }; + }; + + systemd.services.gerrit = { + serviceConfig = { + # There seems to be no easy way to get `DynamicUser` to play + # well with other services (e.g. by using SupplementaryGroups, + # which seem to have no effect) so we force the DynamicUser + # setting for the Gerrit service to be disabled and reuse the + # existing 'git' user. + DynamicUser = lib.mkForce false; + User = "git"; + Group = "git"; + }; + }; +} diff --git a/ops/nixos/nugget/default.nix b/ops/nixos/nugget/default.nix deleted file mode 100644 index 7c9530072d41..000000000000 --- a/ops/nixos/nugget/default.nix +++ /dev/null @@ -1,280 +0,0 @@ -# This file configures nugget, my home desktop machine. -{ depot, lib, ... }: - -config: let - nixpkgs = import depot.third_party.stableNixpkgsSrc { - config.allowUnfree = true; - }; - - unstable = import depot.third_party.nixpkgsSrc {}; - lieer = (depot.third_party.lieer {}); - - # google-c-style is installed only on nugget because other - # machines get it from, eh, elsewhere. - nuggetEmacs = (depot.tools.emacs.overrideEmacs(epkgs: epkgs ++ [ - depot.third_party.emacsPackages.google-c-style - ])); -in depot.lib.fix(self: { - imports = [ - ../modules/v4l2loopback.nix - ]; - - hardware = { - pulseaudio.enable = true; - cpu.intel.updateMicrocode = true; - u2f.enable = true; - }; - - boot = { - cleanTmpDir = true; - kernelModules = [ "kvm-intel" ]; - - loader = { - timeout = 3; - systemd-boot.enable = true; - efi.canTouchEfiVariables = false; - }; - - initrd = { - luks.devices.nugget-crypt.device = "/dev/disk/by-label/nugget-crypt"; - availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ]; - kernelModules = [ "dm-snapshot" ]; - }; - - kernel.sysctl = { - "kernel.perf_event_paranoid" = 1; - }; - }; - - nix = { - package = depot.third_party.nix; - nixPath = [ - "depot=/home/tazjin/depot" - "nixpkgs=${depot.third_party.nixpkgsSrc}" - ]; - }; - - nixpkgs.pkgs = nixpkgs; - - networking = { - hostName = "nugget"; - useDHCP = false; - interfaces.eno1.useDHCP = true; - interfaces.wlp7s0.useDHCP = true; - - # Don't use ISP's DNS servers: - nameservers = [ - "8.8.8.8" - "8.8.4.4" - ]; - - # Open Chromecast-related ports & servedir - firewall.enable = false; - firewall.allowedTCPPorts = [ 4242 5556 5558 ]; - - # Connect to the WiFi to let the Chromecast work. - wireless.enable = true; - wireless.networks = { - "How do I computer?" = { - psk = "washyourface"; - }; - }; - }; - - # 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" '' - ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") self.networking.nameservers)} - options edns0 - ''; - }; - - time.timeZone = "Europe/London"; - - environment.systemPackages = - # programs from the depot - (with depot; [ - fun.idual.script - lieer - nuggetEmacs - ops.kontemplate - third_party.ffmpeg - third_party.git - ]) ++ - - # programs from nixpkgs - (with nixpkgs; [ - age - bat - cachix - chromium - clang-manpages - clang-tools - clang_10 - curl - direnv - dnsutils - exa - fd - gnupg - go - google-chrome - google-cloud-sdk - guile - htop - hyperfine - i3lock - imagemagick - jq - keybase-gui - kubectl - linuxPackages.perf - meson - miller - msmtp - nix-prefetch-github - notmuch - openssh - openssl - pass - pavucontrol - pinentry - pinentry-emacs - pwgen - ripgrep - rr - rustup - sbcl - scrot - spotify - steam - tokei - tree - unzip - vlc - xclip - yubico-piv-tool - yubikey-personalization - ]) ++ - - # programs from unstable nixpkgs - (with unstable; [ - zoxide - ]); - - fileSystems = { - "/".device = "/dev/disk/by-label/nugget-root"; - "/boot".device = "/dev/disk/by-label/EFI"; - "/home".device = "/dev/disk/by-label/nugget-home"; - }; - - # Configure user account - users.extraUsers.tazjin = { - extraGroups = [ "wheel" "audio" ]; - isNormalUser = true; - uid = 1000; - shell = nixpkgs.fish; - }; - - security.sudo = { - enable = true; - extraConfig = "wheel ALL=(ALL:ALL) SETENV: ALL"; - }; - - fonts = { - fonts = with nixpkgs; [ - corefonts - dejavu_fonts - jetbrains-mono - noto-fonts-cjk - noto-fonts-emoji - ]; - - fontconfig = { - hinting.enable = true; - subpixel.lcdfilter = "light"; - - defaultFonts = { - monospace = [ "JetBrains Mono" ]; - }; - }; - }; - - # Configure location (Vauxhall, London) for services that need it. - location = { - latitude = 51.4819109; - longitude = -0.1252998; - }; - - programs.fish.enable = true; - programs.ssh.startAgent = true; - - services.redshift.enable = true; - services.openssh.enable = true; - services.keybase.enable = true; - - # Required for Yubikey usage as smartcard - services.pcscd.enable = true; - services.udev.packages = [ - nixpkgs.yubikey-personalization - ]; - - services.xserver = { - enable = true; - layout = "us"; - xkbOptions = "caps:super"; - exportConfiguration = true; - videoDrivers = [ "nvidia" ]; - - displayManager = { - # Give EXWM permission to control the session. - sessionCommands = "${nixpkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; - - lightdm.enable = true; - lightdm.greeters.gtk.clock-format = "%H·%M"; - }; - - windowManager.session = lib.singleton { - name = "exwm"; - start = "${nuggetEmacs}/bin/tazjins-emacs"; - }; - }; - - # Do not restart the display manager automatically - systemd.services.display-manager.restartIfChanged = lib.mkForce false; - - # Configure email setup - systemd.user.services.lieer-tazjin = { - description = "Synchronise mail@tazj.in via lieer"; - script = "${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"; - }; - }; - - # Use Tailscale \o/ - services.tailscale.enable = true; - - # nugget has an SSD - services.fstrim.enable = true; - - # clangd needs more than ~2GB in the runtime directory to start up - services.logind.extraConfig = '' - RuntimeDirectorySize=4G - ''; - - # ... and other nonsense. - system.stateVersion = "19.09"; -}) diff --git a/ops/nixos/smtprelay.nix b/ops/nixos/smtprelay.nix new file mode 100644 index 000000000000..ca960f5190a8 --- /dev/null +++ b/ops/nixos/smtprelay.nix @@ -0,0 +1,52 @@ +# NixOS module for configuring the simple SMTP relay. +{ pkgs, config, lib, ... }: + +let + inherit (builtins) attrValues mapAttrs; + inherit (lib) + concatStringsSep + mkEnableOption + mkOption + types +; + + cfg = config.services.depot.smtprelay; + description = "Simple SMTP relay"; + + # Configuration values that are always overridden. In particular, + # `config` is specified to always load $StateDirectory/secure.config + # (so that passwords can be loaded from there) and logging is pinned + # to stdout for journald compatibility. + overrideArgs = { + logfile = ""; + config = "/var/lib/smtprelay/secure.config"; + }; + + # Creates the command line argument string for the service. + prepareArgs = args: + concatStringsSep " " + (attrValues (mapAttrs (key: value: "-${key} '${toString value}'") + (args // overrideArgs))); +in { + options.services.depot.smtprelay = { + enable = mkEnableOption description; + args = mkOption { + type = types.attrsOf types.str; + description = "Key value pairs for command line arguments"; + }; + }; + + config = { + systemd.services.smtprelay = { + inherit description; + script = "${config.depot.third_party.smtprelay}/bin/smtprelay ${prepareArgs cfg.args}"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Restart = "always"; + StateDirectory = "smtprelay"; + DynamicUser = true; + }; + }; + }; +} diff --git a/ops/nixos/tvl-slapd/contents.ldif b/ops/nixos/tvl-slapd/contents.ldif new file mode 100644 index 000000000000..4ac5bcecdf01 --- /dev/null +++ b/ops/nixos/tvl-slapd/contents.ldif @@ -0,0 +1,92 @@ +dn: dc=tvl,dc=fyi +dc: tvl +o: TVL LDAP server +description: Root entry for tvl.fyi +objectClass: top +objectClass: dcObject +objectClass: organization + +dn: ou=users,dc=tvl,dc=fyi +ou: users +description: All users in TVL +objectClass: top +objectClass: organizationalUnit + +dn: ou=groups,dc=tvl,dc=fyi +ou: groups +description: All groups in TVL +objectClass: top +objectClass: organizationalUnit + +# Users in tvl.fyi +dn: cn=edef,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: edef +sn: edef +title: edef +mail: edef@edef.eu +userPassword: {SSHA}7w2XC6xxuhlUX2KvBpK4fD/X7ZCpfN/E + +dn: cn=eta,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: eta +sn: eta +title: eta +mail: eta@theta.eu.org +userPassword: {SSHA}sOR5xzi7Lfv376XGQA8Hf6jyhTvo0XYc + +dn: cn=isomer,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: isomer +sn: isomer +title: isomer +mail: isomer@tvl.fyi +userPassword: {SSHA}OhWQkPJgH1rRJqYIaMUbbKC4iLEzvCev + +dn: cn=lukegb,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: lukegb +sn: lukegb +title: lukegb +mail: lukegb@tvl.fyi +userPassword: {SSHA}7a85VNhpFElFw+N5xcjgGmt4HnBsaGp4 + +dn: cn=nyanotech,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: nyanotech +sn: nyanotech +title: nyanotech +mail: nyanotechnology@gmail.com +userPassword: {SSHA}NIJ2RCRb1+Q4Bs63cyE91VZyiN47DG6y + +dn: cn=q3k,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: q3k +sn: q3k +title: q3k +mail: q3k@q3k.org +userPassword: {SSHA}BEccJdtnhVLDzOn+pxNfayNi3QFcEABE + +dn: cn=riking,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: riking +sn: Kane York +title: riking +mail: rikingcoding@gmail.com +userPassword: {SSHA}6rPxMOofHMGNTEYdyBOYbza7NT/RmiGz + +dn: cn=tazjin,ou=users,dc=tvl,dc=fyi +objectClass: organizationalPerson +objectClass: inetOrgPerson +cn: tazjin +sn: tazjin +title: tazjin +mail: mail@tazj.in +userPassword: {SSHA}67H341jRfAFBDz/R9+T3fHQiPfjwTbpQ diff --git a/ops/nixos/tvl-slapd/default.nix b/ops/nixos/tvl-slapd/default.nix new file mode 100644 index 000000000000..294a6636d719 --- /dev/null +++ b/ops/nixos/tvl-slapd/default.nix @@ -0,0 +1,30 @@ +# Configures an OpenLDAP instance for TVL +# +# TODO(tazjin): Configure ldaps:// +{ pkgs, config, ... }: + +{ + services.openldap = { + enable = true; + dataDir = "/var/lib/openldap"; + suffix = "dc=tvl,dc=fyi"; + rootdn = "cn=admin,dc=tvl,dc=fyi"; + rootpw = "{SSHA}yEEO6Ol2W3ritdiJzPSsjOtyPGxWF2JW"; + + # Contents are immutable at runtime, and adding user accounts etc. + # is done statically in the LDIF-formatted contents in this folder. + declarativeContents = builtins.readFile ./contents.ldif; + + # ACL configuration + extraDatabaseConfig = '' + # Allow users to change their own password + access to attrs=userPassword + by self write + by anonymous auth + by users none + + # Allow default read access to other directory elements + access to * by * read + ''; + }; +} diff --git a/ops/nixos/tvl-slapd/genpasswd.rb b/ops/nixos/tvl-slapd/genpasswd.rb new file mode 100644 index 000000000000..8f6f8d75842e --- /dev/null +++ b/ops/nixos/tvl-slapd/genpasswd.rb @@ -0,0 +1,5 @@ +require 'securerandom' + +passwd = SecureRandom.urlsafe_base64(15) + +puts "your password: [[#{passwd}]]" diff --git a/ops/nixos/v4l2loopback.nix b/ops/nixos/v4l2loopback.nix new file mode 100644 index 000000000000..636b2ff6cf27 --- /dev/null +++ b/ops/nixos/v4l2loopback.nix @@ -0,0 +1,12 @@ +{ config, lib, pkgs, ... }: + +{ + boot = { + extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; + kernelModules = [ "v4l2loopback" ]; + extraModprobeConfig = '' + options v4l2loopback exclusive_caps=1 + ''; + }; +} + diff --git a/users/tazjin/dotfiles/config.fish b/users/tazjin/dotfiles/config.fish new file mode 100644 index 000000000000..de2c99ae6007 --- /dev/null +++ b/users/tazjin/dotfiles/config.fish @@ -0,0 +1,40 @@ +# Configure classic prompt +set fish_color_user --bold blue +set fish_color_cwd --bold white + +# Enable colour hints in VCS prompt: +set __fish_git_prompt_showcolorhints yes +set __fish_git_prompt_color_prefix purple +set __fish_git_prompt_color_suffix purple + +# Fish configuration +set fish_greeting "" +set PATH $HOME/.local/bin $HOME/.cargo/bin $PATH + +# Editor configuration +set -gx EDITOR "emacsclient" +set -gx ALTERNATE_EDITOR "emacs -q -nw" +set -gx VISUAL "emacsclient" + +# Miscellaneous +eval (direnv hook fish) + +# Useful command aliases +alias gpr 'git pull --rebase' +alias gco 'git checkout' +alias gf 'git fetch' +alias gap 'git add -p' +alias pbcopy 'xclip -selection clipboard' +alias edit 'emacsclient -n' +alias servedir 'nix-shell -p haskellPackages.wai-app-static --run warp' + +# Old habits die hard (also ls is just easier to type): +alias ls 'exa' + +# Fix up nix-env & friends for Nix 2.0 +export NIX_REMOTE=daemon + +# Fix display of fish in emacs' term-mode: +function fish_title + true +end diff --git a/users/tazjin/dotfiles/msmtprc b/users/tazjin/dotfiles/msmtprc new file mode 100644 index 000000000000..624b6a77fc4b --- /dev/null +++ b/users/tazjin/dotfiles/msmtprc @@ -0,0 +1,16 @@ +defaults + +port 587 +tls on +tls_trust_file /etc/ssl/certs/ca-certificates.crt + +# Runbox mail +account runbox +from mail@tazj.in +host mail.runbox.com +auth on +user mail@tazj.in +passwordeval pass show general/runbox-tazjin + +# Use Runbox as default +account default : runbox diff --git a/users/tazjin/dotfiles/notmuch-config b/users/tazjin/dotfiles/notmuch-config new file mode 100644 index 000000000000..a490774e635f --- /dev/null +++ b/users/tazjin/dotfiles/notmuch-config @@ -0,0 +1,21 @@ +# .notmuch-config - Configuration file for the notmuch mail system +# +# For more information about notmuch, see https://notmuchmail.org + +[database] +path=/home/vincent/mail + +[user] +name=Vincent Ambo +primary_email=mail@tazj.in +other_email=tazjin@gmail.com; + +[new] +tags=unread;inbox; +ignore= + +[search] +exclude_tags=deleted;spam;draft; + +[maildir] +synchronize_flags=true diff --git a/users/tazjin/dotfiles/offlineimaprc b/users/tazjin/dotfiles/offlineimaprc new file mode 100644 index 000000000000..78315447e4bd --- /dev/null +++ b/users/tazjin/dotfiles/offlineimaprc @@ -0,0 +1,39 @@ +[general] +accounts = tazjin, gmail + +[DEFAULT] +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt + +# Private GMail account (old): +[Account gmail] +maxage = 90 +localrepository = gmail-local +remoterepository = gmail-remote +synclabels = yes + +[Repository gmail-local] +type = GmailMaildir +localfolders = ~/mail/gmail + +[Repository gmail-remote] +type = Gmail +remoteuser = tazjin@gmail.com +remotepassfile = ~/.config/mail/gmail-pass +folderfilter = lambda folder: folder == 'INBOX' + +# Main private account: +[Account tazjin] +localrepository = tazjin-local +remoterepository = tazjin-remote + +[Repository tazjin-local] +type = Maildir +localfolders = ~/mail/tazjin + +[Repository tazjin-remote] +type = IMAP +remotehost = mail.runbox.com +remoteuser = mail@tazj.in +remotepassfile = ~/.config/mail/tazjin-pass +auth_mechanisms = LOGIN diff --git a/users/tazjin/nixos/README.md b/users/tazjin/nixos/README.md new file mode 100644 index 000000000000..fc90cb4b4301 --- /dev/null +++ b/users/tazjin/nixos/README.md @@ -0,0 +1,20 @@ +NixOS configuration +=================== + +My NixOS configuration! 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. + +Building `ops.nixos.rebuilder` yields a script that will automatically +build and activate the newest configuration based on the current +hostname. + +## Configured hosts: + +* `frog` - weapon of mass computation at home +* `nugget` - desktop computer at home +* ~~`urdhva` - T470s~~ (currently with edef) diff --git a/users/tazjin/nixos/camden/default.nix b/users/tazjin/nixos/camden/default.nix new file mode 100644 index 000000000000..9bdebac5f55d --- /dev/null +++ b/users/tazjin/nixos/camden/default.nix @@ -0,0 +1,464 @@ +# This file configures camden.tazj.in, my homeserver. +{ depot, pkgs, lib, ... }: + +config: let + nixpkgs = import depot.third_party.nixpkgsSrc { + config.allowUnfree = true; + }; + + nginxRedirect = { from, to, acmeHost }: { + serverName = from; + useACMEHost = acmeHost; + forceSSL = true; + + extraConfig = "return 301 https://${to}$request_uri;"; + }; +in lib.fix(self: { + imports = [ + "${depot.depotPath}/ops/nixos/depot.nix" + "${depot.depotPath}/ops/nixos/hound.nix" + "${depot.depotPath}/ops/nixos/monorepo-gerrit.nix" + "${depot.depotPath}/ops/nixos/smtprelay.nix" + "${depot.depotPath}/ops/nixos/tvl-slapd/default.nix" + "${pkgs.nixpkgsSrc}/nixos/modules/services/web-apps/gerrit.nix" + ]; + depot = depot; + + # camden is intended to boot unattended, despite having an encrypted + # root partition. + # + # The below configuration uses an externally connected USB drive + # that contains a LUKS key file to unlock the disk automatically at + # boot. + # + # TODO(tazjin): Configure LUKS unlocking via SSH instead. + boot = { + initrd = { + availableKernelModules = [ + "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" + "rtsx_usb_sdmmc" "r8169" + ]; + + kernelModules = [ "dm-snapshot" ]; + + luks.devices.camden-crypt = { + fallbackToPassword = true; + device = "/dev/disk/by-label/camden-crypt"; + keyFile = "/dev/sdb"; + keyFileSize = 4096; + }; + }; + + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + cleanTmpDir = true; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-label/camden-root"; + fsType = "ext4"; + }; + + "/home" = { + device = "/dev/disk/by-label/camden-home"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-label/BOOT"; + fsType = "vfat"; + }; + }; + + nix = { + maxJobs = lib.mkDefault 4; + + nixPath = [ + "depot=/home/tazjin/depot" + "nixpkgs=${depot.third_party.nixpkgsSrc}" + ]; + + trustedUsers = [ "root" "tazjin" ]; + + binaryCaches = [ + "https://tazjin.cachix.org" + ]; + + binaryCachePublicKeys = [ + "tazjin.cachix.org-1:IZkgLeqfOr1kAZjypItHMg1NoBjm4zX9Zzep8oRSh7U=" + ]; + }; + nixpkgs.pkgs = nixpkgs; + + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + + networking = { + hostName = "camden"; + interfaces.enp1s0.useDHCP = true; + interfaces.enp1s0.ipv6.addresses = [ + { + address = "2a01:4b00:821a:ce02::5"; + prefixLength = 64; + } + ]; + + firewall.enable = false; + }; + + time.timeZone = "UTC"; + + # System-wide application setup + programs.fish.enable = true; + programs.mosh.enable = true; + + environment.systemPackages = + # programs from the depot + (with depot; [ + fun.idual.script + fun.idual.setAlarm + third_party.pounce + ]) ++ + + # programs from nixpkgs + (with nixpkgs; [ + bat + curl + direnv + emacs26-nox + gnupg + git + htop + jq + pass + pciutils + ripgrep + ]); + + users = { + # Set up my own user for logging in and doing things ... + users.tazjin = { + isNormalUser = true; + uid = 1000; + extraGroups = [ "git" "wheel" ]; + shell = nixpkgs.fish; + }; + + # Set up a user & group for general git shenanigans + groups.git = {}; + users.git = { + group = "git"; + isNormalUser = false; + }; + }; + + # Services setup + services.openssh.enable = true; + services.haveged.enable = true; + + # Join Tailscale into home network + services.tailscale.enable = true; + + # Allow sudo-ing via the forwarded SSH agent. + security.pam.enableSSHAgentAuth = true; + + # Run cgit for the depot. The onion here is nginx(thttpd(cgit)). + systemd.services.cgit = { + wantedBy = [ "multi-user.target" ]; + script = "${depot.web.cgit-taz}/bin/cgit-launch"; + + serviceConfig = { + Restart = "on-failure"; + User = "git"; + Group = "git"; + }; + }; + + # Run honk as the ActivityPub server, using all the fancy systemd + # magic. + systemd.services.honk = { + wantedBy = [ "multi-user.target" ]; + script = lib.concatStringsSep " " [ + "${depot.third_party.honk}/bin/honk" + "-datadir /var/lib/honk" + "-viewdir ${depot.third_party.honk.src}" + ]; + + serviceConfig = { + Restart = "always"; + DynamicUser = true; + StateDirectory = "honk"; + WorkingDirectory = "/var/lib/honk"; + }; + }; + + # 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"; + + serviceConfig = { + User = "root"; + Type = "oneshot"; + }; + }; + + systemd.timers.fix-nginx = { + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnCalendar = "minutely"; + }; + }; + + # Provision a TLS certificate outside of nginx to avoid + # nixpkgs#38144 + security.acme = { + acceptTerms = true; + email = "mail@tazj.in"; + + certs."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; + + # Local domains (for this machine only) + "camden.tazj.in" = null; + }; + postRun = "systemctl reload nginx"; + }; + + certs."tvl.fyi" = { + user = "nginx"; + group = "nginx"; + webroot = "/var/lib/acme/acme-challenge"; + postRun = "systemctl reload nginx"; + extraDomains = { + "cl.tvl.fyi" = null; + "code.tvl.fyi" = null; + "cs.tvl.fyi" = null; + }; + }; + }; + + # Forward logs to Google Cloud Platform + services.journaldriver = { + enable = true; + logStream = "home"; + googleCloudProject = "tazjins-infrastructure"; + applicationCredentials = "/etc/gcp/key.json"; + }; + + # Serve a code search (hound) instance + services.depot.hound = { + enable = true; + title = "tazjin's depot"; + repos.depot = { + url = "file:///var/lib/gerrit/git/depot.git"; + vcs = "git"; + url-pattern = { + base-url = "https://code.tvl.fyi/tree/{path}{anchor}"; + anchor = "#n{line}"; + }; + }; + repos.nixpkgs = { + url = "file:///var/git/nixpkgs"; + vcs = "git"; + url-pattern = { + base-url = "https://github.com/NixOS/nixpkgs/blob/${pkgs.nixpkgsCommit}/{path}{anchor}"; + anchor = "#L{line}"; + }; + }; + }; + + # Start a local SMTP relay to Gmail (used by gerrit) + services.depot.smtprelay = { + enable = true; + args = { + listen = ":2525"; + remote_host = "smtp.gmail.com:587"; + remote_auth = "plain"; + remote_user = "tvlbot@tazj.in"; + }; + }; + + # serve my website(s) + services.nginx = { + enable = true; + enableReload = true; + package = with nixpkgs; nginx.override { + modules = [ nginxModules.rtmp ]; + }; + + recommendedTlsSettings = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + + + appendConfig = '' + rtmp_auto_push on; + rtmp { + server { + listen 1935; + chunk_size 4000; + + application tvl { + live on; + + allow publish 88.98.195.213; + allow publish 10.0.1.0/24; + deny publish all; + + allow play all; + } + } + } + ''; + + commonHttpConfig = '' + log_format json_combined escape=json + '{' + '"remote_addr":"$remote_addr",' + '"method":"$request_method",' + '"uri":"$request_uri",' + '"status":$status,' + '"request_size":$request_length,' + '"response_size":$body_bytes_sent,' + '"response_time":$request_time,' + '"referrer":"$http_referer",' + '"user_agent":"$http_user_agent"' + '}'; + + access_log syslog:server=unix:/dev/log,nohostname json_combined; + ''; + + virtualHosts.homepage = { + serverName = "tazj.in"; + serverAliases = [ "camden.tazj.in" ]; + default = true; + useACMEHost = "tazj.in"; + root = depot.web.homepage; + forceSSL = true; + + extraConfig = '' + ${depot.web.blog.oldRedirects} + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + + location ~* \.(webp|woff2)$ { + add_header Cache-Control "public, max-age=31536000"; + } + + location /blog/ { + alias ${depot.web.blog.rendered}/; + + if ($request_uri ~ ^/(.*)\.html$) { + return 302 /$1; + } + + try_files $uri $uri.html $uri/ =404; + } + + location /blobs/ { + alias /var/www/blobs/; + } + ''; + }; + + virtualHosts.tvl = { + serverName = "tvl.fyi"; + useACMEHost = "tvl.fyi"; + root = depot.web.tvl; + forceSSL = true; + + extraConfig = '' + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + + rewrite ^/builds/?$ https://builds.sr.ht/~tazjin/depot last; + rewrite ^/meet/?$ https://meet.google.com/mng-biyw-xbb last; + + rewrite ^/monorepo-doc/?$ https://docs.google.com/document/d/1nnyByXcH0F6GOmEezNOUa2RFelpeRpDToBLYD_CtjWE/edit?usp=sharing last; + + rewrite ^/irc/?$ ircs://chat.freenode.net:6697/##tvl last; + + location ~* \.(webp|woff2)$ { + add_header Cache-Control "public, max-age=31536000"; + } + ''; + }; + + virtualHosts.cgit = { + serverName = "code.tvl.fyi"; + useACMEHost = "tvl.fyi"; + forceSSL = true; + + extraConfig = '' + # Static assets must always hit the root. + location ~ ^/(favicon\.ico|cgit\.(css|png))$ { + proxy_pass http://localhost:2448; + } + + # Everything else hits the depot directly. + location / { + proxy_pass http://localhost:2448/cgit.cgi/depot/; + } + ''; + }; + + virtualHosts.hound = { + serverName = "cs.tvl.fyi"; + useACMEHost = "tvl.fyi"; + forceSSL = true; + + extraConfig = '' + location / { + proxy_pass http://localhost:6080; + } + ''; + }; + + virtualHosts.gerrit = { + serverName = "cl.tvl.fyi"; + useACMEHost = "tvl.fyi"; + forceSSL = true; + + extraConfig = '' + location / { + proxy_pass http://localhost:4778; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + } + ''; + }; + + virtualHosts.cgit-old = nginxRedirect { + from = "git.tazj.in"; + to = "code.tvl.fyi"; + acmeHost = "tazj.in"; + }; + + virtualHosts.cs-old = nginxRedirect { + from = "cs.tazj.in"; + to = "cs.tvl.fyi"; + acmeHost = "tazj.in"; + }; + }; + + # Timer units that can be started with systemd-run to set my alarm. + systemd.user.services.light-alarm = { + script = "${depot.fun.idual.script}/bin/idualctl wakey"; + postStart = "${pkgs.systemd}/bin/systemctl --user stop light-alarm.timer"; + serviceConfig = { + Type = "oneshot"; + }; + }; + + system.stateVersion = "19.09"; +}) diff --git a/users/tazjin/nixos/default.nix b/users/tazjin/nixos/default.nix new file mode 100644 index 000000000000..4f8923af79d4 --- /dev/null +++ b/users/tazjin/nixos/default.nix @@ -0,0 +1,46 @@ +# 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 {}).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 "nugget"} + ${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; + + nuggetSystem = systemFor [ depot.users.tazjin.nixos.nugget ]; + camdenSystem = systemFor [ depot.users.tazjin.nixos.camden ]; + frogSystem = systemFor [ depot.users.tazjin.nixos.frog ]; +} diff --git a/users/tazjin/nixos/frog/default.nix b/users/tazjin/nixos/frog/default.nix new file mode 100644 index 000000000000..72b1c9ed3612 --- /dev/null +++ b/users/tazjin/nixos/frog/default.nix @@ -0,0 +1,254 @@ +{ depot, lib, ... }: + +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.tools.emacs.overrideEmacs(epkgs: epkgs ++ [ + depot.third_party.emacsPackages.google-c-style + ])); +in depot.lib.fix(self: { + # TODO(tazjin): v4l2loopback + + boot = { + tmpOnTmpfs = true; + kernelModules = [ "kvm-amd" ]; + + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + initrd = { + luks.devices.frog-crypt.device = "/dev/disk/by-label/frog-crypt"; + availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ]; + kernelModules = [ "dm-snapshot" ]; + }; + + kernelPackages = nixpkgs.linuxPackages_latest; + kernel.sysctl = { + "kernel.perf_event_paranoid" = 1; + }; + }; + + hardware = { + cpu.amd.updateMicrocode = true; + enableRedistributableFirmware = true; + pulseaudio.enable = true; + u2f.enable = true; + opengl = { + enable = true; + driSupport = true; + }; + }; + + nix = { + maxJobs = 48; + nixPath = [ + "depot=/depot" + "nixpkgs=${depot.third_party.nixpkgsSrc}" + ]; + }; + + nixpkgs.pkgs = nixpkgs; + + networking = { + hostName = "frog"; + useDHCP = false; + interfaces.enp67s0.useDHCP = true; + + # Don't use ISP's DNS servers: + nameservers = [ + "8.8.8.8" + "8.8.4.4" + ]; + + firewall.enable = false; + }; + + # 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" '' + ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") self.networking.nameservers)} + options edns0 + ''; + }; + + time.timeZone = "Europe/London"; + + fileSystems = { + "/".device = "/dev/disk/by-label/frog-root"; + "/boot".device = "/dev/disk/by-label/BOOT"; + "/home".device = "/dev/disk/by-label/frog-home"; + }; + + # Configure user account + users.extraUsers.tazjin = { + extraGroups = [ "wheel" "audio" ]; + isNormalUser = true; + uid = 1000; + shell = nixpkgs.fish; + }; + + security.sudo = { + enable = true; + extraConfig = "wheel ALL=(ALL:ALL) SETENV: ALL"; + }; + + fonts = { + fonts = with nixpkgs; [ + corefonts + dejavu_fonts + jetbrains-mono + noto-fonts-cjk + noto-fonts-emoji + ]; + + fontconfig = { + hinting.enable = true; + subpixel.lcdfilter = "light"; + + defaultFonts = { + monospace = [ "JetBrains Mono" ]; + }; + }; + }; + + # Configure location (Vauxhall, London) for services that need it. + location = { + latitude = 51.4819109; + longitude = -0.1252998; + }; + + programs.fish.enable = true; + programs.ssh.startAgent = true; + + services.redshift.enable = true; + services.openssh.enable = true; + services.fstrim.enable = true; + + # Required for Yubikey usage as smartcard + services.pcscd.enable = true; + services.udev.packages = [ + nixpkgs.yubikey-personalization + ]; + + services.xserver = { + enable = true; + layout = "us"; + xkbOptions = "caps:super"; + exportConfiguration = true; + displayManager = { + # Give EXWM permission to control the session. + sessionCommands = "${nixpkgs.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 = "${frogEmacs}/bin/tazjins-emacs"; + }; + }; + + # Do not restart the display manager automatically + systemd.services.display-manager.restartIfChanged = lib.mkForce false; + + # clangd needs more than ~2GB in the runtime directory to start up + services.logind.extraConfig = '' + RuntimeDirectorySize=16G + ''; + + # Configure email setup + systemd.user.services.lieer-tazjin = { + description = "Synchronise mail@tazj.in via lieer"; + script = "${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"; + }; + }; + + environment.systemPackages = + # programs from the depot + (with depot; [ + fun.idual.script + lieer + frogEmacs + ops.kontemplate + third_party.ffmpeg + third_party.git + ]) ++ + + # programs from nixpkgs + (with nixpkgs; [ + age + bat + chromium + clang-manpages + clang-tools + clang_10 + curl + direnv + dnsutils + emacs26 # mostly for emacsclient + exa + fd + gnupg + go + google-chrome + google-cloud-sdk + htop + hyperfine + i3lock + imagemagick + jq + kubectl + linuxPackages.perf + miller + msmtp + nix-prefetch-github + notmuch + openssh + openssl + pass + pavucontrol + pinentry + pinentry-emacs + pwgen + ripgrep + rr + rustup + scrot + spotify + steam + tokei + tree + unzip + vlc + xclip + yubico-piv-tool + yubikey-personalization + zoxide + ]); + + # ... and other nonsense. + system.stateVersion = "20.03"; +}) diff --git a/users/tazjin/nixos/nugget/default.nix b/users/tazjin/nixos/nugget/default.nix new file mode 100644 index 000000000000..7c9530072d41 --- /dev/null +++ b/users/tazjin/nixos/nugget/default.nix @@ -0,0 +1,280 @@ +# This file configures nugget, my home desktop machine. +{ depot, lib, ... }: + +config: let + nixpkgs = import depot.third_party.stableNixpkgsSrc { + config.allowUnfree = true; + }; + + unstable = import depot.third_party.nixpkgsSrc {}; + lieer = (depot.third_party.lieer {}); + + # google-c-style is installed only on nugget because other + # machines get it from, eh, elsewhere. + nuggetEmacs = (depot.tools.emacs.overrideEmacs(epkgs: epkgs ++ [ + depot.third_party.emacsPackages.google-c-style + ])); +in depot.lib.fix(self: { + imports = [ + ../modules/v4l2loopback.nix + ]; + + hardware = { + pulseaudio.enable = true; + cpu.intel.updateMicrocode = true; + u2f.enable = true; + }; + + boot = { + cleanTmpDir = true; + kernelModules = [ "kvm-intel" ]; + + loader = { + timeout = 3; + systemd-boot.enable = true; + efi.canTouchEfiVariables = false; + }; + + initrd = { + luks.devices.nugget-crypt.device = "/dev/disk/by-label/nugget-crypt"; + availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ]; + kernelModules = [ "dm-snapshot" ]; + }; + + kernel.sysctl = { + "kernel.perf_event_paranoid" = 1; + }; + }; + + nix = { + package = depot.third_party.nix; + nixPath = [ + "depot=/home/tazjin/depot" + "nixpkgs=${depot.third_party.nixpkgsSrc}" + ]; + }; + + nixpkgs.pkgs = nixpkgs; + + networking = { + hostName = "nugget"; + useDHCP = false; + interfaces.eno1.useDHCP = true; + interfaces.wlp7s0.useDHCP = true; + + # Don't use ISP's DNS servers: + nameservers = [ + "8.8.8.8" + "8.8.4.4" + ]; + + # Open Chromecast-related ports & servedir + firewall.enable = false; + firewall.allowedTCPPorts = [ 4242 5556 5558 ]; + + # Connect to the WiFi to let the Chromecast work. + wireless.enable = true; + wireless.networks = { + "How do I computer?" = { + psk = "washyourface"; + }; + }; + }; + + # 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" '' + ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") self.networking.nameservers)} + options edns0 + ''; + }; + + time.timeZone = "Europe/London"; + + environment.systemPackages = + # programs from the depot + (with depot; [ + fun.idual.script + lieer + nuggetEmacs + ops.kontemplate + third_party.ffmpeg + third_party.git + ]) ++ + + # programs from nixpkgs + (with nixpkgs; [ + age + bat + cachix + chromium + clang-manpages + clang-tools + clang_10 + curl + direnv + dnsutils + exa + fd + gnupg + go + google-chrome + google-cloud-sdk + guile + htop + hyperfine + i3lock + imagemagick + jq + keybase-gui + kubectl + linuxPackages.perf + meson + miller + msmtp + nix-prefetch-github + notmuch + openssh + openssl + pass + pavucontrol + pinentry + pinentry-emacs + pwgen + ripgrep + rr + rustup + sbcl + scrot + spotify + steam + tokei + tree + unzip + vlc + xclip + yubico-piv-tool + yubikey-personalization + ]) ++ + + # programs from unstable nixpkgs + (with unstable; [ + zoxide + ]); + + fileSystems = { + "/".device = "/dev/disk/by-label/nugget-root"; + "/boot".device = "/dev/disk/by-label/EFI"; + "/home".device = "/dev/disk/by-label/nugget-home"; + }; + + # Configure user account + users.extraUsers.tazjin = { + extraGroups = [ "wheel" "audio" ]; + isNormalUser = true; + uid = 1000; + shell = nixpkgs.fish; + }; + + security.sudo = { + enable = true; + extraConfig = "wheel ALL=(ALL:ALL) SETENV: ALL"; + }; + + fonts = { + fonts = with nixpkgs; [ + corefonts + dejavu_fonts + jetbrains-mono + noto-fonts-cjk + noto-fonts-emoji + ]; + + fontconfig = { + hinting.enable = true; + subpixel.lcdfilter = "light"; + + defaultFonts = { + monospace = [ "JetBrains Mono" ]; + }; + }; + }; + + # Configure location (Vauxhall, London) for services that need it. + location = { + latitude = 51.4819109; + longitude = -0.1252998; + }; + + programs.fish.enable = true; + programs.ssh.startAgent = true; + + services.redshift.enable = true; + services.openssh.enable = true; + services.keybase.enable = true; + + # Required for Yubikey usage as smartcard + services.pcscd.enable = true; + services.udev.packages = [ + nixpkgs.yubikey-personalization + ]; + + services.xserver = { + enable = true; + layout = "us"; + xkbOptions = "caps:super"; + exportConfiguration = true; + videoDrivers = [ "nvidia" ]; + + displayManager = { + # Give EXWM permission to control the session. + sessionCommands = "${nixpkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; + + lightdm.enable = true; + lightdm.greeters.gtk.clock-format = "%H·%M"; + }; + + windowManager.session = lib.singleton { + name = "exwm"; + start = "${nuggetEmacs}/bin/tazjins-emacs"; + }; + }; + + # Do not restart the display manager automatically + systemd.services.display-manager.restartIfChanged = lib.mkForce false; + + # Configure email setup + systemd.user.services.lieer-tazjin = { + description = "Synchronise mail@tazj.in via lieer"; + script = "${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"; + }; + }; + + # Use Tailscale \o/ + services.tailscale.enable = true; + + # nugget has an SSD + services.fstrim.enable = true; + + # clangd needs more than ~2GB in the runtime directory to start up + services.logind.extraConfig = '' + RuntimeDirectorySize=4G + ''; + + # ... and other nonsense. + system.stateVersion = "19.09"; +}) -- cgit 1.4.1