Skip to content

Commit

Permalink
Merge pull request #268 from s-urbaniak/bz-1669258
Browse files Browse the repository at this point in the history
pkg/operator: fix progressing state of cluster operator
  • Loading branch information
openshift-merge-robot committed Feb 26, 2019
2 parents edaa78c + 1249a26 commit 60d95cb
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 111 deletions.
90 changes: 21 additions & 69 deletions pkg/client/clusteroperator.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,24 @@ func (r *StatusReporter) SetDone() error {

time := metav1.Now()

conditions := ensureConditionsInitialized(co.Status.Conditions, time)
conditions = setCondition(conditions, v1.OperatorAvailable, v1.ConditionTrue, "Successfully rolled out the stack.", time)
conditions = setCondition(conditions, v1.OperatorProgressing, v1.ConditionFalse, "", time)
conditions = setCondition(conditions, v1.OperatorFailing, v1.ConditionFalse, "", time)
co.Status.Conditions = conditions
conditions := newConditions(co.Status.Conditions, time)
conditions.setCondition(v1.OperatorAvailable, v1.ConditionTrue, "Successfully rolled out the stack.", time)
conditions.setCondition(v1.OperatorProgressing, v1.ConditionFalse, "", time)
conditions.setCondition(v1.OperatorFailing, v1.ConditionFalse, "", time)
co.Status.Conditions = conditions.entries()
//co.Status.Version = r.version

_, err = r.client.UpdateStatus(co)
return err
}

