Repository navigation
Ensure node is fully removed instead of partially. - #785
crypticC0der wants to merge 2 commits into
Conversation
roosterfish
left a comment
There was a problem hiding this comment.
Thanks for this! One remark from my side.
Also does this actually fix #784 or does it rather allow cleanly removing the member from the cluster after you hit the consistency error?
| } | ||
|
|
||
| if err != nil { | ||
| logger.Error("Failed to remove cluster member from dqlite, continuing with other cleanup", slog.String("error", err.Error())) |
There was a problem hiding this comment.
Can you please omit the part after the ,? Just logging Failed to remove cluster member from dqlite should be enough.
Also can you please add slog.Bool("force", force) and maybe also a slog.String("name", name) to give a bit more context which member couldn't be deleted?
|
DeleteClusterMember is called with force on so this does fix it when it fails with prejoin, it also means deleting a cluster member will 100% fix the trust store if its somehow still broken |
There was a problem hiding this comment.
Pull request overview
Fixes forced cluster-member removal so that cleanup continues even if the dqlite removal step fails, preventing leftover truststore state after an incomplete join/remove flow (per issue #784).
Changes:
- Allow
clusterMemberDeleteto proceed with subsequent cleanup whenleader.Remove()fails during a forced removal. - Add an error log when
leader.Remove()fails but removal continues.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if err != nil { | ||
| logger.Error("Failed to remove cluster member from dqlite, continuing with other cleanup", slog.String("error", err.Error())) | ||
| } |
I see thanks. Please also append the package name as prefix to the commit message. For example see 065316a. Also would it be feasible to extend any of the tests in |
66a9be1 to
35005d0
Compare
|
@crypticC0der tests are failing. |
|
I'll move this to draft until the failing test/comments are addressed. |
|
@crypticC0der do you plan to continue working on this? |
When a join fails (for example because the PreJoin hook returns an error), the revert handler removes the joining member from the cluster. Previously this cleanup was unreliable and could strand the cluster in an inconsistent state, blocking the node from rejoining: - The cluster member delete request was issued in a goroutine that only ran after the request finished, so a process exit or failed network call after the error could leave stale core_cluster_members and truststore entries. - A failure removing the node from dqlite returned early even when `force` was set, skipping the rest of the cleanup. - Propagating the truststore removal to the other members returned on the first error, so a member that never received the entry (a join that failed before propagation) aborted the local removal and left a stale entry. Run the delete synchronously, ignore dqlite removal errors when forcing, and make the truststore propagation best-effort so the local entry is always removed. This keeps core_cluster_members, the truststore and dqlite consistent after a failed join. Fixes: canonical#784 Signed-off-by: MJ Ponsonby <mj.ponsonby@canonical.com>
Extend the example daemon's PreJoin hook to bail out when the init config carries `fail=1`, and add a system test that verifies a node whose PreJoin hook fails can still rejoin the cluster afterwards. The config-driven failure replaces the previous environment-variable approach, which survived the daemon reset (re-exec) after the failed join and racy restart. Signed-off-by: MJ Ponsonby <mj.ponsonby@canonical.com>
|
@roosterfish this now fixes #784 at the root, not just recover after the fact. The leftover was the truststore entry. On a failed join the revert calls Fixed by making the truststore propagation best-effort (log + continue), so the local entry is always removed. Together with the synchronous Also reworked the test into a real regression test — the PreJoin failure is now driven via CI is green now. Mind taking another look? |
Previously on removing the node failing, which happens if the node is not in the cluster, the function exits. Which means the trust store isn't cleaned. This stops an issue wherin a prejoin hook could fail and cause the trust store to remain in a broken state which is not good.
Fixes: #784