@@ -21,14 +21,15 @@ import (
2121 "context"
2222 "errors"
2323 "fmt"
24- "time"
2524 "sync"
25+ "time"
2626
2727 "github.com/gophercloud/gophercloud"
2828 "github.com/gophercloud/gophercloud/openstack"
2929 "github.com/gophercloud/gophercloud/openstack/imageservice/v2/imageimport"
3030 "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
3131 apiv1alpha1 "github.com/sovereignCloudStack/cluster-stack-provider-openstack/api/v1alpha1"
32+ apierrors "k8s.io/apimachinery/pkg/api/errors"
3233 "k8s.io/apimachinery/pkg/runtime"
3334 ctrl "sigs.k8s.io/controller-runtime"
3435 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -42,29 +43,29 @@ type OpenStackNodeImageReleaseReconciler struct {
4243}
4344
4445func findImageByName (imagesClient * gophercloud.ServiceClient , imageName string ) (string , error ) {
45- var imageID string
46-
4746 listOpts := images.ListOpts {
4847 Name : imageName ,
4948 }
5049
5150 allPages , err := images .List (imagesClient , listOpts ).AllPages ()
52- imageList , err := images .ExtractImages (allPages )
53- for _ , image := range imageList {
54- if image .Name == imageName {
55- imageID = image .ID
56- break
57- }
51+ if err != nil {
52+ return "" , fmt .Errorf ("failed to list images with name %s: %w" , imageName , err )
5853 }
5954
55+ imageList , err := images .ExtractImages (allPages )
6056 if err != nil {
61- return "" , err
57+ return "" , fmt . Errorf ( "failed to extract images with name %s: %w" , imageName , err )
6258 }
6359
64- return imageID , nil
60+ for i := range imageList {
61+ if imageList [i ].Name == imageName {
62+ return imageList [i ].ID , nil
63+ }
64+ }
65+ return "" , fmt .Errorf ("failed to find image with name %s: %w" , imageName , err )
6566}
6667
67- func waitForImageActive (client * gophercloud.ServiceClient , imageID string , interval time. Duration , timeout time.Duration ) (bool , error ) {
68+ func waitForImageActive (serviceClient * gophercloud.ServiceClient , imageID string , interval , timeout time.Duration ) (bool , error ) {
6869 type result struct {
6970 IsAvailable bool
7071 Err error
@@ -79,10 +80,10 @@ func waitForImageActive(client *gophercloud.ServiceClient, imageID string, inter
7980 for {
8081 select {
8182 case _ = <- waiter :
82- resultChannel <- result {IsAvailable : false , Err : errors .New ("Timeout waiting for image to become active" )}
83+ resultChannel <- result {IsAvailable : false , Err : errors .New ("timeout waiting for image to become active" )}
8384 return
8485 case _ = <- ticker :
85- image , err := images .Get (client , imageID ).Extract ()
86+ image , err := images .Get (serviceClient , imageID ).Extract ()
8687 if err != nil {
8788 resultChannel <- result {IsAvailable : false , Err : err }
8889 return
@@ -103,7 +104,7 @@ func waitForImageActive(client *gophercloud.ServiceClient, imageID string, inter
103104func createImage (imageClient * gophercloud.ServiceClient , createOpts images.CreateOpts ) (* images.Image , error ) {
104105 image , err := images .Create (imageClient , createOpts ).Extract ()
105106 if err != nil {
106- return nil , err
107+ return nil , fmt . Errorf ( "failed to create image with name %s: %w" , createOpts . Name , err )
107108 }
108109
109110 return image , nil
@@ -112,7 +113,7 @@ func createImage(imageClient *gophercloud.ServiceClient, createOpts images.Creat
112113func importImage (imageClient * gophercloud.ServiceClient , imageID string , createOpts imageimport.CreateOpts ) error {
113114 err := imageimport .Create (imageClient , imageID , createOpts ).ExtractErr ()
114115 if err != nil {
115- return err
116+ return fmt . Errorf ( "failed to import image with ID %s: %w" , imageID , err )
116117 }
117118
118119 return nil
@@ -138,19 +139,19 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
138139 openstacknodeimagerelease := apiv1alpha1.OpenStackNodeImageRelease {}
139140 err := r .Client .Get (ctx , req .NamespacedName , & openstacknodeimagerelease )
140141 if err != nil {
141- return ctrl.Result {}, fmt .Errorf ("Failed to get OpenStackNodeImageRelease %s/%s: %w" , req .Namespace , req .Name , err )
142+ if apierrors .IsNotFound (err ) {
143+ return ctrl.Result {}, nil
144+ }
145+ return ctrl.Result {}, fmt .Errorf ("failed to get OpenStackNodeImageRelease %s/%s: %w" , req .Namespace , req .Name , err )
142146 }
143-
144- var (
145- imageStatus bool = false
146- secretName string = openstacknodeimagerelease .Spec .IdentityRef .Name
147- secretNamespace string = "default"
148- cloudName string = openstacknodeimagerelease .Spec .CloudName
149- imageName string = openstacknodeimagerelease .Spec .Name
150- imageURL string = openstacknodeimagerelease .Spec .URL
151- containerFormat string = openstacknodeimagerelease .Spec .ContainerFormat
152- diskFormat string = openstacknodeimagerelease .Spec .DiskFormat
153- )
147+ imageStatus := false
148+ secretName := openstacknodeimagerelease .Spec .IdentityRef .Name
149+ secretNamespace := "default"
150+ cloudName := openstacknodeimagerelease .Spec .CloudName
151+ imageName := openstacknodeimagerelease .Spec .Name
152+ imageURL := openstacknodeimagerelease .Spec .URL
153+ containerFormat := openstacknodeimagerelease .Spec .ContainerFormat
154+ diskFormat := openstacknodeimagerelease .Spec .DiskFormat
154155
155156 // Create a channel to receive errors from the goroutine
156157 resultChan := make (chan error , 1 )
@@ -162,8 +163,7 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
162163 defer wg .Done () // Decrement the wait group counter when the goroutine completes
163164 cloud , err := getCloudFromSecret (ctx , r .Client , secretNamespace , secretName , cloudName )
164165 if err != nil {
165- // Handle error
166- resultChan <- err
166+ resultChan <- fmt .Errorf ("failed to get cloud from secret: %w" , err )
167167 return
168168 }
169169
@@ -178,61 +178,63 @@ func (r *OpenStackNodeImageReleaseReconciler) Reconcile(ctx context.Context, req
178178
179179 provider , err := openstack .AuthenticatedClient (authOpts )
180180 if err != nil {
181- // Handle error
182- resultChan <- err
181+ resultChan <- fmt .Errorf ("failed to create an athenticate client: %w" , err )
183182 return
184183 }
185184
186185 // Create an Image service client
187186 imageClient , err := openstack .NewImageServiceV2 (provider , gophercloud.EndpointOpts {
188187 Region : cloud .RegionName ,
189188 })
189+ if err != nil {
190+ resultChan <- fmt .Errorf ("failed to create an image client: %w" , err )
191+ return
192+ }
190193
191194 imageID , err := findImageByName (imageClient , imageName )
192195 if err != nil {
193- resultChan <- fmt . Errorf ( "Error finding image: %w" , err )
196+ resultChan <- err
194197 return
195- } else {
196- if imageID == "" {
197- visibility := images .ImageVisibilityShared
198-
199- createOptsImage := images.CreateOpts {
200- Name : imageName ,
201- ContainerFormat : containerFormat ,
202- DiskFormat : diskFormat ,
203- Visibility : & visibility ,
204- }
198+ }
205199
206- image , err := createImage (imageClient , createOptsImage )
207- if err != nil {
208- // Handle error
209- logger .Error (err , "Failed to find or create image" )
210- return
211- }
200+ if imageID == "" {
201+ visibility := images .ImageVisibilityShared
212202
213- createOpts := imageimport.CreateOpts {
214- Name : imageimport .WebDownloadMethod ,
215- URI : imageURL ,
216- }
217- imageID = image .ID
203+ createOptsImage := images.CreateOpts {
204+ Name : imageName ,
205+ ContainerFormat : containerFormat ,
206+ DiskFormat : diskFormat ,
207+ Visibility : & visibility ,
208+ }
218209
219- // Handle error during image import
220- err = importImage (imageClient , image .ID , createOpts )
221- if err != nil {
222- // Handle error
223- logger .Error (err , "Failed to import image" )
224- return
225- }
210+ image , err := createImage (imageClient , createOptsImage )
211+ if err != nil {
212+ resultChan <- err
213+ return
214+ }
215+
216+ createOpts := imageimport.CreateOpts {
217+ Name : imageimport .WebDownloadMethod ,
218+ URI : imageURL ,
219+ }
220+ imageID = image .ID
221+
222+ // Handle error during image import
223+ err = importImage (imageClient , image .ID , createOpts )
224+ if err != nil {
225+ resultChan <- err
226+ return
226227 }
227228 }
228229 // Check if image is active
229230 imageStatus , err = waitForImageActive (imageClient , imageID , 5 * time .Second , 3 * time .Minute )
230231 if err != nil {
231- // Handle error
232- logger .Error (err , "Failed to wait for image to become active" )
232+ resultChan <- fmt .Errorf ("failed to wait for an image to become active: %w" , err )
233233 return
234- } else if imageStatus {
235- logger .Info ("Image is active." )
234+ }
235+
236+ if imageStatus {
237+ logger .Info ("Image with name %s and ID %s is **active**." , imageName , imageID )
236238 }
237239 }
238240
0 commit comments