Skip to content

Commit cc5c8f9

Browse files
Merge pull request #481 from fmount/conditions
Re-init conditions for each reconcile
2 parents 611ab23 + 8a10e74 commit cc5c8f9

File tree

11 files changed

+216
-106
lines changed

11 files changed

+216
-106
lines changed

api/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.20
55
require (
66
github.com/gophercloud/gophercloud v1.11.0
77
github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240313143432-9108b7f7290a
8-
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240314165949-fec16b14c33b
8+
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240326081751-56015b1ae3f6
99
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240314165949-fec16b14c33b
1010
github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240314165949-fec16b14c33b
1111
k8s.io/api v0.28.7

api/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxC
6969
github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4=
7070
github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240313143432-9108b7f7290a h1:XcUHh0j65hm8/4orLTH6aRTv3Ah4rGP1rA4yu7G0fR0=
7171
github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240313143432-9108b7f7290a/go.mod h1:8C7VPKXAxiwB5Z4Kwn12VL0guW6onIG0Ayxiio5Vyu0=
72-
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240314165949-fec16b14c33b h1:5EzrrjcGziV69MsEgoBwPdsggY56M6jUxGBP9pp+hwo=
73-
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240314165949-fec16b14c33b/go.mod h1:DL+Ts0k+fzgZmx0XxWArIeAmdKuTkPa1I5DThdybfmE=
72+
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240326081751-56015b1ae3f6 h1:4Z7LjnjEF82XiusXJTI/4TqgwnJas3cdvg/qEgkrW8Q=
73+
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240326081751-56015b1ae3f6/go.mod h1:DL+Ts0k+fzgZmx0XxWArIeAmdKuTkPa1I5DThdybfmE=
7474
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240314165949-fec16b14c33b h1:FEbadtLx4+ktxf79ZJoKZmfMNsQyqqgL5T9NXWc3i/k=
7575
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240314165949-fec16b14c33b/go.mod h1:ghnFgNIzj4amS897wEto+L+jYzDSg2cJ6y32RNfFGhk=
7676
github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240314165949-fec16b14c33b h1:lygG1KiF5d9HpKpGAl5fa8JVlC9j5VFvC4iKvJkJslA=

api/v1beta1/conditions.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
const (
2424
// GlanceAPIReadyCondition Status=True condition which indicates if the GlanceAPI is configured and operational
2525
GlanceAPIReadyCondition condition.Type = "GlanceAPIReady"
26+
// CinderCondition
27+
CinderCondition= "CinderReady"
2628
)
2729

2830
// Glance Reasons used by API objects.
@@ -35,7 +37,10 @@ const (
3537
//
3638
// GlanceAPIReadyInitMessage
3739
GlanceAPIReadyInitMessage = "GlanceAPI not started"
38-
3940
// GlanceAPIReadyErrorMessage
4041
GlanceAPIReadyErrorMessage = "GlanceAPI error occured %s"
42+
// CinderInitMessage
43+
CinderInitMessage = "Waiting for Cinder resources"
44+
// CinderReadyMessage
45+
CinderReadyMessage = "Cinder resources exist"
4146
)

api/v1beta1/glance_types.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,11 @@ func init() {
206206
SchemeBuilder.Register(&Glance{}, &GlanceList{})
207207
}
208208

209-
// IsReady - returns true if Glance is reconciled successfully
209+
// IsReady - returns true if the underlying GlanceAPI is reconciled successfully
210+
// and set the ReadyCondition to True: it is mirrored to the top-level CR, so
211+
// the purpose of this function is to let the openstack-operator to gather the
212+
// Status of the entire Glance Deployment (intended as a single entity) from a
213+
// single place
210214
func (instance Glance) IsReady() bool {
211215
return instance.Status.Conditions.IsTrue(condition.ReadyCondition)
212216
}

controllers/glance_controller.go

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ func (r *GlanceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
123123
return ctrl.Result{}, err
124124
}
125125

126+
// initialize status if Conditions is nil, but do not reset if it already
127+
// exists
128+
isNewInstance := instance.Status.Conditions == nil
129+
if isNewInstance {
130+
instance.Status.Conditions = condition.Conditions{}
131+
}
132+
133+
// Save a copy of the condtions so that we can restore the LastTransitionTime
134+
// when a condition's state doesn't change.
135+
savedConditions := instance.Status.Conditions.DeepCopy()
136+
126137
// Always patch the instance status when exiting this function so we can persist any changes.
127138
defer func() {
128139
// update the Ready condition based on the sub conditions
@@ -137,46 +148,40 @@ func (r *GlanceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
137148
instance.Status.Conditions.Set(
138149
instance.Status.Conditions.Mirror(condition.ReadyCondition))
139150
}
151+
condition.RestoreLastTransitionTimes(&instance.Status.Conditions, savedConditions)
140152
err := helper.PatchInstance(ctx, instance)
141153
if err != nil {
142154
_err = err
143155
return
144156
}
145157
}()
146158

147-
// If we're not deleting this and the service object doesn't have our finalizer, add it.
148-
if instance.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(instance, helper.GetFinalizer()) {
149-
return ctrl.Result{}, nil
150-
}
151-
152-
//
153-
// initialize status
154-
//
155-
if instance.Status.Conditions == nil {
156-
instance.Status.Conditions = condition.Conditions{}
157-
// initialize conditions used later as Status=Unknown
158-
cl := condition.CreateList(
159-
condition.UnknownCondition(condition.DBReadyCondition, condition.InitReason, condition.DBReadyInitMessage),
160-
condition.UnknownCondition(condition.DBSyncReadyCondition, condition.InitReason, condition.DBSyncReadyInitMessage),
161-
condition.UnknownCondition(condition.MemcachedReadyCondition, condition.InitReason, condition.MemcachedReadyInitMessage),
162-
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
163-
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage),
164-
condition.UnknownCondition(glancev1.GlanceAPIReadyCondition, condition.InitReason, glancev1.GlanceAPIReadyInitMessage),
165-
// right now we have no dedicated KeystoneServiceReadyInitMessage
166-
condition.UnknownCondition(condition.KeystoneServiceReadyCondition, condition.InitReason, ""),
167-
condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage),
168-
// service account, role, rolebinding conditions
169-
condition.UnknownCondition(condition.ServiceAccountReadyCondition, condition.InitReason, condition.ServiceAccountReadyInitMessage),
170-
condition.UnknownCondition(condition.RoleReadyCondition, condition.InitReason, condition.RoleReadyInitMessage),
171-
condition.UnknownCondition(condition.RoleBindingReadyCondition, condition.InitReason, condition.RoleBindingReadyInitMessage),
172-
condition.UnknownCondition(condition.CronJobReadyCondition, condition.InitReason, condition.CronJobReadyInitMessage),
173-
)
174-
175-
instance.Status.Conditions.Init(&cl)
159+
// initialize conditions used later as Status=Unknown, except the ReadyCondition
160+
// that should be False when we start
161+
cl := condition.CreateList(
162+
// Mark ReadyCondition as False from the beginning
163+
condition.FalseCondition(condition.ReadyCondition, condition.InitReason, condition.SeverityInfo, condition.ReadyInitMessage),
164+
condition.UnknownCondition(condition.DBReadyCondition, condition.InitReason, condition.DBReadyInitMessage),
165+
condition.UnknownCondition(condition.DBSyncReadyCondition, condition.InitReason, condition.DBSyncReadyInitMessage),
166+
condition.UnknownCondition(condition.MemcachedReadyCondition, condition.InitReason, condition.MemcachedReadyInitMessage),
167+
condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage),
168+
condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage),
169+
condition.UnknownCondition(glancev1.GlanceAPIReadyCondition, condition.InitReason, glancev1.GlanceAPIReadyInitMessage),
170+
condition.UnknownCondition(condition.KeystoneServiceReadyCondition, condition.InitReason, ""),
171+
// service account, role, rolebinding conditions
172+
condition.UnknownCondition(condition.ServiceAccountReadyCondition, condition.InitReason, condition.ServiceAccountReadyInitMessage),
173+
condition.UnknownCondition(condition.RoleReadyCondition, condition.InitReason, condition.RoleReadyInitMessage),
174+
condition.UnknownCondition(condition.RoleBindingReadyCondition, condition.InitReason, condition.RoleBindingReadyInitMessage),
175+
condition.UnknownCondition(condition.CronJobReadyCondition, condition.InitReason, condition.CronJobReadyInitMessage),
176+
)
177+
instance.Status.Conditions.Init(&cl)
176178

