Pre-stages the upstream loft-sh vcluster Helm chart source on the
Sovereign cluster so the Organization controller
(core/controllers/organization) can render per-tenant
`helm.toolkit.fluxcd.io/v2 HelmRelease` CRs that reference
`chart.spec.sourceRef name=loft namespace=vcluster-system` (the
controller's defaults at core/controllers/organization/cmd/main.go).
Without this slot, every per-tenant vcluster HelmRelease the
Organization controller writes into the per-Org Gitea repo fails
Source reconcile with:
HelmRepository.source.toolkit.fluxcd.io "loft" not found
→ no per-tenant vCluster is ever spawned → the Organization
controller's reconciliation loop blocks on tenant onboarding.
Convergence blocker #2 (vCluster source install on Sovereign).
Different layer from existing slots 54/58/59 (bp-dmz/mgmt/rtz-
vcluster): those bundle loft-sh/vcluster 0.20.0 as a Helm subchart
to ship Sovereign-tier DMZ/MGMT/RTZ vClusters in a single OCI
artifact; this slot registers a live Flux source CR so per-TENANT
vClusters can be spawned by the Organization controller at runtime.
The two paths are independent.
Changes:
- platform/bp-vcluster-helmrepo/chart/ — new chart (no upstream
subchart, same shape as bp-gateway-api); installs
Namespace `vcluster-system` + HelmRepository `loft` pointing
at https://charts.loft.sh.
- platform/bp-vcluster-helmrepo/blueprint.yaml — Blueprint CR.
- clusters/_template/bootstrap-kit/60-bp-vcluster-helmrepo.yaml
— slot 60 (first free slot after the vCluster cohort 54/58/59);
dependsOn: bp-flux only. Default-ON.
- clusters/_template/bootstrap-kit/kustomization.yaml — wires
slot 60 in.
- scripts/expected-bootstrap-deps.yaml — declares slot 60 in
the canonical dependency DAG (audit `check-bootstrap-deps.sh`
passes).
Verification:
- helm lint platform/bp-vcluster-helmrepo/chart/ — clean.
- kubectl kustomize clusters/_template/bootstrap-kit/ — renders
HelmRepository name=loft namespace=vcluster-system.
- bash scripts/check-bootstrap-deps.sh — PASSED (Present: 49,
Drift: 0, Cycles: 0).
- TestBootstrapKit_TemplateClusterParses — PASS for slot 60.
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>