1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

GT-134 Add annotation to change architecture (#1107)

This commit is contained in:
jwierzbo 2022-10-03 10:21:32 +02:00 committed by ajanikow
parent 2a11165f8e
commit effed19d53
No known key found for this signature in database
GPG key ID: D59E36FB488484FA
25 changed files with 325 additions and 26 deletions

View file

@ -3,6 +3,7 @@
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- (Feature) Add action progress
- (Feature) Ensure consistency during replication cancellation
- (Feature) Add annotation to change architecture of a member
## [1.2.19](https://github.com/arangodb/kube-arangodb/tree/1.2.19) (2022-10-05)
- (Bugfix) Prevent changes when UID is wrong

View file

@ -0,0 +1,20 @@
# Member Architecture change
To change manually architecture of specific member, you can use annotation:
```bash
kubectl annotate pod arango-pod deployment.arangodb.com/arch=arm64
```
It will add to the member status `ArchitectureMismatch` condition, e.g.:
```yaml
- lastTransitionTime: "2022-09-15T07:38:05Z"
lastUpdateTime: "2022-09-15T07:38:05Z"
reason: Member has a different architecture than the deployment
status: "True"
type: ArchitectureMismatch
```
To provide requested arch changes for the member we need rotate it, so additional step is required:
```bash
`kubectl annotate pod arango-pod deployment.arangodb.com/rotate=true`
```

View file

@ -60,6 +60,7 @@
| SetCondition | 10m0s | Community & Enterprise | (Deprecated) Set deployment condition |
| SetConditionV2 | 10m0s | Community & Enterprise | Set deployment condition |
| SetCurrentImage | 6h0m0s | Community & Enterprise | Update deployment current image after image discovery |
| SetCurrentMemberArch | 10m0s | Community & Enterprise | Set current member architecture |
| SetMaintenanceCondition | 10m0s | Community & Enterprise | Update ArangoDB maintenance condition |
| SetMemberCondition | 10m0s | Community & Enterprise | (Deprecated) Set member condition |
| SetMemberConditionV2 | 10m0s | Community & Enterprise | Set member condition |
@ -141,6 +142,7 @@ spec:
SetCondition: 10m0s
SetConditionV2: 10m0s
SetCurrentImage: 6h0m0s
SetCurrentMemberArch: 10m0s
SetMaintenanceCondition: 10m0s
SetMemberCondition: 10m0s
SetMemberConditionV2: 10m0s

View file

@ -84,6 +84,9 @@ actions:
enterprise: true
description: Update certificate in SNI
timeout: 10m
SetCurrentMemberArch:
description: Set current member architecture
timeout: 10m
SetCurrentImage:
description: Update deployment current image after image discovery
timeout: 6h

View file

@ -23,6 +23,7 @@ package deployment
const (
ArangoDeploymentAnnotationPrefix = "deployment.arangodb.com"
ArangoDeploymentPodMaintenanceAnnotation = ArangoDeploymentAnnotationPrefix + "/maintenance"
ArangoDeploymentPodChangeArchAnnotation = ArangoDeploymentAnnotationPrefix + "/arch"
ArangoDeploymentPodRotateAnnotation = ArangoDeploymentAnnotationPrefix + "/rotate"
ArangoDeploymentPodReplaceAnnotation = ArangoDeploymentAnnotationPrefix + "/replace"
ArangoDeploymentPodDeleteNow = ArangoDeploymentAnnotationPrefix + "/delete_now"

View file

@ -137,6 +137,8 @@ const (
ActionSetConditionV2DefaultTimeout time.Duration = ActionsDefaultTimeout
// ActionSetCurrentImageDefaultTimeout define default timeout for action ActionSetCurrentImage
ActionSetCurrentImageDefaultTimeout time.Duration = 21600 * time.Second // 6h0m0s
// ActionSetCurrentMemberArchDefaultTimeout define default timeout for action ActionSetCurrentMemberArch
ActionSetCurrentMemberArchDefaultTimeout time.Duration = 600 * time.Second // 10m0s
// ActionSetMaintenanceConditionDefaultTimeout define default timeout for action ActionSetMaintenanceCondition
ActionSetMaintenanceConditionDefaultTimeout time.Duration = ActionsDefaultTimeout
// ActionSetMemberConditionDefaultTimeout define default timeout for action ActionSetMemberCondition
@ -286,6 +288,8 @@ const (
ActionTypeSetConditionV2 ActionType = "SetConditionV2"
// ActionTypeSetCurrentImage in scopes Normal. Update deployment current image after image discovery
ActionTypeSetCurrentImage ActionType = "SetCurrentImage"
// ActionTypeSetCurrentMemberArch in scopes Normal. Set current member architecture
ActionTypeSetCurrentMemberArch ActionType = "SetCurrentMemberArch"
// ActionTypeSetMaintenanceCondition in scopes Normal. Update ArangoDB maintenance condition
ActionTypeSetMaintenanceCondition ActionType = "SetMaintenanceCondition"
// ActionTypeSetMemberCondition in scopes High. (Deprecated) Set member condition
@ -436,6 +440,8 @@ func ActionDefaultTimeout(in ActionType) time.Duration {
return ActionSetConditionV2DefaultTimeout
case ActionTypeSetCurrentImage:
return ActionSetCurrentImageDefaultTimeout
case ActionTypeSetCurrentMemberArch:
return ActionSetCurrentMemberArchDefaultTimeout
case ActionTypeSetMaintenanceCondition:
return ActionSetMaintenanceConditionDefaultTimeout
case ActionTypeSetMemberCondition:
@ -589,6 +595,8 @@ func GetActionPriority(in ActionType) ActionPriority {
return ActionPriorityHigh
case ActionTypeSetCurrentImage:
return ActionPriorityNormal
case ActionTypeSetCurrentMemberArch:
return ActionPriorityNormal
case ActionTypeSetMaintenanceCondition:
return ActionPriorityNormal
case ActionTypeSetMemberCondition:

View file

@ -49,6 +49,16 @@ func (a ArangoDeploymentArchitecture) Validate() error {
return nil
}
func (a ArangoDeploymentArchitecture) IsArchAllowed(arch ArangoDeploymentArchitectureType) bool {
for id := range a {
if a[id] == arch {
return true
}
}
return false
}
type ArangoDeploymentArchitectureType string
const (
@ -93,7 +103,22 @@ func (a ArangoDeploymentArchitectureType) AsNodeSelectorRequirement() core.NodeS
}
}
func GetArchsFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
func (a ArangoDeploymentArchitectureType) IsArchMismatch(deploymentArch ArangoDeploymentArchitecture, memberArch *ArangoDeploymentArchitectureType) bool {
if a.Validate() != nil {
return false
}
if deploymentArch.IsArchAllowed(a) {
if memberArch == nil {
return true
} else if a != *memberArch {
return true
}
}
return false
}
func GetAllArchFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
result := make(map[ArangoDeploymentArchitectureType]bool)
for _, selector := range selectors {
if selector.MatchExpressions != nil {

View file

@ -74,6 +74,8 @@ const (
ConditionTypeScaleDownCandidate ConditionType = "ScaleDownCandidate"
// ConditionTypeUpgradeFailed indicates that upgrade failed
ConditionTypeUpgradeFailed ConditionType = "UpgradeFailed"
// ConditionTypeArchitectureMismatch indicates that the member has a different architecture than the deployment.
ConditionTypeArchitectureMismatch ConditionType = "ArchitectureMismatch"
// ConditionTypeMemberMaintenanceMode indicates that Maintenance is enabled on particular member
ConditionTypeMemberMaintenanceMode ConditionType = "MemberMaintenanceMode"

View file

@ -97,6 +97,8 @@ type Action struct {
Locals PlanLocals `json:"locals,omitempty"`
// ID reference of the task involved in this action (if any)
TaskID types.UID `json:"taskID,omitempty"`
// Architecture of the member involved in this action (if any)
Architecture ArangoDeploymentArchitectureType `json:"arch,omitempty"`
// Progress describes what is a status of the current action.
Progress string `json:"progress,omitempty"`
}
@ -115,6 +117,7 @@ func (a Action) Equal(other Action) bool {
equality.Semantic.DeepEqual(a.Params, other.Params) &&
a.Locals.Equal(other.Locals) &&
a.TaskID == other.TaskID &&
a.Architecture == other.Architecture &&
a.Progress == other.Progress
}
@ -194,6 +197,12 @@ func (a Action) SetImage(image string) Action {
return a
}
// SetArch sets the Architecture field to the given value and returns the modified
func (a Action) SetArch(arch ArangoDeploymentArchitectureType) Action {
a.Architecture = arch
return a
}
// IsStarted returns true if the action has been started already.
func (a Action) IsStarted() bool {
return !a.StartTime.IsZero()

View file

@ -137,6 +137,8 @@ const (
ActionSetConditionV2DefaultTimeout time.Duration = ActionsDefaultTimeout
// ActionSetCurrentImageDefaultTimeout define default timeout for action ActionSetCurrentImage
ActionSetCurrentImageDefaultTimeout time.Duration = 21600 * time.Second // 6h0m0s
// ActionSetCurrentMemberArchDefaultTimeout define default timeout for action ActionSetCurrentMemberArch
ActionSetCurrentMemberArchDefaultTimeout time.Duration = 600 * time.Second // 10m0s
// ActionSetMaintenanceConditionDefaultTimeout define default timeout for action ActionSetMaintenanceCondition
ActionSetMaintenanceConditionDefaultTimeout time.Duration = ActionsDefaultTimeout
// ActionSetMemberConditionDefaultTimeout define default timeout for action ActionSetMemberCondition
@ -286,6 +288,8 @@ const (
ActionTypeSetConditionV2 ActionType = "SetConditionV2"
// ActionTypeSetCurrentImage in scopes Normal. Update deployment current image after image discovery
ActionTypeSetCurrentImage ActionType = "SetCurrentImage"
// ActionTypeSetCurrentMemberArch in scopes Normal. Set current member architecture
ActionTypeSetCurrentMemberArch ActionType = "SetCurrentMemberArch"
// ActionTypeSetMaintenanceCondition in scopes Normal. Update ArangoDB maintenance condition
ActionTypeSetMaintenanceCondition ActionType = "SetMaintenanceCondition"
// ActionTypeSetMemberCondition in scopes High. (Deprecated) Set member condition
@ -436,6 +440,8 @@ func ActionDefaultTimeout(in ActionType) time.Duration {
return ActionSetConditionV2DefaultTimeout
case ActionTypeSetCurrentImage:
return ActionSetCurrentImageDefaultTimeout
case ActionTypeSetCurrentMemberArch:
return ActionSetCurrentMemberArchDefaultTimeout
case ActionTypeSetMaintenanceCondition:
return ActionSetMaintenanceConditionDefaultTimeout
case ActionTypeSetMemberCondition:
@ -589,6 +595,8 @@ func GetActionPriority(in ActionType) ActionPriority {
return ActionPriorityHigh
case ActionTypeSetCurrentImage:
return ActionPriorityNormal
case ActionTypeSetCurrentMemberArch:
return ActionPriorityNormal
case ActionTypeSetMaintenanceCondition:
return ActionPriorityNormal
case ActionTypeSetMemberCondition:

View file

@ -49,6 +49,16 @@ func (a ArangoDeploymentArchitecture) Validate() error {
return nil
}
func (a ArangoDeploymentArchitecture) IsArchAllowed(arch ArangoDeploymentArchitectureType) bool {
for id := range a {
if a[id] == arch {
return true
}
}
return false
}
type ArangoDeploymentArchitectureType string
const (
@ -93,7 +103,22 @@ func (a ArangoDeploymentArchitectureType) AsNodeSelectorRequirement() core.NodeS
}
}
func GetArchsFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
func (a ArangoDeploymentArchitectureType) IsArchMismatch(deploymentArch ArangoDeploymentArchitecture, memberArch *ArangoDeploymentArchitectureType) bool {
if a.Validate() != nil {
return false
}
if deploymentArch.IsArchAllowed(a) {
if memberArch == nil {
return true
} else if a != *memberArch {
return true
}
}
return false
}
func GetAllArchFromNodeSelector(selectors []core.NodeSelectorTerm) map[ArangoDeploymentArchitectureType]bool {
result := make(map[ArangoDeploymentArchitectureType]bool)
for _, selector := range selectors {
if selector.MatchExpressions != nil {

View file

@ -74,6 +74,8 @@ const (
ConditionTypeScaleDownCandidate ConditionType = "ScaleDownCandidate"
// ConditionTypeUpgradeFailed indicates that upgrade failed
ConditionTypeUpgradeFailed ConditionType = "UpgradeFailed"
// ConditionTypeArchitectureMismatch indicates that the member has a different architecture than the deployment.
ConditionTypeArchitectureMismatch ConditionType = "ArchitectureMismatch"
// ConditionTypeMemberMaintenanceMode indicates that Maintenance is enabled on particular member
ConditionTypeMemberMaintenanceMode ConditionType = "MemberMaintenanceMode"

View file

@ -97,6 +97,8 @@ type Action struct {
Locals PlanLocals `json:"locals,omitempty"`
// ID reference of the task involved in this action (if any)
TaskID types.UID `json:"taskID,omitempty"`
// Architecture of the member involved in this action (if any)
Architecture ArangoDeploymentArchitectureType `json:"arch,omitempty"`
// Progress describes what is a status of the current action.
Progress string `json:"progress,omitempty"`
}
@ -115,6 +117,7 @@ func (a Action) Equal(other Action) bool {
equality.Semantic.DeepEqual(a.Params, other.Params) &&
a.Locals.Equal(other.Locals) &&
a.TaskID == other.TaskID &&
a.Architecture == other.Architecture &&
a.Progress == other.Progress
}
@ -194,6 +197,12 @@ func (a Action) SetImage(image string) Action {
return a
}
// SetArch sets the Architecture field to the given value and returns the modified
func (a Action) SetArch(arch ArangoDeploymentArchitectureType) Action {
a.Architecture = arch
return a
}
// IsStarted returns true if the action has been started already.
func (a Action) IsStarted() bool {
return !a.StartTime.IsZero()

View file

@ -101,6 +101,7 @@ func removeMemberConditionsMapFunc(m *api.MemberStatus) {
m.Conditions.Remove(api.ConditionTypeTopologyAware)
m.Conditions.Remove(api.MemberReplacementRequired)
m.Conditions.Remove(api.ConditionTypePVCResizePending)
m.Conditions.Remove(api.ConditionTypeArchitectureMismatch)
m.RemoveTerminationsBefore(time.Now().Add(-1 * recentTerminationsKeepPeriod))

View file

@ -60,6 +60,27 @@ func AppendArchSelector(a *core.NodeAffinity, arch api.ArangoDeploymentArchitect
a.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = append(a.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms, arch.AsNodeSelectorRequirement())
}
func GetArchFromAffinity(a *core.Affinity) api.ArangoDeploymentArchitectureType {
if a != nil && a.NodeAffinity != nil && a.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
for _, nst := range a.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms {
for _, req := range nst.MatchExpressions {
if req.Key == shared.NodeArchAffinityLabel || req.Key == shared.NodeArchAffinityLabelBeta {
for _, arch := range req.Values {
return api.ArangoDeploymentArchitectureType(arch)
}
}
}
}
}
return ""
}
func SetArchInAffinity(a *core.Affinity, arch api.ArangoDeploymentArchitectureType) {
if a != nil && a.NodeAffinity != nil && a.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
a.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = []core.NodeSelectorTerm{arch.AsNodeSelectorRequirement()}
}
}
func AppendAffinityWithRole(p interfaces.PodCreator, a *core.PodAffinity, role string) {
labelSelector := &meta.LabelSelector{
MatchLabels: k8sutil.LabelsForDeployment(p.GetName(), role),

View file

@ -195,6 +195,9 @@ var (
_ Action = &actionSetCurrentImage{}
_ actionFactory = newSetCurrentImageAction
_ Action = &actionSetCurrentMemberArch{}
_ actionFactory = newSetCurrentMemberArchAction
_ Action = &actionSetMaintenanceCondition{}
_ actionFactory = newSetMaintenanceConditionAction
@ -924,6 +927,18 @@ func init() {
registerAction(action, function)
}
// SetCurrentMemberArch
{
// Get Action defition
function := newSetCurrentMemberArchAction
action := api.ActionTypeSetCurrentMemberArch
// Wrap action main function
// Register action
registerAction(action, function)
}
// SetMaintenanceCondition
{
// Get Action defition

View file

@ -256,6 +256,10 @@ func Test_Actions(t *testing.T) {
ActionsExistence(t, api.ActionTypeSetCurrentImage)
})
t.Run("SetCurrentMemberArch", func(t *testing.T) {
ActionsExistence(t, api.ActionTypeSetCurrentMemberArch)
})
t.Run("SetMaintenanceCondition", func(t *testing.T) {
ActionsExistence(t, api.ActionTypeSetMaintenanceCondition)
})

View file

@ -0,0 +1,84 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package reconcile
import (
"context"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
// newSetCurrentMemberArchAction creates a new Action that implements the given planned SetMemberCurrentArch action.
func newSetCurrentMemberArchAction(action api.Action, actionCtx ActionContext) Action {
a := &actionSetCurrentMemberArch{}
a.actionImpl = newActionImplDefRef(action, actionCtx)
return a
}
// actionSetCurrentMemberArch implements an SetMemberCurrentArch.
type actionSetCurrentMemberArch struct {
// actionImpl implement timeout and member id functions
actionImpl
}
// Start performs the start of the action.
// Returns true if the action is completely finished, false in case
// the start time needs to be recorded and a ready condition needs to be checked.
func (a *actionSetCurrentMemberArch) Start(ctx context.Context) (bool, error) {
ready, _, err := a.CheckProgress(ctx)
if err != nil {
return false, errors.WithStack(err)
}
return ready, nil
}
// CheckProgress checks the progress of the action.
// Returns true if the action is completely finished, false otherwise.
func (a *actionSetCurrentMemberArch) CheckProgress(ctx context.Context) (bool, bool, error) {
arch := a.action.Architecture
if err := a.actionCtx.WithStatusUpdate(ctx, func(s *api.DeploymentStatus) bool {
m, g, found := s.Members.ElementByID(a.action.MemberID)
if !found {
a.log.Error("No such member")
return false
}
if !m.Architecture.Equal(&arch) {
m.Architecture = &arch
}
if err := s.Members.Update(m, g); err != nil {
a.log.Error("Member update failed")
return false
}
return true
}); err != nil {
a.log.Error("Member failed")
return true, false, nil
}
return true, false, nil
}

View file

@ -251,3 +251,8 @@ func getRequiredReplaceMessage(podName string) string {
return fmt.Sprintf("%s annotation is required to be set on the pod %s",
deployment.ArangoDeploymentPodReplaceAnnotation, podName)
}
func getRequiredRotateMessage(podName string) string {
return fmt.Sprintf("%s annotation is required to be set on the pod %s",
deployment.ArangoDeploymentPodRotateAnnotation, podName)
}

View file

@ -52,6 +52,7 @@ func (r *Reconciler) createHighPlan(ctx context.Context, apiObject k8sutil.APIOb
ApplyIfEmpty(r.updateMemberRotationConditionsPlan).
ApplyIfEmpty(r.createMemberRecreationConditionsPlan).
ApplyIfEmpty(r.createRotateServerStoragePVCPendingResizeConditionPlan).
ApplyIfEmpty(r.createChangeMemberArchPlan).
ApplyIfEmpty(r.createRotateServerStorageResizePlanRuntime).
ApplyIfEmpty(r.createTopologyMemberUpdatePlan).
ApplyIfEmptyWithBackOff(LicenseCheck, 30*time.Second, r.updateClusterLicense).

View file

@ -0,0 +1,62 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package reconcile
import (
"context"
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/actions"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
// createChangeMemberArchPlan goes over all pods to check if an Architecture type is set correctly
func (r *Reconciler) createChangeMemberArchPlan(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() {
member := m.Member
cache, ok := context.ACS().ClusterCache(member.ClusterID)
if !ok {
return p
}
if pod, ok := cache.Pod().V1().GetSimple(member.Pod.GetName()); ok {
if v, ok := pod.GetAnnotations()[deployment.ArangoDeploymentPodChangeArchAnnotation]; ok {
arch := api.ArangoDeploymentArchitectureType(v)
if arch.IsArchMismatch(spec.Architecture, member.Architecture) {
r.log.
Str("pod-name", member.Pod.GetName()).
Str("server-group", m.Group.AsRole()).
Warn("try changing an Architecture type, but %s", getRequiredRotateMessage(member.Pod.GetName()))
p = append(p,
actions.NewAction(api.ActionTypeSetCurrentMemberArch, m.Group, member, "Architecture Mismatch").SetArch(arch),
)
}
}
}
}
return p
}

View file

@ -29,6 +29,7 @@ import (
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/deployment/agency"
@ -274,6 +275,15 @@ func (r *Resources) InspectPods(ctx context.Context, cachedStatus inspectorInter
}
}
// Member arch check
if v, ok := pod.Annotations[deployment.ArangoDeploymentPodChangeArchAnnotation]; ok {
if api.ArangoDeploymentArchitectureType(v).IsArchMismatch(spec.Architecture, memberStatus.Architecture) {
if memberStatus.Conditions.Update(api.ConditionTypeArchitectureMismatch, true, "Member has a different architecture than the deployment", "") {
updateMemberStatusNeeded = true
}
}
}
// Member Maintenance
if agencyCachePresent {
if agencyCache.Current.MaintenanceServers.InMaintenance(agency.Server(memberStatus.ID)) {

View file

@ -21,8 +21,6 @@
package rotation
import (
"reflect"
core "k8s.io/api/core/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
@ -55,7 +53,7 @@ func affinityCompare(_ api.DeploymentSpec, _ api.ServerGroup, spec, status *core
e = err
return
} else if specC != statusC {
mode = mode.And(getRotationMode(spec, status))
mode = mode.And(SilentRotation)
status.Affinity = spec.Affinity.DeepCopy()
return
} else {
@ -64,21 +62,3 @@ func affinityCompare(_ api.DeploymentSpec, _ api.ServerGroup, spec, status *core
}
}
}
func getRotationMode(spec, status *core.PodSpec) Mode {
var specArchs map[api.ArangoDeploymentArchitectureType]bool
var statusArchs map[api.ArangoDeploymentArchitectureType]bool
if spec.Affinity != nil && spec.Affinity.NodeAffinity != nil && spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
specArchs = api.GetArchsFromNodeSelector(spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms)
}
if status.Affinity != nil && status.Affinity.NodeAffinity != nil && status.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
statusArchs = api.GetArchsFromNodeSelector(status.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms)
}
if !reflect.DeepEqual(specArchs, statusArchs) {
return GracefulRotation
}
return SilentRotation
}

View file

@ -150,7 +150,7 @@ func Test_ArangoD_Affinity(t *testing.T) {
}),
TestCaseOverride: TestCaseOverride{
expectedMode: GracefulRotation,
expectedMode: SilentRotation,
},
},
{
@ -180,7 +180,7 @@ func Test_ArangoD_Affinity(t *testing.T) {
}),
TestCaseOverride: TestCaseOverride{
expectedMode: GracefulRotation,
expectedMode: SilentRotation,
},
},
{
@ -278,7 +278,7 @@ func Test_ArangoD_Affinity(t *testing.T) {
}),
TestCaseOverride: TestCaseOverride{
expectedMode: GracefulRotation,
expectedMode: SilentRotation,
},
},
{

View file

@ -36,6 +36,7 @@ type Mode int
const (
SkippedRotation Mode = iota
// SilentRotation Propagates changes without restart
SilentRotation
InPlaceRotation
GracefulRotation