about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2024-12-08 13:58:02 -0800
committerFranck Cuny <franck@fcuny.net>2024-12-08 15:35:17 -0800
commit52ac07299f2342afe0c309f3b8be3ea05c7549ff (patch)
treebad76e67ba8a1f9301eb87a8c5e66c8a5a260e76
parentadd targets to create virtual machines (diff)
downloadworld-52ac07299f2342afe0c309f3b8be3ea05c7549ff.tar.gz
refactor overall configuration
The configuration of the various hosts and home-manager was becoming a
bit complex for no valid reasons. Try to simplify this a bit.
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--flake.lock179
-rw-r--r--flake.nix47
-rw-r--r--nix/lib/mkSystem.nix50
-rw-r--r--nix/machines/darwin-shared.nix91
-rw-r--r--nix/machines/hardware/vm-aarch64-utm.nix33
-rw-r--r--nix/machines/macbook-air-m2.nix13
-rw-r--r--nix/machines/macbook-pro-intel.nix8
-rw-r--r--nix/machines/vm-aarch64.nix16
-rw-r--r--nix/machines/vm-shared.nix51
-rw-r--r--nix/users/fcuny/darwin.nix8
-rw-r--r--nix/users/fcuny/home-manager.nix256
-rw-r--r--nix/users/fcuny/nixos.nix20
13 files changed, 572 insertions, 201 deletions
diff --git a/.gitignore b/.gitignore
index 14d4519..7f2acd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
 **/target/
 /*.qcow2
 bin/
+/.direnv/
diff --git a/flake.lock b/flake.lock
index 7fa3051..1a51900 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,97 +20,6 @@
         "type": "github"
       }
     },
-    "devshell": {
-      "inputs": {
-        "nixpkgs": "nixpkgs"
-      },
-      "locked": {
-        "lastModified": 1728330715,
-        "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
-        "owner": "numtide",
-        "repo": "devshell",
-        "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "devshell",
-        "type": "github"
-      }
-    },
-    "flake-compat": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
-        "type": "github"
-      },
-      "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
-      }
-    },
-    "flake-parts": {
-      "inputs": {
-        "nixpkgs-lib": "nixpkgs-lib"
-      },
-      "locked": {
-        "lastModified": 1730504689,
-        "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "rev": "506278e768c2a08bec68eb62932193e341f55c90",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "type": "github"
-      }
-    },
-    "futils": {
-      "inputs": {
-        "systems": "systems"
-      },
-      "locked": {
-        "lastModified": 1731533236,
-        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "gitignore": {
-      "inputs": {
-        "nixpkgs": [
-          "pre-commit-hooks",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1709087332,
-        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "type": "github"
-      }
-    },
     "home-manager": {
       "inputs": {
         "nixpkgs": [
@@ -134,50 +43,6 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1722073938,
-        "narHash": "sha256-OpX0StkL8vpXyWOGUD6G+MA26wAXK6SpT94kLJXo6B4=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "e36e9f57337d0ff0cf77aceb58af4c805472bfae",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs-lib": {
-      "locked": {
-        "lastModified": 1730504152,
-        "narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
-        "type": "tarball",
-        "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
-      },
-      "original": {
-        "type": "tarball",
-        "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
-      }
-    },
-    "nixpkgs-stable": {
-      "locked": {
-        "lastModified": 1730741070,
-        "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "nixpkgs_2": {
-      "locked": {
         "lastModified": 1732981179,
         "narHash": "sha256-F7thesZPvAMSwjRu0K8uFshTk3ZZSNAsXTIFvXBT+34=",
         "owner": "nixos",
@@ -192,56 +57,14 @@
         "type": "github"
       }
     },
-    "pre-commit-hooks": {
-      "inputs": {
-        "flake-compat": "flake-compat",
-        "gitignore": "gitignore",
-        "nixpkgs": [
-          "nixpkgs"
-        ],
-        "nixpkgs-stable": "nixpkgs-stable"
-      },
-      "locked": {
-        "lastModified": 1732021966,
-        "narHash": "sha256-mnTbjpdqF0luOkou8ZFi2asa1N3AA2CchR/RqCNmsGE=",
-        "owner": "cachix",
-        "repo": "pre-commit-hooks.nix",
-        "rev": "3308484d1a443fc5bc92012435d79e80458fe43c",
-        "type": "github"
-      },
-      "original": {
-        "owner": "cachix",
-        "repo": "pre-commit-hooks.nix",
-        "type": "github"
-      }
-    },
     "root": {
       "inputs": {
         "darwin": "darwin",
-        "devshell": "devshell",
-        "flake-parts": "flake-parts",
-        "futils": "futils",
         "home-manager": "home-manager",
-        "nixpkgs": "nixpkgs_2",
-        "pre-commit-hooks": "pre-commit-hooks",
+        "nixpkgs": "nixpkgs",
         "treefmt-nix": "treefmt-nix"
       }
     },
-    "systems": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
-    },
     "treefmt-nix": {
       "inputs": {
         "nixpkgs": [
diff --git a/flake.nix b/flake.nix
index 02a25cd..e82e17f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -18,31 +18,32 @@
       url = "github:numtide/treefmt-nix";
       inputs.nixpkgs.follows = "nixpkgs";
     };
-
-    pre-commit-hooks = {
-      url = "github:cachix/pre-commit-hooks.nix";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
-
-    devshell.url = "github:numtide/devshell";
-
-    # utils
-    futils.url = "github:numtide/flake-utils";
-    flake-parts.url = "github:hercules-ci/flake-parts";
   };
 
   # Output config, or config for NixOS system
-  outputs = inputs:
-    inputs.flake-parts.lib.mkFlake { inherit inputs; } {
-
-      systems = [
-        "aarch64-darwin"
-        "x86_64-darwin"
-
-        "aarch64-linux"
-        "x86_64-linux"
-      ];
-
-      imports = [ ./nix/flake/devshell.nix ./nix/flake/hosts.nix ];
+  outputs = { nixpkgs, darwin, ... }@inputs:
+    let mkSystem = import ./nix/lib/mkSystem.nix { inherit nixpkgs inputs; };
+    in {
+      nixosConfigurations.vm-aarch64 = mkSystem "vm-aarch64" {
+        system = "aarch64-linux";
+        user = "fcuny";
+      };
+
+      nixosConfigurations.vm-synology = mkSystem "vm-synology" {
+        system = "x86_64-linux";
+        user = "fcuny";
+      };
+
+      darwinConfigurations.macbook-air-m2 = mkSystem "macbook-air-m2" {
+        system = "aarch64-darwin";
+        user = "fcuny";
+        darwin = true;
+      };
+
+      darwinConfigurations.macbook-pro-intel = mkSystem "macbook-pro-intel" {
+        system = "x86_64-darwin";
+        user = "fcuny";
+        darwin = true;
+      };
     };
 }
diff --git a/nix/lib/mkSystem.nix b/nix/lib/mkSystem.nix
new file mode 100644
index 0000000..dbacac6
--- /dev/null
+++ b/nix/lib/mkSystem.nix
@@ -0,0 +1,50 @@
+# This function creates a NixOS system based on our VM setup for a
+# particular architecture.
+{ nixpkgs, inputs }:
+
+name:
+{ system, user, darwin ? false, }:
+
+let
+  # The config files for this system.
+  machineConfig = ../machines/${name}.nix;
+  userOSConfig = ../users/${user}/${if darwin then "darwin" else "nixos"}.nix;
+  userHMConfig = ../users/${user}/home-manager.nix;
+
+  # NixOS vs nix-darwin functionst
+  systemFunc =
+    if darwin then inputs.darwin.lib.darwinSystem else nixpkgs.lib.nixosSystem;
+  home-manager =
+    if darwin then
+      inputs.home-manager.darwinModules
+    else
+      inputs.home-manager.nixosModules;
+in
+systemFunc rec {
+  inherit system;
+
+  modules = [
+    # Allow unfree packages.
+    { nixpkgs.config.allowUnfree = true; }
+
+    machineConfig
+    userOSConfig
+    home-manager.home-manager
+    {
+      home-manager.useGlobalPkgs = true;
+      home-manager.useUserPackages = true;
+      home-manager.users.${user} = import userHMConfig { inputs = inputs; };
+    }
+
+    # We expose some extra arguments so that our modules can parameterize
+    # better based on these values.
+    {
+      config._module.args = {
+        currentSystem = system;
+        currentSystemName = name;
+        currentSystemUser = user;
+        inputs = inputs;
+      };
+    }
+  ];
+}
diff --git a/nix/machines/darwin-shared.nix b/nix/machines/darwin-shared.nix
new file mode 100644
index 0000000..6c727f8
--- /dev/null
+++ b/nix/machines/darwin-shared.nix
@@ -0,0 +1,91 @@
+{ pkgs, ... }: {
+  nix = {
+    package = pkgs.nixVersions.stable;
+
+    gc = {
+      user = "root";
+      automatic = true;
+      interval = [{
+        Hour = 7;
+        Minute = 0;
+        Weekday = 0;
+      }];
+      options = "--delete-older-than 7d";
+    };
+
+    settings = {
+      trusted-users = [ "@admin" "fcuny" ];
+      experimental-features = [ "nix-command" "flakes" ];
+    };
+  };
+
+  system.defaults = {
+    dock = {
+      autohide = true;
+      orientation = "left";
+      showhidden = false;
+      show-recents = false;
+      mru-spaces = false; # don’t rearrange spaces based on the most recent use
+    };
+    finder.AppleShowAllExtensions = true;
+    screencapture.location = "~/Documents/screenshots";
+    SoftwareUpdate.AutomaticallyInstallMacOSUpdates = true;
+  };
+
+  fonts.packages = with pkgs; [
+    emacs-all-the-icons-fonts
+    google-fonts
+    roboto
+    source-code-pro
+    source-serif-pro
+    source-sans-pro
+    go-font
+  ];
+
+  system.keyboard = {
+    enableKeyMapping = true;
+    remapCapsLockToControl = true;
+  };
+
+  # Touch ID for sudo auth
+  security.pam.enableSudoTouchIdAuth = true;
+
+  services.nix-daemon.enable = true;
+
+  system.defaults.CustomUserPreferences = {
+    "com.apple.desktopservices" = {
+      # Avoid creating .DS_Store files on network or USB volumes
+      DSDontWriteNetworkStores = true;
+      DSDontWriteUSBStores = true;
+    };
+  };
+
+  programs.fish.enable = true;
+  programs.fish.shellInit = ''
+    # Nix
+    if test -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'
+      source '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'
+    end
+    # End Nix
+  '';
+
+  # Required for homebrew on aarch64
+  environment.systemPath = [ "/opt/homebrew/bin" "/opt/homebrew/sbin" ];
+
+  homebrew = {
+    enable = true;
+    onActivation.autoUpdate = true;
+    onActivation.upgrade = true;
+
+    casks = [
+      "1password-cli"
+      "docker"
+      "element"
+      "emacs"
+      "iterm2"
+      "transmission"
+      "vlc"
+      "wireshark"
+    ];
+  };
+}
diff --git a/nix/machines/hardware/vm-aarch64-utm.nix b/nix/machines/hardware/vm-aarch64-utm.nix
new file mode 100644
index 0000000..084cc74
--- /dev/null
+++ b/nix/machines/hardware/vm-aarch64-utm.nix
@@ -0,0 +1,33 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ lib, modulesPath, ... }: {
+  imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
+
+  boot.initrd.availableKernelModules = [ "xhci_pci" "sr_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ ];
+  boot.extraModulePackages = [ ];
+
+  fileSystems."/" = {
+    device = "/dev/disk/by-label/nixos";
+    fsType = "ext4";
+  };
+
+  fileSystems."/boot" = {
+    device = "/dev/disk/by-label/boot";
+    fsType = "vfat";
+    options = [ "fmask=0022" "dmask=0022" ];
+  };
+
+  swapDevices = [ ];
+
+  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+  # (the default) this is the recommended approach. When using systemd-networkd it's
+  # still possible to use this option, but it's recommended to use it in conjunction
+  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
+  networking.useDHCP = lib.mkDefault true;
+  # networking.interfaces.enp0s1.useDHCP = lib.mkDefault true;
+
+  nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
+}
diff --git a/nix/machines/macbook-air-m2.nix b/nix/machines/macbook-air-m2.nix
new file mode 100644
index 0000000..9b0265a
--- /dev/null
+++ b/nix/machines/macbook-air-m2.nix
@@ -0,0 +1,13 @@
+{ pkgs, ... }: {
+  imports = [ ./darwin-shared.nix ];
+
+  system.stateVersion = 5;
+
+  networking.hostName = "mba-fcuny";
+
+  programs.fish.enable = true;
+  environment.shells = [ pkgs.fish ];
+
+  # brew packages I only want to get installed on this machine
+  homebrew.casks = [ "zoom" ];
+}
diff --git a/nix/machines/macbook-pro-intel.nix b/nix/machines/macbook-pro-intel.nix
new file mode 100644
index 0000000..07b464e
--- /dev/null
+++ b/nix/machines/macbook-pro-intel.nix
@@ -0,0 +1,8 @@
+{ pkgs, ... }: {
+  imports = [ ./darwin-shared.nix ];
+
+  system.stateVersion = 5;
+
+  programs.fish.enable = true;
+  environment.shells = [ pkgs.fish ];
+}
diff --git a/nix/machines/vm-aarch64.nix b/nix/machines/vm-aarch64.nix
new file mode 100644
index 0000000..8e84ed5
--- /dev/null
+++ b/nix/machines/vm-aarch64.nix
@@ -0,0 +1,16 @@
+{ ... }: {
+  imports = [ ./hardware/vm-aarch64-utm.nix ./vm-shared.nix ];
+
+  # Interface is this on my M1
+  networking.interfaces.enp0s10.useDHCP = true;
+
+  # Qemu
+  services.spice-vdagentd.enable = true;
+
+  # For now, we need this since hardware acceleration does not work.
+  environment.variables.LIBGL_ALWAYS_SOFTWARE = "1";
+
+  # Lots of stuff that uses aarch64 that claims doesn't work, but actually works.
+  nixpkgs.config.allowUnfree = true;
+  nixpkgs.config.allowUnsupportedSystem = true;
+}
diff --git a/nix/machines/vm-shared.nix b/nix/machines/vm-shared.nix
new file mode 100644
index 0000000..04eedf0
--- /dev/null
+++ b/nix/machines/vm-shared.nix
@@ -0,0 +1,51 @@
+{ pkgs, ... }: {
+  boot.kernelPackages = pkgs.linuxPackages_latest;
+
+  nix = {
+    package = pkgs.nixVersions.latest;
+    extraOptions = ''
+      experimental-features = nix-command flakes
+      keep-outputs = true
+      keep-derivations = true
+    '';
+  };
+
+  # Use the systemd-boot EFI boot loader.
+  boot.loader.systemd-boot.enable = true;
+  boot.loader.efi.canTouchEfiVariables = true;
+
+  networking.hostName = "dev";
+
+  time.timeZone = "America/Los_Angeles";
+
+  # Don't require password for sudo
+  security.sudo.wheelNeedsPassword = false;
+
+  # Virtualization settings
+  virtualisation.docker.enable = true;
+
+  # Select internationalisation properties.
+  i18n = { defaultLocale = "en_US.UTF-8"; };
+
+  # Define a user account. Don't forget to set a password with ‘passwd’.
+  users.mutableUsers = false;
+
+  # List packages installed in system profile. To search, run:
+  # $ nix search wget
+  environment.systemPackages = with pkgs; [ curl git ];
+
+  # Enable the OpenSSH daemon.
+  services.openssh.enable = true;
+  services.openssh.settings.PasswordAuthentication = true;
+  services.openssh.settings.PermitRootLogin = "no";
+
+  networking.firewall.enable = false;
+
+  # This value determines the NixOS release from which the default
+  # settings for stateful data, like file locations and database versions
+  # on your system were taken. It‘s perfectly fine and recommended to leave
+  # this value at the release version of the first install of this system.
+  # Before changing this value read the documentation for this option
+  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
+  system.stateVersion = "23.11"; # Did you read the comment?
+}
diff --git a/nix/users/fcuny/darwin.nix b/nix/users/fcuny/darwin.nix
new file mode 100644
index 0000000..b56a67d
--- /dev/null
+++ b/nix/users/fcuny/darwin.nix
@@ -0,0 +1,8 @@
+{ pkgs, ... }: {
+  # The user should already exist, but we need to set this up so Nix knows
+  # what our home directory is (https://github.com/LnL7/nix-darwin/issues/423).
+  users.users.fcuny = {
+    home = "/Users/fcuny";
+    shell = pkgs.fish;
+  };
+}
diff --git a/nix/users/fcuny/home-manager.nix b/nix/users/fcuny/home-manager.nix
new file mode 100644
index 0000000..6c3342b
--- /dev/null
+++ b/nix/users/fcuny/home-manager.nix
@@ -0,0 +1,256 @@
+{ ... }:
+
+{ config, lib, pkgs, ... }: {
+  home.stateVersion = "23.05";
+
+  xdg.enable = true;
+
+  home.packages = with pkgs; [
+    # go
+    go-tools
+    golangci-lint
+    gopls
+    delve
+
+    # docker
+    dive # explore layers in docker images
+
+    # shell
+    shellcheck
+
+    # git
+    gitAndTools.pre-commit
+    git-credential-manager
+    gh
+
+    # shell utils
+    coreutils
+    direnv
+    dust
+    procs
+    ripgrep
+    tree
+    wget
+
+    # network
+    bandwhich
+
+    # data manipulation
+    jless
+    jq
+    yq
+
+    # encryption
+    age
+
+    # media
+    mpv
+    ffmpeg
+
+    # dicts
+    aspell
+    aspellDicts.en
+    aspellDicts.en-computers
+    aspellDicts.en-science
+
+    # nix
+    nil
+    nix-direnv
+    nixd
+    nixfmt-classic
+    nixpkgs-fmt
+    nil # nix lsp
+
+    # k8s
+    kind # k8s in docker
+    kubebuilder # generate controller
+    kubectl
+    kubernetes-helm # deploy applications
+    kubie # kubeconfig browser https://github.com/sbstp/kubie
+    kubelogin-oidc # OIDC plugin
+    k9s # object explorer
+
+    # hashicorp
+    boundary
+    nomad-pack
+    tfswitch
+  ];
+
+  programs.go = {
+    enable = true;
+    goPath = ".local/share/pkg.go";
+    goBin = ".local/bin.go";
+    goPrivate = [ "github.rbx.com/*" "github.com/fcuny/*" "git.fcuny.net/*" ];
+  };
+
+  # an alternative to ls
+  programs.eza = {
+    enable = true;
+    icons = "never";
+    enableFishIntegration = false;
+    extraOptions = [
+      "--group-directories-first"
+      "--no-quotes"
+      "--git-ignore"
+      "--icons=never"
+    ];
+  };
+
+  # an alternative to find
+  programs.fd = {
+    enable = true;
+    hidden = true;
+    ignores = [ ".git/" ".direnv/" ];
+  };
+
+  programs.direnv = {
+    enable = true;
+    nix-direnv.enable = true;
+    enableZshIntegration = true;
+    config = {
+      global.disable_stdin = true;
+      global.strict_env = true;
+    };
+  };
+
+  programs.fish = {
+    enable = true;
+    interactiveShellInit = ''
+      set fish_greeting ""
+    '';
+
+    shellAbbrs = { ncg = "nix-collect-garbage -d"; };
+    shellAliases = {
+      c = "clear";
+      ls = "eza -l -L=1 --git --color=always --group-directories-first";
+      la = "eza -la --git --color=always --group-directories-first";
+      ll = "eza -la -L=1 --git --color=always --group-directories-first";
+      lt = "eza -aT -L=2 --git --color=always --group-directories-first";
+    };
+  };
+
+  programs.git = {
+    enable = true;
+    userName = "Franck Cuny";
+    userEmail = "franck@fcuny.net";
+
+    aliases = { amend = "commit --amend"; };
+
+    includes = [
+      {
+        condition = "hasconfig:remote.*.url:git@github.rbx.com:**";
+        path = pkgs.writeText "finsitGitConfig"
+          (lib.generators.toGitINI { user.email = "fcuny@roblox.com"; });
+      }
+      {
+        condition = "hasconfig:remote.*.url:git@github.com:Roblox/**";
+        path = pkgs.writeText "finsitGitConfig"
+          (lib.generators.toGitINI { user.email = "fcuny@roblox.com"; });
+      }
+    ];
+
+    extraConfig = {
+      core.whitespace = "trailing-space,space-before-tab";
+      color.ui = "true";
+
+      # abort if the remote branch does not match the local one
+      push.default = "simple";
+
+      # https://adamj.eu/tech/2024/01/18/git-improve-diff-histogram/
+      diff.algorithm = "histogram";
+
+      init.defaultBranch = "main";
+
+      pull.rebase = true;
+      rebase = {
+        # Automatically create a temporary stash entry before the
+        # operation begins, and apply it after the operation ends.
+        autoStash = true;
+        # Print a warning if some commits are removed
+        missingCommitsCheck = "warn";
+      };
+
+      branch.autosetuprebase = "remote";
+      branch.sort = "authordate";
+
+      url = {
+        "ssh://git@github.rbx.com/" = {
+          insteadOf = "https://github.rbx.com/";
+        };
+      };
+    };
+  };
+
+  programs.ssh = {
+    enable = true;
+    forwardAgent = true;
+    serverAliveInterval = 60;
+    controlMaster = "auto";
+    controlPersist = "30m";
+    extraConfig = ''
+      IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
+    '';
+    matchBlocks = {
+      "personal" = {
+        hostname = "github.com";
+        user = "git";
+        forwardAgent = false;
+        extraOptions = { preferredAuthentications = "publickey"; };
+      };
+      "github.com" = {
+        hostname = "github.com";
+        user = "git";
+        forwardAgent = false;
+        extraOptions = { preferredAuthentications = "publickey"; };
+      };
+      "github.rbx.com" = {
+        hostname = "github.rbx.com";
+        user = "git";
+        forwardAgent = false;
+        extraOptions = { preferredAuthentications = "publickey"; };
+      };
+    };
+  };
+
+  home.sessionPath = [ config.home.sessionVariables.GOBIN ];
+
+  home.sessionVariables = with config.xdg; {
+    ASPELL_CONF = "conf ${config.xdg.configHome}/aspell/config;";
+    EDITOR = "emacsclient -a=";
+    HOMEBREW_NO_AUTO_UPDATE = 1;
+    IPYTHONDIR = "${cacheHome}/ipython";
+    LESS = "-FRSXM";
+    LESSCHARSET = "utf-8";
+    MYPY_CACHE_DIR = "${cacheHome}/mypy";
+    PAGER = "less";
+    PIP_LOG = "${cacheHome}/pip/pip.log";
+    PYLINTHOME = "${cacheHome}/pylint";
+    PYTHON_EGG_CACHE = "${cacheHome}/python-eggs";
+    SHELL = "${pkgs.fish}/bin/fish";
+    VISUAL = "emacsclient -a=";
+  };
+
+  # Generate ssh agent config for 1Password
+  # I want both my personal and work keys
+  home.file.".config/1Password/ssh/agent.toml".text = ''
+    [[ssh-keys]]
+    account = "my.1password.com"
+
+    [[ssh-keys]]
+    account = "roblox.1password.com"
+    item = "GitHub ssh key"
+    vault = "Private"
+  '';
+
+  home.file.kubie = {
+    target = ".kube/kubie.yaml";
+    text = ''
+      shell: fish
+      configs:
+        include:
+          - ~/.kube/rksconfig
+      prompt:
+        fish_use_rprompt: true
+    '';
+  };
+}
diff --git a/nix/users/fcuny/nixos.nix b/nix/users/fcuny/nixos.nix
new file mode 100644
index 0000000..662c0b1
--- /dev/null
+++ b/nix/users/fcuny/nixos.nix
@@ -0,0 +1,20 @@
+{ pkgs, ... }: {
+  # https://github.com/nix-community/home-manager/pull/2408
+  environment.pathsToLink = [ "/share/fish" ];
+
+  # Add ~/.local/bin to PATH
+  environment.localBinInPath = true;
+
+  # we're using fish as our shell
+  programs.fish.enable = true;
+
+  users.users.fcuny = {
+    isNormalUser = true;
+    home = "/home/fcuny";
+    extraGroups = [ "docker" "wheel" ];
+    shell = pkgs.fish;
+    openssh.authorizedKeys.keys = [
+      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBkozy+X96u5ciX766bJ/AyQ3xm1tXZTIr5+4PVFZFi"
+    ];
+  };
+}