refactor(nix): auto-load flake-modules + extract shared dotfiles-rebuild 🌳

- Add import-tree input; flake.nix now auto-loads every file under
  ./flake-modules so new hosts/features drop in without editing flake.nix.
- Extract the duplicated dotfiles-rebuild service, timer, and
  safe.directory wiring into nixos/modules/dotfiles-rebuild.nix, exposed
  via flake.nixosModules.dotfiles-rebuild.
- sunken-ship and phantom-ship now pull it in from their flake-modules;
  hostname-specific flakeRef is derived from config.networking.hostName.
This commit is contained in:
DannyDannyDanny 2026-04-18 18:00:54 +02:00
parent 5e7b76bdcf
commit 975b2a3ee9
8 changed files with 80 additions and 81 deletions

View file

@ -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;
}

View file

@ -1,9 +1,10 @@
{ inputs, ... }: { { inputs, config, ... }: {
flake.nixosConfigurations.phantom-ship = inputs.nixpkgs.lib.nixosSystem { flake.nixosConfigurations.phantom-ship = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ modules = [
inputs.nix-openclaw.nixosModules.openclaw-gateway inputs.nix-openclaw.nixosModules.openclaw-gateway
../hosts/phantom-ship.nix ../hosts/phantom-ship.nix
config.flake.nixosModules.dotfiles-rebuild
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
(import ../lib/home-manager-user.nix { (import ../lib/home-manager-user.nix {

View file

@ -1,8 +1,9 @@
{ inputs, ... }: { { inputs, config, ... }: {
flake.nixosConfigurations.sunken-ship = inputs.nixpkgs.lib.nixosSystem { flake.nixosConfigurations.sunken-ship = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ modules = [
../hosts/sunken-ship.nix ../hosts/sunken-ship.nix
config.flake.nixosModules.dotfiles-rebuild
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
(import ../lib/home-manager-user.nix { (import ../lib/home-manager-user.nix {

16
nixos/flake.lock generated
View file

@ -154,6 +154,21 @@
"type": "github" "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": { "nix-darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -303,6 +318,7 @@
"disko": "disko", "disko": "disko",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"home-manager": "home-manager", "home-manager": "home-manager",
"import-tree": "import-tree",
"nix-darwin": "nix-darwin", "nix-darwin": "nix-darwin",
"nix-openclaw": "nix-openclaw", "nix-openclaw": "nix-openclaw",
"nixos-wsl": "nixos-wsl", "nixos-wsl": "nixos-wsl",

View file

@ -7,6 +7,9 @@
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; 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.url = "github:nix-darwin/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
@ -23,17 +26,9 @@
nix-openclaw.inputs.nixpkgs.follows = "nixpkgs"; nix-openclaw.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = inputs @ { flake-parts, ... }: outputs = inputs @ { flake-parts, import-tree, ... }:
flake-parts.lib.mkFlake { inherit inputs; } { flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-darwin" ]; systems = [ "x86_64-linux" "aarch64-darwin" ];
imports = [ (import-tree ./flake-modules) ];
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
];
}; };
} }

View file

@ -2,9 +2,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
dotfilesDir = "/etc/dotfiles";
flakeRef = "${dotfilesDir}/nixos#phantom-ship";
# Telegram user ID(s) — gitignored, not committed to public repo. # Telegram user ID(s) — gitignored, not committed to public repo.
# Create openclaw-allow-from.nix with e.g.: [ 12345678 ] # Create openclaw-allow-from.nix with e.g.: [ 12345678 ]
allowFromPath = ./openclaw-allow-from.nix; allowFromPath = ./openclaw-allow-from.nix;
@ -134,35 +131,6 @@ in
ReadWritePaths = [ "/var/lib/openclaw" "/etc/openclaw" ]; ReadWritePaths = [ "/var/lib/openclaw" "/etc/openclaw" ];
}; };
# Trust /etc/dotfiles as root even though it's owned by `danny`. # Auto-rebuild service/timer + safe.directory provided by the
# The GIT_CONFIG_* env vars below only affect the git CLI; nix/libgit2 # shared dotfiles-rebuild NixOS module (see nixos/modules/dotfiles-rebuild.nix).
# 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";
};
} }

View file

@ -7,10 +7,6 @@
# Timer runs every 15 min: git fetch, pull if origin/main changed, rebuild. # Timer runs every 15 min: git fetch, pull if origin/main changed, rebuild.
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let
dotfilesDir = "/etc/dotfiles";
flakeRef = "${dotfilesDir}/nixos#sunken-ship";
in
{ {
imports = [ ./sunken-ship-hardware.nix ]; imports = [ ./sunken-ship-hardware.nix ];
@ -185,35 +181,6 @@ in
timerConfig.RandomizedDelaySec = "2min"; timerConfig.RandomizedDelaySec = "2min";
}; };
# Trust /etc/dotfiles as root even though it's owned by `danny`. # Auto-rebuild service/timer + safe.directory provided by the
# The GIT_CONFIG_* env vars below only affect the git CLI; nix/libgit2 # shared dotfiles-rebuild NixOS module (see nixos/modules/dotfiles-rebuild.nix).
# 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";
};
} }

View file

@ -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 `<dotfilesDir>/nixos#<host>`.
#
# 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";
};
}