From 99658b27dc46e62105a71079561365a98ccd3f54 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 10 Apr 2026 17:25:08 +0200 Subject: [PATCH] feat: rework to modular --- README.md | 141 +++++++++++++--- flake.lock | 159 ++---------------- flake.nix | 133 ++++++++++++--- lib/defaults.nix | 20 +++ lib/mkProfile.nix | 7 + lib/mkSystem.nix | 15 ++ modules/base/core.nix | 19 +++ modules/base/fonts.nix | 11 ++ modules/base/nix.nix | 14 ++ modules/base/shell.nix | 20 +++ modules/dev/docker.nix | 16 ++ modules/dev/go.nix | 7 + modules/dev/node.nix | 10 ++ modules/dev/rust.nix | 13 ++ modules/helpers/home.nix | 6 - modules/home.nix | 22 +-- modules/optional/devtools.nix | 11 ++ modules/optional/gui.nix | 9 + modules/optional/homebrew.nix | 6 + modules/roles/backend.nix | 13 ++ modules/roles/frontend.nix | 11 ++ modules/roles/infra.nix | 15 ++ modules/roles/minimal.nix | 9 + modules/secrets/env.nix | 7 + modules/secrets/openbao.nix | 6 + modules/services/gpg.nix | 11 ++ modules/services/ssh.nix | 22 +++ modules/services/tailscale.nix | 9 + .../__pycache__/test_cli.cpython-313.pyc | Bin 10366 -> 0 bytes profiles/backend.nix | 8 + profiles/frontend.nix | 8 + profiles/minimal.nix | 10 ++ shells/default.nix | 20 +++ shells/go.nix | 16 ++ shells/node.nix | 19 +++ shells/rust.nix | 24 +++ systems/darwin/default.nix | 42 +++++ systems/linux/default.nix | 24 +++ templates/user-flake/flake.nix | 36 ++++ 39 files changed, 738 insertions(+), 211 deletions(-) create mode 100644 lib/defaults.nix create mode 100644 lib/mkProfile.nix create mode 100644 lib/mkSystem.nix create mode 100644 modules/base/core.nix create mode 100644 modules/base/fonts.nix create mode 100644 modules/base/nix.nix create mode 100644 modules/base/shell.nix create mode 100644 modules/dev/docker.nix create mode 100644 modules/dev/go.nix create mode 100644 modules/dev/node.nix create mode 100644 modules/dev/rust.nix delete mode 100644 modules/helpers/home.nix create mode 100644 modules/optional/devtools.nix create mode 100644 modules/optional/gui.nix create mode 100644 modules/optional/homebrew.nix create mode 100644 modules/roles/backend.nix create mode 100644 modules/roles/frontend.nix create mode 100644 modules/roles/infra.nix create mode 100644 modules/roles/minimal.nix create mode 100644 modules/secrets/env.nix create mode 100644 modules/secrets/openbao.nix create mode 100644 modules/services/gpg.nix create mode 100644 modules/services/ssh.nix create mode 100644 modules/services/tailscale.nix delete mode 100644 pkgs/helpers/tests/__pycache__/test_cli.cpython-313.pyc create mode 100644 profiles/backend.nix create mode 100644 profiles/frontend.nix create mode 100644 profiles/minimal.nix create mode 100644 shells/default.nix create mode 100644 shells/go.nix create mode 100644 shells/node.nix create mode 100644 shells/rust.nix create mode 100644 systems/darwin/default.nix create mode 100644 systems/linux/default.nix create mode 100644 templates/user-flake/flake.nix diff --git a/README.md b/README.md index fb4f94e..4dae8d8 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,132 @@ # nix-nodeiwest -Employee and workstation flake for NodeiWest. +Composable company Nix for NodeiWest workstations and project shells. -Server deployment moved to the sibling repo `../nix-deployment`. +This repo is now structured as a shared SDK: -This repo now owns: +- `modules/` holds focused Home Manager building blocks +- `profiles/` bundles those modules into opinionated employee entrypoints +- `shells/` exposes reusable flake dev shells for project repos +- `systems/` adapts the shared modules into Darwin or standalone Linux Home Manager configs +- `lib/` holds the small helpers that keep composition consistent +- `templates/` bootstraps downstream user flakes -- shared Home Manager modules -- employee shell packages and environment variables -- workstation-side access to the `nodeiwest` helper by consuming it from `../nix-deployment` +It does not define users or machines directly. Downstream flakes decide who uses which profile. -This repo no longer owns: +## Layout -- NixOS server host definitions -- Colmena deployment state -- Tailscale server bootstrap -- k3s bootstrap -- OpenBao server or Kubernetes infra manifests - -## Helper Consumption - -The helper package is re-exported from the deployment repo: - -```bash -nix run .#nodeiwest-helper -- --help +```text +. +├── flake.nix +├── lib/ +├── modules/ +│ ├── base/ +│ ├── dev/ +│ ├── optional/ +│ ├── roles/ +│ ├── secrets/ +│ └── services/ +├── profiles/ +├── shells/ +├── systems/ +└── templates/ ``` -If you import `modules/helpers/home.nix` directly, pass the deployment flake as a special arg: +## Flake Interface + +Primary outputs: + +- `homeManagerModules.base.*`: low-level base modules +- `homeManagerModules.dev.*`: language and workflow modules +- `homeManagerModules.roles.*`: reusable role bundles +- `homeManagerModules.profiles.*`: ready-made employee profiles +- `homeManagerModules.default`: compatibility shim for the old default home module +- `lib.mkSystem`: chooses the Darwin or Linux adapter for a downstream flake +- `lib.shells.*`: shell factories for repo-local dev environments +- `devShells..*`: ready-to-use company shells +- `templates.user-flake`: starter personal flake + +## Workstation Consumption + +Downstream user flakes own the actual machine definitions. They consume profiles from this repo: ```nix -extraSpecialArgs = { - deployment = inputs.deployment; +{ + inputs.company.url = "git+ssh://git@git.dgren.dev/employees/company-nix.git"; + + outputs = { company, ... }: { + darwinConfigurations.eric = company.lib.mkSystem { + target = "darwin"; + system = "aarch64-darwin"; + username = "eric"; + homeDirectory = "/Users/eric"; + modules = [ + company.homeManagerModules.profiles.frontend + ]; + }; + }; +} +``` + +For Linux Home Manager: + +```nix +{ + inputs.company.url = "git+ssh://git@git.dgren.dev/employees/company-nix.git"; + + outputs = { company, ... }: { + homeConfigurations."eric@work" = company.lib.mkSystem { + target = "linux"; + system = "x86_64-linux"; + username = "eric"; + homeDirectory = "/home/eric"; + modules = [ + company.homeManagerModules.profiles.backend + ]; + }; + }; +} +``` + +## Project Shell Consumption + +Project repos should keep their own flake and compose shells from this repo instead of outsourcing project ownership here. + +Use the ready-made shell directly: + +```nix +{ + inputs.company.url = "git+ssh://git@git.dgren.dev/employees/company-nix.git"; + + outputs = { nixpkgs, company, ... }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + in + { + devShells.${system}.default = company.lib.shells.node { + inherit pkgs; + extraPackages = [ pkgs.ffmpeg ]; + }; + }; +} +``` + +Or extend the published company shell in place: + +```nix +devShells.${system}.default = pkgs.mkShell { + inputsFrom = [ company.devShells.${system}.node ]; + packages = [ pkgs.ffmpeg ]; }; ``` + +## Template + +Bootstrap a personal flake with: + +```bash +nix flake init -t .#user-flake +``` + +That template is intentionally small. Add machine-specific modules in the personal repo, not here. diff --git a/flake.lock b/flake.lock index 258b093..a2e44b3 100644 --- a/flake.lock +++ b/flake.lock @@ -1,98 +1,5 @@ { "nodes": { - "colmena": { - "inputs": { - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "nix-github-actions": "nix-github-actions", - "nixpkgs": "nixpkgs", - "stable": "stable" - }, - "locked": { - "lastModified": 1762034856, - "narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=", - "owner": "zhaofengli", - "repo": "colmena", - "rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed", - "type": "github" - }, - "original": { - "owner": "zhaofengli", - "repo": "colmena", - "type": "github" - } - }, - "deployment": { - "inputs": { - "colmena": "colmena", - "disko": "disko", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 0, - "narHash": "sha256-BW+YgPQb2t5davyiQ6gb4sIbBdIL72jCaLGiehkGT9U=", - "type": "git", - "url": "file:../nix-deployment" - }, - "original": { - "type": "git", - "url": "file:../nix-deployment" - } - }, - "disko": { - "inputs": { - "nixpkgs": [ - "deployment", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1773506317, - "narHash": "sha256-qWKbLUJpavIpvOdX1fhHYm0WGerytFHRoh9lVck6Bh0=", - "owner": "nix-community", - "repo": "disko", - "rev": "878ec37d6a8f52c6c801d0e2a2ad554c75b9353c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "disko", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1650374568, - "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "b4a34015c698c7793d592d66adbab377907a2be8", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-utils": { - "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "home-manager": { "inputs": { "nixpkgs": [ @@ -100,11 +7,11 @@ ] }, "locked": { - "lastModified": 1773681856, - "narHash": "sha256-+bRqxoFCJFO9ZTFhcCkzNXbDT3b8AEk88fyjB7Is6eo=", + "lastModified": 1775781825, + "narHash": "sha256-L5yKTpR+alrZU2XYYvIxCeCP4LBHU5jhwSj7H1VAavg=", "owner": "nix-community", "repo": "home-manager", - "rev": "57d5560ee92a424fb71fde800acd6ed2c725dfce", + "rev": "e35c39fca04fee829cecdf839a50eb9b54d8a701", "type": "github" }, "original": { @@ -113,51 +20,33 @@ "type": "github" } }, - "nix-github-actions": { + "nix-darwin": { "inputs": { "nixpkgs": [ - "deployment", - "colmena", "nixpkgs" ] }, "locked": { - "lastModified": 1729742964, - "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "e04df33f62cdcf93d73e9a04142464753a16db67", + "lastModified": 1775037210, + "narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "06648f4902343228ce2de79f291dd5a58ee12146", "type": "github" }, "original": { - "owner": "nix-community", - "repo": "nix-github-actions", + "owner": "LnL7", + "repo": "nix-darwin", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1750134718, - "narHash": "sha256-v263g4GbxXv87hMXMCpjkIxd/viIF7p3JpJrwgKdNiI=", + "lastModified": 1775763530, + "narHash": "sha256-BuTK9z1QEwWPOIakQ1gCN4pa4VwVJpfptYCviy2uOGc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9e83b64f727c88a7711a2c463a7b16eedb69a84c", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1773628058, - "narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df", + "rev": "b0188973b4b2a5b6bdba8b65381d6cd09a533da0", "type": "github" }, "original": { @@ -169,25 +58,9 @@ }, "root": { "inputs": { - "deployment": "deployment", "home-manager": "home-manager", - "nixpkgs": "nixpkgs_2" - } - }, - "stable": { - "locked": { - "lastModified": 1750133334, - "narHash": "sha256-urV51uWH7fVnhIvsZIELIYalMYsyr2FCalvlRTzqWRw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "36ab78dab7da2e4e27911007033713bab534187b", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.05", - "repo": "nixpkgs", - "type": "github" + "nix-darwin": "nix-darwin", + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index f0430a4..c6c29ef 100644 --- a/flake.nix +++ b/flake.nix @@ -1,14 +1,16 @@ { - description = "NodeiWest employee and workstation flake"; + description = "NodeiWest company Nix SDK"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; - deployment = { - url = "git+file:../nix-deployment"; + + nix-darwin = { + url = "github:LnL7/nix-darwin"; inputs.nixpkgs.follows = "nixpkgs"; }; }; @@ -17,33 +19,116 @@ inputs@{ self, nixpkgs, - deployment, ... }: let lib = nixpkgs.lib; - supportedSystems = [ - "aarch64-darwin" - "x86_64-darwin" - "x86_64-linux" - ]; - forAllSystems = lib.genAttrs supportedSystems; + defaults = import ./lib/defaults.nix { inherit lib; }; + inherit (defaults) forAllSystems supportedSystems; + + shellFactories = { + default = args: import ./shells/default.nix args; + node = args: import ./shells/node.nix (args // { inherit lib; }); + go = args: import ./shells/go.nix args; + rust = args: import ./shells/rust.nix (args // { inherit lib; }); + }; + + profileModules = { + backend = import ./profiles/backend.nix; + frontend = import ./profiles/frontend.nix; + minimal = import ./profiles/minimal.nix; + }; + + darwinSystem = args: import ./systems/darwin/default.nix ({ inherit inputs; } // args); + linuxHome = args: import ./systems/linux/default.nix ({ inherit inputs; } // args); in { - homeManagerModules.default = ./modules/home.nix; - homeManagerModules.helpers = ./modules/helpers/home.nix; - - packages = forAllSystems (system: { - nodeiwest-helper = deployment.packages.${system}.nodeiwest-helper; - default = self.packages.${system}.nodeiwest-helper; - }); - - apps = forAllSystems (system: { - nodeiwest-helper = { - type = "app"; - program = "${self.packages.${system}.nodeiwest-helper}/bin/nodeiwest"; + lib = { + inherit (defaults) companySessionVariables forAllSystems supportedSystems; + mkProfile = import ./lib/mkProfile.nix; + mkSystem = import ./lib/mkSystem.nix { + systems = { + darwin = darwinSystem; + linux = linuxHome; + }; }; - default = self.apps.${system}.nodeiwest-helper; - }); + shells = shellFactories; + systems = { + darwin = darwinSystem; + linux = linuxHome; + }; + }; + + homeManagerModules = { + base = { + nix = import ./modules/base/nix.nix; + core = import ./modules/base/core.nix; + shell = import ./modules/base/shell.nix; + fonts = import ./modules/base/fonts.nix; + }; + + dev = { + node = import ./modules/dev/node.nix; + go = import ./modules/dev/go.nix; + rust = import ./modules/dev/rust.nix; + docker = import ./modules/dev/docker.nix; + }; + + roles = { + backend = import ./modules/roles/backend.nix; + frontend = import ./modules/roles/frontend.nix; + infra = import ./modules/roles/infra.nix; + minimal = import ./modules/roles/minimal.nix; + }; + + services = { + tailscale = import ./modules/services/tailscale.nix; + ssh = import ./modules/services/ssh.nix; + gpg = import ./modules/services/gpg.nix; + }; + + secrets = { + env = import ./modules/secrets/env.nix; + openbao = import ./modules/secrets/openbao.nix; + }; + + optional = { + homebrew = import ./modules/optional/homebrew.nix; + gui = import ./modules/optional/gui.nix; + devtools = import ./modules/optional/devtools.nix; + }; + + profiles = profileModules; + + default = import ./modules/home.nix; + }; + + devShells = forAllSystems ( + system: + let + pkgs = import nixpkgs { inherit system; }; + in + { + default = shellFactories.default { inherit pkgs; }; + node = shellFactories.node { inherit pkgs; }; + go = shellFactories.go { inherit pkgs; }; + rust = shellFactories.rust { inherit pkgs; }; + } + ); + + formatter = forAllSystems ( + system: + let + pkgs = import nixpkgs { inherit system; }; + in + pkgs.nixfmt + ); + + templates = { + user-flake = { + path = ./templates/user-flake; + description = "Starter personal flake wired to NodeiWest profiles."; + }; + }; }; } diff --git a/lib/defaults.nix b/lib/defaults.nix new file mode 100644 index 0000000..2ca8e22 --- /dev/null +++ b/lib/defaults.nix @@ -0,0 +1,20 @@ +{ lib }: +let + supportedSystems = [ + "aarch64-darwin" + "x86_64-darwin" + "x86_64-linux" + ]; +in +{ + inherit supportedSystems; + + forAllSystems = f: lib.genAttrs supportedSystems f; + + companySessionVariables = { + BAO_ADDR = "https://secrets.api.nodeiwest.se"; + SOME_REGISTRY = "git.dgren.dev"; + }; + + stateVersion = "24.11"; +} diff --git a/lib/mkProfile.nix b/lib/mkProfile.nix new file mode 100644 index 0000000..358c87b --- /dev/null +++ b/lib/mkProfile.nix @@ -0,0 +1,7 @@ +{ + modules ? [ ], + extraModules ? [ ], +}: +{ + imports = modules ++ extraModules; +} diff --git a/lib/mkSystem.nix b/lib/mkSystem.nix new file mode 100644 index 0000000..c0759c9 --- /dev/null +++ b/lib/mkSystem.nix @@ -0,0 +1,15 @@ +{ systems }: +{ + target, + ... +}@args: +let + adapter = + if target == "darwin" then + systems.darwin + else if target == "linux" then + systems.linux + else + throw "Unsupported target `${target}`. Expected `darwin` or `linux`."; +in +adapter (builtins.removeAttrs args [ "target" ]) diff --git a/modules/base/core.nix b/modules/base/core.nix new file mode 100644 index 0000000..6238849 --- /dev/null +++ b/modules/base/core.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, ... }: +{ + home.packages = with pkgs; [ + age + curl + fd + git + jq + just + ripgrep + sops + ]; + + programs.git = { + enable = true; + lfs.enable = true; + signing.format = lib.mkDefault "openpgp"; + }; +} diff --git a/modules/base/fonts.nix b/modules/base/fonts.nix new file mode 100644 index 0000000..4ac7030 --- /dev/null +++ b/modules/base/fonts.nix @@ -0,0 +1,11 @@ +{ lib, pkgs, ... }: +let + jetbrainsMono = lib.attrByPath [ "nerd-fonts" "jetbrains-mono" ] null pkgs; +in +{ + fonts.fontconfig.enable = pkgs.stdenv.isLinux; + + home.packages = builtins.filter (pkg: pkg != null) [ + jetbrainsMono + ]; +} diff --git a/modules/base/nix.nix b/modules/base/nix.nix new file mode 100644 index 0000000..23fac5b --- /dev/null +++ b/modules/base/nix.nix @@ -0,0 +1,14 @@ +{ lib, pkgs, ... }: +{ + programs.home-manager.enable = true; + + nix.package = lib.mkDefault pkgs.nix; + + nix.settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + warn-dirty = false; + }; +} diff --git a/modules/base/shell.nix b/modules/base/shell.nix new file mode 100644 index 0000000..48e8533 --- /dev/null +++ b/modules/base/shell.nix @@ -0,0 +1,20 @@ +{ ... }: +{ + programs.bash.enable = true; + + programs.zsh = { + enable = true; + autocd = true; + enableCompletion = true; + shellAliases = { + l = "ls -CF"; + la = "ls -A"; + ll = "ls -alF"; + }; + }; + + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; +} diff --git a/modules/dev/docker.nix b/modules/dev/docker.nix new file mode 100644 index 0000000..0577146 --- /dev/null +++ b/modules/dev/docker.nix @@ -0,0 +1,16 @@ +{ lib, pkgs, ... }: +let + optionalPackage = path: lib.attrByPath path null pkgs; +in +{ + home.packages = builtins.filter (pkg: pkg != null) ( + [ + (optionalPackage [ "docker-client" ]) + (optionalPackage [ "docker-compose" ]) + (optionalPackage [ "lazydocker" ]) + ] + ++ lib.optionals pkgs.stdenv.isDarwin [ + (optionalPackage [ "colima" ]) + ] + ); +} diff --git a/modules/dev/go.nix b/modules/dev/go.nix new file mode 100644 index 0000000..486a105 --- /dev/null +++ b/modules/dev/go.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + go + gopls + ]; +} diff --git a/modules/dev/node.nix b/modules/dev/node.nix new file mode 100644 index 0000000..081931d --- /dev/null +++ b/modules/dev/node.nix @@ -0,0 +1,10 @@ +{ lib, pkgs, ... }: +let + nodejs = lib.attrByPath [ "nodejs_20" ] pkgs.nodejs pkgs; +in +{ + home.packages = [ + nodejs + pkgs.pnpm + ]; +} diff --git a/modules/dev/rust.nix b/modules/dev/rust.nix new file mode 100644 index 0000000..2c42acb --- /dev/null +++ b/modules/dev/rust.nix @@ -0,0 +1,13 @@ +{ lib, pkgs, ... }: +let + optionalPackage = path: lib.attrByPath path null pkgs; +in +{ + home.packages = builtins.filter (pkg: pkg != null) [ + pkgs.cargo + pkgs.rustc + (optionalPackage [ "rust-analyzer" ]) + (optionalPackage [ "rustfmt" ]) + (optionalPackage [ "clippy" ]) + ]; +} diff --git a/modules/helpers/home.nix b/modules/helpers/home.nix deleted file mode 100644 index 760161a..0000000 --- a/modules/helpers/home.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ pkgs, deployment, ... }: -{ - home.packages = [ - deployment.packages.${pkgs.system}.nodeiwest-helper - ]; -} diff --git a/modules/home.nix b/modules/home.nix index d388605..3654a89 100644 --- a/modules/home.nix +++ b/modules/home.nix @@ -1,19 +1,9 @@ -{ pkgs, lib, ... }: +{ pkgs, ... }: { - imports = [ ./helpers/home.nix ]; - - # Company env vars — available in all shells - home.sessionVariables = { - BAO_ADDR = "https://secrets.api.nodeiwest.se"; - SOME_REGISTRY = "git.dgren.dev"; - # etc. - }; - - home.packages = with pkgs; [ - # Tools every dev needs - openbao - colmena - # etc. - sops + imports = [ + ../profiles/minimal.nix + ./secrets/openbao.nix ]; + + home.packages = [ pkgs.colmena ]; } diff --git a/modules/optional/devtools.nix b/modules/optional/devtools.nix new file mode 100644 index 0000000..6b40594 --- /dev/null +++ b/modules/optional/devtools.nix @@ -0,0 +1,11 @@ +{ lib, pkgs, ... }: +let + optionalPackage = path: lib.attrByPath path null pkgs; +in +{ + home.packages = builtins.filter (pkg: pkg != null) [ + (optionalPackage [ "nil" ]) + (optionalPackage [ "nixd" ]) + (optionalPackage [ "nixfmt" ]) + ]; +} diff --git a/modules/optional/gui.nix b/modules/optional/gui.nix new file mode 100644 index 0000000..ab449eb --- /dev/null +++ b/modules/optional/gui.nix @@ -0,0 +1,9 @@ +{ lib, pkgs, ... }: +let + wezterm = lib.attrByPath [ "wezterm" ] null pkgs; +in +{ + home.packages = builtins.filter (pkg: pkg != null) [ + wezterm + ]; +} diff --git a/modules/optional/homebrew.nix b/modules/optional/homebrew.nix new file mode 100644 index 0000000..0449b43 --- /dev/null +++ b/modules/optional/homebrew.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + # Intentionally empty. This is the seam downstream workstations can use to + # compose nix-homebrew or Homebrew-specific activation without coupling it + # into the shared base roles. +} diff --git a/modules/roles/backend.nix b/modules/roles/backend.nix new file mode 100644 index 0000000..f8bde06 --- /dev/null +++ b/modules/roles/backend.nix @@ -0,0 +1,13 @@ +{ ... }: +{ + imports = [ + ./minimal.nix + ../dev/node.nix + ../dev/go.nix + ../dev/docker.nix + ../services/ssh.nix + ../services/gpg.nix + ../secrets/openbao.nix + ../optional/devtools.nix + ]; +} diff --git a/modules/roles/frontend.nix b/modules/roles/frontend.nix new file mode 100644 index 0000000..570f59f --- /dev/null +++ b/modules/roles/frontend.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + imports = [ + ./minimal.nix + ../base/fonts.nix + ../dev/node.nix + ../services/gpg.nix + ../optional/devtools.nix + ../optional/gui.nix + ]; +} diff --git a/modules/roles/infra.nix b/modules/roles/infra.nix new file mode 100644 index 0000000..5ef4c00 --- /dev/null +++ b/modules/roles/infra.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + imports = [ + ./minimal.nix + ../dev/go.nix + ../dev/docker.nix + ../services/ssh.nix + ../services/tailscale.nix + ../services/gpg.nix + ../secrets/openbao.nix + ../optional/devtools.nix + ]; + + home.packages = [ pkgs.colmena ]; +} diff --git a/modules/roles/minimal.nix b/modules/roles/minimal.nix new file mode 100644 index 0000000..dda46f2 --- /dev/null +++ b/modules/roles/minimal.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + imports = [ + ../base/nix.nix + ../base/core.nix + ../base/shell.nix + ../secrets/env.nix + ]; +} diff --git a/modules/secrets/env.nix b/modules/secrets/env.nix new file mode 100644 index 0000000..86b8cc4 --- /dev/null +++ b/modules/secrets/env.nix @@ -0,0 +1,7 @@ +{ lib, ... }: +let + defaults = import ../../lib/defaults.nix { inherit lib; }; +in +{ + home.sessionVariables = defaults.companySessionVariables; +} diff --git a/modules/secrets/openbao.nix b/modules/secrets/openbao.nix new file mode 100644 index 0000000..061489a --- /dev/null +++ b/modules/secrets/openbao.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + imports = [ ./env.nix ]; + + home.packages = [ pkgs.openbao ]; +} diff --git a/modules/services/gpg.nix b/modules/services/gpg.nix new file mode 100644 index 0000000..615b51e --- /dev/null +++ b/modules/services/gpg.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + programs.gpg.enable = true; + + services.gpg-agent = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + pinentry.package = pkgs.pinentry-curses; + }; +} diff --git a/modules/services/ssh.nix b/modules/services/ssh.nix new file mode 100644 index 0000000..a6de5d6 --- /dev/null +++ b/modules/services/ssh.nix @@ -0,0 +1,22 @@ +{ lib, ... }: +{ + programs.ssh = { + enable = true; + enableDefaultConfig = false; + + matchBlocks."*" = { + addKeysToAgent = lib.mkDefault "yes"; + compression = lib.mkDefault false; + controlMaster = lib.mkDefault "no"; + controlPath = lib.mkDefault "~/.ssh/master-%r@%n:%p"; + controlPersist = lib.mkDefault "no"; + forwardAgent = lib.mkDefault true; + hashKnownHosts = lib.mkDefault false; + serverAliveCountMax = lib.mkDefault 3; + serverAliveInterval = lib.mkDefault 0; + userKnownHostsFile = lib.mkDefault "~/.ssh/known_hosts"; + }; + }; + + services.ssh-agent.enable = true; +} diff --git a/modules/services/tailscale.nix b/modules/services/tailscale.nix new file mode 100644 index 0000000..b0b1243 --- /dev/null +++ b/modules/services/tailscale.nix @@ -0,0 +1,9 @@ +{ lib, pkgs, ... }: +let + tailscale = lib.attrByPath [ "tailscale" ] null pkgs; +in +{ + home.packages = builtins.filter (pkg: pkg != null) [ + tailscale + ]; +} diff --git a/pkgs/helpers/tests/__pycache__/test_cli.cpython-313.pyc b/pkgs/helpers/tests/__pycache__/test_cli.cpython-313.pyc deleted file mode 100644 index 10427fe13d9ef7fbda709a7a8d8b396f180cb1bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10366 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