Skip to content

fix: report a missing instance as a final state - #19

Open
corioliskraft wants to merge 5 commits into
stackitcloud:mainfrom
corioliskraft:fix/instance-not-found
Open

fix: report a missing instance as a final state#19
corioliskraft wants to merge 5 commits into
stackitcloud:mainfrom
corioliskraft:fix/instance-not-found

Conversation

@corioliskraft

@corioliskraft corioliskraft commented Sep 2, 2026

Copy link
Copy Markdown

Fixes #15

Today the reconcile of a StackitMachine whose server is gone sets the reason
InstanceError and returns an error, so the controller retries a state that no
retry changes. With this change the StackitMachine becomes not ready with the
reason InstanceNotFound, and a warning event names the server. The reconcile
gives no error back, so the retry loop stops. It still creates no replacement
server. The automatic replacement is out of scope here and is addressed by #7.

The trade-off: no error means no requeue, so a false InstanceNotFound does not
correct itself. The machine would then keep a false "not ready", and the
provider would not repair its load balancer target or its bastion SSH access,
until a watch event arrives, or in a quiet cluster until the cache resync, up to
10 hours. A false InstanceNotFound needs the API to hide a live server from
the lookup by ID and from the lookup by tags, so it is unlikely.

The terminal state keeps Status.InstanceID, so the deletion of such a machine
goes to DeleteServer and not to the early finalizer removal. Two new tests
cover that call: cloud.ErrNotFound still removes the load balancer target and
infrav1.MachineFinalizer, and any other error keeps the object and its
finalizer, so the next reconcile can repeat the delete. The not-found test is the
fourth caller of updateMachineControlPlaneLabel, so unparam reported the
namespace parameter that always receives "default", therefore this parameter
was refactored out. The helper now writes "default" itself, like
updateMachineBootstrapSecret does.

When the server of an already provisioned machine was gone, the reconcile
used the reason InstanceError and returned an error, so the controller
retried for ever and wrote an error line for a state that no retry changes.

The provider now reports that state with its own error value. The reconcile turns
it into the reason InstanceNotFound on the conditions and into a warning event,
and it gives no error back to the controller runtime, so the retry stops. It
still creates no replacement server.
The regression test for the gone server asserted this before. It now asserts the opposite,
so a rejected VM creation covers it instead.
@corioliskraft

Copy link
Copy Markdown
Author

Description updated, added trade-off paragraph.

The spec drives a provisioned control plane machine into the terminal
state of a missing instance, then deletes it while the cloud answers the
server delete with not found. The load balancer target and the finalizer
must go.

The spec is the fourth caller of updateMachineControlPlaneLabel, so
unparam reports the namespace parameter that always receives "default".
The parameter has been refactored away, and the helper writes the
namespace like the helper above it.
The delete path removes the finalizer only after the cloud reports the
server as deleted or as already gone. The other exit had no spec: a
deletion that answers with any other error must keep the object.

The new spec injects a transient error into the server delete, then
asserts that the reconcile returns that error, that the server is still
there, and that the finalizer still holds the object, so the next
attempt can find the instance ID.
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.

Fix handling of disappearing VMs/Nodes

1 participant