// SetInProgress sets the OperatorProgressing condition to true, either:
// 1. If there has been no previous status yet
// 2. If the previous ClusterOperator OperatorAvailable condition was false
//
// This will ensure that the progressing state will be only set initially or in case of failure.
// Once controller operator versions are available, an additional check will be introduced that toggles
// the OperatorProgressing state in case of version upgrades.
func (r *StatusReporter) SetInProgress() error {
co, err := r.client.Get(r.clusterOperatorName, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
Expand All @@ -58,9 +65,9 @@ func (r *StatusReporter) SetInProgress() error {

time := metav1.Now()

conditions := ensureConditionsInitialized(co.Status.Conditions, time)
conditions = setCondition(conditions, v1.OperatorProgressing, v1.ConditionTrue, "Rolling out the stack.", time)
co.Status.Conditions = conditions
conditions := newConditions(co.Status.Conditions, time)
conditions.setCondition(v1.OperatorProgressing, v1.ConditionTrue, "Rolling out the stack.", time)
co.Status.Conditions = conditions.entries()
//co.Status.Version = r.version

_, err = r.client.UpdateStatus(co)
Expand All @@ -79,11 +86,11 @@ func (r *StatusReporter) SetFailed(statusErr error) error {

time := metav1.Now()

conditions := ensureConditionsInitialized(co.Status.Conditions, time)
conditions = setCondition(conditions, v1.OperatorAvailable, v1.ConditionFalse, "", time)
conditions = setCondition(conditions, v1.OperatorProgressing, v1.ConditionFalse, "", time)
conditions = setCondition(conditions, v1.OperatorFailing, v1.ConditionTrue, fmt.Sprintf("Failed to rollout the stack. Error: %v", statusErr), time)
co.Status.Conditions = conditions
conditions := newConditions(co.Status.Conditions, time)
conditions.setCondition(v1.OperatorAvailable, v1.ConditionFalse, "", time)
conditions.setCondition(v1.OperatorProgressing, v1.ConditionFalse, "", time)
conditions.setCondition(v1.OperatorFailing, v1.ConditionTrue, fmt.Sprintf("Failed to rollout the stack. Error: %v", statusErr), time)
co.Status.Conditions = conditions.entries()
//co.Status.Version = r.version

_, err = r.client.UpdateStatus(co)
Expand All @@ -103,62 +110,7 @@ func (r *StatusReporter) newClusterOperator() *v1.ClusterOperator {
Spec: v1.ClusterOperatorSpec{},
Status: v1.ClusterOperatorStatus{},
}
co.Status.Conditions = ensureConditionsInitialized(co.Status.Conditions, time)
co.Status.Conditions = newConditions(co.Status.Conditions, time).entries()

return co
}

func ensureConditionsInitialized(conditions []v1.ClusterOperatorStatusCondition, time metav1.Time) []v1.ClusterOperatorStatusCondition {
if len(conditions) == 0 {
return []v1.ClusterOperatorStatusCondition{
{
Type: v1.OperatorAvailable,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
{
Type: v1.OperatorProgressing,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
{
Type: v1.OperatorFailing,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
}
}

return conditions
}

func setCondition(conditions []v1.ClusterOperatorStatusCondition, condition v1.ClusterStatusConditionType, status v1.ConditionStatus, message string, time metav1.Time) []v1.ClusterOperatorStatusCondition {
newConditions := []v1.ClusterOperatorStatusCondition{}
found := false
for _, c := range conditions {
if c.Type == condition {
found = true

if c.Status != status || c.Message != message {
newConditions = append(newConditions, v1.ClusterOperatorStatusCondition{
Type: condition,
Status: status,
LastTransitionTime: time,
Message: message,
})
continue
}
}
newConditions = append(newConditions, c)
}
if !found {
newConditions = append(newConditions, v1.ClusterOperatorStatusCondition{
Type: condition,
Status: status,
LastTransitionTime: time,
Message: message,
})
}

return newConditions
}
42 changes: 0 additions & 42 deletions pkg/client/clusteroperator_test.go

This file was deleted.

94 changes: 94 additions & 0 deletions pkg/client/condition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2018 The Cluster Monitoring Operator Authors
//
// 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.

package client

import (
v1 "github.com/openshift/api/config/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type conditions struct {
entryMap map[v1.ClusterStatusConditionType]v1.ClusterOperatorStatusCondition
}

func newConditions(cs []v1.ClusterOperatorStatusCondition, time metav1.Time) *conditions {
entries := map[v1.ClusterStatusConditionType]v1.ClusterOperatorStatusCondition{
v1.OperatorAvailable: {
Type: v1.OperatorAvailable,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
v1.OperatorProgressing: {
Type: v1.OperatorProgressing,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
v1.OperatorFailing: {
Type: v1.OperatorFailing,
Status: v1.ConditionUnknown,
LastTransitionTime: time,
},
}

for _, c := range cs {
entries[c.Type] = c
}

return &conditions{
entryMap: entries,
}
}

func (cs *conditions) setCondition(condition v1.ClusterStatusConditionType, status v1.ConditionStatus, message string, time metav1.Time) {
entries := make(map[v1.ClusterStatusConditionType]v1.ClusterOperatorStatusCondition)
for k, v := range cs.entryMap {
entries[k] = v
}

c, ok := cs.entryMap[condition]

if !ok || c.Status != status || c.Message != message {
entries[condition] = v1.ClusterOperatorStatusCondition{
Type: condition,
Status: status,
LastTransitionTime: time,
Message: message,
}
}

// If the operator is already available, we don't set it into progressing state again.
if condition == v1.OperatorProgressing && status == v1.ConditionTrue {
available, ok := cs.entryMap[v1.OperatorAvailable]
if ok && available.Status == v1.ConditionTrue {
return
}
}

cs.entryMap = entries
}

func (cs *conditions) entries() []v1.ClusterOperatorStatusCondition {
var res []v1.ClusterOperatorStatusCondition
for _, v := range cs.entryMap {
res = append(res, v)
}
return res
}

type byType []v1.ClusterOperatorStatusCondition

func (b byType) Len() int { return len(b) }
func (b byType) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b byType) Less(i, j int) bool { return b[i].Type < b[j].Type }
Loading

0 comments on commit 60d95cb

Please sign in to comment.