1
0
Fork 0
mirror of https://git.sr.ht/~goorzhel/turboprop synced 2024-12-14 11:37:37 +00:00
turboprop/lib/builders.nix
Antonio Gurgel ff01a6dcf7 Rant about namespace pitfalls
Several charts have tripped me up by lacking a namespace and therefore
dumping their resources into my default one.
2023-11-26 00:51:49 -08:00

66 lines
2.3 KiB
Nix

# All builders used to require a name and namespace, due to my previous
# (regrettable) decision to use the resultant derivations' names as
# path signifiers. No longer, because:
# 1. derivations are collected and directly mapped to target paths, and
# 2. the output derivation contains symbolic links to each sub-derivation
# for easy identification.
# Still, the pnames make derivations easy to identify in the Nix store
# at a glance, so I've kept them.
{
kubelib,
pkgs,
}: let
setNsOnObjects = namespace:
# Attrset is on LHS in case object sets its own namespace.
map (obj: pkgs.lib.attrsets.recursiveUpdate {metadata.namespace = namespace;} obj);
in {
derivation = {
name,
namespace,
src,
...
}:
pkgs.stdenv.mkDerivation {
pname = "copied-drv-${namespace}-${name}";
inherit (src) version;
inherit src;
phases = ["installPhase"];
installPhase = "cp -rv $src $out";
};
helmChart = kubelib.buildHelmChart;
# BUG: some charts lack diligence in setting `Release.Namespace` on every
# object they create. Perhaps they assume the user has `.kube/config` with
# the correct context set.
# See, this is why I can't stand `helm install` and the like. Kubernetes
# manifests are _declarative_. Why throw all of that away?
# Anyway, the simplest solution I see is to wrap this within `yamlStream`
# (and make this attrset recursive).
# Adapted from github:farcaller/nix-kube-generators ("kubelib").
yamlStream = {
name,
namespace,
objs,
...
}: let
# Some services may include extra objects outside of their charts.
# Additionally, there are services that consist only of a list of objects.
# The following line removes the need for `namespace` to be passed into
# a service module.
# (Because all objects' metadata is of the ObjectMeta type, non-namespaced
# objects can have `metadata.namespace` set, too. It will just be ignored
# when such an object is created.)
namespacedObjs = setNsOnObjects namespace objs;
in
pkgs.stdenv.mkDerivation {
name = "yaml-stream-${namespace}-${name}";
yamlText = pkgs.lib.strings.concatStringsSep "\n---\n" (map builtins.toJSON namespacedObjs);
passAsFile = "yamlText";
phases = ["installPhase"];
installPhase = "${pkgs.yq-go}/bin/yq -P -M $yamlTextPath > $out";
};
}