fix: restore init container uses configured registry auth secret name#1615
fix: restore init container uses configured registry auth secret name#1615akurinnoy wants to merge 2 commits intodevfile:mainfrom
Conversation
When backing up, CopySecret always named the copied secret with the
hardcoded constant DevWorkspaceBackupAuthSecretName ("devworkspace-
backup-registry-auth") regardless of the admin-configured name (e.g.
"quay-backup-auth"). On restore, GetNamespaceRegistryAuthSecret was
called with an empty operatorConfigNamespace, so it only searched the
workspace namespace, did not find the secret there (it was either not
copied at all or copied under the wrong name), and returned nil — causing
the workspace-restore init container to start without registry auth and
immediately crash with CrashLoopBackOff.
Changes:
- CopySecret: add secretName parameter; use it for the copy's ObjectMeta
Name instead of the hardcoded constant.
- HandleRegistryAuthSecret: pass secretName (the configured auth secret
name) to CopySecret.
- GetNamespaceRegistryAuthSecret: add operatorConfigNamespace parameter
and thread it through to HandleRegistryAuthSecret.
- pkg/library/restore: resolve the operator namespace via
infrastructure.GetNamespace() and pass it to
GetNamespaceRegistryAuthSecret so the lookup can fall back to the
operator namespace when the secret is absent from the workspace NS.
Migration note: any existing copies named "devworkspace-backup-registry-
auth" become orphaned under their DevWorkspace ownerReference; Kubernetes
garbage-collects them when the workspace is deleted. No active cleanup
code is needed.
Assisted-by: Claude Sonnet 4.6 (1M context)
Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: akurinnoy The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
💤 Files with no reviewable changes (1)
📝 WalkthroughWalkthroughGetWorkspaceRestoreInitContainer now resolves the operator namespace via infrastructure.GetNamespace() and passes it into secrets.GetNamespaceRegistryAuthSecret; secrets functions were updated to accept an operator-config namespace and a configurable secret name, and tests were added to validate the new flows and naming. Changes
Sequence Diagram(s)sequenceDiagram
participant Restore as Restore Module
participant Infra as infrastructure.GetNamespace
participant Secrets as secrets.GetNamespaceRegistryAuthSecret
participant Handler as secrets.HandleRegistryAuthSecret
participant K8s as Kubernetes API (client)
Restore->>Infra: resolve operator namespace
Infra-->>Restore: operator namespace (or error)
Restore->>Secrets: GetNamespaceRegistryAuthSecret(workspace, operatorConfigNamespace)
Secrets->>Handler: HandleRegistryAuthSecret(workspace, operatorConfigNamespace, secretName)
Handler->>K8s: Get secret in workspace namespace
alt secret found in workspace
K8s-->>Handler: secret
Handler-->>Secrets: return secret
else secret missing in workspace
Handler->>K8s: Get secret in operatorConfigNamespace (if non-empty)
alt found in operator namespace
K8s-->>Handler: operator secret
Handler->>K8s: Create copy in workspace namespace with configured secretName
K8s-->>Handler: created secret
Handler-->>Secrets: return copied secret
else not found
K8s-->>Handler: not found
Handler-->>Secrets: return error
end
end
Secrets-->>Restore: secret or error
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
pkg/library/restore/restore.go (1)
118-123: Avoid failing restore when operator namespace lookup is unavailableIf
infrastructure.GetNamespace()fails, restore now exits early even when the registry auth secret may already exist in the workspace namespace. Consider degrading gracefully (pass empty operator namespace and continue) so lookup still works in the workspace namespace path.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/library/restore/restore.go` around lines 118 - 123, The code currently returns an error when infrastructure.GetNamespace() fails, causing the restore to abort instead of attempting to find the registry auth secret in the workspace namespace; change the error path to degrade gracefully by setting operatorNamespace to an empty string and continuing (optionally log a warning) before calling secrets.GetNamespaceRegistryAuthSecret(ctx, k8sClient, workspace.DevWorkspace, workspace.Config, operatorNamespace, scheme, log) so that the secret lookup still proceeds using the workspace namespace path.pkg/secrets/backup_test.go (1)
197-207: Align test name with actual expectationThe test title says “returns nil, nil” but the assertion expects an error. Renaming the test to reflect
nil, errorwill avoid confusion during failure triage.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/secrets/backup_test.go` around lines 197 - 207, Rename the test description for the It block that calls secrets.HandleRegistryAuthSecret so it accurately reflects the assertions: change the title from "returns nil, nil when operator namespace is given but secret is in neither namespace" to something like "returns nil and an error when operator namespace is given but secret is in neither namespace" so the test name matches the expectation that result is nil and err is non-nil; update only the string passed to It(...) in the test containing the HandleRegistryAuthSecret invocation and its Expect(err).To(HaveOccurred()) / Expect(result).To(BeNil()) assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@pkg/library/restore/restore.go`:
- Around line 118-123: The code currently returns an error when
infrastructure.GetNamespace() fails, causing the restore to abort instead of
attempting to find the registry auth secret in the workspace namespace; change
the error path to degrade gracefully by setting operatorNamespace to an empty
string and continuing (optionally log a warning) before calling
secrets.GetNamespaceRegistryAuthSecret(ctx, k8sClient, workspace.DevWorkspace,
workspace.Config, operatorNamespace, scheme, log) so that the secret lookup
still proceeds using the workspace namespace path.
In `@pkg/secrets/backup_test.go`:
- Around line 197-207: Rename the test description for the It block that calls
secrets.HandleRegistryAuthSecret so it accurately reflects the assertions:
change the title from "returns nil, nil when operator namespace is given but
secret is in neither namespace" to something like "returns nil and an error when
operator namespace is given but secret is in neither namespace" so the test name
matches the expectation that result is nil and err is non-nil; update only the
string passed to It(...) in the test containing the HandleRegistryAuthSecret
invocation and its Expect(err).To(HaveOccurred()) / Expect(result).To(BeNil())
assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 01d1190b-a173-4528-b151-cec9f07bfa0f
📒 Files selected for processing (3)
pkg/library/restore/restore.gopkg/secrets/backup.gopkg/secrets/backup_test.go
The constant was used by CopySecret to hardcode the copy name regardless of the configured secret name. Now that CopySecret takes an explicit secretName parameter, the constant has no remaining callers and can be removed. Assisted-by: Claude Sonnet 4.6 (1M context) Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
What does this PR do?
When a workspace is backed up to a private registry,
CopySecrethardcodes the name of the copied auth secret asdevworkspace-backup-registry-auth, regardless of the name configured in the DWOC. During restore,GetNamespaceRegistryAuthSecretlooks only in the workspace namespace for the configured name and passes an empty operator namespace - so it never finds anything, mounts no credentials, and theworkspace-restoreinit container crashes withCrashLoopBackOff.This PR fixes the root cause:
CopySecretnow takes asecretNameparameter and uses it instead of the hardcoded constant, so the copy in theworkspace namespace gets the correct name
HandleRegistryAuthSecretpasses the configured name through toCopySecretGetNamespaceRegistryAuthSecretgains anoperatorConfigNamespaceparameter so the restore path can look up the operator namespace and copy the secret with the right nameOld copies named
devworkspace-backup-registry-authcreated by previous backups become orphaned but are owned by the workspace and will be garbage-collected when the workspace is deleted.Note: This is the root-cause fix. See #1614 for a more conservative fallback-only approach that avoids changing the
CopySecretsignature.What issues does this PR fix or reference?
CRW-10591
Is it tested? How?
New unit tests added.
PR Checklist
/test v8-devworkspace-operator-e2e, v8-che-happy-pathto trigger)v8-devworkspace-operator-e2e: DevWorkspace e2e testv8-che-happy-path: Happy path for verification integration with CheSummary by CodeRabbit
Refactor
Tests
Bug Fixes