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

Commit 0592970

Browse files
committed
Fix formatting and error handling
Signed-off-by: Matej Feder <[email protected]>
1 parent 7f9b0fe commit 0592970

File tree

2 files changed

+80
-77
lines changed

2 files changed

+80
-77
lines changed

internal/controller/openstacknodeimagerelease_controller.go

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4445
func 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
103104
func 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
112113
func 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

internal/controller/utils.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,43 @@ import (
2020
"context"
2121
"fmt"
2222

23-
"sigs.k8s.io/controller-runtime/pkg/client"
2423
"github.com/gophercloud/utils/openstack/clientconfig"
2524
corev1 "k8s.io/api/core/v1"
26-
"sigs.k8s.io/yaml"
2725
"k8s.io/apimachinery/pkg/types"
28-
26+
"sigs.k8s.io/controller-runtime/pkg/client"
27+
"sigs.k8s.io/yaml"
2928
)
3029

31-
func getCloudFromSecret(ctx context.Context, ctrlClient client.Client, secretNamespace string, secretName string, cloudName string) (clientconfig.Cloud, error) {
30+
func getCloudFromSecret(ctx context.Context, ctrlClient client.Client, secretNamespace, secretName, cloudName string) (clientconfig.Cloud, error) {
3231
const (
3332
cloudsSecretKey = "clouds.yaml"
3433
)
35-
34+
var clouds clientconfig.Clouds
3635
emptyCloud := clientconfig.Cloud{}
3736

3837
if cloudName == "" {
39-
return emptyCloud, fmt.Errorf("secret name set to %v but no cloud was specified. Please set cloud_name in your machine spec", secretName)
38+
return emptyCloud, fmt.Errorf("secret name set to %s but no cloud was specified. Please set cloud_name in your machine spec", secretName)
4039
}
4140
secret := &corev1.Secret{}
4241
err := ctrlClient.Get(ctx, types.NamespacedName{
4342
Namespace: secretNamespace,
4443
Name: secretName,
4544
}, secret)
4645
if err != nil {
47-
return emptyCloud, err
46+
return emptyCloud, fmt.Errorf("failed to get secret %s: %w", secretName, err)
4847
}
4948
content, ok := secret.Data[cloudsSecretKey]
5049
if !ok {
51-
return emptyCloud, fmt.Errorf("OpenStack credentials secret %v did not contain key %v",
50+
return emptyCloud, fmt.Errorf("OpenStack credentials secret %s did not contain key %s",
5251
secretName, cloudsSecretKey)
5352
}
54-
var clouds clientconfig.Clouds
5553
if err = yaml.Unmarshal(content, &clouds); err != nil {
56-
return emptyCloud, fmt.Errorf("failed to unmarshal clouds credentials stored in secret %v: %v", secretName, err)
54+
return emptyCloud, fmt.Errorf("failed to unmarshal clouds credentials stored in secret %s: %w", secretName, err)
5755
}
5856

59-
return clouds.Clouds[cloudName], nil
57+
cloud, ok := clouds.Clouds[cloudName]
58+
if !ok {
59+
return emptyCloud, fmt.Errorf("failed to find cloud %s in %s", cloudName, cloudsSecretKey)
60+
}
61+
return cloud, nil
6062
}
61-

0 commit comments

Comments
 (0)