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

Commit c06113c

Browse files
NotTheEvilOnematofeder
authored andcommitted
Rewrite "waitForImageActive" to be non-blocking
Signed-off-by: Tobias Wolf <[email protected]>
1 parent 71195a8 commit c06113c

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

internal/controller/openstacknodeimagerelease_controller.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@ package controller
1919

2020
import (
2121
"context"
22+
"errors"
2223
"fmt"
2324
"time"
2425

26+
"github.com/gophercloud/gophercloud"
27+
"github.com/gophercloud/gophercloud/openstack"
28+
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/imageimport"
29+
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
2530
apiv1alpha1 "github.com/sovereignCloudStack/cluster-stack-provider-openstack/api/v1alpha1"
2631
"k8s.io/apimachinery/pkg/runtime"
2732
ctrl "sigs.k8s.io/controller-runtime"
2833
"sigs.k8s.io/controller-runtime/pkg/client"
2934
"sigs.k8s.io/controller-runtime/pkg/log"
30-
"github.com/gophercloud/gophercloud"
31-
"github.com/gophercloud/gophercloud/openstack"
32-
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
33-
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/imageimport"
3435
)
3536

3637
// OpenStackNodeImageReleaseReconciler reconciles a OpenStackNodeImageRelease object.
@@ -63,24 +64,39 @@ func findImageByName(imagesClient *gophercloud.ServiceClient, imageName string)
6364
}
6465

6566
func waitForImageActive(client *gophercloud.ServiceClient, imageID string, interval time.Duration, timeout time.Duration) (bool, error) {
66-
startTime := time.Now()
67-
68-
for {
69-
image, err := images.Get(client, imageID).Extract()
70-
if err != nil {
71-
return false, err
72-
}
73-
74-
if image.Status == "active" {
75-
return true, nil
76-
}
67+
type result struct {
68+
IsAvailable bool
69+
Err error
70+
}
7771

78-
if time.Since(startTime) > timeout {
79-
return false, fmt.Errorf("Timeout waiting for image to become active")
72+
ticker := time.Tick(interval)
73+
waiter := time.Tick(timeout)
74+
75+
resultChannel := make(chan result)
76+
77+
go func() {
78+
for {
79+
select {
80+
case _ = <-waiter:
81+
resultChannel <- result{IsAvailable: false, Err: errors.New("Timeout waiting for image to become active")}
82+
return
83+
case _ = <-ticker:
84+
image, err := images.Get(client, imageID).Extract()
85+
if err != nil {
86+
resultChannel <- result{IsAvailable: false, Err: err}
87+
return
88+
}
89+
90+
if image.Status == "active" {
91+
resultChannel <- result{IsAvailable: true, Err: nil}
92+
return
93+
}
94+
}
8095
}
96+
}()
8197

82-
time.Sleep(interval)
83-
}
98+
resultStruct := <-resultChannel
99+
return resultStruct.IsAvailable, resultStruct.Err
84100
}
85101

86102
func createImage(imageClient *gophercloud.ServiceClient, createOpts images.CreateOpts) (*images.Image, error) {
@@ -170,25 +186,25 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
170186
} else {
171187
if imageID == "" {
172188
visibility := images.ImageVisibilityShared
173-
189+
174190
createOptsImage := images.CreateOpts{
175191
Name: imageName,
176-
ContainerFormat: "bare",
192+
ContainerFormat: "bare",
177193
DiskFormat: "iso",
178-
Visibility: &visibility,
194+
Visibility: &visibility,
179195
}
180-
196+
181197
image, err := createImage(imageClient, createOptsImage)
182198
if err != nil {
183199
return ctrl.Result{}, err
184200
}
185-
201+
186202
createOpts := imageimport.CreateOpts{
187203
Name: imageimport.WebDownloadMethod,
188204
URI: imageURL,
189205
}
190206
imageID = image.ID
191-
207+
192208
// Handle error during image import
193209
err = importImage(imageClient, image.ID, createOpts)
194210
if err != nil {

0 commit comments

Comments
 (0)