-
Notifications
You must be signed in to change notification settings - Fork 84
/
runner.go
107 lines (96 loc) · 4.19 KB
/
runner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package upgradesteps
import (
"context"
"fmt"
"time"
"github.com/go-logr/logr"
upgradev1alpha1 "github.com/openshift/managed-upgrade-operator/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// UpgradeStep is the interface for steps that the upgrade runner
// can execute.
type UpgradeStep interface {
run(ctx context.Context, logger logr.Logger) (bool, error)
String() string
}
// Run executes the provided steps in order until one fails or all steps
// are completed. The function returns an indication of the last-completed
// UpgradePhase any associated error.
func Run(ctx context.Context, upgradeConfig *upgradev1alpha1.UpgradeConfig, logger logr.Logger, steps []UpgradeStep) (upgradev1alpha1.UpgradePhase, error) {
for _, step := range steps {
logger.Info(fmt.Sprintf("running step %s", step))
setConditionStart(step, upgradeConfig)
result, err := step.run(ctx, logger)
if err != nil {
logger.Error(err, fmt.Sprintf("error when %s", step.String()))
setConditionInProgress(step, err.Error(), upgradeConfig)
return upgradev1alpha1.UpgradePhaseUpgrading, err
}
if !result {
logger.Info(fmt.Sprintf("%s not done, skip following steps", step.String()))
setConditionInProgress(step, fmt.Sprintf("%s still in progress", step.String()), upgradeConfig)
return upgradev1alpha1.UpgradePhaseUpgrading, nil
}
setConditionComplete(step, upgradeConfig)
}
return upgradev1alpha1.UpgradePhaseUpgraded, nil
}
// newUpgradeCondition is a helper function for creating and returning
// an UpgradeCondition
func newUpgradeCondition(reason, msg string, conditionType upgradev1alpha1.UpgradeConditionType, s corev1.ConditionStatus) *upgradev1alpha1.UpgradeCondition {
return &upgradev1alpha1.UpgradeCondition{
Type: conditionType,
Status: s,
Reason: reason,
Message: msg,
}
}
// setConditionStart adds an UpgradeCondition to the UpgradeConfig indicating
// that a given step has commenced execution.
// If the UpgradeCondition already exists, no action is taken.
func setConditionStart(step UpgradeStep, upgradeConfig *upgradev1alpha1.UpgradeConfig) {
history := upgradeConfig.Status.History.GetHistory(upgradeConfig.Spec.Desired.Version)
c := history.Conditions.GetCondition(upgradev1alpha1.UpgradeConditionType(step.String()))
// Only set the condition if it doesn't already exist - the start time should already appear
if c == nil {
condition := newUpgradeCondition(fmt.Sprintf("%s not done", step.String()),
fmt.Sprintf("%s has started", step.String()),
upgradev1alpha1.UpgradeConditionType(step.String()),
corev1.ConditionFalse)
condition.StartTime = &metav1.Time{Time: time.Now()}
history.Conditions.SetCondition(*condition)
upgradeConfig.Status.History.SetHistory(*history)
}
}
// setConditionInProgress adds or updates an UpgradeCondition in the UpgradeConfig indicating
// that a given step is currently executing.
func setConditionInProgress(step UpgradeStep, message string, upgradeConfig *upgradev1alpha1.UpgradeConfig) {
history := upgradeConfig.Status.History.GetHistory(upgradeConfig.Spec.Desired.Version)
c := history.Conditions.GetCondition(upgradev1alpha1.UpgradeConditionType(step.String()))
if c != nil {
c.Message = message
c.Status = corev1.ConditionFalse
// Reset completion time because some steps can fail after an earlier success
c.CompleteTime = nil
history.Conditions.SetCondition(*c)
upgradeConfig.Status.History.SetHistory(*history)
}
}
// setConditionComplete adds or updates an UpgradeCondition in the UpgradeConfig indicating
// that a given step has completed.
func setConditionComplete(step UpgradeStep, upgradeConfig *upgradev1alpha1.UpgradeConfig) {
history := upgradeConfig.Status.History.GetHistory(upgradeConfig.Spec.Desired.Version)
c := history.Conditions.GetCondition(upgradev1alpha1.UpgradeConditionType(step.String()))
if c != nil {
c.Reason = fmt.Sprintf("%s done", step.String())
c.Message = fmt.Sprintf("%s is completed", step.String())
c.Status = corev1.ConditionTrue
// Only set completion time if it isn't already set
if c.CompleteTime == nil {
c.CompleteTime = &metav1.Time{Time: time.Now()}
}
history.Conditions.SetCondition(*c)
upgradeConfig.Status.History.SetHistory(*history)
}
}