179+
// If we're not deleting this and the service object doesn't have our finalizer, add it.
180+
if instance.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(instance, helper.GetFinalizer()) || isNewInstance {
177181
// Register overall status immediately to have an early feedback e.g. in the cli
178182
return ctrl.Result{}, nil
179183
}
184+
180185
if instance.Status.Hash == nil {
181186
instance.Status.Hash = map[string]string{}
182187
}
@@ -479,12 +484,7 @@ func (r *GlanceReconciler) reconcileInit(
479484
r.Log.Info(fmt.Sprintf("Service '%s' - Job %s hash added - %s", instance.Name, jobDef.Name, instance.Status.Hash[glancev1.DbSyncHash]))
480485
}
481486
instance.Status.Conditions.MarkTrue(condition.DBSyncReadyCondition, condition.DBSyncReadyMessage)
482-
483-
// when job passed, mark NetworkAttachmentsReadyCondition ready
484-
instance.Status.Conditions.MarkTrue(condition.NetworkAttachmentsReadyCondition, condition.NetworkAttachmentsReadyMessage)
485-
486487
// run Glance db sync - end
487-
488488
r.Log.Info(fmt.Sprintf("Reconciled Service '%s' init successfully", instance.Name))
489489
return ctrl.Result{}, nil
490490
}
@@ -699,8 +699,14 @@ func (r *GlanceReconciler) reconcileNormal(ctx context.Context, instance *glance
699699
return ctrlResult, err
700700
}
701701
instance.Status.Conditions.MarkTrue(condition.CronJobReadyCondition, condition.CronJobReadyMessage)
702-
703702
// create CronJob - end
703+
704+
// We reached the end of the Reconcile, update the Ready condition based on
705+
// the sub conditions
706+
if instance.Status.Conditions.AllSubConditionIsTrue() {
707+
instance.Status.Conditions.MarkTrue(
708+
condition.ReadyCondition, condition.ReadyMessage)
709+
}
704710
return ctrl.Result{}, nil
705711
}
706712

@@ -873,6 +879,10 @@ func (r *GlanceReconciler) apiDeploymentCreateOrUpdate(
873879
apiSpec.GlanceAPITemplate.StorageRequest = instance.Spec.StorageRequest
874880
apiSpec.GlanceAPITemplate.StorageClass = instance.Spec.StorageClass
875881
apiSpec.MemcachedInstance = memcached.Name
882+
// Make sure to inject the ContainerImage passed by the OpenStackVersions
883+
// resource to all the underlying instances and rollout a new StatefulSet
884+
// if it has been changed
885+
apiSpec.GlanceAPITemplate.ContainerImage = instance.Spec.ContainerImage
876886

877887
// We select which glanceAPI should register the keystoneEndpoint by using
878888
// an API selector defined in the main glance CR; if it matches with the

0 commit comments

Comments
 (0)