Skip to content

Reconcile bug that fetches images several times per second - #49

Closed
yahor-kurachkin wants to merge 28 commits into
cobaltcore-dev:masterfrom
yahor-kurachkin:fix/reconcile-bug
Closed

yahor-kurachkin wants to merge 28 commits into
cobaltcore-dev:masterfrom
yahor-kurachkin:fix/reconcile-bug

Conversation

@yahor-kurachkin

Copy link
Copy Markdown
Collaborator

No description provided.

Add machine-image discovery for OpenStack CloudProfiles:

- Glance source: discover public gardenlinux images across regions,
  parse versions from image names, keep the newest N (default 3),
  skip _usi variants.
- OpenStackProvider: write per-region image UUIDs into the
  gardener-extension-provider-openstack providerConfig.
- Lifecycle: mark the oldest kept version deprecated and stamp its
  expirationDate once on the transition, preserving it thereafter
  (ImageUpdater.resolveExpiration).
- Wire GlanceSource into the ManagedCloudProfile API and controller;
  regenerate CRD and deepcopy.
- Unit tests for expiration, usi skipping, and provider config.
Add machine-image discovery for OpenStack CloudProfiles:

- Glance source: discover public gardenlinux images across regions,
  parse versions from image names, keep the newest N (default 3),
  skip _usi variants.
- OpenStackProvider: write per-region image UUIDs into the
  gardener-extension-provider-openstack providerConfig.
- Lifecycle: mark the oldest kept version deprecated and stamp its
  expirationDate once on the transition, preserving it thereafter
  (ImageUpdater.resolveExpiration).
- Wire GlanceSource into the ManagedCloudProfile API and controller;
  regenerate CRD and deepcopy.
- Unit tests for expiration, usi skipping, and provider config.
# Conflicts:
#	cloudprofilesync/ossync/source/glance/os_source_test.go
# Conflicts:
#	cloudprofilesync/ossync/os_image_updater.go
#	cloudprofilesync/ossync/os_image_updater_test.go
#	cloudprofilesync/ossync/provider/openstack/provider.go
#	cloudprofilesync/ossync/source/glance/os_source.go
Copilot AI lite review requested due to automatic review settings September 1, 2026 08:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a reconcile loop that was causing very frequent re-reconciliation (and repeated image fetching) by reducing needless status patches, filtering reconcile triggers on ManagedCloudProfile status-only updates, and stabilizing CloudProfile-related serialized output.

Changes:

  • Avoids issuing a status patch when the ManagedCloudProfile status is semantically unchanged.
  • Adds a GenerationChangedPredicate to the controller watch on ManagedCloudProfile to prevent status-only updates from retriggering reconciliation.
  • Stabilizes OpenStack ProviderConfig output by sorting region mappings; additionally preserves machine image expiration dates across spec regeneration.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
controllers/managedcloudprofile_controller.go Prevents status-only update loops by skipping no-op status patches and filtering reconcile events to generation changes.
controllers/cloud_profile.go Preserves machine image expiration dates across CloudProfile spec regeneration to reduce churn.
cloudprofilesync/ossync/provider/openstack/provider.go Ensures deterministic ProviderConfig marshaling by sorting regions, reducing spec churn.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread controllers/cloud_profile.go
Copilot AI review requested due to automatic review settings September 1, 2026 09:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

Comment thread controllers/cloud_profile.go
Comment thread controllers/cloud_profile.go
Comment thread cloudprofilesync/ossync/provider/openstack/provider.go
Comment thread cloudprofilesync/ossync/provider/openstack/provider.go
sapcc-bot and others added 12 commits September 1, 2026 11:20
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Add machine-image discovery for OpenStack CloudProfiles:

- Glance source: discover public gardenlinux images across regions,
  parse versions from image names, keep the newest N (default 3),
  skip _usi variants.
- OpenStackProvider: write per-region image UUIDs into the
  gardener-extension-provider-openstack providerConfig.
- Lifecycle: mark the oldest kept version deprecated and stamp its
  expirationDate once on the transition, preserving it thereafter
  (ImageUpdater.resolveExpiration).
- Wire GlanceSource into the ManagedCloudProfile API and controller;
  regenerate CRD and deepcopy.
- Unit tests for expiration, usi skipping, and provider config.

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
…obaltcore-dev#44)

* Run go-makefile-maker

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

* feat: add OpenStack Glance source and provider for gardenlinux images

Add machine-image discovery for OpenStack CloudProfiles:

- Glance source: discover public gardenlinux images across regions,
  parse versions from image names, keep the newest N (default 3),
  skip _usi variants.
- OpenStackProvider: write per-region image UUIDs into the
  gardener-extension-provider-openstack providerConfig.
- Lifecycle: mark the oldest kept version deprecated and stamp its
  expirationDate once on the transition, preserving it thereafter
  (ImageUpdater.resolveExpiration).
- Wire GlanceSource into the ManagedCloudProfile API and controller;
  regenerate CRD and deepcopy.
- Unit tests for expiration, usi skipping, and provider config.

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

* feat: add OpenStack Glance source and provider for gardenlinux images

Add machine-image discovery for OpenStack CloudProfiles:

- Glance source: discover public gardenlinux images across regions,
  parse versions from image names, keep the newest N (default 3),
  skip _usi variants.
- OpenStackProvider: write per-region image UUIDs into the
  gardener-extension-provider-openstack providerConfig.
