fix: reconfigure WireGuard peers when listed >=1 machines in cluster store (fixes #155)

This commit is contained in:
Pasha Sviderski
2025-11-07 12:51:40 +10:00
parent 48d2239f5d
commit b6dfc2175f
4 changed files with 18 additions and 3 deletions
+8
View File
@@ -358,6 +358,14 @@ func (cc *clusterController) handleMachineChanges(ctx context.Context) error {
slog.Error("Failed to list machines.", "err", err) slog.Error("Failed to list machines.", "err", err)
continue continue
} }
// Skip reconfiguration if the machines list is empty. This can happen when joining the cluster.
// Corrosion can notifies about table changes before the data is fully replicated.
// Reconfiguring with an empty list would remove all peers and lock this machine out of the cluster.
// See https://github.com/psviderski/uncloud/issues/155.
if len(machines) == 0 {
slog.Debug("Skipping peer reconfiguration: machines list in store is empty.")
continue
}
if err = cc.configurePeers(machines); err != nil { if err = cc.configurePeers(machines); err != nil {
slog.Error("Failed to configure peers.", "err", err) slog.Error("Failed to configure peers.", "err", err)
} }
+8 -1
View File
@@ -821,7 +821,14 @@ func (m *Machine) JoinCluster(_ context.Context, req *pb.JoinClusterRequest) (*e
if err := m.state.Save(); err != nil { if err := m.state.Save(); err != nil {
return nil, status.Errorf(codes.Internal, "save machine state: %v", err) return nil, status.Errorf(codes.Internal, "save machine state: %v", err)
} }
slog.Info("Machine configured to join the cluster.", "id", m.state.ID, "name", m.state.Name) slog.Info(
"Machine configured to join the cluster.",
"id", m.state.ID,
"name", m.state.Name,
"subnet", m.state.Network.Subnet.String(),
"management_ip", m.state.Network.ManagementIP.String(),
"peers", len(m.state.Network.Peers),
)
// Signal that the machine is initialised as a member of a cluster. // Signal that the machine is initialised as a member of a cluster.
m.initialised <- struct{}{} m.initialised <- struct{}{}
+1 -1
View File
@@ -79,7 +79,7 @@ func (n *WireGuardNetwork) Configure(config Config) error {
if err := n.configureDevice(config); err != nil { if err := n.configureDevice(config); err != nil {
return err return err
} }
slog.Info("Configured WireGuard interface.", "name", n.link.Attrs().Name) slog.Info("Configured WireGuard interface.", "name", n.link.Attrs().Name, "peers", len(n.peers))
managementPrefix, err := addrToSingleIPPrefix(config.ManagementIP) managementPrefix, err := addrToSingleIPPrefix(config.ManagementIP)
if err != nil { if err != nil {
+1 -1
View File
@@ -42,7 +42,7 @@ Some of the common use cases Uncloud is a great fit for:
- **Dev/staging environments**: Spin up additional environments for development and testing that mirror production - **Dev/staging environments**: Spin up additional environments for development and testing that mirror production
reusing the same Compose configuration. reusing the same Compose configuration.
## What makes Uncloud different ## What makes Uncloud special
Here are the design decisions that make Uncloud stand out: Here are the design decisions that make Uncloud stand out: