blob: 655436ea31ddc4ba5d1f8050a5a72e07fd3f9aca [file] [log] [blame]
Jon Perrittfa2c65e2014-10-02 20:32:43 -05001package gophercloud
2
3import (
Jamie Hannafordf9b8bf52014-10-23 16:56:36 +02004 "errors"
Pratik Mallya5fddb2a2015-09-14 14:04:49 -05005 "net/url"
6 "path/filepath"
Ash Wilsona8440642014-10-07 09:55:58 -04007 "strings"
Jon Perrittfa2c65e2014-10-02 20:32:43 -05008 "time"
9)
10
Jamie Hannafordb280dea2014-10-24 15:14:06 +020011// WaitFor polls a predicate function, once per second, up to a timeout limit.
Ash Wilson03af57e2014-10-31 14:33:39 -040012// It usually does this to wait for a resource to transition to a certain state.
13// Resource packages will wrap this in a more convenient function that's
14// specific to a certain resource, but it can also be useful on its own.
Jamie Hannafordf9b8bf52014-10-23 16:56:36 +020015func WaitFor(timeout int, predicate func() (bool, error)) error {
16 start := time.Now().Second()
17 for {
18 // Force a 1s sleep
Jon Perrittfa2c65e2014-10-02 20:32:43 -050019 time.Sleep(1 * time.Second)
20
Jamie Hannaford3ac3aa72014-10-23 17:30:49 +020021 // If a timeout is set, and that's been exceeded, shut it down
22 if timeout >= 0 && time.Now().Second()-start >= timeout {
23 return errors.New("A timeout occurred")
24 }
25
Jamie Hannafordf9b8bf52014-10-23 16:56:36 +020026 // Execute the function
Jon Perrittfa2c65e2014-10-02 20:32:43 -050027 satisfied, err := predicate()
28 if err != nil {
29 return err
30 }
31 if satisfied {
32 return nil
33 }
34 }
Jon Perrittfa2c65e2014-10-02 20:32:43 -050035}
Ash Wilsona8440642014-10-07 09:55:58 -040036
Ash Wilsonad108b92014-10-31 16:12:05 -040037// NormalizeURL is an internal function to be used by provider clients.
38//
39// It ensures that each endpoint URL has a closing `/`, as expected by
40// ServiceClient's methods.
Ash Wilsona8440642014-10-07 09:55:58 -040041func NormalizeURL(url string) string {
42 if !strings.HasSuffix(url, "/") {
43 return url + "/"
44 }
45 return url
46}
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050047
48// NormalizeFilePathURL is used to convert rawPath to a fqdn, using basePath as
49// a reference in the filesystem, if necessary. basePath is assumed to contain
50// either '.' when first used, or the file:// type fqdn of the parent resource.
51// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml
52func NormalizePathURL(basePath, rawPath string) (string, error) {
53 u, err := url.Parse(rawPath)
54 if err != nil {
55 return "", err
56 }
57 // if a scheme is defined, it must be a fqdn already
58 if u.Scheme != "" {
59 return u.String(), nil
60 }
61 // if basePath is a url, then child resources are assumed to be relative to it
62 bu, err := url.Parse(basePath)
63 if err != nil {
64 return "", err
65 }
66 var basePathSys, absPathSys string
67 if bu.Scheme != "" {
68 basePathSys = filepath.FromSlash(bu.Path)
69 absPathSys = filepath.Join(basePathSys, rawPath)
70 bu.Path = filepath.ToSlash(absPathSys)
71 return bu.String(), nil
72 } else {
73 absPathSys = filepath.Join(basePath, rawPath)
74 u.Path = filepath.ToSlash(absPathSys)
75 if err != nil {
76 return "", err
77 }
78 u.Scheme = "file"
79 return u.String(), nil
80 }
81}