Skip to content

fix(secret): stop pulp-server Secret churn from nondeterministic map iteration#1649

Open
mouchar wants to merge 1 commit into
pulp:mainfrom
mouchar:fix-secret
Open

fix(secret): stop pulp-server Secret churn from nondeterministic map iteration#1649
mouchar wants to merge 1 commit into
pulp:mainfrom
mouchar:fix-secret

Conversation

@mouchar
Copy link
Copy Markdown

@mouchar mouchar commented Jun 6, 2026

Summary

The pulp-server Secret containing settings.py was being rewritten on nearly every reconcile when spec.redirect_to_object_storage=true. The rewrite removed and re-added the REDIRECT_TO_OBJECT_STORAGE = True line in rapid succession, and each change restarted all pulpcore Deployments.

Observed in operator logs:

INFO controllers/utils.go:741   The Data from Secret pulp-server has been modified! Reconciling ...
INFO repo_manager/utils.go:430  Reprovisioning pulpcore pods to get the new settings ...
INFO controllers/utils.go:741   The Data from Secret pulp-server has been modified! Reconciling ...
INFO repo_manager/utils.go:430  Reprovisioning pulpcore pods to get the new settings ...
... (repeats several times in 1–2 s) ...
INFO controllers/utils.go:741   The Spec from Deployment pulp-api has been modified! Reconciling ...
INFO controllers/utils.go:741   The Spec from Deployment pulp-content has been modified! Reconciling ...
INFO controllers/utils.go:741   The Spec from Deployment pulp-worker has been modified! Reconciling ...

Root cause

needsMigrationSetting (in controllers/repo_manager/secret.go) iterated controllers.MigrationSettingsList() as a Go map[string]string. Go randomizes map range order per invocation. With the default CR (RedirectToObjectStorage=true, HideGuardedDistributions=false), the generated settings.py differed depending on which key the runtime visited first:

  • If HideGuardedDistributions was visited first, if !config { return } aborted the loop and REDIRECT_TO_OBJECT_STORAGE was never written.
  • If RedirectToObjectStorage was visited first, the line was written, then HideGuardedDistributions triggered the same early return.

Each time the freshly generated string differed from the stored Secret, ReconcileObject updated it and called restartPulpCorePods, cascading into Deployment reconciles.

Fix

Two issues addressed at the source:

  • MigrationSettingsList now returns []MigrationSetting — a slice of named OperatorField / PulpField pairs — so iteration order is fixed at the data definition rather than reconstructed at each call site.
  • The buggy return in needsMigrationSetting is replaced with continue, so a single disabled flag no longer skips later settings. (This latent bug would have resurfaced if both flags were ever true and ordering swapped.)

Both call sites of MigrationSettingsList were updated.

Test plan

  • Apply a Pulp CR with spec.redirect_to_object_storage=true and observe operator logs over several reconcile cycles — the "Data from Secret pulp-server has been modified" / "Reprovisioning pulpcore pods" churn should not appear.
  • Verify the pulp-server Secret's settings.py contains REDIRECT_TO_OBJECT_STORAGE = True and is stable across reconciles.
  • Verify the pulpcore Deployments (pulp-api, pulp-content, pulp-worker) are not restarted on the steady-state reconcile.
  • Verify migration is still triggered when redirect_to_object_storage or hide_guarded_distributions actually changes (SettingNeedsMigrationChanged path).

…ings

needsMigrationSetting iterated MigrationSettingsList as a map, whose
range order Go randomizes per invocation. With RedirectToObjectStorage=true
and HideGuardedDistributions=false (the default), each reconcile produced
one of two different settings.py contents depending on which key the
runtime visited first:

  - if HideGuardedDistributions was visited first, the loop hit
    `if !config { return }` and aborted, dropping REDIRECT_TO_OBJECT_STORAGE
    entirely;
  - if RedirectToObjectStorage was visited first, the line was written and
    HideGuardedDistributions then triggered the early return.

The two outputs differed, so ReconcileObject kept rewriting the
pulp-server Secret and restarting pulpcore pods on every reconcile.

Fix both issues at the source:

  - change MigrationSettingsList to return []MigrationSetting (a slice of
    named OperatorField/PulpField pairs) so iteration order is fixed at
    the data definition rather than reconstructed at each call site;
  - replace the buggy `return` with `continue` so a single disabled flag
    no longer skips subsequent settings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Robert Moucha <robert.moucha@gooddata.com>
@openshift-ci openshift-ci Bot requested review from dkliban and git-hyagi June 6, 2026 17:33
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Jun 6, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mouchar
Once this PR has been reviewed and has the lgtm label, please assign git-hyagi for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Jun 6, 2026

Hi @mouchar. Thanks for your PR.

I'm waiting for a pulp member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant