about summary refs log tree commit diff
path: root/ops/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'ops/nixos')
-rw-r--r--ops/nixos/.gitignore3
-rw-r--r--ops/nixos/README.md19
-rw-r--r--ops/nixos/default.nix39
-rw-r--r--ops/nixos/dotfiles/config.fish40
-rw-r--r--ops/nixos/dotfiles/msmtprc16
-rw-r--r--ops/nixos/dotfiles/notmuch-config21
-rw-r--r--ops/nixos/dotfiles/offlineimaprc39
-rw-r--r--ops/nixos/mail.nix77
-rw-r--r--ops/nixos/nugget/default.nix228
9 files changed, 482 insertions, 0 deletions
diff --git a/ops/nixos/.gitignore b/ops/nixos/.gitignore
new file mode 100644
index 000000000000..773fa1667019
--- /dev/null
+++ b/ops/nixos/.gitignore
@@ -0,0 +1,3 @@
+hardware-configuration.nix
+local-configuration.nix
+result
diff --git a/ops/nixos/README.md b/ops/nixos/README.md
new file mode 100644
index 000000000000..9e88193dad7e
--- /dev/null
+++ b/ops/nixos/README.md
@@ -0,0 +1,19 @@
+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:
+
+* `nugget` - desktop computer at home
+* ~~`urdhva` - T470s~~ (currently with edef)
diff --git a/ops/nixos/default.nix b/ops/nixos/default.nix
new file mode 100644
index 000000000000..d4aa9705d6a7
--- /dev/null
+++ b/ops/nixos/default.nix
@@ -0,0 +1,39 @@
+# TODO(tazjin): rename 'pkgs' -> 'depot'?
+{ pkgs, ... }:
+
+let
+  inherit (pkgs) lib;
+  inherit (builtins) foldl';
+
+  systemFor = configs: (pkgs.third_party.nixos {
+    configuration = lib.fix(config:
+      foldl' lib.recursiveUpdate {} (map (c: c config) configs)
+    );
+  }).system;
+
+  nuggetSystem = systemFor [ pkgs.ops.nixos.nugget ];
+
+  rebuilder = pkgs.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 <depot> {}).ops.nixos.nuggetSystem' --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 nuggetSystem rebuilder;
+}
diff --git a/ops/nixos/dotfiles/config.fish b/ops/nixos/dotfiles/config.fish
new file mode 100644
index 000000000000..de2c99ae6007
--- /dev/null
+++ b/ops/nixos/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/ops/nixos/dotfiles/msmtprc b/ops/nixos/dotfiles/msmtprc
new file mode 100644
index 000000000000..624b6a77fc4b
--- /dev/null
+++ b/ops/nixos/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/ops/nixos/dotfiles/notmuch-config b/ops/nixos/dotfiles/notmuch-config
new file mode 100644
index 000000000000..a490774e635f
--- /dev/null
+++ b/ops/nixos/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/ops/nixos/dotfiles/offlineimaprc b/ops/nixos/dotfiles/offlineimaprc
new file mode 100644
index 000000000000..78315447e4bd
--- /dev/null
+++ b/ops/nixos/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/ops/nixos/mail.nix b/ops/nixos/mail.nix
new file mode 100644
index 000000000000..ba4ebfa06026
--- /dev/null
+++ b/ops/nixos/mail.nix
@@ -0,0 +1,77 @@
+# 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/nugget/default.nix b/ops/nixos/nugget/default.nix
new file mode 100644
index 000000000000..cffb555d821e
--- /dev/null
+++ b/ops/nixos/nugget/default.nix
@@ -0,0 +1,228 @@
+# This file contains the configuration for my home desktop.
+
+{ pkgs, ... }:
+
+config: let
+  inherit (pkgs) lib;
+
+  nixpkgs = import pkgs.third_party.nixpkgsSrc {
+    config.allowUnfree = true;
+  };
+
+  lieer = (pkgs.third_party.lieer {});
+in pkgs.lib.fix(self: {
+  hardware = {
+    pulseaudio.enable = true;
+    cpu.intel.updateMicrocode = 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" ];
+    };
+  };
+
+  nix = {
+    nixPath = [
+      "depot=/home/tazjin/depot"
+      "nixpkgs=${pkgs.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; with pkgs; {
+    source = 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 pkgs; [
+      lieer
+      ops.kontemplate
+      third_party.git
+      third_party.guile
+      tools.emacs
+    ]) ++
+
+    # programs from nixpkgs
+    (with nixpkgs; [
+      age
+      bat
+      cachix
+      chromium
+      curl
+      direnv
+      dnsutils
+      exa
+      fd
+      gnupg
+      go
+      google-chrome
+      google-cloud-sdk
+      htop
+      imagemagick
+      jq
+      kubectl
+      miller
+      msmtp
+      nix-prefetch-github
+      notmuch
+      openssh
+      openssl
+      pass
+      pavucontrol
+      pinentry
+      pinentry-emacs
+      pwgen
+      ripgrep
+      rustup
+      sbcl
+      scrot
+      spotify
+      tokei
+      tree
+      vlc
+      xclip
+    ]);
+
+    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
+        input-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;
+
+    services.redshift.enable = true;
+    services.openssh.enable = true;
+
+    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 = pkgs.lib.singleton {
+        name = "exwm";
+        start = "${pkgs.tools.emacs}/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";
+      };
+    };
+
+    # ... and other nonsense.
+    system.stateVersion = "19.09";
+})