Skip to content

Commit 6ec828d

Browse files
committed
Initialise plan status correctly if an upgraded plan adds new phases or steps (#1755)
* Add e2e-test to confirm missing phase status bug * Initialize status correctly for newly added phases and steps Signed-off-by: Andreas Neumann <[email protected]>
1 parent d902714 commit 6ec828d

File tree

14 files changed

+248
-11
lines changed

14 files changed

+248
-11
lines changed

pkg/apis/kudo/v1beta1/instance_types.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ func (s *StepStatus) SetWithMessage(status ExecutionStatus, message string) {
116116
s.Message = message
117117
}
118118

119+
// Step returns the StepStatus with the given name, or nil if no such step status exists
120+
func (s *PhaseStatus) Step(name string) *StepStatus {
121+
for _, stepStatus := range s.Steps {
122+
if stepStatus.Name == name {
123+
return &stepStatus
124+
}
125+
}
126+
return nil
127+
}
128+
119129
func (s *PhaseStatus) Set(status ExecutionStatus) {
120130
s.Status = status
121131
s.Message = ""
@@ -126,6 +136,16 @@ func (s *PhaseStatus) SetWithMessage(status ExecutionStatus, message string) {
126136
s.Message = message
127137
}
128138

139+
// Step returns the PhaseStatus with the given name, or nil if no such phase status exists
140+
func (s *PlanStatus) Phase(name string) *PhaseStatus {
141+
for _, phaseStatus := range s.Phases {
142+
if phaseStatus.Name == name {
143+
return &phaseStatus
144+
}
145+
}
146+
return nil
147+
}
148+
129149
func (s *PlanStatus) Set(status ExecutionStatus) {
130150
if s.Status != status {
131151
s.LastUpdatedTimestamp = &metav1.Time{Time: time.Now()}

pkg/controller/instance/instance_controller.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -532,29 +532,36 @@ func ensurePlanStatusInitialized(i *kudoapi.Instance, ov *kudoapi.OperatorVersio
532532
}
533533

534534
for planName, plan := range ov.Spec.Plans {
535-
if _, ok := i.Status.PlanStatus[planName]; !ok {
536-
planStatus := kudoapi.PlanStatus{
535+
planStatus, ok := i.Status.PlanStatus[planName]
536+
if !ok {
537+
planStatus = kudoapi.PlanStatus{
537538
Name: planName,
538539
Status: kudoapi.ExecutionNeverRun,
539540
Phases: make([]kudoapi.PhaseStatus, 0),
540541
}
541-
for _, phase := range plan.Phases {
542-
phaseStatus := kudoapi.PhaseStatus{
542+
}
543+
for _, phase := range plan.Phases {
544+
phaseStatus := planStatus.Phase(phase.Name)
545+
if phaseStatus == nil {
546+
planStatus.Phases = append(planStatus.Phases, kudoapi.PhaseStatus{
543547
Name: phase.Name,
544548
Status: kudoapi.ExecutionNeverRun,
545549
Steps: make([]kudoapi.StepStatus, 0),
546-
}
547-
for _, step := range phase.Steps {
548-
stepStatus := kudoapi.StepStatus{
550+
})
551+
phaseStatus = &planStatus.Phases[len(planStatus.Phases)-1]
552+
}
553+
for _, step := range phase.Steps {
554+
stepStatus := phaseStatus.Step(step.Name)
555+
if stepStatus == nil {
556+
phaseStatus.Steps = append(phaseStatus.Steps, kudoapi.StepStatus{
549557
Name: step.Name,
550558
Status: kudoapi.ExecutionNeverRun,
551-
}
552-
phaseStatus.Steps = append(phaseStatus.Steps, stepStatus)
559+
})
553560
}
554-
planStatus.Phases = append(planStatus.Phases, phaseStatus)
555561
}
556-
i.Status.PlanStatus[planName] = planStatus
557562
}
563+
// We might have updated the plan status, so set it just to make sure
564+
i.Status.PlanStatus[planName] = planStatus
558565
}
559566
}
560567

pkg/controller/instance/instance_controller_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,57 @@ func Test_ensurePlanStatusInitialized(t *testing.T) {
575575
},
576576
},
577577
},
578+
{
579+
name: "a new phase is correctly initialized",
580+
i: instance,
581+
ov: func() *kudoapi.OperatorVersion {
582+
modifiedOv := ov.DeepCopy()
583+
pln := modifiedOv.Spec.Plans["deploy"]
584+
pln.Phases = append(pln.Phases, kudoapi.Phase{
585+
Name: "newphase",
586+
Steps: []kudoapi.Step{
587+
{
588+
Name: "additionalstep",
589+
Tasks: []string{},
590+
},
591+
},
592+
})
593+
modifiedOv.Spec.Plans["deploy"] = pln
594+
return modifiedOv
595+
}(),
596+
want: kudoapi.InstanceStatus{
597+
PlanStatus: map[string]kudoapi.PlanStatus{
598+
"deploy": {
599+
Name: "deploy",
600+
Status: kudoapi.ExecutionNeverRun,
601+
UID: "",
602+
Phases: []kudoapi.PhaseStatus{
603+
{
604+
Name: "phase",
605+
Status: kudoapi.ExecutionNeverRun,
606+
Steps: []kudoapi.StepStatus{
607+
{
608+
Name: "step",
609+
Status: kudoapi.ExecutionNeverRun,
610+
},
611+
},
612+
},
613+
{
614+
Name: "newphase",
615+
Status: kudoapi.ExecutionNeverRun,
616+
Steps: []kudoapi.StepStatus{
617+
{
618+
Name: "additionalstep",
619+
Status: kudoapi.ExecutionNeverRun,
620+
},
621+
},
622+
},
623+
},
624+
},
625+
"backup": backupStatus,
626+
},
627+
},
628+
},
578629
}
579630

580631
for _, tt := range tests {

test/e2e/upgrade/00-assert.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: kudo.dev/v1beta1
2+
kind: Instance
3+
metadata:
4+
name: upgrade-operator
5+
status:
6+
conditions:
7+
- type: Ready
8+
status: "True"
9+
planStatus:
10+
deploy:
11+
status: COMPLETE
12+
---
13+
apiVersion: apps/v1
14+
kind: Deployment
15+
metadata:
16+
name: nginx-deployment

test/e2e/upgrade/00-install.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: kudo.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- command: kubectl kudo install --instance upgrade-operator ./first-operator
5+
namespaced: true

test/e2e/upgrade/01-assert.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: kudo.dev/v1beta1
2+
kind: Instance
3+
metadata:
4+
name: upgrade-operator
5+
status:
6+
planStatus:
7+
deploy:
8+
status: COMPLETE
9+
---
10+
apiVersion: apps/v1
11+
kind: Deployment
12+
metadata:
13+
name: nginx-deployment
14+
---
15+
apiVersion: v1
16+
kind: ConfigMap
17+
metadata:
18+
name: test

test/e2e/upgrade/01-upgrade.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: kudo.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- command: kubectl kudo upgrade --instance upgrade-operator ./first-operator-v2
5+
namespaced: true
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: kudo.dev/v1beta1
2+
name: "first-operator"
3+
operatorVersion: "0.2.0"
4+
appVersion: "1.7.9"
5+
kubernetesVersion: 1.17.0
6+
maintainers:
7+
- name: Your name
8+
9+
url: https://kudo.dev
10+
tasks:
11+
- name: app
12+
kind: Apply
13+
spec:
14+
resources:
15+
- deployment.yaml
16+
- name: config
17+
kind: Apply
18+
spec:
19+
resources:
20+
- configmap.yaml
21+
plans:
22+
deploy:
23+
strategy: serial
24+
phases:
25+
- name: newphase
26+
strategy: parallel
27+
steps:
28+
- name: config
29+
tasks:
30+
- config
31+
- name: main
32+
strategy: parallel
33+
steps:
34+
- name: everything
35+
tasks:
36+
- app
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: kudo.dev/v1beta1
2+
parameters:
3+
- name: replicas
4+
description: Number of replicas that should be run as part of the deployment
5+
default: 2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: test
5+
data:
6+
foo: bar

0 commit comments

Comments
 (0)