Skip to content

Commit 0bfbff2

Browse files
fix(platform): restore the isp-hosted dependency closure
The isp-hosted preset shipped bundles.system.enabled: false with paas and naas enabled. templates/bundles/system.yaml is gated end to end on that flag, but it carries two separable things: a variant-selected data-plane head (kubeovn/cilium/linstor on isp-full, a noop networking Package on isp-hosted) and a variant-agnostic control-plane body — cozystack-engine, the sole source of the application-definition-crd component, plus cert-manager, prometheus-operator-crds, postgres-operator and objectstorage-controller. "Hosted" means the host already provides CNI, storage and virtualisation, so only the data-plane head should be dropped. Disabling the whole bundle also deleted the control-plane body, leaving an app catalog whose entire dependency closure was absent: all 24 emitted Packages sat in DependenciesNotReady, the *-rd HelmReleases failed with `no matches for kind "ApplicationDefinition" in version "cozystack.io/v1alpha1"`, and the cozystack-platform HelmRelease never went Ready. That the variant field was still set to isp-hosted — and that system.yaml has an isp-hosted branch which could never render — shows the disable was the mistake, not the intent; iaas.yaml already refuses to render on this variant, encoding the same "system bundle minus iaas" contract. The preset has never worked since it was introduced in 2d022e3. Enable the system bundle for the preset. isp-hosted now emits 53 Packages with every dependsOn satisfied, and installs 59 components against the 60 of the pre-refactor bundles/paas-hosted.yaml, with no LINSTOR, KubeVirt, CAPI or Kamaji leakage. Also move cozystack.bucket-application from the iaas bundle into the system bundle. Its own dependsOn closure is networking, objectstorage-controller and cozystack-engine, none of which are iaas, and cozystack.backupstrategy-controller — a default package of the system bundle — hard-depends on it. Any system-on/iaas-off configuration therefore wedged backupstrategy-controller; both isp-full presets masked this by enabling iaas. Guard the class of bug rather than only these two instances. The existing paas/naas/iaas guards check bundles.system.variant, which keeps its value when the bundle is disabled, so they passed on exactly this configuration. Make all three require bundles.system.enabled too and point the operator at the supported topology, turning a silent multi-hour DependenciesNotReady hang into a render-time failure. Covered by two helm-unittest suites: one pinning the dependency closure the catalog needs — including a case that loads values-isp-hosted.yaml unmodified, so a regression in the preset itself is caught — and one pinning the guards. The fix changes and the guards were mutation-tested by reverting each in turn and confirming the suite fails. This restores the dependency closure; it is not by itself sufficient for a fully converged hosted install. Review surfaced further hosted-unaware defaults that the dead bundle had been masking — notably apps/tenant rendering cilium.io/v2 policies with no .Capabilities guard, and extra/monitoring defaulting logsStorages to the LINSTOR-only "replicated" StorageClass. Those are tracked separately. bundles.disabledPackages can also still remove a dependency while its dependents stay emitted; the guards do not cover that path. Refs #3376 Signed-off-by: Myasnikov Daniil <[email protected]>
1 parent f5227ee commit 0bfbff2

7 files changed

Lines changed: 299 additions & 2 deletions

File tree

