MCPcopy
hub / github.com/lxc/incus / UpgradeMembersWithoutRole

Function UpgradeMembersWithoutRole

internal/server/cluster/upgrade.go:142–219  ·  view source on GitHub ↗

UpgradeMembersWithoutRole assigns the Spare raft role to all cluster members that are not currently part of the raft configuration. It's used for upgrading a cluster from a version without roles support.

(gateway *Gateway, members []db.NodeInfo)

Source from the content-addressed store, hash-verified

140// UpgradeMembersWithoutRole assigns the Spare raft role to all cluster members that are not currently part of the
141// raft configuration. It's used for upgrading a cluster from a version without roles support.
142func UpgradeMembersWithoutRole(gateway *Gateway, members []db.NodeInfo) error {
143 nodes, err := gateway.currentRaftNodes()
144 if errors.Is(err, ErrNotLeader) {
145 return nil
146 }
147
148 if err != nil {
149 return fmt.Errorf("Failed to get current raft members: %w", err)
150 }
151
152 // Convert raft node list to map keyed on ID.
153 raftNodeIDs := map[uint64]bool{}
154 for _, node := range nodes {
155 raftNodeIDs[node.ID] = true
156 }
157
158 cowsqlClient, err := gateway.getClient()
159 if err != nil {
160 return fmt.Errorf("Failed to connect to local cowsql member: %w", err)
161 }
162
163 defer logger.WarnOnError(cowsqlClient.Close, "Failed to close client")
164
165 // Check that each member is present in the raft configuration, and add it if not.
166 for _, member := range members {
167 found := false
168 for _, node := range nodes {
169 if member.ID == 1 && node.ID == 1 || member.Address == node.Address {
170 found = true
171 break
172 }
173 }
174 if found {
175 continue
176 }
177
178 // Try to use the same ID as the node, but it might not be possible if it's use.
179 id := uint64(member.ID)
180 _, ok := raftNodeIDs[id]
181 if ok {
182 for _, other := range members {
183 _, ok := raftNodeIDs[uint64(other.ID)]
184 if !ok {
185 id = uint64(other.ID) // Found unused raft ID for member.
186 break
187 }
188 }
189
190 // This can't really happen (but has in the past) since there are always at least as many
191 // members as there are nodes, and all of them have different IDs.
192 if id == uint64(member.ID) {
193 logger.Error("No available raft ID for cluster member", logger.Ctx{"memberID": member.ID, "members": members, "raftMembers": nodes})
194 return fmt.Errorf("No available raft ID for cluster member ID %d", member.ID)
195 }
196 }
197 raftNodeIDs[id] = true
198
199 info := db.RaftNode{

Callers 1

Calls 7

WarnOnErrorFunction · 0.92
ErrorFunction · 0.92
InfoFunction · 0.92
currentRaftNodesMethod · 0.80
ErrorfMethod · 0.80
getClientMethod · 0.80
AddMethod · 0.65

Tested by 1

Used in the wild real call sites across dependent graphs

searching dependent graphs…