2024-03-06 10:23:25 +00:00
|
|
|
{
|
|
|
|
|
lib,
|
2024-11-24 17:19:17 +01:00
|
|
|
kubenix,
|
2024-03-06 10:23:25 +00:00
|
|
|
...
|
2026-02-09 17:37:02 +01:00
|
|
|
} @ attrs: let
|
|
|
|
|
inherit (lib) mkOption types evalModules concatMapStringsSep assertMsg;
|
|
|
|
|
nixlet-lib = rec {
|
|
|
|
|
nixletModule = ./nixletModule.nix;
|
|
|
|
|
|
|
|
|
|
evalValues = file: {
|
|
|
|
|
rawValues,
|
|
|
|
|
dependencies,
|
|
|
|
|
args,
|
|
|
|
|
check ? true,
|
|
|
|
|
...
|
|
|
|
|
}: let
|
|
|
|
|
moduleArgs =
|
|
|
|
|
args
|
|
|
|
|
// {
|
|
|
|
|
utils = import ./utils.nix attrs;
|
|
|
|
|
};
|
|
|
|
|
# get the values from the dependencies, then import them nested
|
|
|
|
|
# (so you can set postgres.replicaCount in values.nix for example when adding "postgres" as dependency)
|
|
|
|
|
extraModules = map (depName: {
|
|
|
|
|
options.${depName} = mkOption {
|
|
|
|
|
type = types.submodule {
|
|
|
|
|
imports = ["${dependencies.${depName}.path}/values.nix"];
|
|
|
|
|
_module.args =
|
|
|
|
|
moduleArgs
|
|
|
|
|
// {
|
|
|
|
|
# make sure that dependencies see their own name and version etc.
|
|
|
|
|
nixlet = {
|
|
|
|
|
inherit (dependencies.${depName}) name version description;
|
|
|
|
|
inherit (moduleArgs.nixlet) project;
|
|
|
|
|
};
|
|
|
|
|
};
|
2025-07-19 16:25:46 +02:00
|
|
|
};
|
2026-02-09 17:37:02 +01:00
|
|
|
default = {};
|
|
|
|
|
description = let
|
|
|
|
|
n = dependencies.${depName};
|
|
|
|
|
in ''
|
|
|
|
|
Imported Nixlet as a dependency:
|
2024-03-06 10:23:25 +00:00
|
|
|
|
2026-02-09 17:37:02 +01:00
|
|
|
|Name|Version|Description|
|
|
|
|
|
|----|-------|-----------|
|
|
|
|
|
|${n.name}|${n.version}|${n.description}|
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
}) (builtins.attrNames dependencies);
|
|
|
|
|
in
|
|
|
|
|
builtins.addErrorContext "[nixlets] while evaluating values" (
|
|
|
|
|
evalModules {
|
|
|
|
|
modules =
|
|
|
|
|
[
|
|
|
|
|
file
|
|
|
|
|
{
|
|
|
|
|
_module = {
|
|
|
|
|
args = moduleArgs;
|
|
|
|
|
inherit check;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
{config = rawValues;}
|
|
|
|
|
]
|
|
|
|
|
++ extraModules;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
# wraps mkNixletInner to allow passing either a path or an attrset
|
|
|
|
|
mkNixlet = arg:
|
|
|
|
|
mkNixletInner (
|
|
|
|
|
if (builtins.typeOf arg) == "set"
|
|
|
|
|
then arg
|
|
|
|
|
else
|
|
|
|
|
{path = arg;}
|
|
|
|
|
// (
|
|
|
|
|
if builtins.pathExists "${arg}/nixlet.nix"
|
|
|
|
|
then (import "${arg}/nixlet.nix")
|
|
|
|
|
else throw "Nixlet at '${arg}' does not contain nixlet.nix and mkNixlet was called with just a path"
|
|
|
|
|
)
|
|
|
|
|
);
|
2024-05-08 17:09:17 +00:00
|
|
|
|
2026-02-09 17:37:02 +01:00
|
|
|
mkNixletInner = {
|
|
|
|
|
path,
|
|
|
|
|
name,
|
|
|
|
|
version ? null,
|
|
|
|
|
description ? "",
|
|
|
|
|
defaultProject ? null,
|
|
|
|
|
...
|
|
|
|
|
}: let
|
|
|
|
|
# every nixlet gets "nixlet" as arg with some useful data about itself
|
|
|
|
|
baseNixletArg = {
|
|
|
|
|
inherit name version description;
|
|
|
|
|
project = defaultProject;
|
2025-07-19 16:25:46 +02:00
|
|
|
};
|
2026-02-09 17:37:02 +01:00
|
|
|
nixlet = {
|
|
|
|
|
_type = "nixlet";
|
|
|
|
|
inherit name version description path;
|
|
|
|
|
# just values of the current nixlet (lighweight)
|
|
|
|
|
values = evalValues "${path}/values.nix" {
|
|
|
|
|
rawValues = {};
|
|
|
|
|
dependencies = {};
|
|
|
|
|
# no checking since this doesn't include dependencies
|
|
|
|
|
check = false;
|
|
|
|
|
args.nixlet = baseNixletArg;
|
|
|
|
|
};
|
|
|
|
|
# full values, including dependencies etc. (complex)
|
|
|
|
|
fullValues = args: let
|
|
|
|
|
evaled = nixlet.eval args;
|
2025-12-18 13:42:14 +01:00
|
|
|
in
|
2026-02-09 17:37:02 +01:00
|
|
|
evalValues "${path}/values.nix" {
|
|
|
|
|
rawValues = {};
|
|
|
|
|
inherit (evaled.config.nixlet) dependencies;
|
|
|
|
|
args.nixlet = baseNixletArg;
|
2025-07-19 16:25:46 +02:00
|
|
|
};
|
2026-02-09 17:37:02 +01:00
|
|
|
mkDocs = opts: mkDocs (opts // {inherit nixlet;});
|
|
|
|
|
eval = {
|
|
|
|
|
system,
|
|
|
|
|
project ? defaultProject,
|
|
|
|
|
overrides ? (_: {}),
|
|
|
|
|
values ? {},
|
|
|
|
|
}:
|
|
|
|
|
assert assertMsg (project != null) "No default project set, please pass a project to the eval/render method"; let
|
|
|
|
|
nixletArg = baseNixletArg // {inherit project;};
|
|
|
|
|
in
|
|
|
|
|
builtins.addErrorContext "[nixlets] while evaluating nixlet ${name}" (
|
|
|
|
|
kubenix.evalModules.${system} {
|
|
|
|
|
module = {
|
|
|
|
|
config,
|
|
|
|
|
kubenix,
|
|
|
|
|
...
|
|
|
|
|
}: {
|
|
|
|
|
imports = with kubenix.modules; [
|
|
|
|
|
k8s
|
|
|
|
|
helm
|
|
|
|
|
docker
|
|
|
|
|
files
|
|
|
|
|
./secretsModule.nix
|
|
|
|
|
./nixletModule.nix
|
|
|
|
|
(let
|
|
|
|
|
finalValues =
|
|
|
|
|
(evalValues "${path}/values.nix" {
|
|
|
|
|
rawValues = values;
|
|
|
|
|
inherit (config.nixlet) dependencies;
|
|
|
|
|
args.nixlet = nixletArg;
|
|
|
|
|
}).config;
|
|
|
|
|
in {
|
|
|
|
|
imports = [path];
|
|
|
|
|
_module.args = {
|
|
|
|
|
nixlet =
|
|
|
|
|
{
|
|
|
|
|
values = finalValues;
|
|
|
|
|
}
|
|
|
|
|
// nixletArg;
|
|
|
|
|
inherit nixlet-lib system;
|
|
|
|
|
};
|
|
|
|
|
})
|
|
|
|
|
overrides
|
|
|
|
|
];
|
|
|
|
|
kubenix.project = project;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
render = {
|
|
|
|
|
system,
|
|
|
|
|
project ? defaultProject,
|
|
|
|
|
overrides ? (_: {}),
|
|
|
|
|
values ? {},
|
|
|
|
|
}:
|
|
|
|
|
(nixlet.eval {
|
|
|
|
|
inherit system project overrides values;
|
|
|
|
|
})
|
|
|
|
|
.config
|
|
|
|
|
.kubernetes
|
|
|
|
|
.resultYAML;
|
|
|
|
|
# combines all secrets files in a single directory
|
|
|
|
|
secrets = args: (nixlet.eval args).config.kubernetes.secretsCombined;
|
2024-03-06 10:23:25 +00:00
|
|
|
|
2026-02-09 17:37:02 +01:00
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
nixlet;
|
|
|
|
|
|
|
|
|
|
fetchNixlet = url: sha256: mkNixlet (builtins.fetchTarball {inherit url sha256;});
|
|
|
|
|
fetchNixletFromGitlab = {
|
|
|
|
|
project,
|
|
|
|
|
name,
|
|
|
|
|
version,
|
|
|
|
|
sha256,
|
|
|
|
|
}: let
|
|
|
|
|
projectEscaped = builtins.replaceStrings ["/"] ["%2F"] project;
|
|
|
|
|
in
|
|
|
|
|
fetchNixlet "https://gitlab.com/api/v4/projects/${projectEscaped}/packages/generic/${name}/${version}/${name}.tar.gz" sha256;
|
2024-03-06 10:23:25 +00:00
|
|
|
|
2026-02-09 17:37:02 +01:00
|
|
|
uploadNixletsToGitlab = {
|
|
|
|
|
pkgs,
|
|
|
|
|
projectId,
|
|
|
|
|
nixlets,
|
|
|
|
|
...
|
|
|
|
|
}:
|
|
|
|
|
pkgs.writeShellScriptBin "nixlets-upload" (
|
|
|
|
|
''
|
|
|
|
|
if [[ -z "$AUTH_HEADER" ]]; then
|
|
|
|
|
echo "Must provide AUTH_HEADER environment variable!" 1>&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
''
|
|
|
|
|
+ concatMapStringsSep "\n" (
|
|
|
|
|
(nixlet:
|
|
|
|
|
with nixlet; ''
|
|
|
|
|
URL="https://gitlab.com/api/v4/projects/${projectId}/packages/generic/${name}/${version}/${name}.tar.gz"
|
|
|
|
|
if ${pkgs.curl}/bin/curl --output /dev/null --silent --head --fail --header "$AUTH_HEADER" $URL; then
|
|
|
|
|
echo "> Skipped ${name}@${version} because it already exists in the Package Registry"
|
|
|
|
|
else
|
|
|
|
|
echo "> Uploading new version ${name}@${version}"
|
|
|
|
|
${pkgs.gnutar}/bin/tar -czf /tmp/${name}.tar.gz --mode='u+rwX' -C ${path} --transform 's/^\./\/${name}/' .
|
|
|
|
|
${pkgs.curl}/bin/curl --header "$AUTH_HEADER" --upload-file "/tmp/${name}.tar.gz" "$URL"; echo;
|
|
|
|
|
${pkgs.coreutils}/bin/rm -f /tmp/${nixlet.name}.tar.gz
|
|
|
|
|
echo "> Finished ${name}@${version}, see above"
|
|
|
|
|
fi
|
|
|
|
|
'')
|
|
|
|
|
nixlets
|
|
|
|
|
)
|
|
|
|
|
);
|
2025-07-19 16:25:46 +02:00
|
|
|
|
2026-02-09 17:37:02 +01:00
|
|
|
mkDocs = opts:
|
|
|
|
|
import ./valuesDocs.nix (opts // {inherit lib;});
|
|
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
nixlet-lib
|