feat: Add templates for external configs
This commit is contained in:
committed by
Hunter Halloran
parent
f658a4a5cc
commit
11edaada84
@@ -38,18 +38,31 @@ let
|
||||
system ? "x86_64-linux",
|
||||
hostType,
|
||||
configOverrides ? { },
|
||||
externalModulePath ? null,
|
||||
}:
|
||||
let
|
||||
# Load users.nix to find external user flakes
|
||||
# Load users.nix to find external user modules
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
usersData = import ../users.nix { inherit pkgs; };
|
||||
accounts = usersData.ugaif.users or { };
|
||||
|
||||
# Extract flakeUrls and convert to modules
|
||||
userFlakeModules = lib.mapAttrsToList (
|
||||
# Extract external user NixOS modules (if they exist)
|
||||
# External user modules can optionally provide a nixos.nix file for system-level config
|
||||
userNixosModules = lib.mapAttrsToList (
|
||||
name: user:
|
||||
if (user ? flakeUrl && user.flakeUrl != "") then
|
||||
(builtins.getFlake user.flakeUrl).nixosModules.default
|
||||
if (user ? home && user.home != null) then
|
||||
let
|
||||
homePath =
|
||||
if builtins.isAttrs user.home && user.home ? outPath then
|
||||
user.home.outPath
|
||||
else
|
||||
user.home;
|
||||
nixosModulePath = homePath + "/nixos.nix";
|
||||
in
|
||||
if (builtins.isPath homePath || (builtins.isString homePath && lib.hasPrefix "/" homePath)) && builtins.pathExists nixosModulePath then
|
||||
import nixosModulePath { inherit inputs; }
|
||||
else
|
||||
{ }
|
||||
else
|
||||
{ }
|
||||
) accounts;
|
||||
@@ -69,6 +82,13 @@ let
|
||||
else
|
||||
{ };
|
||||
|
||||
# External module from fetchGit/fetchurl
|
||||
externalPathModule =
|
||||
if externalModulePath != null then
|
||||
import externalModulePath { inherit inputs; }
|
||||
else
|
||||
{ };
|
||||
|
||||
# Config override module - translate special keys to ugaif options
|
||||
overrideModule =
|
||||
{ ... }:
|
||||
@@ -108,13 +128,14 @@ let
|
||||
};
|
||||
|
||||
allModules =
|
||||
userFlakeModules
|
||||
userNixosModules
|
||||
++ [
|
||||
typeModule
|
||||
overrideModule
|
||||
{ networking.hostName = hostName; }
|
||||
]
|
||||
++ lib.optional (configOverrides ? flakeUrl) externalFlakeModule;
|
||||
++ lib.optional (configOverrides ? flakeUrl) externalFlakeModule
|
||||
++ lib.optional (externalModulePath != null) externalPathModule;
|
||||
in
|
||||
{
|
||||
system = lib.nixosSystem {
|
||||
@@ -170,16 +191,52 @@ let
|
||||
lib.mapAttrsToList (
|
||||
deviceKey: deviceConfig:
|
||||
let
|
||||
# Merge: base config -> overrides -> device-specific config
|
||||
mergedConfig = lib.recursiveUpdate (lib.recursiveUpdate baseConfig overrides) deviceConfig;
|
||||
# Check if deviceConfig is a path/derivation (from fetchGit, fetchurl, etc.)
|
||||
# fetchGit/fetchTarball return an attrset with outPath attribute
|
||||
isExternalModule =
|
||||
(builtins.isPath deviceConfig)
|
||||
|| (builtins.isString deviceConfig && lib.hasPrefix "/" deviceConfig)
|
||||
|| (lib.isDerivation deviceConfig)
|
||||
|| (builtins.isAttrs deviceConfig && deviceConfig ? outPath);
|
||||
|
||||
# Extract the actual path from fetchGit/fetchTarball results
|
||||
extractedPath =
|
||||
if builtins.isAttrs deviceConfig && deviceConfig ? outPath then
|
||||
deviceConfig.outPath
|
||||
else
|
||||
deviceConfig;
|
||||
|
||||
# If external module, we use base config + overrides as the config
|
||||
# and pass the module path separately
|
||||
actualConfig = if isExternalModule then (lib.recursiveUpdate baseConfig overrides) else deviceConfig;
|
||||
|
||||
# Merge: base config -> overrides -> device-specific config (only if not external module)
|
||||
mergedConfig =
|
||||
if isExternalModule then
|
||||
actualConfig
|
||||
else
|
||||
lib.recursiveUpdate (lib.recursiveUpdate baseConfig overrides) deviceConfig;
|
||||
|
||||
# Check useHostPrefix from the merged config
|
||||
usePrefix = mergedConfig.ugaif.host.useHostPrefix or true;
|
||||
hostName = mkHostName prefix deviceKey usePrefix;
|
||||
|
||||
# If external module, also add a default.nix path for import
|
||||
externalModulePath =
|
||||
if isExternalModule then
|
||||
if builtins.isPath extractedPath then
|
||||
extractedPath + "/default.nix"
|
||||
else if lib.isDerivation extractedPath then
|
||||
extractedPath + "/default.nix"
|
||||
else
|
||||
extractedPath + "/default.nix"
|
||||
else
|
||||
null;
|
||||
in
|
||||
{
|
||||
name = hostName;
|
||||
value = mkHost {
|
||||
inherit hostName system hostType;
|
||||
inherit hostName system hostType externalModulePath;
|
||||
configOverrides = mergedConfig;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -49,10 +49,16 @@ let
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [ ];
|
||||
};
|
||||
flakeUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "URL of a flake to import Home Manager configuration from (e.g. github:user/dotfiles).";
|
||||
home = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.oneOf [ lib.types.path lib.types.package lib.types.attrs ]);
|
||||
default = null;
|
||||
description = ''
|
||||
External home-manager configuration. Can be:
|
||||
- A path to a local module
|
||||
- A fetchGit/fetchTarball result pointing to a repository
|
||||
- An attribute set with home-manager configuration
|
||||
Example: builtins.fetchGit { url = "https://github.com/user/dotfiles"; rev = "..."; }
|
||||
'';
|
||||
};
|
||||
opensshKeys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
@@ -138,18 +144,37 @@ in
|
||||
name: user:
|
||||
{ ... }:
|
||||
let
|
||||
isExternal = user.flakeUrl != "";
|
||||
# Check if user has external home configuration
|
||||
hasExternalHome = user.home != null;
|
||||
|
||||
# Extract path from fetchGit/fetchTarball if needed
|
||||
externalHomePath =
|
||||
if hasExternalHome then
|
||||
if builtins.isAttrs user.home && user.home ? outPath then
|
||||
user.home.outPath
|
||||
else
|
||||
user.home
|
||||
else
|
||||
null;
|
||||
|
||||
# Import external module if it's a path
|
||||
externalHomeModule =
|
||||
if externalHomePath != null && (builtins.isPath externalHomePath || (builtins.isString externalHomePath && lib.hasPrefix "/" externalHomePath)) then
|
||||
import (externalHomePath + "/home.nix") { inherit inputs; }
|
||||
else if builtins.isAttrs user.home && !(user.home ? outPath) then
|
||||
user.home # Direct attrset configuration
|
||||
else
|
||||
{ };
|
||||
|
||||
# Common imports based on flags
|
||||
commonImports = lib.optional user.useZshTheme ../sw/theme.nix ++ [
|
||||
(import ../sw/nvim.nix { inherit user; })
|
||||
];
|
||||
in
|
||||
if isExternal then
|
||||
if hasExternalHome then
|
||||
{
|
||||
# External users: Only apply requested system modules.
|
||||
# The external flake is responsible for home.username, home.packages, etc.
|
||||
imports = commonImports;
|
||||
# External users: Merge external config with common imports
|
||||
imports = commonImports ++ [ externalHomeModule ];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user