Skip to content

fix: scope SpinAppExecutor finalizer check to executor's namespace#481

Open
melderan wants to merge 1 commit intospinframework:mainfrom
melderan:fix/executor-finalizer-cross-namespace
Open

fix: scope SpinAppExecutor finalizer check to executor's namespace#481
melderan wants to merge 1 commit intospinframework:mainfrom
melderan:fix/executor-finalizer-cross-namespace

Conversation

@melderan
Copy link

@melderan melderan commented Mar 6, 2026

Summary

Fixes #480 — the handleDeletion() finalizer check for dependent SpinApps matches by executor name across all namespaces instead of scoping to the executor's own namespace. A SpinApp in namespace B blocks deletion of an unrelated SpinAppExecutor with the same name in namespace A.

Changes

One-line fix in internal/controller/spinappexecutor_controller.go:

// Before (matches all namespaces):
r.Client.List(ctx, &spinApps, client.MatchingFields{spinAppExecutorKey: executor.Name})

// After (scoped to executor's namespace):
r.Client.List(ctx, &spinApps, client.InNamespace(executor.Namespace), client.MatchingFields{spinAppExecutorKey: executor.Name})

Regression test (TestSpinAppExecutorReconcile_CrossNamespaceDoesNotBlockDeletion):

  • Creates same-named executors in two namespaces
  • Creates a SpinApp in namespace B only
  • Deletes executor in namespace A
  • Asserts it deletes successfully (was blocked before the fix)
  • Asserts executor in namespace B is unaffected

Verification

Reproduced the bug on K8s 1.33.6 with spin-operator v0.6.1:

  1. Created two namespaces with same-named executors, SpinApp only in ns-b
  2. Deleted executor in ns-a → stuck with finalizer, operator logs "cannot delete SpinAppExecutor with dependent SpinApps"
  3. Built and deployed the patched operator
  4. Repeated the test → executor in ns-a deletes immediately, SpinApp in ns-b unaffected

The handleDeletion() method lists dependent SpinApps by executor name
across all namespaces. This causes a SpinApp in namespace B to block
deletion of an unrelated SpinAppExecutor with the same name in
namespace A — even though there are zero SpinApps in namespace A.

This is particularly impactful because the common pattern (and the Helm
chart bootstrap hook) uses the same executor name "containerd-shim-spin"
in every namespace. All executors with that name become cross-coupled.

The fix adds client.InNamespace(executor.Namespace) to scope the
dependent SpinApp lookup to the executor's own namespace.

Includes a regression test that creates same-named executors in two
namespaces with a SpinApp only in one, then verifies deleting the
executor in the other namespace succeeds.

Fixes spinframework#480

Signed-off-by: John Moore <melderan@gmail.com>
@melderan melderan force-pushed the fix/executor-finalizer-cross-namespace branch from ce85681 to 843aa03 Compare March 6, 2026 16:37
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.

SpinAppExecutor finalizer checks for dependent SpinApps across all namespaces instead of its own

1 participant