- Lifecycle: mark the oldest kept version deprecated and stamp its
  expirationDate once on the transition, preserving it thereafter
  (ImageUpdater.resolveExpiration).
- Wire GlanceSource into the ManagedCloudProfile API and controller;
  regenerate CRD and deepcopy.
- Unit tests for expiration, usi skipping, and provider config.

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

# Conflicts:
#	cloudprofilesync/ossync/source/glance/os_source_test.go

* fix: codeRabbitAI review

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

* fix: CopilotAI review

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

* fix: Linter error

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

* fix: add license

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>

---------

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: yahor-kurachkin <yahor.kurachkin@sap.com>
Co-authored-by: sapcc-bot <sapcc-bot@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
* Populate capabilities

Signed-off-by: Anton Paulovich <a.paulovich@sap.com>

* Changes motivated by AI code review

Signed-off-by: Anton Paulovich <a.paulovich@sap.com>

---------

Signed-off-by: Anton Paulovich <a.paulovich@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: Anton Paulovich <a.paulovich@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 1, 2026 09:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 27 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • api/v1alpha1/zz_generated.deepcopy.go: Generated file

Comment thread cloudprofilesync/ossync/provider/openstack/provider.go Outdated
Comment thread crd/README.md
Signed-off-by: yahor-kurachkin <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 11:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new expiration-preservation logic can incorrectly retain stale ExpirationDate values when a version becomes supported again (e.g., KeepLatest changes), which is a correctness issue.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread cloudprofilesync/ossync/os_image_updater.go Outdated
Comment thread controllers/cloud_profile.go
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 12:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

resolveExpiration currently drops an existing expiration date when the source doesn’t provide one, contradicting intended behavior and breaking the existing expiration-preservation test.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cloudprofilesync/ossync/os_image_updater.go Outdated
Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 13:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are targeted, improve reconcile idempotency/stability, and include corresponding unit-test updates for the new expiration-date semantics.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 14:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The updated expiration resolution logic ignores version classification and will not clear stale expiration dates for supported versions, conflicting with the intended behavior and tests.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cloudprofilesync/ossync/os_image_updater.go
…ration

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 14:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The updated expiration resolution logic does not respect version classification and can incorrectly retain an expiration date for supported versions.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

controllers/cloud_profile.go:237

  • expirationDateKey uses '/' to join imageName and version, which can produce ambiguous keys if either part ever contains '/'. Using a separator that cannot occur in either value avoids accidental collisions.

cloudprofilesync/ossync/os_image_updater.go:121

  • resolveExpiration's implementation ignores the version classification and will preserve an existing ExpirationDate even when the source reports the version as supported (Classification=nil/Supported), which contradicts the function comment and can leave supported versions with a stale expiration date from spec input.
// resolveExpiration decides a version's expiration date from the source's
// classification. A version the source reports as supported carries no date, so
// any previously stamped date is cleared (e.g. it returned to supported after a
// KeepLatest increase). For a deprecated version the existing date is preserved
// so the timestamp does not drift on every reconcile; otherwise the source's
// date is used. The updater never invents a date.
func (iu *ImageUpdater) resolveExpiration(src SourceImage, existing *metav1.Time) *metav1.Time {
	return cmp.Or(existing, src.ExpirationDate)
}
  • Files reviewed: 7/7 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Signed-off-by: C5421281 <yahor.kurachkin@sap.com>
Copilot AI review requested due to automatic review settings September 2, 2026 14:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The loop-prevention behavior is largely untested at the controller/provider integration points, so adding targeted regression tests is needed to prevent reintroducing reconcile churn.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

controllers/cloud_profile.go:54

  • Add test coverage to ensure expiration dates on deprecated MachineImage versions are preserved across reconciles (i.e., an existing ExpirationDate is retained even if the source stamps a new one each run). This preservation is key to preventing CloudProfile spec churn, but there is no test asserting it in the controller suite.
		storedExpirations := collectExpirationDates(cloudProfile.Spec.MachineImages)
		cloudProfile.Spec = CloudProfileSpecToGardener(&mcp.Spec.CloudProfile)
		errs := make([]error, 0)
		for _, updates := range mcp.Spec.MachineImageUpdates {
			log.V(1).Info("updating machine images", "cloudProfile", cloudProfile.Name)
			if updateErr := r.updateMachineImages(ctx, log, updates, &cloudProfile.Spec); updateErr != nil {
				errs = append(errs, updateErr)
			}
		}
		applyExpirationDates(cloudProfile.Spec.MachineImages, storedExpirations)
		if mcp.Spec.KubernetesUpdate != nil {

cloudprofilesync/ossync/provider/openstack/provider.go:79

  • Please add a unit test to lock in the new deterministic region ordering (e.g., feed regions in a different order and assert the resulting ProviderConfig has regions sorted by name/ID). Without a test, a future refactor could accidentally reintroduce ProviderConfig churn and the reconcile loop this change is addressing.
		// Sort regions by name so the marshaled ProviderConfig is stable across
		// reconciles; the source does not guarantee a consistent region order,
		// which would otherwise churn the CloudProfile and cause a reconcile loop.
		slices.SortFunc(entry.Regions, func(a, b openstackv1alpha1.RegionIDMapping) int {
			if c := cmp.Compare(a.Name, b.Name); c != 0 {
				return c
			}
			return cmp.Compare(a.ID, b.ID)
		})
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread controllers/managedcloudprofile_controller.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants