Skip to content

Commit

Permalink
Compute GlanceAPI storage configuration hash
Browse files Browse the repository at this point in the history
Add .Spec.Storage configuration and .Spec.ImageCache to the Hash based on the
enabled_backends.
This will trigger an API refresh not only when the enabled_backends string
changes, but also if the Storage interface or imageCache (e.g. storageClass,
storageRequest, externalStorage) changes as part of any day2 ops.

Signed-off-by: Francesco Pantano <fpantano@redhat.com>
  • Loading branch information
fmount committed Nov 8, 2024
1 parent f6c6771 commit 0651443
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
59 changes: 43 additions & 16 deletions controllers/glanceapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -926,15 +926,15 @@ func (r *GlanceAPIReconciler) reconcileNormal(
return ctrlResult, err
}
}
// Cleanup any existing (but not used) ImageCache cronJob
if ctrlResult, err := r.deleteImageCacheJob(
ctx,
helper,
instance,
GetServiceLabels(instance),
); err != nil {
return ctrlResult, err
}
}
// Cleanup any existing (but not used) ImageCache cronJob
if ctrlResult, err := r.deleteImageCacheJob(
ctx,
helper,
instance,
GetServiceLabels(instance),
); err != nil {
return ctrlResult, err
}

// If we reach this point, we can mark the CronJobReadyCondition as True
Expand Down Expand Up @@ -1121,17 +1121,40 @@ func (r *GlanceAPIReconciler) createHashOfInputHashes(
}

// createHashOfBackendConfig - It creates an Hash of the current "enabledBackend"
// string, and it's set in the .Status.Hash of the current GlanceAPI.
// If a backend is added or removed, we're able to attach a new PVC for an existing
// API by recreating the StateFulSet through the glanceAPIRefresh function. This
// function helps to figure out if the glanceAPIRefresh should be triggered or not
// string, combined with the storage interface configuration (both PVCs and imageCache).
// The resulting hash is set in the .Status.Hash of the GlanceAPI object.
// If a backend is added or removed, we're able to plug or unplug a PVC for an
// existing API by recreating the StateFulSet through the glanceAPIRefresh function.
// The hash update results in a glanceAPIRefresh trigger.
func (r *GlanceAPIReconciler) createHashOfBackendConfig(
instance *glancev1.GlanceAPI,
backends []string,
) (string, bool, error) {
var hashMap map[string]string
changed := false
hash, err := util.ObjectHash(backends)
// Compute enabled_backend hash
backendHash, err := util.ObjectHash(backends)
if err != nil {
return backendHash, changed, err
}
// Compute storage interface settings hash
storageHash, err := util.ObjectHash(instance.Spec.Storage)
if err != nil {
return storageHash, changed, err
}
// Compute Image Cache settings hash (using only the Size parameter as we
// don't need to check the cronJobs settings)
cacheHash, err := util.ObjectHash(instance.Spec.ImageCache.Size)
if err != nil {
return cacheHash, changed, err
}
// The final Hash (stored in instance.Status.Hash) is the concatenation
// between backendHash (retrieved by customServiceConfig), storageHash
// (coming from instance.Spec.Storage interface), and cacheHash (based on
// instance.Spec.ImageCache.Size).
// The combination of the three represents the "Storage" configuration
// of the current GlanceAPI
hash, err := util.ObjectHash((backendHash + storageHash + cacheHash))
if err != nil {
return hash, changed, err
}
Expand Down Expand Up @@ -1303,7 +1326,7 @@ func (r *GlanceAPIReconciler) deleteImageCacheJob(
if err := r.Client.Get(ctx, types.NamespacedName{
Name: strings.TrimPrefix(pvcName, "glance-cache-"),
Namespace: instance.Namespace,
}, &pod); err != nil && k8s_errors.IsNotFound(err) {
}, &pod); err != nil && k8s_errors.IsNotFound(err) || instance.Spec.ImageCache.Size == "" {
// if we have no pod Running with the associated cache pvc,
// we can delete the imageCache cronJob if still exists
if ctrlResult, err = r.deleteJob(ctx, instance, pvcName); err != nil {
Expand Down Expand Up @@ -1385,7 +1408,11 @@ func (r *GlanceAPIReconciler) glanceAPIRefresh(
h *helper.Helper,
instance *glancev1.GlanceAPI,
) error {
sts, err := statefulset.GetStatefulSetWithName(ctx, h, fmt.Sprintf("%s-api", instance.Name), instance.Namespace)
stsName := instance.Name
if instance.Spec.APIType != glancev1.APISingle {
stsName = fmt.Sprintf("%s-api", instance.Name)
}
sts, err := statefulset.GetStatefulSetWithName(ctx, h, stsName, instance.Namespace)
if err != nil {
if k8s_errors.IsNotFound(err) {
// Request object not found
Expand Down
8 changes: 4 additions & 4 deletions docs/design-decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,10 +537,10 @@ When the `External` model is adopted, if `Ceph` is used as a backend and an
storage that is tied to the staging area, and the conversion operation that
uses the `os_glance_staging_store` directory (within the `Pod`) interacts with
the `RWX` `NFS` backend provided via `extraMounts`.
With this scenario, no image-cache PVC can be requested and mounted to a
subPath, because it should be the human administrator responsibility to plan
for persistence via ExtraMounts (where mounts are realized using SubPath to
avoid directory overlapping).
With this scenario, an image-cache PVC can still be requested and mounted to
a subPath, unless the human administrator would like to manage it externally
via ExtraMounts (where mounts are realized using SubPath to avoid directory
overlapping).

### PVC

Expand Down
15 changes: 8 additions & 7 deletions pkg/glanceapi/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,15 @@ func StatefulSet(
return statefulset, err
}
statefulset.Spec.VolumeClaimTemplates = []corev1.PersistentVolumeClaim{localPvc}

if len(instance.Spec.ImageCache.Size) > 0 {
cachePvc, err := glance.GetPvc(instance, labels, glance.PvcCache)
if err != nil {
return statefulset, err
}
statefulset.Spec.VolumeClaimTemplates = append(statefulset.Spec.VolumeClaimTemplates, cachePvc)
}
// Staging and Cache are realized through separate interfaces
// (TODO) Allow to externally manage image-cache
if len(instance.Spec.ImageCache.Size) > 0 {
cachePvc, err := glance.GetPvc(instance, labels, glance.PvcCache)
if err != nil {
return statefulset, err
}
statefulset.Spec.VolumeClaimTemplates = append(statefulset.Spec.VolumeClaimTemplates, cachePvc)
}

statefulset.Spec.Template.Spec.Volumes = append(glance.GetVolumes(
Expand Down

0 comments on commit 0651443

Please sign in to comment.