mirror of
https://git.sr.ht/~goorzhel/turboprop
synced 2024-12-15 17:50:52 +00:00
Re-implement service-builder
`apiVersions` gave me a headache while writing the foldl so I made it a separate input. Now the service modules have this signature, without my having to change any code in the modules themselves: {charts, etc, ...} -> [apiVersion] -> {out, extra}
This commit is contained in:
parent
6b97777fe9
commit
97dbdec7f7
5 changed files with 106 additions and 53 deletions
10
flake.nix
10
flake.nix
|
@ -36,15 +36,9 @@
|
||||||
in {
|
in {
|
||||||
packages = {
|
packages = {
|
||||||
inherit charts lib;
|
inherit charts lib;
|
||||||
default = {
|
default = user:
|
||||||
# TODO: move to default.nix
|
|
||||||
charts ? charts,
|
|
||||||
lib ? lib,
|
|
||||||
pkgs ? pkgs,
|
|
||||||
user ? {},
|
|
||||||
}:
|
|
||||||
import ./src {
|
import ./src {
|
||||||
inherit charts lib pkgs user;
|
inherit charts haumea lib pkgs user;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
# TODO: make a template
|
# TODO: make a template
|
||||||
|
|
|
@ -38,6 +38,10 @@ in rec {
|
||||||
# Some charts lack diligence in setting `Release.Namespace`
|
# Some charts lack diligence in setting `Release.Namespace`
|
||||||
# on the objects they create, necessitating a round-trip through
|
# on the objects they create, necessitating a round-trip through
|
||||||
# yamlStream, which sets namespaces on all objects lacking one.
|
# yamlStream, which sets namespaces on all objects lacking one.
|
||||||
|
|
||||||
|
# BUG: However, this creates a derivation with no knowledge of
|
||||||
|
# the Helm chart derivation that is its input, which would be
|
||||||
|
# useful to debug with.
|
||||||
in
|
in
|
||||||
yamlStream {inherit name namespace objs;};
|
yamlStream {inherit name namespace objs;};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,13 @@
|
||||||
parseYAMLsFile = p: kubelib.fromYAML (builtins.readFile p);
|
parseYAMLsFile = p: kubelib.fromYAML (builtins.readFile p);
|
||||||
parseYAMLFile = p: builtins.head (parseYAMLsFile p);
|
parseYAMLFile = p: builtins.head (parseYAMLsFile p);
|
||||||
|
|
||||||
|
liftDefault = _: mod:
|
||||||
|
# h.lib.transformers.liftDefault uses pkgs.lib.attrsets.unionOfDisjoint,
|
||||||
|
# which fails here because mod.default is a function, not a set.
|
||||||
|
if mod ? default
|
||||||
|
then mod.default
|
||||||
|
else mod;
|
||||||
|
|
||||||
# Helm cannot see my cluster from within the sandbox, so it cannot
|
# Helm cannot see my cluster from within the sandbox, so it cannot
|
||||||
# infer capabilities from it. Therefore, API versions must be gathered
|
# infer capabilities from it. Therefore, API versions must be gathered
|
||||||
# from charts that provide them.
|
# from charts that provide them.
|
||||||
|
@ -60,15 +67,39 @@
|
||||||
# and remove this transformer
|
# and remove this transformer
|
||||||
};
|
};
|
||||||
|
|
||||||
mkStages = map (src:
|
mkSvcTrees = src:
|
||||||
haumea.lib.load {
|
haumea.lib.load {
|
||||||
inherit src;
|
inherit src;
|
||||||
loader = haumea.lib.loaders.verbatim;
|
loader = haumea.lib.loaders.verbatim;
|
||||||
transformer = _: mod:
|
transformer = liftDefault;
|
||||||
# transformers.liftDefault uses pkgs.lib.attrsets.unionOfDisjoint,
|
};
|
||||||
# which fails here because mod.default is a function, not a set.
|
|
||||||
if mod ? default
|
# Borrowed from divnix/digga, with minor modifications:
|
||||||
then mod.default
|
# https://github.com/divnix/digga/blob/baa54f8/src/importers.nix#L2-L59
|
||||||
else mod;
|
flattenTree = tree: let
|
||||||
});
|
op = sum: path: val: let
|
||||||
|
pathStr = builtins.concatStringsSep "/" path;
|
||||||
|
in
|
||||||
|
if builtins.isFunction val
|
||||||
|
then
|
||||||
|
# builtins.trace "${toString val} is a path"
|
||||||
|
(sum
|
||||||
|
// {
|
||||||
|
"${pathStr}" = val;
|
||||||
|
})
|
||||||
|
else if builtins.isAttrs val
|
||||||
|
then
|
||||||
|
# builtins.trace "${builtins.toJSON val} is an attrset"
|
||||||
|
(recurse sum path val)
|
||||||
|
else
|
||||||
|
# builtins.trace "${toString path} is something else"
|
||||||
|
sum; # ignore val
|
||||||
|
|
||||||
|
recurse = sum: path: val:
|
||||||
|
builtins.foldl'
|
||||||
|
(sum: key: op sum (path ++ [key]) val.${key})
|
||||||
|
sum
|
||||||
|
(builtins.attrNames val);
|
||||||
|
in
|
||||||
|
recurse {} [] tree;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,40 @@
|
||||||
{
|
{
|
||||||
charts,
|
charts,
|
||||||
|
haumea,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
user ? {},
|
user ? {},
|
||||||
}: let
|
}: let
|
||||||
mkNamespace = name: extraMetadata: {
|
|
||||||
};
|
|
||||||
|
|
||||||
flakeBuilders = (import ./flake-builders.nix) {inherit charts lib pkgs user;};
|
flakeBuilders = (import ./flake-builders.nix) {inherit charts lib pkgs user;};
|
||||||
|
|
||||||
buildServices = roots: kubeVersion: {};
|
|
||||||
in {
|
in {
|
||||||
inherit flakeBuilders; # TODO: remove after debugging
|
inherit flakeBuilders; # TODO: remove after debugging
|
||||||
|
|
||||||
inherit (lib) mkCharts;
|
inherit (lib) mkCharts;
|
||||||
|
|
||||||
|
mkServices = src: kubeVersion: let
|
||||||
|
modules = haumea.lib.load {
|
||||||
|
inherit src;
|
||||||
|
inputs = {inherit charts lib pkgs user kubeVersion;};
|
||||||
|
loader = flakeBuilders.serviceLoader;
|
||||||
|
transformer = lib.liftDefault;
|
||||||
|
};
|
||||||
|
folder = acc: path: mod: let
|
||||||
|
module = mod acc.apis;
|
||||||
|
outPath = "${module.srcPath}/SERVICE.yaml:${module.out.outPath}";
|
||||||
|
outPaths =
|
||||||
|
if module ? extra
|
||||||
|
then [outPath "${module.srcPath}/EXTRA.yaml:${module.extra.outPath}"]
|
||||||
|
else [outPath];
|
||||||
|
in {
|
||||||
|
apis = acc.apis ++ (lib.gatherApis module.out.outPath);
|
||||||
|
paths = acc.paths ++ outPaths;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.lib.attrsets.foldlAttrs
|
||||||
|
folder
|
||||||
|
{ apis = []; paths = []; }
|
||||||
|
(lib.flattenTree modules);
|
||||||
|
|
||||||
mkNamespaces = {
|
mkNamespaces = {
|
||||||
roots,
|
roots,
|
||||||
extraMetadata ? {},
|
extraMetadata ? {},
|
||||||
|
@ -48,15 +68,11 @@ in {
|
||||||
namespaceData,
|
namespaceData,
|
||||||
kubeVersion,
|
kubeVersion,
|
||||||
src,
|
src,
|
||||||
}: let
|
}:
|
||||||
builtServices = buildServices serviceData kubeVersion;
|
|
||||||
in
|
|
||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
inherit pname version src;
|
inherit pname version src;
|
||||||
derivation_paths = flakeBuilders.paths {
|
derivation_paths = []; # TODO
|
||||||
services = builtServices;
|
namespace_drv = []; # TODO:
|
||||||
};
|
|
||||||
namespace_drv = flakeBuilders.namespaces namespaceData;
|
|
||||||
|
|
||||||
phases = ["installPhase"];
|
phases = ["installPhase"];
|
||||||
installPhase = builtins.readFile ./src/output.sh;
|
installPhase = builtins.readFile ./src/output.sh;
|
||||||
|
|
|
@ -10,32 +10,40 @@
|
||||||
mapAttrs = builtins.mapAttrs;
|
mapAttrs = builtins.mapAttrs;
|
||||||
in {
|
in {
|
||||||
serviceLoader = {
|
serviceLoader = {
|
||||||
inputs, # {charts, lib, pkgs, user, kubeVersion, apiVersions}
|
charts,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
user,
|
||||||
|
kubeVersion,
|
||||||
...
|
...
|
||||||
}: p: let
|
} @ inputs: p: let
|
||||||
module = import p inputs;
|
module = import p inputs;
|
||||||
name = builtins.baseNameOf p;
|
# p is `.../${ns}/${name}/default.nix`
|
||||||
namespace = builtins.baseNameOf (builtins.dirOf p);
|
name = with builtins; baseNameOf (dirOf p);
|
||||||
in {
|
namespace = with builtins; baseNameOf (dirOf (dirOf p));
|
||||||
out = module.builder (module.args
|
in
|
||||||
// {
|
apiVersions: {
|
||||||
# By injecting `name` and `namespace` here, I remove
|
out = module.builder (module.args
|
||||||
# the need to specify it in every service in the flake;
|
// {
|
||||||
# the directory structure can speak for me instead.
|
# By injecting `name` and `namespace` here, I remove
|
||||||
inherit name namespace;
|
# the need to specify it in every service in the flake;
|
||||||
|
# the directory structure can speak for me instead.
|
||||||
# Values understood by lib.builders.helmChart
|
|
||||||
# and ignored by the rest.
|
|
||||||
inherit (inputs) kubeVersion apiVersions;
|
|
||||||
});
|
|
||||||
|
|
||||||
extra =
|
|
||||||
if module ? extraObjects
|
|
||||||
then
|
|
||||||
lib.builders.yamlStream {
|
|
||||||
inherit name namespace;
|
inherit name namespace;
|
||||||
objs = module.extraObjects;
|
|
||||||
}
|
# Values understood by lib.builders.helmChart
|
||||||
else null;
|
# and ignored by the rest.
|
||||||
};
|
inherit (inputs) kubeVersion;
|
||||||
|
});
|
||||||
|
|
||||||
|
extra =
|
||||||
|
if module ? extraObjects
|
||||||
|
then
|
||||||
|
lib.builders.yamlStream {
|
||||||
|
inherit name namespace;
|
||||||
|
objs = module.extraObjects;
|
||||||
|
}
|
||||||
|
else null;
|
||||||
|
|
||||||
|
srcPath = builtins.dirOf p;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue