Skip to content

Commit ff2e7cd

Browse files
Merge pull request #1316 from njhale/installplangen
Bug 1784024: Use generations to prevent duplicate InstallPlans
2 parents deb58f1 + a27f3d9 commit ff2e7cd

File tree

13 files changed

+566
-407
lines changed

13 files changed

+566
-407
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ clean:
156156

157157
# Generate manifests for CRDs
158158
manifests: vendor
159-
$(CONTROLLER_GEN) schemapatch:manifests=./deploy/chart/templates paths=./pkg/api/apis/operators/v1alpha1/... output:dir=./deploy/chart/templates
160-
$(CONTROLLER_GEN) schemapatch:manifests=./deploy/chart/templates paths=./pkg/api/apis/operators/v1/... output:dir=./deploy/chart/templates
159+
$(CONTROLLER_GEN) schemapatch:manifests=./deploy/chart/templates paths=./pkg/api/apis/operators/... output:dir=./deploy/chart/templates
160+
161161
$(YQ_INTERNAL) w --inplace deploy/chart/templates/0000_50_olm_03-clusterserviceversion.crd.yaml spec.validation.openAPIV3Schema.properties.spec.properties.install.properties.spec.properties.deployments.items.properties.spec.properties.template.properties.metadata.x-kubernetes-preserve-unknown-fields true
162162

163163
# Generate clients, listers, and informers

deploy/chart/templates/0000_50_olm_04-installplan.crd.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ spec:
6767
- approval
6868
- approved
6969
- clusterServiceVersionNames
70+
- generation
7071
properties:
7172
approval:
7273
description: Approval is the user approval policy for an InstallPlan.
@@ -77,6 +78,8 @@ spec:
7778
type: array
7879
items:
7980
type: string
81+
generation:
82+
type: integer
8083
source:
8184
type: string
8285
sourceNamespace:
@@ -128,17 +131,21 @@ spec:
128131
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
129132
type: string
130133
bundleLookups:
134+
description: BundleLookups is the set of in-progress requests to pull
135+
and unpackage bundle content to the cluster.
131136
type: array
132137
items:
138+
description: BundleLookup is a request to pull and unpackage the content
139+
of a bundle to the cluster.
133140
type: object
134141
required:
135142
- catalogSourceRef
136143
- path
137144
- replaces
138145
properties:
139146
catalogSourceRef:
140-
description: ObjectReference contains enough information to let
141-
you inspect or modify the referred object.
147+
description: CatalogSourceRef is a reference to the CatalogSource
148+
the bundle path was resolved from.
142149
type: object
143150
properties:
144151
apiVersion:
@@ -174,6 +181,7 @@ spec:
174181
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
175182
type: string
176183
conditions:
184+
description: Conditions represents the overall state of a BundleLookup.
177185
type: array
178186
items:
179187
type: object
@@ -187,7 +195,7 @@ spec:
187195
type: string
188196
format: date-time
189197
lastUpdateTime:
190-
description: Last time the condition was probed
198+
description: Last time the condition was probed.
191199
type: string
192200
format: date-time
193201
message:
@@ -205,8 +213,12 @@ spec:
205213
description: Type of condition.
206214
type: string
207215
path:
216+
description: Path refers to the location of a bundle to pull.
217+
It's typically an image reference.
208218
type: string
209219
replaces:
220+
description: Replaces is the name of the bundle to replace with
221+
the one found at Path.
210222
type: string
211223
catalogSources:
212224
type: array

deploy/chart/templates/0000_50_olm_05-subscription.crd.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,10 @@ spec:
17021702
currentCSV:
17031703
description: CurrentCSV is the CSV the Subscription is progressing to.
17041704
type: string
1705+
installPlanGeneration:
1706+
description: InstallPlanGeneration is the current generation of the
1707+
installplan
1708+
type: integer
17051709
installPlanRef:
17061710
description: InstallPlanRef is a reference to the latest InstallPlan
17071711
that contains the Subscription's current CSV.

pkg/api/apis/operators/installplan_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type InstallPlanSpec struct {
2626
ClusterServiceVersionNames []string
2727
Approval Approval
2828
Approved bool
29+
Generation int
2930
}
3031

3132
// InstallPlanPhase is the current status of a InstallPlan as a whole.

pkg/api/apis/operators/subscription_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ type SubscriptionStatus struct {
183183
// +optional
184184
Reason ConditionReason
185185

186+
// InstallPlanGeneration is the current generation of the installplan
187+
// +optional
188+
InstallPlanGeneration int `json:"installPlanGeneration,omitempty"`
189+
186190
// InstallPlanRef is a reference to the latest InstallPlan that contains the Subscription's current CSV.
187191
// +optional
188192
InstallPlanRef *corev1.ObjectReference

pkg/api/apis/operators/v1alpha1/installplan_types.go

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type InstallPlanSpec struct {
2828
ClusterServiceVersionNames []string `json:"clusterServiceVersionNames"`
2929
Approval Approval `json:"approval"`
3030
Approved bool `json:"approved"`
31+
Generation int `json:"generation"`
3132
}
3233

3334
// InstallPlanPhase is the current status of a InstallPlan as a whole.
@@ -305,39 +306,6 @@ func (b *BundleLookup) SetCondition(cond BundleLookupCondition) BundleLookupCond
305306
return cond
306307
}
307308

