Skip to content

Commit 93d8ba1

Browse files
authored
[Bugfix] Prevent Runtime update restarts (#1205)
1 parent 463ab90 commit 93d8ba1

15 files changed

+250
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
- (Feature) Allow to exclude metrics
3939
- (Bugfix) Do not stop Sync if Synchronization is in progress
4040
- (Bugfix) Wait for Pod to be Ready in post-restart actions
41+
- (Bugfix) Prevent Runtime update restarts
4142

4243
## [1.2.20](https://github.com/arangodb/kube-arangodb/tree/1.2.20) (2022-10-25)
4344
- (Feature) Add action progress

pkg/apis/deployment/v1/conditions.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ type Condition struct {
144144
Message string `json:"message,omitempty"`
145145
// Hash keep propagation hash id, for example checksum of secret
146146
Hash string `json:"hash,omitempty"`
147+
// Params keeps additional params for the condition
148+
Params ConditionParams `json:"params,omitempty"`
147149
}
148150

149151
func (c Condition) IsTrue() bool {
@@ -154,6 +156,7 @@ func (c Condition) IsTrue() bool {
154156
func (c Condition) Equal(other Condition) bool {
155157
return c.Type == other.Type &&
156158
c.Status == other.Status &&
159+
c.Params.Equal(other.Params) &&
157160
util.TimeCompareEqual(c.LastUpdateTime, other.LastUpdateTime) &&
158161
util.TimeCompareEqual(c.LastTransitionTime, other.LastTransitionTime) &&
159162
c.Reason == other.Reason &&
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2022 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 v1
22+
23+
const (
24+
// ConditionParamContainerUpdatingName define parameter used during Image Runtime update
25+
ConditionParamContainerUpdatingName ConditionParam = "updatingContainerName"
26+
)
27+
28+
// ConditionParam is a strongly typed condition parameter
29+
type ConditionParam string
30+
31+
type ConditionParams map[ConditionParam]string
32+
33+
// Equal compare two ConditionParams objects
34+
func (c ConditionParams) Equal(b ConditionParams) bool {
35+
if len(c) != len(b) {
36+
return false
37+
}
38+
39+
for k, v := range c {
40+
if v2, ok := b[k]; !ok || v != v2 {
41+
return false
42+
}
43+
}
44+
45+
return true
46+
}

pkg/apis/deployment/v1/zz_generated.deepcopy.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/deployment/v2alpha1/conditions.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ type Condition struct {
144144
Message string `json:"message,omitempty"`
145145
// Hash keep propagation hash id, for example checksum of secret
146146
Hash string `json:"hash,omitempty"`
147+
// Params keeps additional params for the condition
148+
Params ConditionParams `json:"params,omitempty"`
147149
}
148150

149151
func (c Condition) IsTrue() bool {
@@ -154,6 +156,7 @@ func (c Condition) IsTrue() bool {
154156
func (c Condition) Equal(other Condition) bool {
155157
return c.Type == other.Type &&
156158
c.Status == other.Status &&
159+
c.Params.Equal(other.Params) &&
157160
util.TimeCompareEqual(c.LastUpdateTime, other.LastUpdateTime) &&
158161
util.TimeCompareEqual(c.LastTransitionTime, other.LastTransitionTime) &&
159162
c.Reason == other.Reason &&
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2022 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 v2alpha1
22+
23+
const (
24+
// ConditionParamContainerUpdatingName define parameter used during Image Runtime update
25+
ConditionParamContainerUpdatingName ConditionParam = "updatingContainerName"
26+
)
27+
28+
// ConditionParam is a strongly typed condition parameter
29+
type ConditionParam string
30+
31+
type ConditionParams map[ConditionParam]string
32+
33+
// Equal compare two ConditionParams objects
34+
func (c ConditionParams) Equal(b ConditionParams) bool {
35+
if len(c) != len(b) {
36+
return false
37+
}
38+
39+
for k, v := range c {
40+
if v2, ok := b[k]; !ok || v != v2 {
41+
return false
42+
}
43+
}
44+
45+
return true
46+
}

pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/reconcile/action.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ func getActionPost(a Action, ctx context.Context) error {
8181
}
8282
}
8383

84+
// ActionPre keep interface which is executed before action is started.
85+
type ActionPre interface {
86+
Action
87+
88+
// Pre execute after action is completed
89+
Pre(ctx context.Context) error
90+
}
91+
92+
func getActionPre(a Action, ctx context.Context) error {
93+
if c, ok := a.(ActionPre); !ok {
94+
return nil
95+
} else {
96+
return c.Pre(ctx)
97+
}
98+
}
99+
84100
// ActionReloadCachedStatus keeps information about CachedStatus reloading (executed after action has been executed)
85101
type ActionReloadCachedStatus interface {
86102
Action

pkg/deployment/reconcile/action_runtime_container_image_update.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,44 @@ func newRuntimeContainerImageUpdateAction(action api.Action, actionCtx ActionCon
4343
}
4444

4545
var _ ActionPost = &actionRuntimeContainerImageUpdate{}
46+
var _ ActionPre = &actionRuntimeContainerImageUpdate{}
4647

4748
type actionRuntimeContainerImageUpdate struct {
4849
// actionImpl implement timeout and member id functions
4950
actionImpl
5051
}
5152

53+
func (a actionRuntimeContainerImageUpdate) Pre(ctx context.Context) error {
54+
a.log.Info("Updating member condition")
55+
m, ok := a.actionCtx.GetMemberStatusByID(a.action.MemberID)
56+
if !ok {
57+
a.log.Info("member is gone already")
58+
return nil
59+
}
60+
61+
cname, _, ok := a.getContainerDetails()
62+
if !ok {
63+
a.log.Info("Unable to find container details")
64+
return nil
65+
}
66+
67+
if c, ok := m.Conditions.Get(api.ConditionTypeUpdating); ok {
68+
if c.Params == nil {
69+
c.Params = api.ConditionParams{}
70+
}
71+
72+
if c.Params[api.ConditionParamContainerUpdatingName] != cname {
73+
c.Params[api.ConditionParamContainerUpdatingName] = cname
74+
75+
if err := a.actionCtx.UpdateMember(ctx, m); err != nil {
76+
return err
77+
}
78+
}
79+
}
80+
81+
return nil
82+
}
83+
5284
func (a actionRuntimeContainerImageUpdate) Post(ctx context.Context) error {
5385
a.log.Info("Updating container image")
5486
m, ok := a.actionCtx.GetMemberStatusByID(a.action.MemberID)
@@ -57,6 +89,22 @@ func (a actionRuntimeContainerImageUpdate) Post(ctx context.Context) error {
5789
return nil
5890
}
5991

92+
if c, ok := m.Conditions.Get(api.ConditionTypeUpdating); ok {
93+
if c.Params != nil {
94+
if _, ok := c.Params[api.ConditionParamContainerUpdatingName]; ok {
95+
delete(c.Params, api.ConditionParamContainerUpdatingName)
96+
97+
if len(c.Params) == 0 {
98+
c.Params = nil
99+
}
100+
101+
if err := a.actionCtx.UpdateMember(ctx, m); err != nil {
102+
return err
103+
}
104+
}
105+
}
106+
}
107+
60108
cname, image, ok := a.getContainerDetails()
61109
if !ok {
62110
a.log.Info("Unable to find container details")

pkg/deployment/reconcile/action_wait_for_member_ready.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,9 @@ func (a *actionWaitForMemberReady) CheckProgress(ctx context.Context) (bool, boo
6363
return true, false, nil
6464
}
6565

66+
if a.actionCtx.GetMode() == api.DeploymentModeActiveFailover {
67+
return true, false, nil
68+
}
69+
6670
return member.Conditions.IsTrue(api.ConditionTypeReady), false, nil
6771
}

0 commit comments

Comments
 (0)