@@ -17,7 +17,6 @@ import (
17
17
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
18
18
v1beta1 "github.com/openstack-k8s-operators/test-operator/api/v1beta1"
19
19
"gopkg.in/yaml.v3"
20
- batchv1 "k8s.io/api/batch/v1"
21
20
corev1 "k8s.io/api/core/v1"
22
21
rbacv1 "k8s.io/api/rbac/v1"
23
22
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
@@ -27,6 +26,7 @@ import (
27
26
"k8s.io/client-go/kubernetes"
28
27
ctrl "sigs.k8s.io/controller-runtime"
29
28
"sigs.k8s.io/controller-runtime/pkg/client"
29
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
30
30
)
31
31
32
32
const (
@@ -80,13 +80,13 @@ const (
80
80
// to change
81
81
Wait = iota
82
82
83
- // CreateFirstJob indicates that the Reconcile loop should create the first job
83
+ // CreateFirstPod indicates that the Reconcile loop should create the first job
84
84
// either specified in the .Spec section or in the .Spec.Workflow section.
85
- CreateFirstJob
85
+ CreateFirstPod
86
86
87
- // CreateNextJob indicates that the Reconcile loop should create a next job
87
+ // CreateNextPod indicates that the Reconcile loop should create a next job
88
88
// specified in the .Spec.Workflow section (if .Spec.Workflow is defined)
89
- CreateNextJob
89
+ CreateNextPod
90
90
91
91
// EndTesting indicates that all jobs have already finished. The Reconcile
92
92
// loop should end the testing and release resources that are required to
@@ -97,59 +97,100 @@ const (
97
97
Failure
98
98
)
99
99
100
+ // GetPod returns pod that has a specific name (podName) in a given namespace
101
+ // (podNamespace).
102
+ func (r * Reconciler ) GetPod (
103
+ ctx context.Context ,
104
+ podName string ,
105
+ podNamespace string ,
106
+ ) (* corev1.Pod , error ) {
107
+ pod := & corev1.Pod {}
108
+ objectKey := client.ObjectKey {Namespace : podNamespace , Name : podName }
109
+ if err := r .Client .Get (ctx , objectKey , pod ); err != nil {
110
+ return pod , err
111
+ }
112
+
113
+ return pod , nil
114
+ }
115
+
116
+ // CreatePod creates a pod based on a spec provided via PodSpec.
117
+ func (r * Reconciler ) CreatePod (
118
+ ctx context.Context ,
119
+ h helper.Helper ,
120
+ podSpec * corev1.Pod ,
121
+ ) (ctrl.Result , error ) {
122
+ _ , err := r .GetPod (ctx , podSpec .Name , podSpec .Namespace )
123
+ if err == nil {
124
+ return ctrl.Result {}, nil
125
+ } else if ! k8s_errors .IsNotFound (err ) {
126
+ return ctrl.Result {}, err
127
+ }
128
+
129
+ err = controllerutil .SetControllerReference (h .GetBeforeObject (), podSpec , r .GetScheme ())
130
+ if err != nil {
131
+ return ctrl.Result {}, err
132
+ }
133
+
134
+ if err := r .Client .Create (ctx , podSpec ); err != nil {
135
+ return ctrl.Result {}, err
136
+ }
137
+
138
+ return ctrl.Result {}, nil
139
+ }
140
+
100
141
// NextAction indicates what action needs to be performed by the Reconcile loop
101
142
// based on the current state of the OpenShift cluster.
102
143
func (r * Reconciler ) NextAction (
103
144
ctx context.Context ,
104
145
instance client.Object ,
105
146
workflowLength int ,
106
147
) (NextAction , int , error ) {
107
- // Get the latest job . The latest job is job with the highest value stored
148
+ // Get the latest pod . The latest pod is pod with the highest value stored
108
149
// in workflowStep label
109
150
workflowStepIdx := 0
110
- lastJob , err := r .GetLastJob (ctx , instance )
151
+ lastPod , err := r .GetLastPod (ctx , instance )
111
152
if err != nil {
112
153
return Failure , workflowStepIdx , err
113
154
}
114
155
115
- // If there is a job associated with the current instance.
116
- if lastJob != nil {
117
- workflowStepIdx , err := strconv .Atoi (lastJob .Labels [workflowStepLabel ])
156
+ // If there is a pod associated with the current instance.
157
+ if lastPod != nil {
158
+ workflowStepIdx , err := strconv .Atoi (lastPod .Labels [workflowStepLabel ])
118
159
if err != nil {
119
160
return Failure , workflowStepIdx , err
120
161
}
121
162
122
- // If the last job is not in Failed or Succeded state -> Wait
123
- lastJobFinished := ( lastJob .Status .Failed + lastJob . Status .Succeeded ) > 0
124
- if ! lastJobFinished {
163
+ // If the last pod is not in Failed or Succeded state -> Wait
164
+ lastPodFinished := lastPod .Status .Phase == corev1 . PodFailed || lastPod . Status .Phase == corev1 . PodSucceeded
165
+ if ! lastPodFinished {
125
166
return Wait , workflowStepIdx , nil
126
167
}
127
168
128
- // If the last job is in Failed or Succeeded state and it is NOT the last
129
- // job which was supposed to be created -> CreateNextJob
130
- if lastJobFinished && ! isLastJobIndex (workflowStepIdx , workflowLength ) {
169
+ // If the last pod is in Failed or Succeeded state and it is NOT the last
170
+ // pod which was supposed to be created -> CreateNextPod
171
+ if lastPodFinished && ! isLastPodIndex (workflowStepIdx , workflowLength ) {
131
172
workflowStepIdx ++
132
- return CreateNextJob , workflowStepIdx , nil
173
+ return CreateNextPod , workflowStepIdx , nil
133
174
}
134
175
135
- // Otherwise if the job is in Failed or Succeded stated and it IS the
136
- // last job -> EndTesting
137
- if lastJobFinished && isLastJobIndex (workflowStepIdx , workflowLength ) {
176
+ // Otherwise if the pod is in Failed or Succeded stated and it IS the
177
+ // last pod -> EndTesting
178
+ if lastPodFinished && isLastPodIndex (workflowStepIdx , workflowLength ) {
138
179
return EndTesting , workflowStepIdx , nil
139
180
}
140
181
}
141
182
142
- // If there is not any job associated with the instance -> createFirstJob
143
- if lastJob == nil {
144
- return CreateFirstJob , workflowStepIdx , nil
183
+ // If there is not any pod associated with the instance -> createFirstPod
184
+ if lastPod == nil {
185
+ return CreateFirstPod , workflowStepIdx , nil
145
186
}
146
187
147
188
return Failure , workflowStepIdx , nil
148
189
}
149
190
150
- // isLastJobIndex returns true when jobIndex is the index of the last job that
191
+ // isLastPodIndex returns true when jobIndex is the index of the last job that
151
192
// should be executed. Otherwise the return value is false.
152
- func isLastJobIndex (jobIndex int , workflowLength int ) bool {
193
+ func isLastPodIndex (jobIndex int , workflowLength int ) bool {
153
194
switch workflowLength {
154
195
case 0 :
155
196
return jobIndex == workflowLength
@@ -160,26 +201,26 @@ func isLastJobIndex(jobIndex int, workflowLength int) bool {
160
201
161
202
// GetLastJob returns job associated with an instance which has the highest value
162
203
// stored in the workflowStep label
163
- func (r * Reconciler ) GetLastJob (
204
+ func (r * Reconciler ) GetLastPod (
164
205
ctx context.Context ,
165
206
instance client.Object ,
166
- ) (* batchv1. Job , error ) {
207
+ ) (* corev1. Pod , error ) {
167
208
labels := map [string ]string {instanceNameLabel : instance .GetName ()}
168
209
namespaceListOpt := client .InNamespace (instance .GetNamespace ())
169
210
labelsListOpt := client .MatchingLabels (labels )
170
- jobList := & batchv1. JobList {}
171
- err := r .Client .List (ctx , jobList , namespaceListOpt , labelsListOpt )
211
+ podList := & corev1. PodList {}
212
+ err := r .Client .List (ctx , podList , namespaceListOpt , labelsListOpt )
172
213
if err != nil {
173
214
return nil , err
174
215
}
175
216
176
- var maxJob * batchv1. Job
217
+ var maxJob * corev1. Pod
177
218
maxJobWorkflowStep := 0
178
219
179
- for _ , job := range jobList .Items {
220
+ for _ , job := range podList .Items {
180
221
workflowStep , err := strconv .Atoi (job .Labels [workflowStepLabel ])
181
222
if err != nil {
182
- return & batchv1. Job {}, err
223
+ return & corev1. Pod {}, err
183
224
}
184
225
185
226
if workflowStep >= maxJobWorkflowStep {
@@ -307,7 +348,7 @@ func (r *Reconciler) GetContainerImage(
307
348
return "" , nil
308
349
}
309
350
310
- func (r * Reconciler ) GetJobName (instance interface {}, workflowStepNum int ) string {
351
+ func (r * Reconciler ) GetPodName (instance interface {}, workflowStepNum int ) string {
311
352
if typedInstance , ok := instance .(* v1beta1.Tobiko ); ok {
312
353
if len (typedInstance .Spec .Workflow ) == 0 || workflowStepNum == workflowStepNumInvalid {
313
354
return typedInstance .Name
@@ -552,11 +593,11 @@ func (r *Reconciler) ReleaseLock(ctx context.Context, instance client.Object) (b
552
593
return false , errors .New ("failed to delete test-operator-lock" )
553
594
}
554
595
555
- func (r * Reconciler ) JobExists (ctx context.Context , instance client.Object , workflowStepNum int ) bool {
556
- job := & batchv1. Job {}
557
- jobName := r .GetJobName (instance , workflowStepNum )
558
- objectKey := client.ObjectKey {Namespace : instance .GetNamespace (), Name : jobName }
559
- err := r .Client .Get (ctx , objectKey , job )
596
+ func (r * Reconciler ) PodExists (ctx context.Context , instance client.Object , workflowStepNum int ) bool {
597
+ pod := & corev1. Pod {}
598
+ podName := r .GetPodName (instance , workflowStepNum )
599
+ objectKey := client.ObjectKey {Namespace : instance .GetNamespace (), Name : podName }
600
+ err := r .Client .Get (ctx , objectKey , pod )
560
601
if err != nil && k8s_errors .IsNotFound (err ) {
561
602
return false
562
603
}
0 commit comments