Skip to content

Commit 694b887

Browse files
authored
[Feature] Member Replace Operation (#1817)
1 parent f81a2da commit 694b887

24 files changed

+606
-80
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- (Feature) UpgradeByReplace Flow
1717
- (Feature) (Platform) ArangoRoute Timeout option
1818
- (Feature) Delay Action
19+
- (Feature) MigrateMember Action
1920

2021
## [1.2.44](https://github.com/arangodb/kube-arangodb/tree/1.2.44) (2025-02-03)
2122
- (Maintenance) Kubernetes 1.31.1 libraries

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ Flags:
173173
--deployment.feature.local-volume-replacement-check Replace volume for local-storage if volume is unschedulable (ex. node is gone) - Required ArangoDB >= 3.8.0
174174
--deployment.feature.random-pod-names Enables generating random pod names - Required ArangoDB >= 3.8.0
175175
--deployment.feature.rebalancer-v2 Rebalancer V2 feature - Required ArangoDB >= 3.10.0
176+
--deployment.feature.replace-migration During member replacement shards are migrated directly to the new server - Required ArangoDB >= 3.8.0 (default true)
176177
--deployment.feature.restart-policy-always Allow to restart containers with always restart policy - Required ArangoDB >= 3.8.0
177178
--deployment.feature.secured-containers Create server's containers with non root privileges. It enables 'ephemeral-volumes' feature implicitly - Required ArangoDB >= 3.8.0
178179
--deployment.feature.sensitive-information-protection Hide sensitive information from metrics and logs - Required ArangoDB >= 3.8.0

docs/cli/arangodb_operator.md

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Flags:
5757
--deployment.feature.local-volume-replacement-check Replace volume for local-storage if volume is unschedulable (ex. node is gone) - Required ArangoDB >= 3.8.0
5858
--deployment.feature.random-pod-names Enables generating random pod names - Required ArangoDB >= 3.8.0
5959
--deployment.feature.rebalancer-v2 Rebalancer V2 feature - Required ArangoDB >= 3.10.0
60+
--deployment.feature.replace-migration During member replacement shards are migrated directly to the new server - Required ArangoDB >= 3.8.0 (default true)
6061
--deployment.feature.restart-policy-always Allow to restart containers with always restart policy - Required ArangoDB >= 3.8.0
6162
--deployment.feature.secured-containers Create server's containers with non root privileges. It enables 'ephemeral-volumes' feature implicitly - Required ArangoDB >= 3.8.0
6263
--deployment.feature.sensitive-information-protection Hide sensitive information from metrics and logs - Required ArangoDB >= 3.8.0

docs/generated/actions.md

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ nav_order: 11
5151
| MemberPhaseUpdate | no | 10m0s | no | Community & Enterprise | Change member phase |
5252
| ~~MemberRIDUpdate~~ | no | 10m0s | no | Community & Enterprise | Update Run ID of member |
5353
| MemberStatusSync | no | 10m0s | no | Community & Enterprise | Sync ArangoMember Status with ArangoDeployment Status, to keep Member information up to date |
54+
| MigrateMember | no | 48h0m0s | yes | Community & Enterprise | Run the data movement actions on the member (migration) |
5455
| PVCResize | no | 30m0s | no | Community & Enterprise | Start the resize procedure. Updates PVC Requests field |
5556
| PVCResized | no | 15m0s | no | Community & Enterprise | Waits for PVC resize to be completed |
5657
| PlaceHolder | no | 10m0s | no | Community & Enterprise | Empty placeholder action |
@@ -148,6 +149,7 @@ spec:
148149
MemberPhaseUpdate: 10m0s
149150
MemberRIDUpdate: 10m0s
150151
MemberStatusSync: 10m0s
152+
MigrateMember: 48h0m0s
151153
PVCResize: 30m0s
152154
PVCResized: 15m0s
153155
PlaceHolder: 10m0s

internal/actions.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ actions:
2727
CleanOutMember:
2828
description: Run the CleanOut job on member
2929
timeout: 48h
30+
MigrateMember:
31+
description: Run the data movement actions on the member (migration)
32+
timeout: 48h
33+
optional: true
3034
ShutdownMember:
3135
description: Sends Shutdown requests and waits for container to be stopped
3236
timeout: 30m

pkg/apis/deployment/v1/actions.generated.go

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/deployment/v2alpha1/actions.generated.go

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/agency/definitions.go

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const (
4747

4848
SupervisionKey = "Supervision"
4949
SupervisionMaintenanceKey = "Maintenance"
50+
SupervisionHealthKey = "Health"
5051

5152
TargetJobToDoKey = "ToDo"
5253
TargetJobPendingKey = "Pending"
@@ -74,6 +75,7 @@ func GetAgencyReadRequest(elements ...[]string) ReadRequest {
7475
func GetAgencyReadRequestFields() ReadRequest {
7576
return GetAgencyReadRequest([]string{
7677
GetAgencyKey(ArangoKey, SupervisionKey, SupervisionMaintenanceKey),
78+
GetAgencyKey(ArangoKey, SupervisionKey, SupervisionHealthKey),
7779
GetAgencyKey(ArangoKey, PlanKey, PlanCollectionsKey),
7880
GetAgencyKey(ArangoKey, PlanKey, PlanDatabasesKey),
7981
GetAgencyKey(ArangoKey, PlanKey, PlanDBServersKey),

pkg/deployment/agency/state/state.go

-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ type Plan struct {
6161
Coordinators ServerMap[string] `json:"Coordinators,omitempty"`
6262
}
6363

64-
type Supervision struct {
65-
Maintenance Timestamp `json:"Maintenance,omitempty"`
66-
}
67-
6864
type ShardCountDetails struct {
6965
Leader, Follower int
7066
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package state
22+
23+
type Supervision struct {
24+
Maintenance Timestamp `json:"Maintenance,omitempty"`
25+
26+
Health ServerMap[SupervisionHealthServer] `json:"Health,omitempty"`
27+
}
28+
29+
type SupervisionHealthServerStatus string
30+
31+
const (
32+
SupervisionHealthServerStatusGood SupervisionHealthServerStatus = "GOOD"
33+
)
34+
35+
type SupervisionHealthServerSyncStatus string
36+
37+
const (
38+
SupervisionHealthServerSyncStatusServing SupervisionHealthServerSyncStatus = "SERVING"
39+
)
40+
41+
type SupervisionHealthServer struct {
42+
Status SupervisionHealthServerStatus `json:"Status,omitempty"`
43+
SyncStatus SupervisionHealthServerSyncStatus `json:"SyncStatus,omitempty"`
44+
}
45+
46+
func (s SupervisionHealthServer) IsHealthy() bool {
47+
return s.Status == SupervisionHealthServerStatusGood && s.SyncStatus == SupervisionHealthServerSyncStatusServing
48+
}
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package client
22+
23+
import (
24+
"context"
25+
"net/http"
26+
27+
"github.com/arangodb/kube-arangodb/pkg/util"
28+
)
29+
30+
type RebalanceExecuteRequest struct {
31+
Version int `json:"version"`
32+
33+
Moves RebalanceExecuteRequestMoves `json:"moves,omitempty"`
34+
}
35+
36+
type RebalanceExecuteRequestMoves []RebalanceExecuteRequestMove
37+
38+
type RebalanceExecuteRequestMove struct {
39+
Database string `json:"database"`
40+
Collection string `json:"collection"`
41+
Shard string `json:"shard"`
42+
43+
From string `json:"from"`
44+
To string `json:"to"`
45+
46+
IsLeader bool `json:"isLeader"`
47+
}
48+
49+
func (c *client) RebalanceExecuteMoves(ctx context.Context, moves ...RebalanceExecuteRequestMove) error {
50+
return c.RebalanceExecute(ctx, &RebalanceExecuteRequest{
51+
Version: 1,
52+
Moves: moves,
53+
})
54+
}
55+
56+
func (c *client) RebalanceExecute(ctx context.Context, request *RebalanceExecuteRequest) error {
57+
req, err := c.c.NewRequest(http.MethodPost, "/_admin/cluster/rebalance/execute")
58+
if err != nil {
59+
return err
60+
}
61+
62+
request = util.InitType(request)
63+
64+
// Always set to 1
65+
request.Version = 1
66+
67+
if r, err := req.SetBody(request); err != nil {
68+
return err
69+
} else {
70+
req = r
71+
}
72+
73+
resp, err := c.c.Do(ctx, req)
74+
if err != nil {
75+
return err
76+
}
77+
78+
if err := resp.CheckStatus(http.StatusAccepted); err != nil {
79+
return err
80+
}
81+
82+
return nil
83+
}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package client
22+
23+
import (
24+
"context"
25+
"net/http"
26+
)
27+
28+
type RebalanceGetResponse struct {
29+
Result RebalanceGetResponseResult `json:"result,omitempty"`
30+
}
31+
32+
type RebalanceGetResponseResult struct {
33+
PendingMoveShards int `json:"pendingMoveShards"`
34+
TodoMoveShards int `json:"todoMoveShards"`
35+
}
36+
37+
func (c *client) RebalanceGet(ctx context.Context) (RebalanceGetResponse, error) {
38+
req, err := c.c.NewRequest(http.MethodGet, "/_admin/cluster/rebalance")
39+
if err != nil {
40+
return RebalanceGetResponse{}, err
41+
}
42+
43+
resp, err := c.c.Do(ctx, req)
44+
if err != nil {
45+
return RebalanceGetResponse{}, err
46+
}
47+
48+
if err := resp.CheckStatus(http.StatusOK); err != nil {
49+
return RebalanceGetResponse{}, err
50+
}
51+
52+
var d RebalanceGetResponse
53+
54+
if err := resp.ParseBody("", &d); err != nil {
55+
return RebalanceGetResponse{}, err
56+
}
57+
58+
return d, nil
59+
}

0 commit comments

Comments
 (0)