Skip to content
This repository was archived by the owner on Dec 16, 2025. It is now read-only.

Commit 7990f5f

Browse files
committed
Add timeout logic
Signed-off-by: Matej Feder <[email protected]>
1 parent 43d1ee5 commit 7990f5f

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

api/v1alpha1/conditions_const.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,15 @@ const (
6464
)
6565

6666
const (
67-
// OpenStackImageReadyCondition reports on whether the image of cluster stack release is imported and actice.
67+
// OpenStackImageImportStartCondition reports the image import start.
68+
OpenStackImageImportStartCondition = "OpenStackImageImportStart"
69+
70+
// OpenStackImageImportNotStartReason is used when image import does not start yet.
71+
OpenStackImageImportNotStartReason = "OpenStackImageImportNotStartReason"
72+
)
73+
74+
const (
75+
// OpenStackImageReadyCondition reports on whether the image of cluster stack release is imported and active.
6876
OpenStackImageReadyCondition clusterv1beta1.ConditionType = "OpenStackImageActive"
6977

7078
// OpenStackImageNotCreatedYetReason is used when image is not yet created.
@@ -73,6 +81,9 @@ const (
7381
// OpenStackImageNotImportedYetReason is used when image is not yet imported.
7482
OpenStackImageNotImportedYetReason = "OpenStackImageNotImportedYet"
7583

84+
// OpenStackImageImportTimeOutReason is used when image import timeout.
85+
OpenStackImageImportTimeOutReason = "OpenStackImageImportTimeOutReason"
86+
7687
// IssueWithOpenStackImageReason is used when image has an issue.
7788
IssueWithOpenStackImageReason = "IssueWithOpenStackImage"
7889
)

cmd/main.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func init() {
4848
//+kubebuilder:scaffold:scheme
4949
}
5050

51-
var releaseDir string
51+
var (
52+
releaseDir string
53+
waitForImageBecomeActiveMinutes int
54+
)
5255

5356
func main() {
5457
var metricsAddr string
@@ -60,6 +63,7 @@ func main() {
6063
"Enable leader election for controller manager. "+
6164
"Enabling this will ensure there is only one active controller manager.")
6265
flag.StringVar(&releaseDir, "release-dir", "/tmp/downloads/", "Specify release directory for cluster-stack releases")
66+
flag.IntVar(&waitForImageBecomeActiveMinutes, "import-timeout", 0, "Maximum time in minutes that you allow cspo to import image. If import-timeout <= 0, cspo waits forever.")
6367
opts := zap.Options{
6468
Development: true,
6569
}
@@ -103,8 +107,9 @@ func main() {
103107
os.Exit(1)
104108
}
105109
if err = (&controller.OpenStackNodeImageReleaseReconciler{
106-
Client: mgr.GetClient(),
107-
Scheme: mgr.GetScheme(),
110+
Client: mgr.GetClient(),
111+
Scheme: mgr.GetScheme(),
112+
WaitForImageBecomeActiveMinutes: waitForImageBecomeActiveMinutes,
108113
}).SetupWithManager(mgr); err != nil {
109114
setupLog.Error(err, "unable to create controller", "controller", "OpenStackNodeImageRelease")
110115
os.Exit(1)

internal/controller/openstackclusterstackrelease_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ func (r *OpenStackClusterStackReleaseReconciler) Reconcile(ctx context.Context,
179179
return ctrl.Result{RequeueAfter: waitForOpenStackNodeImageReleasesBecomeReady}, nil
180180
}
181181
for _, openStackNodeImageRelease := range ownedOpenStackNodeImageReleases {
182+
// TODO: Handle case when `import-timeout > 0`. Then the oscsr_controller should stop the reconciliation
182183
if openStackNodeImageRelease.Status.Ready {
183184
continue
184185
}

internal/controller/openstacknodeimagerelease_controller.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ import (
4545
// OpenStackNodeImageReleaseReconciler reconciles a OpenStackNodeImageRelease object.
4646
type OpenStackNodeImageReleaseReconciler struct {
4747
client.Client
48-
Scheme *runtime.Scheme
48+
Scheme *runtime.Scheme
49+
WaitForImageBecomeActiveMinutes int
4950
}
5051

5152
const (
@@ -143,6 +144,7 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
143144

144145
if imageID == "" {
145146
conditions.MarkFalse(openstacknodeimagerelease, apiv1alpha1.OpenStackImageReadyCondition, apiv1alpha1.OpenStackImageNotCreatedYetReason, clusterv1beta1.ConditionSeverityInfo, "image is not created yet")
147+
conditions.MarkFalse(openstacknodeimagerelease, apiv1alpha1.OpenStackImageImportStartCondition, apiv1alpha1.OpenStackImageImportNotStartReason, clusterv1beta1.ConditionSeverityInfo, "image import not start yet")
146148
openstacknodeimagerelease.Status.Ready = false
147149

148150
imageCreateOpts := (*images.CreateOpts)(openstacknodeimagerelease.Spec.Image.CreateOpts)
@@ -172,6 +174,7 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
172174
return ctrl.Result{}, fmt.Errorf("failed to import an image: %w", err)
173175
}
174176

177+
conditions.MarkTrue(openstacknodeimagerelease, apiv1alpha1.OpenStackImageImportStartCondition)
175178
// requeue to make sure that image ID can be find by image name
176179
return ctrl.Result{Requeue: true}, nil
177180
}
@@ -188,7 +191,27 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
188191
return ctrl.Result{}, fmt.Errorf("failed to get an image: %w", err)
189192
}
190193

191-
// TODO: Add timeout logic - import start time could be taken from OpenStackImageNotImportedYetReason condition, or somehow better
194+
// Check wait for image ACTIVE status duration
195+
if r.WaitForImageBecomeActiveMinutes > 0 && conditions.IsTrue(openstacknodeimagerelease, apiv1alpha1.OpenStackImageImportStartCondition) {
196+
// Calculate elapsed time since the OpenStackImageImportStartCondition is true
197+
startTime := conditions.GetLastTransitionTime(openstacknodeimagerelease, apiv1alpha1.OpenStackImageImportStartCondition)
198+
elapsedTime := time.Since(startTime.Time)
199+
200+
waitForImageBecomeActiveTimeout := time.Duration(r.WaitForImageBecomeActiveMinutes) * time.Minute
201+
202+
// Check if the image has been active after waitForImageBecomeActiveTimeout minutes
203+
if image.Status != images.ImageStatusActive && elapsedTime > waitForImageBecomeActiveTimeout {
204+
err = fmt.Errorf("timeout - wait for the image %s to transition to the ACTIVE status exceeds the timeout duration %d minutes", image.Name, r.WaitForImageBecomeActiveMinutes)
205+
conditions.MarkFalse(openstacknodeimagerelease,
206+
apiv1alpha1.OpenStackImageReadyCondition,
207+
apiv1alpha1.OpenStackImageImportTimeOutReason,
208+
clusterv1beta1.ConditionSeverityError,
209+
err.Error(),
210+
)
211+
// Image import timeout - nothing to do
212+
return ctrl.Result{}, nil
213+
}
214+
}
192215

193216
// Manage image statuses according to the guidelines outlined in https://docs.openstack.org/glance/stein/user/statuses.html.
194217
switch image.Status {

0 commit comments

Comments
 (0)