Merge pull request 'fix: Lazily fetch external modules only if needed' (#32) from external-refactor into main
All checks were successful
CI / Format Check (push) Successful in 2s
CI / Flake Check (push) Successful in 1m45s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 11s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 7s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 8s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 18s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 12s
CI / Build and Publish Documentation (push) Successful in 8s
All checks were successful
CI / Format Check (push) Successful in 2s
CI / Flake Check (push) Successful in 1m45s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 11s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 7s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 8s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 18s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 12s
CI / Build and Publish Documentation (push) Successful in 8s
Reviewed-on: #32
This commit was merged in pull request #32.
This commit is contained in:
@@ -36,8 +36,20 @@ let
|
|||||||
externalModulePath =
|
externalModulePath =
|
||||||
if externalModuleThunk != null then
|
if externalModuleThunk != null then
|
||||||
let
|
let
|
||||||
# Force evaluation of the thunk (fetchGit, fetchTarball, etc.)
|
# Force evaluation of the thunk
|
||||||
fetchedPath = externalModuleThunk;
|
fetchedPath =
|
||||||
|
if
|
||||||
|
builtins.isAttrs externalModuleThunk
|
||||||
|
&& externalModuleThunk ? _type
|
||||||
|
&& externalModuleThunk._type == "lazy-fetchGit"
|
||||||
|
then
|
||||||
|
# New format: lazy fetchGit - only execute when needed
|
||||||
|
(builtins.fetchGit {
|
||||||
|
inherit (externalModuleThunk) url rev submodules;
|
||||||
|
}).outPath
|
||||||
|
else
|
||||||
|
# Legacy: pre-fetched derivation or path
|
||||||
|
externalModuleThunk;
|
||||||
# Extract outPath from fetchGit/fetchTarball results
|
# Extract outPath from fetchGit/fetchTarball results
|
||||||
extractedPath =
|
extractedPath =
|
||||||
if builtins.isAttrs fetchedPath && fetchedPath ? outPath then fetchedPath.outPath else fetchedPath;
|
if builtins.isAttrs fetchedPath && fetchedPath ? outPath then fetchedPath.outPath else fetchedPath;
|
||||||
@@ -61,10 +73,19 @@ let
|
|||||||
name: user:
|
name: user:
|
||||||
if (user ? external && user.external != null) then
|
if (user ? external && user.external != null) then
|
||||||
let
|
let
|
||||||
|
# Resolve external path (lazy fetchGit if needed)
|
||||||
externalPath =
|
externalPath =
|
||||||
if builtins.isAttrs user.external && user.external ? outPath then
|
if builtins.isAttrs user.external && user.external ? url && user.external ? rev then
|
||||||
|
# New format: lazy fetchGit
|
||||||
|
(builtins.fetchGit {
|
||||||
|
inherit (user.external) url rev;
|
||||||
|
submodules = user.external.submodules or false;
|
||||||
|
}).outPath
|
||||||
|
else if builtins.isAttrs user.external && user.external ? outPath then
|
||||||
|
# Legacy: pre-fetched
|
||||||
user.external.outPath
|
user.external.outPath
|
||||||
else
|
else
|
||||||
|
# Direct path
|
||||||
user.external;
|
user.external;
|
||||||
nixosModulePath = externalPath + "/nixos.nix";
|
nixosModulePath = externalPath + "/nixos.nix";
|
||||||
in
|
in
|
||||||
@@ -205,8 +226,24 @@ let
|
|||||||
# Check if deviceConfig has an 'external' field for lazy evaluation
|
# Check if deviceConfig has an 'external' field for lazy evaluation
|
||||||
hasExternalField = builtins.isAttrs deviceConfig && deviceConfig ? external;
|
hasExternalField = builtins.isAttrs deviceConfig && deviceConfig ? external;
|
||||||
|
|
||||||
# Extract external module thunk if present (don't evaluate yet!)
|
# Extract external module spec (don't evaluate fetchGit yet!)
|
||||||
externalModuleThunk = if hasExternalField then deviceConfig.external else null;
|
externalModuleThunk =
|
||||||
|
if hasExternalField then
|
||||||
|
let
|
||||||
|
ext = deviceConfig.external;
|
||||||
|
in
|
||||||
|
# New format: { url, rev, submodules? } - create lazy fetchGit thunk
|
||||||
|
if builtins.isAttrs ext && ext ? url && ext ? rev then
|
||||||
|
{
|
||||||
|
_type = "lazy-fetchGit";
|
||||||
|
inherit (ext) url rev;
|
||||||
|
submodules = ext.submodules or false;
|
||||||
|
}
|
||||||
|
# Legacy: pre-fetched or path
|
||||||
|
else
|
||||||
|
ext
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
# Remove 'external' from config to avoid conflicts
|
# Remove 'external' from config to avoid conflicts
|
||||||
cleanDeviceConfig =
|
cleanDeviceConfig =
|
||||||
|
|||||||
@@ -125,21 +125,45 @@ let
|
|||||||
type = lib.types.nullOr (
|
type = lib.types.nullOr (
|
||||||
lib.types.oneOf [
|
lib.types.oneOf [
|
||||||
lib.types.path
|
lib.types.path
|
||||||
lib.types.package
|
(lib.types.submodule {
|
||||||
lib.types.attrs
|
options = {
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Git repository URL to fetch user configuration from.";
|
||||||
|
example = "https://github.com/username/dotfiles";
|
||||||
|
};
|
||||||
|
rev = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Git commit hash, tag, or branch to fetch.";
|
||||||
|
example = "abc123def456...";
|
||||||
|
};
|
||||||
|
submodules = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to fetch Git submodules.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
External user configuration module from Git or local path.
|
External user configuration module from Git or local path.
|
||||||
|
|
||||||
|
Can be either:
|
||||||
|
- A local path: /path/to/config
|
||||||
|
- A Git repository: { url = "..."; rev = "..."; submodules? = false; }
|
||||||
|
|
||||||
|
The Git repository is only fetched when the user is actually enabled.
|
||||||
|
|
||||||
Should contain user.nix (user options + home-manager config)
|
Should contain user.nix (user options + home-manager config)
|
||||||
and optionally nixos.nix (system-level config).
|
and optionally nixos.nix (system-level config).
|
||||||
'';
|
'';
|
||||||
example = lib.literalExpression ''
|
example = lib.literalExpression ''
|
||||||
builtins.fetchGit {
|
{
|
||||||
url = "https://github.com/username/dotfiles";
|
url = "https://github.com/username/dotfiles";
|
||||||
rev = "abc123...";
|
rev = "abc123def456789abcdef0123456789abcdef012";
|
||||||
|
submodules = false;
|
||||||
}'';
|
}'';
|
||||||
};
|
};
|
||||||
opensshKeys = lib.mkOption {
|
opensshKeys = lib.mkOption {
|
||||||
|
|||||||
@@ -13,13 +13,21 @@
|
|||||||
# Options are defined in fleet-option.nix for early availability.
|
# Options are defined in fleet-option.nix for early availability.
|
||||||
|
|
||||||
let
|
let
|
||||||
# Helper: Resolve external module path from fetchGit/fetchTarball/path
|
# Helper: Resolve external module path (with lazy Git fetching)
|
||||||
resolveExternalPath =
|
resolveExternalPath =
|
||||||
external:
|
external:
|
||||||
if external == null then
|
if external == null then
|
||||||
null
|
null
|
||||||
|
# New format: { url, rev, submodules? } - only fetch when needed
|
||||||
|
else if builtins.isAttrs external && external ? url && external ? rev then
|
||||||
|
(builtins.fetchGit {
|
||||||
|
inherit (external) url rev;
|
||||||
|
submodules = external.submodules or false;
|
||||||
|
}).outPath
|
||||||
|
# Legacy: pre-fetched derivation/package
|
||||||
else if builtins.isAttrs external && external ? outPath then
|
else if builtins.isAttrs external && external ? outPath then
|
||||||
external.outPath
|
external.outPath
|
||||||
|
# Direct path
|
||||||
else
|
else
|
||||||
external;
|
external;
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
# External modules (instead of config):
|
# External modules (instead of config):
|
||||||
# Device values can be a config attrset with an optional 'external' field:
|
# Device values can be a config attrset with an optional 'external' field:
|
||||||
# devices."hostname" = {
|
# devices."hostname" = {
|
||||||
# external = builtins.fetchGit { ... }; # Lazy: only fetched when building this host
|
# external = { url = "..."; rev = "..."; submodules? = false; }; # Lazy: only fetched when building this host
|
||||||
# # ... additional config options
|
# # ... additional config options
|
||||||
# };
|
# };
|
||||||
# The external module will be imported and evaluated only when this specific host is built.
|
# The external module will be imported and evaluated only when this specific host is built.
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
# devices."alice".athenix.forUser = "alice123"; # Sets up for user alice123
|
# devices."alice".athenix.forUser = "alice123"; # Sets up for user alice123
|
||||||
# };
|
# };
|
||||||
# "external" = {
|
# "external" = {
|
||||||
# devices."remote".external = builtins.fetchGit { # External module via Git (lazy)
|
# devices."remote".external = { url = "..."; rev = "..."; }; # External module via Git (lazy)
|
||||||
# url = "https://github.com/example/config";
|
# url = "https://github.com/example/config";
|
||||||
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
# rev = "e1ccd7cc3e709afe4f50b0627e1c4bde49165014";
|
||||||
# };
|
# };
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"usda-dash".external = builtins.fetchGit {
|
"usda-dash".external = {
|
||||||
url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
|
url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
|
||||||
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
rev = "dab32f5884895cead0fae28cb7d88d17951d0c12";
|
||||||
submodules = true;
|
submodules = true;
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
options.athenix.sw = {
|
options.athenix.sw = {
|
||||||
# Software submodule for the Athenix system suite. sw.enable enables
|
|
||||||
# base packages and common configuration. Each sw.<type>.enable enables
|
|
||||||
# additional packages and services for that system type.
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@@ -57,8 +54,6 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
# DEPRECATED: Backwards compatibility for external modules
|
|
||||||
# Use athenix.sw.<type>.enable instead
|
|
||||||
type = lib.types.nullOr (lib.types.either lib.types.str (lib.types.listOf lib.types.str));
|
type = lib.types.nullOr (lib.types.either lib.types.str (lib.types.listOf lib.types.str));
|
||||||
default = null;
|
default = null;
|
||||||
description = "DEPRECATED: Use athenix.sw.<type>.enable instead. Legacy type selection.";
|
description = "DEPRECATED: Use athenix.sw.<type>.enable instead. Legacy type selection.";
|
||||||
@@ -66,7 +61,6 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
extraPackages = mkOption {
|
extraPackages = mkOption {
|
||||||
# Additional packages to install beyond the defaults
|
|
||||||
type = lib.types.listOf lib.types.package;
|
type = lib.types.listOf lib.types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
@@ -77,7 +71,6 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
excludePackages = mkOption {
|
excludePackages = mkOption {
|
||||||
# Packages to exclude from the default package list
|
|
||||||
type = lib.types.listOf lib.types.package;
|
type = lib.types.listOf lib.types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
#
|
#
|
||||||
# External User Configuration:
|
# External User Configuration:
|
||||||
# Users can specify external configuration modules via the 'external' attribute:
|
# Users can specify external configuration modules via the 'external' attribute:
|
||||||
# external = builtins.fetchGit { url = "..."; rev = "..."; };
|
# external = { url = "..."; rev = "..."; submodules? = false; };
|
||||||
# external = /path/to/local/config;
|
# external = /path/to/local/config;
|
||||||
|
# external = builtins.fetchGit { ... }; # legacy, still supported
|
||||||
#
|
#
|
||||||
# External repositories should contain:
|
# External repositories should contain:
|
||||||
# - user.nix (required): Defines athenix.users.<name> options AND home-manager config
|
# - user.nix (required): Defines athenix.users.<name> options AND home-manager config
|
||||||
@@ -47,9 +48,10 @@
|
|||||||
enable = true; # Default user, enabled everywhere
|
enable = true; # Default user, enabled everywhere
|
||||||
};
|
};
|
||||||
hdh20267 = {
|
hdh20267 = {
|
||||||
external = builtins.fetchGit {
|
external = {
|
||||||
url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
url = "https://git.factory.uga.edu/hdh20267/hdh20267-nix";
|
||||||
rev = "dbdf65c7bd59e646719f724a3acd2330e0c922ec";
|
rev = "dbdf65c7bd59e646719f724a3acd2330e0c922ec";
|
||||||
|
# submodules = false; # optional, defaults to false
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
sv22900 = {
|
sv22900 = {
|
||||||
|
|||||||
Reference in New Issue
Block a user