‎packages/core/platform/templates/bundles/iaas.yaml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
{{- if and .Values.bundles.iaas.enabled (not (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic"))) }}
22
{{- fail "bundles.iaas.enabled can only be true when bundles.system.variant is 'isp-full' or 'isp-full-generic'" }}
33
{{- end }}
4+
{{- /* Same hole as the paas/naas guards closed: bundles.system.variant keeps its
5+
value when bundles.system.enabled is false, so the check above passes on a
6+
configuration that skips the system bundle entirely. Every package below
7+
depends on its control-plane body — rendering iaas without it leaves all 12
8+
Packages in DependenciesNotReady with nothing naming the cause. */ -}}
9+
{{- if and .Values.bundles.iaas.enabled (not .Values.bundles.system.enabled) }}
10+
{{- fail "bundles.iaas.enabled requires bundles.system.enabled: the iaas bundle depends on packages emitted by the system bundle (cozystack.networking, cozystack-engine, cert-manager, prometheus-operator-crds and cozystack-basics). Enable the system bundle with bundles.system.variant: isp-full or isp-full-generic." }}
11+
{{- end }}
412
{{- if and .Values.bundles.iaas.enabled (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic")) }}
513
{{- $kubevirtValues := dict -}}
614
{{- if .Values.resources.cpuAllocationRatio -}}
@@ -155,7 +163,6 @@
155163
{{include "cozystack.platform.package.default" (list "cozystack.capi-provider-core" $) }}
156164
{{include "cozystack.platform.package.default" (list "cozystack.capi-provider-cp-kamaji" $) }}
157165
{{include "cozystack.platform.package.default" (list "cozystack.capi-provider-infra-kubevirt" $) }}
158-
{{include "cozystack.platform.package.default" (list "cozystack.bucket-application" $) }}
159166
{{include "cozystack.platform.package" (list "cozystack.kubernetes-application" "kubevirt" $) }}
160167
{{include "cozystack.platform.package" (list "cozystack.virtualprivatecloud-application" "kubevirt" $) }}
161168
{{include "cozystack.platform.package" (list "cozystack.vm-disk-application" "kubevirt" $) }}

‎packages/core/platform/templates/bundles/naas.yaml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{{- if and .Values.bundles.naas.enabled (not (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic") (eq .Values.bundles.system.variant "isp-hosted"))) }}
22
{{- fail "bundles.naas.enabled can only be true when bundles.system.variant is 'isp-full', 'isp-full-generic', or 'isp-hosted'" }}
33
{{- end }}
4+
{{- /* See the matching guard in paas.yaml: a valid bundles.system.variant does not
5+
imply the system bundle is actually emitted, and every package below depends
6+
on its control-plane body. */ -}}
7+
{{- if and .Values.bundles.naas.enabled (not .Values.bundles.system.enabled) }}
8+
{{- fail "bundles.naas.enabled requires bundles.system.enabled: the naas catalog depends on packages emitted by the system bundle (cozystack-engine, which ships the ApplicationDefinition CRD, plus cozystack.networking). To run a hosted platform where the host provides CNI, storage and virtualisation, keep bundles.system.enabled: true and set bundles.system.variant: isp-hosted (which selects a noop networking Package) with bundles.iaas.enabled: false — do not disable the system bundle." }}
9+
{{- end }}
410
{{- if and .Values.bundles.naas.enabled (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic") (eq .Values.bundles.system.variant "isp-hosted")) }}
511
{{include "cozystack.platform.package.default" (list "cozystack.http-cache-application" $) }}
612
{{include "cozystack.platform.package.default" (list "cozystack.tcp-balancer-application" $) }}

‎packages/core/platform/templates/bundles/paas.yaml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
{{- if and .Values.bundles.paas.enabled (not (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic") (eq .Values.bundles.system.variant "isp-hosted"))) }}
22
{{- fail "bundles.paas.enabled can only be true when bundles.system.variant is 'isp-full', 'isp-full-generic', or 'isp-hosted'" }}
33
{{- end }}
4+
{{- /* The variant check above is not sufficient: bundles.system.variant keeps its
5+
value when bundles.system.enabled is false, so a preset could select a valid
6+
variant and still skip the whole system bundle. Every package below depends on
7+
the system bundle's control-plane body, so that combination renders an app
8+
catalog whose entire dependency closure is absent — each Package then sits in
9+
DependenciesNotReady forever and the cozystack-platform HelmRelease never goes
10+
Ready, with no error pointing at the cause. Fail the render instead. */ -}}
11+
{{- if and .Values.bundles.paas.enabled (not .Values.bundles.system.enabled) }}
12+
{{- fail "bundles.paas.enabled requires bundles.system.enabled: the paas catalog depends on packages emitted by the system bundle (cozystack-engine, which ships the ApplicationDefinition CRD, plus cozystack.networking, cert-manager, prometheus-operator-crds, postgres-operator and objectstorage-controller). To run a hosted platform where the host provides CNI, storage and virtualisation, keep bundles.system.enabled: true and set bundles.system.variant: isp-hosted (which selects a noop networking Package) with bundles.iaas.enabled: false — do not disable the system bundle." }}
13+
{{- end }}
414
{{- if and .Values.bundles.paas.enabled (or (eq .Values.bundles.system.variant "isp-full") (eq .Values.bundles.system.variant "isp-full-generic") (eq .Values.bundles.system.variant "isp-hosted")) }}
515
{{include "cozystack.platform.package.default" (list "cozystack.mariadb-operator" $) }}
616
{{include "cozystack.platform.package.default" (list "cozystack.kafka-operator" $) }}

‎packages/core/platform/templates/bundles/system.yaml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,17 @@ cozystack-platform HelmRelease never becomes Ready. */}}
233233
{{include "cozystack.platform.package.default" (list "cozystack.etcd-operator" $) }}
234234
{{include "cozystack.platform.package.default" (list "cozystack.postgres-operator" $) }}
235235
{{include "cozystack.platform.package.default" (list "cozystack.objectstorage-controller" $) }}
236+
{{- /* bucket-application belongs to the system bundle, not iaas: its own
237+
dependsOn closure is cozystack.networking + cozystack.objectstorage-controller
238+
+ cozystack.cozystack-engine, all emitted here, and nothing in it needs
239+
KubeVirt or CAPI. It sat in the iaas bundle while cozystack.backupstrategy-controller
240+
— a *default* package of this bundle — hard-depends on it, so every
241+
system-on/iaas-off configuration (i.e. isp-hosted) left
242+
backupstrategy-controller permanently DependenciesNotReady. Both isp-full
243+
presets masked that by enabling iaas. Same reasoning as the velero comment
244+
below: a hard dependency of a default package must itself be emitted
245+
wherever that default package is. */ -}}
246+
{{include "cozystack.platform.package.default" (list "cozystack.bucket-application" $) }}
236247

237248
# Optional System Packages (controlled via bundles.enabledPackages)
238249
{{include "cozystack.platform.package.optional.default" (list "cozystack.nfs-driver" $) }}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
suite: paas/naas catalogs refuse to render without the system bundle
2+
templates:
3+
- templates/bundles/paas.yaml
4+
- templates/bundles/naas.yaml
5+
- templates/bundles/iaas.yaml
6+
release:
7+
name: cozystack
8+
namespace: cozy-system
9+
tests:
10+
# bundles.system.variant keeps its value when bundles.system.enabled is false,
11+
# so the pre-existing variant guard passes on a preset that selects a valid
12+
# variant and still skips the whole system bundle. That combination shipped in
13+
# values-isp-hosted.yaml and produced an app catalog with no dependency
14+
# closure: every Package DependenciesNotReady, the cozystack-platform
15+
# HelmRelease never Ready, and nothing in the output naming the cause. Fail the
16+
# render instead of letting the operator discover it hours later.
17+
#
18+
# Assertions are scoped with `template:` because helm-unittest otherwise checks
19+
# every assertion against every template listed above, and each guard lives in
20+
# only one of them.
21+
- it: fails the render when paas is enabled without the system bundle
22+
set:
23+
bundles:
24+
system:
25+
enabled: false
26+
variant: isp-hosted
27+
paas:
28+
enabled: true
29+
naas:
30+
enabled: false
31+
asserts:
32+
- failedTemplate:
33+
errorPattern: "bundles\\.paas\\.enabled requires bundles\\.system\\.enabled"
34+
template: templates/bundles/paas.yaml
35+
36+
- it: fails the render when naas is enabled without the system bundle
37+
set:
38+
bundles:
39+
system:
40+
enabled: false
41+
variant: isp-hosted
42+
paas:
43+
enabled: false
44+
naas:
45+
enabled: true
46+
asserts:
47+
- failedTemplate:
48+
errorPattern: "bundles\\.naas\\.enabled requires bundles\\.system\\.enabled"
49+
template: templates/bundles/naas.yaml
50+
51+
- it: fails the render when iaas is enabled without the system bundle
52+
set:
53+
bundles:
54+
system:
55+
enabled: false
56+
variant: isp-full
57+
iaas:
58+
enabled: true
59+
paas:
60+
enabled: false
61+
naas:
62+
enabled: false
63+
asserts:
64+
- failedTemplate:
65+
errorPattern: "bundles\\.iaas\\.enabled requires bundles\\.system\\.enabled"
66+
template: templates/bundles/iaas.yaml
67+
68+
# The message has to tell the operator what to do instead, otherwise the
69+
# obvious reading of "requires system" is to abandon the hosted topology.
70+
- it: points the operator at the isp-hosted variant rather than at disabling the bundle
71+
set:
72+
bundles:
73+
system:
74+
enabled: false
75+
variant: isp-hosted
76+
paas:
77+
enabled: true
78+
asserts:
79+
- failedTemplate:
80+
errorPattern: "bundles\\.system\\.variant: isp-hosted.*bundles\\.iaas\\.enabled: false"
81+
template: templates/bundles/paas.yaml
82+
83+
# The guard must not fire on the supported configurations.
84+
- it: renders the catalog when the system bundle is enabled on the hosted variant
85+
set:
86+
bundles:
87+
system:
88+
enabled: true
89+
variant: isp-hosted
90+
paas:
91+
enabled: true
92+
naas:
93+
enabled: true
94+
asserts:
95+
- containsDocument:
96+
apiVersion: cozystack.io/v1alpha1
97+
kind: Package
98+
name: cozystack.harbor-application
99+
any: true
100+
template: templates/bundles/paas.yaml
101+
- containsDocument:
102+
apiVersion: cozystack.io/v1alpha1
103+
kind: Package
104+
name: cozystack.vpn-application
105+
any: true
106+
template: templates/bundles/naas.yaml
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
suite: isp-hosted emits the dependency closure its app catalog needs
2+
templates:
3+
- templates/bundles/system.yaml
4+
release:
5+
name: cozystack
6+
namespace: cozy-system
7+
tests:
8+
# The isp-hosted preset drops the data-plane head (the host provides CNI,
9+
# storage and virtualisation) but MUST still emit the system bundle's
10+
# variant-agnostic control-plane body. Shipping bundles.system.enabled: false
11+
# while paas/naas stayed on rendered an app catalog whose entire dependency
12+
# closure was absent: all 24 Packages sat in DependenciesNotReady forever and
13+
# the cozystack-platform HelmRelease never went Ready. Each package below is a
14+
# dependsOn edge of a paas/naas application PackageSource, so losing any one of
15+
# them reproduces that wedge.
16+
- it: emits every package the paas/naas catalog depends on
17+
set:
18+
bundles:
19+
system:
20+
enabled: true
21+
variant: isp-hosted
22+
iaas:
23+
enabled: false
24+
paas:
25+
enabled: true
26+
naas:
27+
enabled: true
28+
asserts:
29+
# Sole source of the application-definition-crd component, i.e. the
30+
# ApplicationDefinition CRD every *-rd component renders against. Without
31+
# it the *-rd HelmReleases fail with `no matches for kind
32+
# "ApplicationDefinition" in version "cozystack.io/v1alpha1"`.
33+
- containsDocument:
34+
apiVersion: cozystack.io/v1alpha1
35+
kind: Package
36+
name: cozystack.cozystack-engine
37+
any: true
38+
# The noop networking Package for this variant. 23 of the catalog's
39+
# PackageSources declare dependsOn: cozystack.networking.
40+
- containsDocument:
41+
apiVersion: cozystack.io/v1alpha1
42+
kind: Package
43+
name: cozystack.networking
44+
any: true
45+
- containsDocument:
46+
apiVersion: cozystack.io/v1alpha1
47+
kind: Package
48+
name: cozystack.cert-manager
49+
any: true
50+
- containsDocument:
51+
apiVersion: cozystack.io/v1alpha1
52+
kind: Package
53+
name: cozystack.prometheus-operator-crds
54+
any: true
55+
- containsDocument:
56+
apiVersion: cozystack.io/v1alpha1
57+
kind: Package
58+
name: cozystack.postgres-operator
59+
any: true
60+
- containsDocument:
61+
apiVersion: cozystack.io/v1alpha1
62+
kind: Package
63+
name: cozystack.objectstorage-controller
64+
any: true
65+
66+
# bucket-application lives in the system bundle rather than iaas: its own
67+
# dependsOn closure is networking + objectstorage-controller + cozystack-engine
68+
# and nothing in it needs KubeVirt or CAPI, while cozystack.backupstrategy-controller
69+
# — a default package of the system bundle — hard-depends on it. Keeping it in
70+
# iaas left every system-on/iaas-off configuration with a permanently
71+
# DependenciesNotReady backupstrategy-controller.
72+
- it: emits bucket-application from the system bundle even when iaas is disabled
73+
set:
74+
bundles:
75+
system:
76+
enabled: true
77+
variant: isp-hosted
78+
iaas:
79+
enabled: false
80+
asserts:
81+
- containsDocument:
82+
apiVersion: cozystack.io/v1alpha1
83+
kind: Package
84+
name: cozystack.bucket-application
85+
any: true
86+
- containsDocument:
87+
apiVersion: cozystack.io/v1alpha1
88+
kind: Package
89+
name: cozystack.backupstrategy-controller
90+
any: true
91+
92+
# The tests above drive the templates through `set:`, so they pin the template
93+
# logic but would not notice values-isp-hosted.yaml itself regressing. Load the
94+
# shipped preset unmodified — this is the assertion that actually fails if
95+
# bundles.system.enabled goes back to false, which is how the wedge shipped.
96+
- it: ships the isp-hosted preset with the system bundle enabled
97+
values:
98+
- ../values-isp-hosted.yaml
99+
asserts:
100+
- containsDocument:
101+
apiVersion: cozystack.io/v1alpha1
102+
kind: Package
103+
name: cozystack.cozystack-engine
104+
any: true
105+
- containsDocument:
106+
apiVersion: cozystack.io/v1alpha1
107+
kind: Package
108+
name: cozystack.networking
109+
any: true
110+
- containsDocument:
111+
apiVersion: cozystack.io/v1alpha1
112+
kind: Package
113+
name: cozystack.bucket-application
114+
any: true
115+
116+
# The hosted variant must not drag in the data-plane it exists to exclude.
117+
#
118+
# `any: true` is load-bearing on a negated containsDocument. Without it the
119+
# assertion negates "EVERY rendered document matches", which any multi-document
120+
# render satisfies trivially — the case then passes even with cozystack.linstor
121+
# emitted into the hosted branch. With `any: true` it negates "SOME document
122+
# matches", which is the intended meaning.
123+
- it: does not emit data-plane packages on the hosted variant
124+
set:
125+
bundles:
126+
system:
127+
enabled: true
128+
variant: isp-hosted
129+
iaas:
130+
enabled: false
131+
asserts:
132+
- containsDocument:
133+
apiVersion: cozystack.io/v1alpha1
134+
kind: Package
135+
name: cozystack.linstor
136+
any: true
137+
not: true
138+
# securitygroup-controller is emitted from the common-packages helper, which
139+
# only the isp-full branches call — it watches cilium.io CRDs that the noop
140+
# networking variant never installs. Emitted on isp-full, absent here.
141+
- containsDocument:
142+
apiVersion: cozystack.io/v1alpha1
143+
kind: Package
144+
name: cozystack.securitygroup-controller
145+
any: true
146+
not: true

‎packages/core/platform/values-isp-hosted.yaml‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
migrations:
22
enabled: true
33
bundles:
4+
# The system bundle carries two things: a variant-selected data-plane head
5+
# (kubeovn/cilium/linstor on isp-full, a noop networking Package here) and a
6+
# variant-agnostic control-plane body (cozystack-engine — the sole source of
7+
# the ApplicationDefinition CRD — plus cert-manager, prometheus-operator-crds,
8+
# postgres-operator, objectstorage-controller and the *-application catalog).
9+
# "Hosted" drops the data-plane head only: the host already provides CNI,
10+
# storage and virtualisation. That is expressed by variant: isp-hosted, NOT by
11+
# disabling the bundle — turning it off also deletes the control-plane body,
12+
# which leaves every paas/naas application Package permanently
13+
# DependenciesNotReady. iaas stays off; see templates/bundles/iaas.yaml, which
14+
# refuses to render on this variant.
415
system:
5-
enabled: false
16+
enabled: true
617
variant: "isp-hosted"
718
iaas:
819
enabled: false

0 commit comments

Comments
 (0)