Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute GlanceAPI storage configuration hash #648

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 45 additions & 18 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 existing (but not required anymore) ImageCache cronJob
if ctrlResult, err := r.cleanupImageCacheJob(
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 @@ -1278,9 +1301,9 @@ func (r *GlanceAPIReconciler) ensureImageCacheJob(
return ctrlResult, err
}

// deleteImageCacheJob - delete the ImageCache cronJobs associated to a given
// cleanupImageCacheJob - delete the ImageCache cronJobs associated to a given
// GlanceAPI
func (r *GlanceAPIReconciler) deleteImageCacheJob(
func (r *GlanceAPIReconciler) cleanupImageCacheJob(
ctx context.Context,
h *helper.Helper,
instance *glancev1.GlanceAPI,
Expand All @@ -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
Loading