@@ -18,6 +18,8 @@ package controllers
18
18
19
19
import (
20
20
"context"
21
+ "errors"
22
+ "fmt"
21
23
"strconv"
22
24
"time"
23
25
@@ -38,7 +40,6 @@ import (
38
40
rbacv1 "k8s.io/api/rbac/v1"
39
41
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
40
42
ctrl "sigs.k8s.io/controller-runtime"
41
- "sigs.k8s.io/controller-runtime/pkg/client"
42
43
"sigs.k8s.io/controller-runtime/pkg/log"
43
44
)
44
45
@@ -73,9 +74,6 @@ func (r *AnsibleTestReconciler) GetLogger(ctx context.Context) logr.Logger {
73
74
func (r * AnsibleTestReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (result ctrl.Result , _err error ) {
74
75
Log := r .GetLogger (ctx )
75
76
76
- // How much time should we wait before calling Reconcile loop when there is a failure
77
- requeueAfter := time .Second * 60
78
-
79
77
// Fetch the ansible instance
80
78
instance := & testv1beta1.AnsibleTest {}
81
79
err := r .Client .Get (ctx , req .NamespacedName , instance )
@@ -86,11 +84,6 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
86
84
return ctrl.Result {}, err
87
85
}
88
86
89
- workflowActive := false
90
- if len (instance .Spec .Workflow ) > 0 {
91
- workflowActive = true
92
- }
93
-
94
87
// Create a helper
95
88
helper , err := helper .NewHelper (
96
89
instance ,
@@ -147,33 +140,55 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
147
140
148
141
}
149
142
150
- // Ensure that there is an external counter and read its value
151
- // We use the external counter to keep track of the workflow steps
152
- r .WorkflowStepCounterCreate (ctx , instance , helper )
153
- externalWorkflowCounter := r .WorkflowStepCounterRead (ctx , instance )
154
- if externalWorkflowCounter == - 1 {
155
- return ctrl.Result {RequeueAfter : requeueAfter }, nil
156
- }
143
+ workflowLength := len (instance .Spec .Workflow )
144
+ nextAction , nextWorkflowStep , err := r .NextAction (ctx , instance , workflowLength )
157
145
158
- // Each job that is being executed by the test operator has
159
- currentWorkflowStep := 0
160
- runningAnsibleJob := & batchv1.Job {}
161
- runningJobName := r .GetJobName (instance , externalWorkflowCounter - 1 )
162
- err = r .Client .Get (ctx , client.ObjectKey {Namespace : instance .GetNamespace (), Name : runningJobName }, runningAnsibleJob )
163
- if err != nil && ! k8s_errors .IsNotFound (err ) {
146
+ switch nextAction {
147
+ case Failure :
164
148
return ctrl.Result {}, err
165
- } else if err == nil {
166
- currentWorkflowStep , _ = strconv .Atoi (runningAnsibleJob .Labels ["workflowStep" ])
167
- }
168
149
169
- if r .CompletedJobExists (ctx , instance , currentWorkflowStep ) {
170
- // The job created by the instance was completed. Release the lock
171
- // so that other instances can spawn a job.
172
- instance .Status .Conditions .MarkTrue (condition .DeploymentReadyCondition , condition .DeploymentReadyMessage )
173
- Log .Info ("Job completed" )
150
+ case Wait :
151
+ Log .Info (InfoWaitingOnJob )
152
+ return ctrl.Result {RequeueAfter : RequeueAfterValue }, nil
153
+
154
+ case EndTesting :
155
+ // All jobs created by the instance were completed. Release the lock
156
+ // so that other instances can spawn their jobs.
174
157
if lockReleased , err := r .ReleaseLock (ctx , instance ); ! lockReleased {
175
- return ctrl.Result {}, err
158
+ Log .Info (fmt .Sprintf (InfoCanNotReleaseLock , testOperatorLockName ))
159
+ return ctrl.Result {RequeueAfter : RequeueAfterValue }, err
176
160
}
161
+
162
+ instance .Status .Conditions .MarkTrue (
163
+ condition .DeploymentReadyCondition ,
164
+ condition .DeploymentReadyMessage )
165
+
166
+ Log .Info (InfoTestingCompleted )
167
+ return ctrl.Result {}, nil
168
+
169
+ case CreateFirstJob :
170
+ lockAcquired , err := r .AcquireLock (ctx , instance , helper , false )
171
+ if ! lockAcquired {
172
+ Log .Info (fmt .Sprintf (InfoCanNotAcquireLock , testOperatorLockName ))
173
+ return ctrl.Result {RequeueAfter : RequeueAfterValue }, err
174
+ }
175
+
176
+ Log .Info (fmt .Sprintf (InfoCreatingFirstPod , nextWorkflowStep ))
177
+
178
+ case CreateNextJob :
179
+ // Confirm that we still hold the lock. This is useful to check if for
180
+ // example somebody / something deleted the lock and it got claimed by
181
+ // another instance. This is considered to be an error state.
182
+ lockAcquired , err := r .AcquireLock (ctx , instance , helper , false )
183
+ if ! lockAcquired {
184
+ Log .Error (err , ErrConfirmLockOwnership , testOperatorLockName )
185
+ return ctrl.Result {RequeueAfter : RequeueAfterValue }, err
186
+ }
187
+
188
+ Log .Info (fmt .Sprintf (InfoCreatingNextPod , nextWorkflowStep ))
189
+
190
+ default :
191
+ return ctrl.Result {}, errors .New (ErrReceivedUnexpectedAction )
177
192
}
178
193
179
194
// Service account, role, binding
@@ -206,9 +221,9 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
206
221
207
222
serviceLabels := map [string ]string {
208
223
common .AppSelector : ansibletest .ServiceName ,
209
- "workflowStep" : strconv .Itoa (externalWorkflowCounter ),
210
- "instanceName" : instance .Name ,
211
- "operator" : "test-operator" ,
224
+ workflowStepLabel : strconv .Itoa (nextWorkflowStep ),
225
+ instanceNameLabel : instance .Name ,
226
+ operatorNameLabel : "test-operator" ,
212
227
}
213
228
214
229
// Create PersistentVolumeClaim
@@ -227,47 +242,26 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
227
242
}
228
243
// Create PersistentVolumeClaim - end
229
244
230
- // If the current job is executing the last workflow step -> do not create another job
231
- if workflowActive && externalWorkflowCounter >= len (instance .Spec .Workflow ) {
232
- return ctrl.Result {}, nil
233
- } else if ! workflowActive && r .JobExists (ctx , instance , currentWorkflowStep ) {
234
- return ctrl.Result {}, nil
235
- }
236
-
237
- // We are about to start job that spawns the pod with tests.
238
- // This lock ensures that there is always only one pod running.
239
- lockAcquired , err := r .AcquireLock (ctx , instance , helper , false )
240
- if ! lockAcquired {
241
- Log .Info ("Can not acquire lock" )
242
- requeueAfter := time .Second * 60
243
- return ctrl.Result {RequeueAfter : requeueAfter }, err
244
- }
245
- Log .Info ("Lock acquired" )
246
-
247
- if workflowActive {
248
- r .WorkflowStepCounterIncrease (ctx , instance , helper )
249
- }
250
-
251
245
instance .Status .Conditions .MarkTrue (condition .ServiceConfigReadyCondition , condition .ServiceConfigReadyMessage )
252
246
253
247
// Create a new job
254
248
mountCerts := r .CheckSecretExists (ctx , instance , "combined-ca-bundle" )
255
- jobName := r .GetJobName (instance , externalWorkflowCounter )
256
- envVars , workflowOverrideParams := r .PrepareAnsibleEnv (instance , externalWorkflowCounter )
249
+ jobName := r .GetJobName (instance , nextWorkflowStep )
250
+ envVars , workflowOverrideParams := r .PrepareAnsibleEnv (instance , nextWorkflowStep )
257
251
logsPVCName := r .GetPVCLogsName (instance , 0 )
258
252
containerImage , err := r .GetContainerImage (ctx , workflowOverrideParams ["ContainerImage" ], instance )
259
- privileged := r .OverwriteAnsibleWithWorkflow (instance .Spec , "Privileged" , "pbool" , externalWorkflowCounter ).(bool )
253
+ privileged := r .OverwriteAnsibleWithWorkflow (instance .Spec , "Privileged" , "pbool" , nextWorkflowStep ).(bool )
260
254
if err != nil {
261
255
return ctrl.Result {}, err
262
256
}
263
257
264
- if externalWorkflowCounter < len (instance .Spec .Workflow ) {
265
- if instance .Spec .Workflow [externalWorkflowCounter ].NodeSelector != nil {
266
- instance .Spec .NodeSelector = * instance .Spec .Workflow [externalWorkflowCounter ].NodeSelector
258
+ if nextWorkflowStep < len (instance .Spec .Workflow ) {
259
+ if instance .Spec .Workflow [nextWorkflowStep ].NodeSelector != nil {
260
+ instance .Spec .NodeSelector = * instance .Spec .Workflow [nextWorkflowStep ].NodeSelector
267
261
}
268
262
269
- if instance .Spec .Workflow [externalWorkflowCounter ].Tolerations != nil {
270
- instance .Spec .Tolerations = * instance .Spec .Workflow [externalWorkflowCounter ].Tolerations
263
+ if instance .Spec .Workflow [nextWorkflowStep ].Tolerations != nil {
264
+ instance .Spec .Tolerations = * instance .Spec .Workflow [nextWorkflowStep ].Tolerations
271
265
}
272
266
}
273
267
@@ -279,7 +273,7 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
279
273
mountCerts ,
280
274
envVars ,
281
275
workflowOverrideParams ,
282
- externalWorkflowCounter ,
276
+ nextWorkflowStep ,
283
277
containerImage ,
284
278
privileged ,
285
279
)
@@ -316,7 +310,6 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request)
316
310
return ctrlResult , nil
317
311
}
318
312
// Create a new job - end
319
-
320
313
Log .Info ("Reconciled Service successfully" )
321
314
return ctrl.Result {}, nil
322
315
}
0 commit comments