diff --git a/CHANGELOG.md b/CHANGELOG.md
index d737e28de..0ce5ee673 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
- (Feature) (Platform) Service Handler
- (Feature) (Platform) Service Handler Implementation
- (Feature) (Platform) Packer
+- (Feature) Manual Upgrade Mode
## [1.2.49](https://github.com/arangodb/kube-arangodb/tree/1.2.49) (2025-06-17)
- (Maintenance) Optimize go.mod
diff --git a/docs/api/ArangoDeployment.V1.md b/docs/api/ArangoDeployment.V1.md
index 65bedc960..39c31db5d 100644
--- a/docs/api/ArangoDeployment.V1.md
+++ b/docs/api/ArangoDeployment.V1.md
@@ -230,6 +230,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.agents.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.agents.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -611,7 +623,7 @@ Links:
### .spec.agents.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -852,13 +864,14 @@ Links:
### .spec.agents.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -1327,6 +1340,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.coordinators.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.coordinators.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -1708,7 +1733,7 @@ Links:
### .spec.coordinators.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -1949,13 +1974,14 @@ Links:
### .spec.coordinators.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -2292,6 +2318,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.dbservers.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.dbservers.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -2673,7 +2711,7 @@ Links:
### .spec.dbservers.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -2914,13 +2952,14 @@ Links:
### .spec.dbservers.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -3478,6 +3517,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.gateways.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.gateways.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -3859,7 +3910,7 @@ Links:
### .spec.gateways.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -4100,13 +4151,14 @@ Links:
### .spec.gateways.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -5208,6 +5260,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.single.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.single.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -5589,7 +5653,7 @@ Links:
### .spec.single.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -5830,13 +5894,14 @@ Links:
### .spec.single.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -6387,6 +6452,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.syncmasters.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.syncmasters.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -6768,7 +6845,7 @@ Links:
### .spec.syncmasters.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -7009,13 +7086,14 @@ Links:
### .spec.syncmasters.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
@@ -7344,6 +7422,18 @@ LabelsMode Define labels mode which should be use while overriding labels
***
+### .spec.syncworkers.manualUpgradeMode
+
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+
+UpgradeMode Defines the manually triggered upgrade mode for the Member
+
+Possible Values:
+* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
+* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+
+***
+
### .spec.syncworkers.maxCount
Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L50)
@@ -7725,7 +7815,7 @@ Links:
### .spec.syncworkers.restartPolicy
-Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L224)
+Type: `core.RestartPolicy` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L231)
RestartPolicy for all pods within the group.
@@ -7966,13 +8056,14 @@ Links:
### .spec.syncworkers.upgradeMode
-Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L217)
+Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.49/pkg/apis/deployment/v1/server_group_spec.go#L218)
UpgradeMode Defines the upgrade mode for the Member
Possible Values:
* `"inplace"` (default) - Inplace Upgrade procedure (with Upgrade initContainer)
* `"replace"` - Replaces server instead of upgrading. Takes an effect only on DBServer
+* `"manual"` - Waits for the manual upgrade. Requires replacement or the annotation on the member
***
diff --git a/pkg/apis/deployment/annotations.go b/pkg/apis/deployment/annotations.go
index a6316c754..68ca1eb7e 100644
--- a/pkg/apis/deployment/annotations.go
+++ b/pkg/apis/deployment/annotations.go
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
-// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
+// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,11 +21,12 @@
package deployment
const (
- ArangoDeploymentAnnotationPrefix = "deployment.arangodb.com"
- ArangoDeploymentPodMaintenanceAnnotation = ArangoDeploymentAnnotationPrefix + "/maintenance"
- ArangoDeploymentPodChangeArchAnnotation = ArangoDeploymentAnnotationPrefix + "/arch"
- ArangoDeploymentPodRotateAnnotation = ArangoDeploymentAnnotationPrefix + "/rotate"
- ArangoDeploymentPodReplaceAnnotation = ArangoDeploymentAnnotationPrefix + "/replace"
- ArangoDeploymentPodDeleteNow = ArangoDeploymentAnnotationPrefix + "/delete_now"
- ArangoDeploymentPlanCleanAnnotation = "plan." + ArangoDeploymentAnnotationPrefix + "/clean"
+ ArangoDeploymentAnnotationPrefix = "deployment.arangodb.com"
+ ArangoDeploymentPodMaintenanceAnnotation = ArangoDeploymentAnnotationPrefix + "/maintenance"
+ ArangoDeploymentPodChangeArchAnnotation = ArangoDeploymentAnnotationPrefix + "/arch"
+ ArangoDeploymentPodRotateAnnotation = ArangoDeploymentAnnotationPrefix + "/rotate"
+ ArangoDeploymentPodReplaceAnnotation = ArangoDeploymentAnnotationPrefix + "/replace"
+ ArangoDeploymentPodAllowUpgradeAnnotation = "upgrade." + ArangoDeploymentAnnotationPrefix + "/allow"
+ ArangoDeploymentPodDeleteNow = ArangoDeploymentAnnotationPrefix + "/delete_now"
+ ArangoDeploymentPlanCleanAnnotation = "plan." + ArangoDeploymentAnnotationPrefix + "/clean"
)
diff --git a/pkg/apis/deployment/v1/conditions.go b/pkg/apis/deployment/v1/conditions.go
index 9e0cd5ae1..9f83bd997 100644
--- a/pkg/apis/deployment/v1/conditions.go
+++ b/pkg/apis/deployment/v1/conditions.go
@@ -53,6 +53,8 @@ const (
ConditionTypeTerminated ConditionType = "Terminated"
// ConditionTypeAutoUpgrade indicates that the member has to be started with `--database.auto-upgrade` once.
ConditionTypeAutoUpgrade ConditionType = "AutoUpgrade"
+ // ConditionTypeUpgradeAllowed indicates that the member upgrade is allowed in the manual procedure.
+ ConditionTypeUpgradeAllowed ConditionType = "UpgradeAllowed"
// ConditionTypeCleanedOut indicates that the member (dbserver) has been cleaned out.
// Always check in combination with ConditionTypeTerminated.
diff --git a/pkg/apis/deployment/v1/server_group_spec.go b/pkg/apis/deployment/v1/server_group_spec.go
index 4a0e1315f..e89da32ba 100644
--- a/pkg/apis/deployment/v1/server_group_spec.go
+++ b/pkg/apis/deployment/v1/server_group_spec.go
@@ -213,9 +213,16 @@ type ServerGroupSpec struct {
// UpgradeMode Defines the upgrade mode for the Member
// +doc/enum: inplace|Inplace Upgrade procedure (with Upgrade initContainer)
// +doc/enum: replace|Replaces server instead of upgrading. Takes an effect only on DBServer
+ // +doc/enum: manual| Waits for the manual upgrade. Requires replacement or the annotation on the member
// +doc/default: inplace
UpgradeMode *ServerGroupUpgradeMode `json:"upgradeMode,omitempty"`
+ // UpgradeMode Defines the manually triggered upgrade mode for the Member
+ // +doc/enum: inplace|Inplace Upgrade procedure (with Upgrade initContainer)
+ // +doc/enum: replace|Replaces server instead of upgrading. Takes an effect only on DBServer
+ // +doc/default: inplace
+ ManualUpgradeMode *ServerGroupUpgradeMode `json:"manualUpgradeMode,omitempty"`
+
// RestartPolicy for all pods within the group.
// +doc/type: core.RestartPolicy
// +doc/enum: Always|Means that containers within the pod are always restarted.
@@ -479,7 +486,9 @@ func (s *ServerGroupSpec) validate() error {
shared.PrefixResourceError("volumes", s.Volumes.Validate()),
shared.PrefixResourceError("volumeMounts", s.VolumeMounts.Validate()),
shared.PrefixResourceError("initContainers", s.InitContainers.Validate()),
- shared.PrefixResourceError("IndexMethod", s.IndexMethod.Validate()),
+ shared.PrefixResourceError("indexMethod", s.IndexMethod.Validate()),
+ shared.PrefixResourceError("upgradeMode", s.UpgradeMode.Validate()),
+ shared.PrefixResourceError("manualUpgradeMode", s.ManualUpgradeMode.Validate()),
s.validateVolumes(),
)
}
diff --git a/pkg/apis/deployment/v1/server_group_spec_upgrade_mode.go b/pkg/apis/deployment/v1/server_group_spec_upgrade_mode.go
index fbae43202..47aea1f61 100644
--- a/pkg/apis/deployment/v1/server_group_spec_upgrade_mode.go
+++ b/pkg/apis/deployment/v1/server_group_spec_upgrade_mode.go
@@ -32,13 +32,17 @@ const (
// ServerGroupUpgradeModeReplace Replaces server instead of upgrading. Takes an effect only on DBServer
ServerGroupUpgradeModeReplace ServerGroupUpgradeMode = "replace"
+ // ServerGroupUpgradeModeManual Waits for the manual upgrade. Requires replacement or the annotation on the member.
+ // Requires annotation `upgrade.deployment.arangodb.com/allow` on a Pod
+ ServerGroupUpgradeModeManual ServerGroupUpgradeMode = "manual"
+
// DefaultServerGroupUpgradeMode defaults to ServerGroupUpgradeModeInplace
DefaultServerGroupUpgradeMode = ServerGroupUpgradeModeInplace
)
func (n *ServerGroupUpgradeMode) Validate() error {
switch v := n.Get(); v {
- case ServerGroupUpgradeModeInplace, ServerGroupUpgradeModeReplace:
+ case ServerGroupUpgradeModeInplace, ServerGroupUpgradeModeReplace, ServerGroupUpgradeModeManual:
return nil
default:
return errors.WithStack(errors.Wrapf(ValidationError, "Unknown UpgradeMode %s", v.String()))
@@ -46,8 +50,12 @@ func (n *ServerGroupUpgradeMode) Validate() error {
}
func (n *ServerGroupUpgradeMode) Get() ServerGroupUpgradeMode {
+ return n.Default(ServerGroupUpgradeModeInplace)
+}
+
+func (n *ServerGroupUpgradeMode) Default(d ServerGroupUpgradeMode) ServerGroupUpgradeMode {
if n == nil {
- return DefaultServerGroupUpgradeMode
+ return d
}
return *n
diff --git a/pkg/apis/deployment/v1/zz_generated.deepcopy.go b/pkg/apis/deployment/v1/zz_generated.deepcopy.go
index eec0385dc..25dc588f3 100644
--- a/pkg/apis/deployment/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/deployment/v1/zz_generated.deepcopy.go
@@ -2741,6 +2741,11 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) {
*out = new(ServerGroupUpgradeMode)
**out = **in
}
+ if in.ManualUpgradeMode != nil {
+ in, out := &in.ManualUpgradeMode, &out.ManualUpgradeMode
+ *out = new(ServerGroupUpgradeMode)
+ **out = **in
+ }
if in.RestartPolicy != nil {
in, out := &in.RestartPolicy, &out.RestartPolicy
*out = new(corev1.RestartPolicy)
diff --git a/pkg/apis/deployment/v2alpha1/conditions.go b/pkg/apis/deployment/v2alpha1/conditions.go
index 7f116d8b8..2343e97b0 100644
--- a/pkg/apis/deployment/v2alpha1/conditions.go
+++ b/pkg/apis/deployment/v2alpha1/conditions.go
@@ -53,6 +53,8 @@ const (
ConditionTypeTerminated ConditionType = "Terminated"
// ConditionTypeAutoUpgrade indicates that the member has to be started with `--database.auto-upgrade` once.
ConditionTypeAutoUpgrade ConditionType = "AutoUpgrade"
+ // ConditionTypeUpgradeAllowed indicates that the member upgrade is allowed in the manual procedure.
+ ConditionTypeUpgradeAllowed ConditionType = "UpgradeAllowed"
// ConditionTypeCleanedOut indicates that the member (dbserver) has been cleaned out.
// Always check in combination with ConditionTypeTerminated.
diff --git a/pkg/apis/deployment/v2alpha1/server_group_spec.go b/pkg/apis/deployment/v2alpha1/server_group_spec.go
index d5847652a..2a32e2f13 100644
--- a/pkg/apis/deployment/v2alpha1/server_group_spec.go
+++ b/pkg/apis/deployment/v2alpha1/server_group_spec.go
@@ -213,9 +213,16 @@ type ServerGroupSpec struct {
// UpgradeMode Defines the upgrade mode for the Member
// +doc/enum: inplace|Inplace Upgrade procedure (with Upgrade initContainer)
// +doc/enum: replace|Replaces server instead of upgrading. Takes an effect only on DBServer
+ // +doc/enum: manual| Waits for the manual upgrade. Requires replacement or the annotation on the member
// +doc/default: inplace
UpgradeMode *ServerGroupUpgradeMode `json:"upgradeMode,omitempty"`
+ // UpgradeMode Defines the manually triggered upgrade mode for the Member
+ // +doc/enum: inplace|Inplace Upgrade procedure (with Upgrade initContainer)
+ // +doc/enum: replace|Replaces server instead of upgrading. Takes an effect only on DBServer
+ // +doc/default: inplace
+ ManualUpgradeMode *ServerGroupUpgradeMode `json:"manualUpgradeMode,omitempty"`
+
// RestartPolicy for all pods within the group.
// +doc/type: core.RestartPolicy
// +doc/enum: Always|Means that containers within the pod are always restarted.
@@ -479,7 +486,9 @@ func (s *ServerGroupSpec) validate() error {
shared.PrefixResourceError("volumes", s.Volumes.Validate()),
shared.PrefixResourceError("volumeMounts", s.VolumeMounts.Validate()),
shared.PrefixResourceError("initContainers", s.InitContainers.Validate()),
- shared.PrefixResourceError("IndexMethod", s.IndexMethod.Validate()),
+ shared.PrefixResourceError("indexMethod", s.IndexMethod.Validate()),
+ shared.PrefixResourceError("upgradeMode", s.UpgradeMode.Validate()),
+ shared.PrefixResourceError("manualUpgradeMode", s.ManualUpgradeMode.Validate()),
s.validateVolumes(),
)
}
diff --git a/pkg/apis/deployment/v2alpha1/server_group_spec_upgrade_mode.go b/pkg/apis/deployment/v2alpha1/server_group_spec_upgrade_mode.go
index 58bb4f678..a9666f63a 100644
--- a/pkg/apis/deployment/v2alpha1/server_group_spec_upgrade_mode.go
+++ b/pkg/apis/deployment/v2alpha1/server_group_spec_upgrade_mode.go
@@ -32,13 +32,17 @@ const (
// ServerGroupUpgradeModeReplace Replaces server instead of upgrading. Takes an effect only on DBServer
ServerGroupUpgradeModeReplace ServerGroupUpgradeMode = "replace"
+ // ServerGroupUpgradeModeManual Waits for the manual upgrade. Requires replacement or the annotation on the member.
+ // Requires annotation `upgrade.deployment.arangodb.com/allow` on a Pod
+ ServerGroupUpgradeModeManual ServerGroupUpgradeMode = "manual"
+
// DefaultServerGroupUpgradeMode defaults to ServerGroupUpgradeModeInplace
DefaultServerGroupUpgradeMode = ServerGroupUpgradeModeInplace
)
func (n *ServerGroupUpgradeMode) Validate() error {
switch v := n.Get(); v {
- case ServerGroupUpgradeModeInplace, ServerGroupUpgradeModeReplace:
+ case ServerGroupUpgradeModeInplace, ServerGroupUpgradeModeReplace, ServerGroupUpgradeModeManual:
return nil
default:
return errors.WithStack(errors.Wrapf(ValidationError, "Unknown UpgradeMode %s", v.String()))
@@ -46,8 +50,12 @@ func (n *ServerGroupUpgradeMode) Validate() error {
}
func (n *ServerGroupUpgradeMode) Get() ServerGroupUpgradeMode {
+ return n.Default(ServerGroupUpgradeModeInplace)
+}
+
+func (n *ServerGroupUpgradeMode) Default(d ServerGroupUpgradeMode) ServerGroupUpgradeMode {
if n == nil {
- return DefaultServerGroupUpgradeMode
+ return d
}
return *n
diff --git a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go
index c2ef4e715..8d19f2365 100644
--- a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go
@@ -2741,6 +2741,11 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) {
*out = new(ServerGroupUpgradeMode)
**out = **in
}
+ if in.ManualUpgradeMode != nil {
+ in, out := &in.ManualUpgradeMode, &out.ManualUpgradeMode
+ *out = new(ServerGroupUpgradeMode)
+ **out = **in
+ }
if in.RestartPolicy != nil {
in, out := &in.RestartPolicy, &out.RestartPolicy
*out = new(v1.RestartPolicy)
diff --git a/pkg/crd/crds/database-deployment.schema.generated.yaml b/pkg/crd/crds/database-deployment.schema.generated.yaml
index 853f3e8d1..9197a4289 100644
--- a/pkg/crd/crds/database-deployment.schema.generated.yaml
+++ b/pkg/crd/crds/database-deployment.schema.generated.yaml
@@ -915,6 +915,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -1880,6 +1886,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -3210,6 +3217,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -4175,6 +4188,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -5423,6 +5437,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -6388,6 +6408,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -7756,6 +7777,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -8721,6 +8748,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -11184,6 +11212,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -12149,6 +12183,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -13542,6 +13577,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -14507,6 +14548,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -15748,6 +15790,12 @@ v1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -16713,6 +16761,7 @@ v1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -18061,6 +18110,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -19026,6 +19081,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -20356,6 +20412,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -21321,6 +21383,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -22569,6 +22632,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -23534,6 +23603,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -24902,6 +24972,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -25867,6 +25943,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -28330,6 +28407,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -29295,6 +29378,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -30688,6 +30772,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -31653,6 +31743,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
@@ -32894,6 +32985,12 @@ v2alpha1:
labelsMode:
description: LabelsMode Define labels mode which should be use while overriding labels
type: string
+ manualUpgradeMode:
+ description: UpgradeMode Defines the manually triggered upgrade mode for the Member
+ enum:
+ - inplace
+ - replace
+ type: string
maxCount:
description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
format: int32
@@ -33859,6 +33956,7 @@ v2alpha1:
enum:
- inplace
- replace
+ - manual
type: string
volumeAllowShrink:
description: VolumeAllowShrink allows shrinking of the volume
diff --git a/pkg/deployment/reconcile/plan_builder_high.go b/pkg/deployment/reconcile/plan_builder_high.go
index 478001e9c..1341ee775 100644
--- a/pkg/deployment/reconcile/plan_builder_high.go
+++ b/pkg/deployment/reconcile/plan_builder_high.go
@@ -54,6 +54,7 @@ func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIOb
ApplyIfEmpty(r.createSyncPlan).
ApplyIfEmpty(r.updateMemberUpdateConditionsPlan).
ApplyIfEmpty(r.updateMemberRotationConditionsPlan).
+ ApplyIfEmpty(r.createMemberAllowUpgradeConditionPlan).
ApplyIfEmpty(r.createMemberRecreationConditionsPlan).
ApplyIfEmpty(r.createMemberPodSchedulingFailurePlan).
ApplyIfEmpty(r.createRotateServerStoragePVCPendingResizeConditionPlan).
diff --git a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go
index 4177379c8..8b77ebfca 100644
--- a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go
+++ b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go
@@ -292,16 +292,27 @@ func (r *Reconciler) createUpgradePlanInternal(apiObject k8sutil.APIObject, spec
return nil, false
}
- um := spec.GetServerGroupSpec(group).UpgradeMode
+ dum := util.BoolSwitch(features.IsUpgradeIndexOrderIssueEnabled(group, d.upgradeDecision.FromVersion, d.upgradeDecision.ToVersion), api.ServerGroupUpgradeModeReplace, api.ServerGroupUpgradeModeInplace)
- if features.IsUpgradeIndexOrderIssueEnabled(group, d.upgradeDecision.FromVersion, d.upgradeDecision.ToVersion) && um == nil {
- um = util.NewType(api.ServerGroupUpgradeModeReplace)
+ um := spec.GetServerGroupSpec(group).UpgradeMode.Default(dum)
+
+ mum := spec.GetServerGroupSpec(group).ManualUpgradeMode.Default(dum)
+
+ switch um.Get() {
+ case api.ServerGroupUpgradeModeManual:
+ if !m.Member.Conditions.IsTrue(api.ConditionTypeUpgradeAllowed) {
+ continue
+ }
+
+ // Once we pick manual mode, ensure that we still follow planned scenario
+ um = mum
}
- switch group {
- case api.ServerGroupDBServers:
- if um.Get() == api.ServerGroupUpgradeModeReplace {
- // Members are suppose to be replaced
+ switch um.Get() {
+ case api.ServerGroupUpgradeModeReplace:
+ switch group {
+ case api.ServerGroupDBServers:
+ // Members are supposed to be replaced
if !m.Member.Conditions.IsTrue(api.ConditionTypeMarkedToRemove) {
return api.Plan{actions.NewAction(api.ActionTypeMarkToRemoveMember, m.Group, m.Member, "Replace by Upgrade")}, false
}
@@ -549,6 +560,39 @@ func groupReadyForRestart(context PlanBuilderContext, status api.DeploymentStatu
return true, "Restart allowed"
}
+func (r *Reconciler) createMemberAllowUpgradeConditionPlan(ctx context.Context,
+ apiObject k8sutil.APIObject,
+ spec api.DeploymentSpec, status api.DeploymentStatus,
+ context PlanBuilderContext) api.Plan {
+ var p api.Plan
+
+ for _, m := range status.Members.AsList() {
+ if m.Member.Conditions.IsTrue(api.ConditionTypeUpgradeAllowed) {
+ continue
+ }
+
+ cache, ok := context.ACS().ClusterCache(m.Member.ClusterID)
+ if !ok {
+ continue
+ }
+
+ if pod, ok := cache.Pod().V1().GetSimple(m.Member.Pod.GetName()); ok {
+ if _, ok := pod.GetAnnotations()[deployment.ArangoDeploymentPodAllowUpgradeAnnotation]; ok {
+ r.log.
+ Str("pod-name", m.Member.Pod.GetName()).
+ Str("server-group", m.Group.AsRole()).
+ Info("Upgrade Allowed by annotation")
+
+ return api.Plan{
+ sharedReconcile.UpdateMemberConditionActionV2("Upgrade allowed by Annotation", api.ConditionTypeUpgradeAllowed, m.Group, m.Member.ID, true, "Upgrade allowed by Annotation", "", ""),
+ }
+ }
+ }
+ }
+
+ return p
+}
+
// createUpgradeMemberPlan creates a plan to upgrade (stop-recreateWithAutoUpgrade-stop-start) an existing
// member.
func (r *Reconciler) createUpgradeMemberPlan(member api.MemberStatus,