Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / gophercloud / gophercloud / util.go
1 package gophercloud
2
3 import (
4         "fmt"
5         "net/url"
6         "path/filepath"
7         "strings"
8         "time"
9 )
10
11 // WaitFor polls a predicate function, once per second, up to a timeout limit.
12 // This is useful to wait for a resource to transition to a certain state.
13 // To handle situations when the predicate might hang indefinitely, the
14 // predicate will be prematurely cancelled after the timeout.
15 // Resource packages will wrap this in a more convenient function that's
16 // specific to a certain resource, but it can also be useful on its own.
17 func WaitFor(timeout int, predicate func() (bool, error)) error {
18         type WaitForResult struct {
19                 Success bool
20                 Error   error
21         }
22
23         start := time.Now().Unix()
24
25         for {
26                 // If a timeout is set, and that's been exceeded, shut it down.
27                 if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) {
28                         return fmt.Errorf("A timeout occurred")
29                 }
30
31                 time.Sleep(1 * time.Second)
32
33                 var result WaitForResult
34                 ch := make(chan bool, 1)
35                 go func() {
36                         defer close(ch)
37                         satisfied, err := predicate()
38                         result.Success = satisfied
39                         result.Error = err
40                 }()
41
42                 select {
43                 case <-ch:
44                         if result.Error != nil {
45                                 return result.Error
46                         }
47                         if result.Success {
48                                 return nil
49                         }
50                 // If the predicate has not finished by the timeout, cancel it.
51                 case <-time.After(time.Duration(timeout) * time.Second):
52                         return fmt.Errorf("A timeout occurred")
53                 }
54         }
55 }
56
57 // NormalizeURL is an internal function to be used by provider clients.
58 //
59 // It ensures that each endpoint URL has a closing `/`, as expected by
60 // ServiceClient's methods.
61 func NormalizeURL(url string) string {
62         if !strings.HasSuffix(url, "/") {
63                 return url + "/"
64         }
65         return url
66 }
67
68 // NormalizePathURL is used to convert rawPath to a fqdn, using basePath as
69 // a reference in the filesystem, if necessary. basePath is assumed to contain
70 // either '.' when first used, or the file:// type fqdn of the parent resource.
71 // e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml
72 func NormalizePathURL(basePath, rawPath string) (string, error) {
73         u, err := url.Parse(rawPath)
74         if err != nil {
75                 return "", err
76         }
77         // if a scheme is defined, it must be a fqdn already
78         if u.Scheme != "" {
79                 return u.String(), nil
80         }
81         // if basePath is a url, then child resources are assumed to be relative to it
82         bu, err := url.Parse(basePath)
83         if err != nil {
84                 return "", err
85         }
86         var basePathSys, absPathSys string
87         if bu.Scheme != "" {
88                 basePathSys = filepath.FromSlash(bu.Path)
89                 absPathSys = filepath.Join(basePathSys, rawPath)
90                 bu.Path = filepath.ToSlash(absPathSys)
91                 return bu.String(), nil
92         }
93
94         absPathSys = filepath.Join(basePath, rawPath)
95         u.Path = filepath.ToSlash(absPathSys)
96         if err != nil {
97                 return "", err
98         }
99         u.Scheme = "file"
100         return u.String(), nil
101
102 }