diff --git a/nixos/flake-modules/nixos-modules.nix b/nixos/flake-modules/nixos-modules.nix new file mode 100644 index 0000000..c982dd9 --- /dev/null +++ b/nixos/flake-modules/nixos-modules.nix @@ -0,0 +1,7 @@ +# Expose reusable NixOS modules via `flake.nixosModules`. +# +# Consume from a host's flake-module via: +# modules = [ config.flake.nixosModules.dotfiles-rebuild ]; +{ ... }: { + flake.nixosModules.dotfiles-rebuild = ../modules/dotfiles-rebuild.nix; +} diff --git a/nixos/flake-modules/phantom-ship.nix b/nixos/flake-modules/phantom-ship.nix index f77b454..9a1ebbc 100644 --- a/nixos/flake-modules/phantom-ship.nix +++ b/nixos/flake-modules/phantom-ship.nix @@ -1,9 +1,10 @@ -{ inputs, ... }: { +{ inputs, config, ... }: { flake.nixosConfigurations.phantom-ship = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ inputs.nix-openclaw.nixosModules.openclaw-gateway ../hosts/phantom-ship.nix + config.flake.nixosModules.dotfiles-rebuild inputs.home-manager.nixosModules.home-manager (import ../lib/home-manager-user.nix { diff --git a/nixos/flake-modules/sunken-ship.nix b/nixos/flake-modules/sunken-ship.nix index 402a126..0bf77ef 100644 --- a/nixos/flake-modules/sunken-ship.nix +++ b/nixos/flake-modules/sunken-ship.nix @@ -1,8 +1,9 @@ -{ inputs, ... }: { +{ inputs, config, ... }: { flake.nixosConfigurations.sunken-ship = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ ../hosts/sunken-ship.nix + config.flake.nixosModules.dotfiles-rebuild inputs.home-manager.nixosModules.home-manager (import ../lib/home-manager-user.nix { diff --git a/nixos/flake.lock b/nixos/flake.lock index f185299..e2ee1ce 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -154,6 +154,21 @@ "type": "github" } }, + "import-tree": { + "locked": { + "lastModified": 1773693634, + "narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=", + "owner": "vic", + "repo": "import-tree", + "rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, "nix-darwin": { "inputs": { "nixpkgs": [ @@ -303,6 +318,7 @@ "disko": "disko", "flake-parts": "flake-parts", "home-manager": "home-manager", + "import-tree": "import-tree", "nix-darwin": "nix-darwin", "nix-openclaw": "nix-openclaw", "nixos-wsl": "nixos-wsl", diff --git a/nixos/flake.nix b/nixos/flake.nix index c9ab314..c465290 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -7,6 +7,9 @@ flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; + # Auto-loads every .nix file under ./flake-modules as a flake-parts module. + import-tree.url = "github:vic/import-tree"; + nix-darwin.url = "github:nix-darwin/nix-darwin/master"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; @@ -23,17 +26,9 @@ nix-openclaw.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = inputs @ { flake-parts, ... }: + outputs = inputs @ { flake-parts, import-tree, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "aarch64-darwin" ]; - - imports = [ - ./flake-modules/wsl.nix - ./flake-modules/sunken-ship.nix - ./flake-modules/phantom-ship.nix - ./flake-modules/daniel-macbook-air.nix - ./flake-modules/server-install.nix - ./flake-modules/installer-iso.nix - ]; + imports = [ (import-tree ./flake-modules) ]; }; } diff --git a/nixos/hosts/phantom-ship.nix b/nixos/hosts/phantom-ship.nix index 587ecee..4ebc6c4 100644 --- a/nixos/hosts/phantom-ship.nix +++ b/nixos/hosts/phantom-ship.nix @@ -2,9 +2,6 @@ { config, lib, pkgs, ... }: let - dotfilesDir = "/etc/dotfiles"; - flakeRef = "${dotfilesDir}/nixos#phantom-ship"; - # Telegram user ID(s) — gitignored, not committed to public repo. # Create openclaw-allow-from.nix with e.g.: [ 12345678 ] allowFromPath = ./openclaw-allow-from.nix; @@ -134,35 +131,6 @@ in ReadWritePaths = [ "/var/lib/openclaw" "/etc/openclaw" ]; }; - # Trust /etc/dotfiles as root even though it's owned by `danny`. - # The GIT_CONFIG_* env vars below only affect the git CLI; nix/libgit2 - # reads safe.directory from /etc/gitconfig, so set it there too. - programs.git.enable = true; - programs.git.config.safe.directory = [ dotfilesDir ]; - - # Pull dotfiles and rebuild if the repo has new commits. - systemd.services.dotfiles-rebuild = { - description = "Pull dotfiles and run nixos-rebuild if repo changed"; - path = with pkgs; [ git nix nixos-rebuild ]; - environment.GIT_CONFIG_COUNT = "1"; - environment.GIT_CONFIG_KEY_0 = "safe.directory"; - environment.GIT_CONFIG_VALUE_0 = dotfilesDir; - script = '' - set -euo pipefail - cd ${dotfilesDir} - git fetch origin - if [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ]; then - exit 0 - fi - git pull origin main - exec nixos-rebuild switch --flake ${flakeRef} - ''; - serviceConfig.Type = "oneshot"; - }; - - systemd.timers.dotfiles-rebuild = { - wantedBy = [ "timers.target" ]; - timerConfig.OnCalendar = "*-*-* *:00/15:00"; # every 15 minutes - timerConfig.RandomizedDelaySec = "2min"; - }; + # Auto-rebuild service/timer + safe.directory provided by the + # shared dotfiles-rebuild NixOS module (see nixos/modules/dotfiles-rebuild.nix). } diff --git a/nixos/hosts/sunken-ship.nix b/nixos/hosts/sunken-ship.nix index 41c461b..2e8175c 100644 --- a/nixos/hosts/sunken-ship.nix +++ b/nixos/hosts/sunken-ship.nix @@ -7,10 +7,6 @@ # Timer runs every 15 min: git fetch, pull if origin/main changed, rebuild. { config, lib, pkgs, ... }: -let - dotfilesDir = "/etc/dotfiles"; - flakeRef = "${dotfilesDir}/nixos#sunken-ship"; -in { imports = [ ./sunken-ship-hardware.nix ]; @@ -185,35 +181,6 @@ in timerConfig.RandomizedDelaySec = "2min"; }; - # Trust /etc/dotfiles as root even though it's owned by `danny`. - # The GIT_CONFIG_* env vars below only affect the git CLI; nix/libgit2 - # reads safe.directory from /etc/gitconfig, so set it there too. - programs.git.enable = true; - programs.git.config.safe.directory = [ dotfilesDir ]; - - # Pull dotfiles and rebuild if the repo has new commits. - systemd.services.dotfiles-rebuild = { - description = "Pull dotfiles and run nixos-rebuild if repo changed"; - path = with pkgs; [ git nix nixos-rebuild ]; - environment.GIT_CONFIG_COUNT = "1"; - environment.GIT_CONFIG_KEY_0 = "safe.directory"; - environment.GIT_CONFIG_VALUE_0 = dotfilesDir; - script = '' - set -euo pipefail - cd ${dotfilesDir} - git fetch origin - if [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ]; then - exit 0 - fi - git pull origin main - exec nixos-rebuild switch --flake ${flakeRef} - ''; - serviceConfig.Type = "oneshot"; - }; - - systemd.timers.dotfiles-rebuild = { - wantedBy = [ "timers.target" ]; - timerConfig.OnCalendar = "*-*-* *:00/15:00"; # every 15 minutes - timerConfig.RandomizedDelaySec = "2min"; - }; + # Auto-rebuild service/timer + safe.directory provided by the + # shared dotfiles-rebuild NixOS module (see nixos/modules/dotfiles-rebuild.nix). } diff --git a/nixos/modules/dotfiles-rebuild.nix b/nixos/modules/dotfiles-rebuild.nix new file mode 100644 index 0000000..709ebaf --- /dev/null +++ b/nixos/modules/dotfiles-rebuild.nix @@ -0,0 +1,44 @@ +# Shared auto-rebuild-from-git service for homelab hosts. +# +# Every 15 min: git fetch origin, fast-forward main, and if there were any +# new commits run nixos-rebuild switch against `/nixos#`. +# +# Assumes /etc/dotfiles is an already-cloned checkout of the dotfiles repo. +{ config, lib, pkgs, ... }: +let + dotfilesDir = "/etc/dotfiles"; + flakeRef = "${dotfilesDir}/nixos#${config.networking.hostName}"; +in { + environment.systemPackages = [ pkgs.git ]; + + # Trust /etc/dotfiles as root even though it's owned by `danny`. + # nix/libgit2 reads safe.directory from /etc/gitconfig; the GIT_CONFIG_* + # env vars on the service only affect the git CLI, not nix. + programs.git.enable = true; + programs.git.config.safe.directory = [ dotfilesDir ]; + + systemd.services.dotfiles-rebuild = { + description = "Pull dotfiles and run nixos-rebuild if repo changed"; + path = with pkgs; [ git nix nixos-rebuild ]; + environment.GIT_CONFIG_COUNT = "1"; + environment.GIT_CONFIG_KEY_0 = "safe.directory"; + environment.GIT_CONFIG_VALUE_0 = dotfilesDir; + script = '' + set -euo pipefail + cd ${dotfilesDir} + git fetch origin + if [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ]; then + exit 0 + fi + git pull origin main + exec nixos-rebuild switch --flake ${flakeRef} + ''; + serviceConfig.Type = "oneshot"; + }; + + systemd.timers.dotfiles-rebuild = { + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = "*-*-* *:00/15:00"; # every 15 minutes + timerConfig.RandomizedDelaySec = "2min"; + }; +}