Skip to content

Commit

Permalink
Remove k8s.io/apimachinery dependency for wait mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
kishen-v committed May 27, 2024
1 parent b0ad45b commit c310fc0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 41 deletions.
64 changes: 28 additions & 36 deletions cmd/image/import/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/IBM-Cloud/bluemix-go/models"
pmodels "github.com/IBM-Cloud/power-go-client/power/models"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog/v2"

"github.com/ppc64le-cloud/pvsadm/pkg"
Expand All @@ -36,6 +35,9 @@ import (

const (
serviceCredPrefix = "pvsadm-service-cred"
imageStateActive = "active"
jobStateCompleted = "completed"
jobStateFailed = "failed"
)

// Find COSINSTANCE details of the Provided bucket
Expand Down Expand Up @@ -182,71 +184,61 @@ pvsadm image import -n upstream-core-lon04 -b <BUCKETNAME> --object rhel-83-100
if opt.Public {
bucketAccess = "public"
}
klog.Infof("Importing image %s. Please wait...", opt.ImageName)
jobRef, err := pvmclient.ImgClient.ImportImage(opt.ImageName, opt.ImageFilename, opt.Region,
opt.AccessKey, opt.SecretKey, opt.BucketName, strings.ToLower(opt.StorageType), bucketAccess)
if err != nil {
return err
}

start := time.Now()
pollErr := wait.PollImmediate(2*time.Minute, opt.WatchTimeout, func() (bool, error) {
err = utils.PollUntilConditionIsMet(time.Tick(2*time.Minute), time.After(opt.WatchTimeout), func() (error, bool) {
job, err := pvmclient.JobClient.Get(*jobRef.ID)
if err != nil {
return false, err
return fmt.Errorf("image import job failed to complete, err: %v", err), false
}
if *job.Status.State == "completed" {
return true, nil
if *job.Status.State == jobStateCompleted {
klog.Infof("Image imported successfully, took %s", time.Since(start))
return nil, true
}
if *job.Status.State == "failed" {
return false, fmt.Errorf("image import job failed to complete, err: %v", job.Status.Message)
if *job.Status.State == jobStateFailed {
return fmt.Errorf("image import job failed to complete, err: %v", job.Status.Message), false
}
klog.Infof("Image Import Job in-progress, current state: %s", *job.Status.State)
return false, nil
klog.Infof("Image import is in-progress, current state: %s", *job.Status.State)
return nil, false
})
if pollErr == wait.ErrWaitTimeout {
pollErr = fmt.Errorf("timed out while waiting for image import job to complete")
}

if pollErr != nil {
return fmt.Errorf("image import job failed to complete, err: %v", pollErr)
if err != nil {
return err
}

var image *pmodels.ImageReference = &pmodels.ImageReference{}
for image.ImageID == nil {
klog.V(1).Info("Retrieving image details")

if image.ImageID == nil {
image, err = pvmclient.ImgClient.GetImageByName(opt.ImageName)
if err != nil {
return err
}
klog.V(1).Info("Retrieving image details")
}

if !opt.Watch {
klog.Infof("Image import for %s is currently in %s state, Please check the progress in the IBM cloud UI", *image.Name, *image.State)
return nil
}

pollErr = wait.PollImmediate(2*time.Minute, opt.WatchTimeout, func() (bool, error) {
klog.Infof("Waiting for image %s to be active. Please wait...", opt.ImageName)
start = time.Now()
err = utils.PollUntilConditionIsMet(time.Tick(10*time.Second), time.After(opt.WatchTimeout), func() (error, bool) {
img, err := pvmclient.ImgClient.Get(*image.ImageID)
if err != nil {
return false, err
return fmt.Errorf("failed to import the image, err: %v\n\nRun the command \"pvsadm get events -i %s\" to get more information about the failure", err, pvmclient.InstanceID), false
}
if img.State == "active" {
return true, nil
if img.State == imageStateActive {
klog.Infof("Successfully imported the image: %s with ID: %s in %s", *image.Name, *image.ImageID, time.Since(start))
return nil, true
}
klog.Infof("Import in-progress, current state: %s", img.State)
return false, nil
klog.Infof("Waiting for image to be active. Current state: %s", img.State)
return nil, false
})
if pollErr == wait.ErrWaitTimeout {
pollErr = fmt.Errorf("timed out while waiting for image to become ready state")
}

if pollErr != nil {
return fmt.Errorf("failed to import the image, err: %v\n\nRun this command to get more information for the failure: pvsadm get events -i %s", pollErr, pvmclient.InstanceID)
}

klog.Infof("Successfully imported the image: %s with ID: %s within %s", *image.Name, *image.ImageID, time.Since(start))

return nil
return err
},
}

Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/apimachinery v0.29.3
k8s.io/klog/v2 v2.120.1
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
)
Expand Down
4 changes: 1 addition & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
Expand Down Expand Up @@ -572,8 +572,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
Expand Down
29 changes: 28 additions & 1 deletion pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

package utils

import "strconv"
import (
"fmt"
"strconv"
"time"
)

func FormatProcessor(proc *float64) string {
return strconv.FormatFloat(*proc, 'f', -1, 64)
Expand All @@ -32,3 +36,26 @@ func Contains(s []string, e string) bool {
}
return false
}

// PollUntilConditionIsMet validates if a certain condition is met at defined poll intervals.
// If a timeout is reached, an associated error is returned to the caller.
// meetsCondition contains the use-case specific code that returns true when a certain condition is achieved.
func PollUntilConditionIsMet(pollInterval, timeOut <-chan time.Time, meetsCondition func() (error, bool)) error {
for done := false; !done; {
select {
case <-timeOut:
return fmt.Errorf("timed out while waiting for job to complete")
case <-pollInterval:
var done bool
var err error
if err, done = meetsCondition(); err != nil {
done = true
return err
}
if done {
return nil
}
}
}
return nil
}

0 comments on commit c310fc0

Please sign in to comment.