308-
// ManifestsMatch returns true if the CSV manifests in the StepResources of the given list of steps
309-
// matches those in the InstallPlanStatus.
310-
func (s *InstallPlanStatus) CSVManifestsMatch(steps []*Step) bool {
311-
if s.Plan == nil && steps == nil {
312-
return true
313-
}
314-
if s.Plan == nil || steps == nil {
315-
return false
316-
}
317-
318-
manifests := make(map[string]struct{})
319-
for _, step := range s.Plan {
320-
resource := step.Resource
321-
if resource.Kind != ClusterServiceVersionKind {
322-
continue
323-
}
324-
manifests[resource.Manifest] = struct{}{}
325-
}
326-
327-
for _, step := range steps {
328-
resource := step.Resource
329-
if resource.Kind != ClusterServiceVersionKind {
330-
continue
331-
}
332-
if _, ok := manifests[resource.Manifest]; !ok {
333-
return false
334-
}
335-
delete(manifests, resource.Manifest)
336-
}
337-
338-
return len(manifests) == 0
339-
}
340-
341309
func (s *Step) String() string {
342310
return fmt.Sprintf("%s: %s (%s)", s.Resolving, s.Resource, s.Status)
343311
}

pkg/api/apis/operators/v1alpha1/subscription_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ type SubscriptionStatus struct {
186186
// +optional
187187
Reason ConditionReason `json:"reason,omitempty"`
188188

189+
// InstallPlanGeneration is the current generation of the installplan
190+
// +optional
191+
InstallPlanGeneration int `json:"installPlanGeneration,omitempty"`
192+
189193
// InstallPlanRef is a reference to the latest InstallPlan that contains the Subscription's current CSV.
190194
// +optional
191195
InstallPlanRef *corev1.ObjectReference `json:"installPlanRef,omitempty"`

pkg/api/apis/operators/v1alpha1/zz_generated.conversion.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// +k8s:deepcopy-gen=package
2+
// +k8s:conversion-gen=github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators
3+
// +groupName=operators.coreos.com
4+
5+
// Package v1alpha2 contains resources types for version v1alpha2 of the operators.coreos.com API group.
6+
package v1alpha2
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package v1alpha2
2+
3+
import (
4+
"sort"
5+
"strings"
6+
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
const (
12+
OperatorGroupAnnotationKey = "olm.operatorGroup"
13+
OperatorGroupNamespaceAnnotationKey = "olm.operatorNamespace"
14+
OperatorGroupTargetsAnnotationKey = "olm.targetNamespaces"
15+
OperatorGroupProvidedAPIsAnnotationKey = "olm.providedAPIs"
16+
17+
OperatorGroupKind = "OperatorGroup"
18+
)
19+
20+
// OperatorGroupSpec is the spec for an OperatorGroup resource.
21+
type OperatorGroupSpec struct {
22+
// Selector selects the OperatorGroup's target namespaces.
23+
// +optional
24+
Selector *metav1.LabelSelector `json:"selector,omitempty"`
25+
26+
// TargetNamespaces is an explicit set of namespaces to target.
27+
// If it is set, Selector is ignored.
28+
// +optional
29+
TargetNamespaces []string `json:"targetNamespaces,omitempty"`
30+
31+
// ServiceAccountName is the admin specified service account which will be
32+
// used to deploy operator(s) in this operator group.
33+
ServiceAccountName string `json:"serviceAccountName,omitempty"`
34+
35+
// Static tells OLM not to update the OperatorGroup's providedAPIs annotation
36+
// +optional
37+
StaticProvidedAPIs bool `json:"staticProvidedAPIs,omitempty"`
38+
}
39+
40+
// OperatorGroupStatus is the status for an OperatorGroupResource.
41+
type OperatorGroupStatus struct {
42+
// Namespaces is the set of target namespaces for the OperatorGroup.
43+
Namespaces []string `json:"namespaces,omitempty"`
44+
45+
// ServiceAccountRef references the service account object specified.
46+
ServiceAccountRef *corev1.ObjectReference `json:"serviceAccountRef,omitempty"`
47+
48+
// LastUpdated is a timestamp of the last time the OperatorGroup's status was Updated.
49+
LastUpdated *metav1.Time `json:"lastUpdated"`
50+
}
51+
52+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
53+
// +genclient
54+
55+
// OperatorGroup is the unit of multitenancy for OLM managed operators.
56+
// It constrains the installation of operators in its namespace to a specified set of target namespaces.
57+
type OperatorGroup struct {
58+
metav1.TypeMeta `json:",inline"`
59+
metav1.ObjectMeta `json:"metadata"`
60+
61+
// +optional
62+
Spec OperatorGroupSpec `json:"spec"`
63+
Status OperatorGroupStatus `json:"status,omitempty"`
64+
}
65+
66+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
67+
68+
// OperatorGroupList is a list of OperatorGroup resources.
69+
type OperatorGroupList struct {
70+
metav1.TypeMeta `json:",inline"`
71+
metav1.ListMeta `json:"metadata"`
72+
73+
Items []OperatorGroup `json:"items"`
74+
}
75+
76+
func (o *OperatorGroup) BuildTargetNamespaces() string {
77+
sort.Strings(o.Status.Namespaces)
78+
return strings.Join(o.Status.Namespaces, ",")
79+
}
80+
81+
// IsServiceAccountSpecified returns true if the spec has a service account name specified.
82+
func (o *OperatorGroup) IsServiceAccountSpecified() bool {
83+
if o.Spec.ServiceAccountName == "" {
84+
return false
85+
}
86+
87+
return true
88+
}
89+
90+
// HasServiceAccountSynced returns true if the service account specified has been synced.
91+
func (o *OperatorGroup) HasServiceAccountSynced() bool {
92+
if o.IsServiceAccountSpecified() && o.Status.ServiceAccountRef != nil {
93+
return true
94+
}
95+
96+
return false
97+
}

0 commit comments

Comments
 (0)