diff options
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter/client.go')
-rw-r--r-- | vendor/github.com/hashicorp/go-getter/client.go | 140 |
1 files changed, 44 insertions, 96 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/client.go b/vendor/github.com/hashicorp/go-getter/client.go index 300301c..007a78b 100644 --- a/vendor/github.com/hashicorp/go-getter/client.go +++ b/vendor/github.com/hashicorp/go-getter/client.go | |||
@@ -1,15 +1,8 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "bytes" | 4 | "context" |
5 | "crypto/md5" | ||
6 | "crypto/sha1" | ||
7 | "crypto/sha256" | ||
8 | "crypto/sha512" | ||
9 | "encoding/hex" | ||
10 | "fmt" | 5 | "fmt" |
11 | "hash" | ||
12 | "io" | ||
13 | "io/ioutil" | 6 | "io/ioutil" |
14 | "os" | 7 | "os" |
15 | "path/filepath" | 8 | "path/filepath" |
@@ -17,7 +10,7 @@ import ( | |||
17 | "strings" | 10 | "strings" |
18 | 11 | ||
19 | urlhelper "github.com/hashicorp/go-getter/helper/url" | 12 | urlhelper "github.com/hashicorp/go-getter/helper/url" |
20 | "github.com/hashicorp/go-safetemp" | 13 | safetemp "github.com/hashicorp/go-safetemp" |
21 | ) | 14 | ) |
22 | 15 | ||
23 | // Client is a client for downloading things. | 16 | // Client is a client for downloading things. |
@@ -26,6 +19,9 @@ import ( | |||
26 | // Using a client directly allows more fine-grained control over how downloading | 19 | // Using a client directly allows more fine-grained control over how downloading |
27 | // is done, as well as customizing the protocols supported. | 20 | // is done, as well as customizing the protocols supported. |
28 | type Client struct { | 21 | type Client struct { |
22 | // Ctx for cancellation | ||
23 | Ctx context.Context | ||
24 | |||
29 | // Src is the source URL to get. | 25 | // Src is the source URL to get. |
30 | // | 26 | // |
31 | // Dst is the path to save the downloaded thing as. If Dir is set to | 27 | // Dst is the path to save the downloaded thing as. If Dir is set to |
@@ -62,10 +58,20 @@ type Client struct { | |||
62 | // | 58 | // |
63 | // WARNING: deprecated. If Mode is set, that will take precedence. | 59 | // WARNING: deprecated. If Mode is set, that will take precedence. |
64 | Dir bool | 60 | Dir bool |
61 | |||
62 | // ProgressListener allows to track file downloads. | ||
63 | // By default a no op progress listener is used. | ||
64 | ProgressListener ProgressTracker | ||
65 | |||
66 | Options []ClientOption | ||
65 | } | 67 | } |
66 | 68 | ||
67 | // Get downloads the configured source to the destination. | 69 | // Get downloads the configured source to the destination. |
68 | func (c *Client) Get() error { | 70 | func (c *Client) Get() error { |
71 | if err := c.Configure(c.Options...); err != nil { | ||
72 | return err | ||
73 | } | ||
74 | |||
69 | // Store this locally since there are cases we swap this | 75 | // Store this locally since there are cases we swap this |
70 | mode := c.Mode | 76 | mode := c.Mode |
71 | if mode == ClientModeInvalid { | 77 | if mode == ClientModeInvalid { |
@@ -76,18 +82,7 @@ func (c *Client) Get() error { | |||
76 | } | 82 | } |
77 | } | 83 | } |
78 | 84 | ||
79 | // Default decompressor value | 85 | src, err := Detect(c.Src, c.Pwd, c.Detectors) |
80 | decompressors := c.Decompressors | ||
81 | if decompressors == nil { | ||
82 | decompressors = Decompressors | ||
83 | } | ||
84 | |||
85 | // Detect the URL. This is safe if it is already detected. | ||
86 | detectors := c.Detectors | ||
87 | if detectors == nil { | ||
88 | detectors = Detectors | ||
89 | } | ||
90 | src, err := Detect(c.Src, c.Pwd, detectors) | ||
91 | if err != nil { | 86 | if err != nil { |
92 | return err | 87 | return err |
93 | } | 88 | } |
@@ -119,12 +114,7 @@ func (c *Client) Get() error { | |||
119 | force = u.Scheme | 114 | force = u.Scheme |
120 | } | 115 | } |
121 | 116 | ||
122 | getters := c.Getters | 117 | g, ok := c.Getters[force] |
123 | if getters == nil { | ||
124 | getters = Getters | ||
125 | } | ||
126 | |||
127 | g, ok := getters[force] | ||
128 | if !ok { | 118 | if !ok { |
129 | return fmt.Errorf( | 119 | return fmt.Errorf( |
130 | "download not supported for scheme '%s'", force) | 120 | "download not supported for scheme '%s'", force) |
@@ -150,7 +140,7 @@ func (c *Client) Get() error { | |||
150 | if archiveV == "" { | 140 | if archiveV == "" { |
151 | // We don't appear to... but is it part of the filename? | 141 | // We don't appear to... but is it part of the filename? |
152 | matchingLen := 0 | 142 | matchingLen := 0 |
153 | for k, _ := range decompressors { | 143 | for k := range c.Decompressors { |
154 | if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen { | 144 | if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen { |
155 | archiveV = k | 145 | archiveV = k |
156 | matchingLen = len(k) | 146 | matchingLen = len(k) |
@@ -163,7 +153,7 @@ func (c *Client) Get() error { | |||
163 | // real path. | 153 | // real path. |
164 | var decompressDst string | 154 | var decompressDst string |
165 | var decompressDir bool | 155 | var decompressDir bool |
166 | decompressor := decompressors[archiveV] | 156 | decompressor := c.Decompressors[archiveV] |
167 | if decompressor != nil { | 157 | if decompressor != nil { |
168 | // Create a temporary directory to store our archive. We delete | 158 | // Create a temporary directory to store our archive. We delete |
169 | // this at the end of everything. | 159 | // this at the end of everything. |
@@ -182,44 +172,16 @@ func (c *Client) Get() error { | |||
182 | mode = ClientModeFile | 172 | mode = ClientModeFile |
183 | } | 173 | } |
184 | 174 | ||
185 | // Determine if we have a checksum | 175 | // Determine checksum if we have one |
186 | var checksumHash hash.Hash | 176 | checksum, err := c.extractChecksum(u) |
187 | var checksumValue []byte | 177 | if err != nil { |
188 | if v := q.Get("checksum"); v != "" { | 178 | return fmt.Errorf("invalid checksum: %s", err) |
189 | // Delete the query parameter if we have it. | ||
190 | q.Del("checksum") | ||
191 | u.RawQuery = q.Encode() | ||
192 | |||
193 | // Determine the checksum hash type | ||
194 | checksumType := "" | ||
195 | idx := strings.Index(v, ":") | ||
196 | if idx > -1 { | ||
197 | checksumType = v[:idx] | ||
198 | } | ||
199 | switch checksumType { | ||
200 | case "md5": | ||
201 | checksumHash = md5.New() | ||
202 | case "sha1": | ||
203 | checksumHash = sha1.New() | ||
204 | case "sha256": | ||
205 | checksumHash = sha256.New() | ||
206 | case "sha512": | ||
207 | checksumHash = sha512.New() | ||
208 | default: | ||
209 | return fmt.Errorf( | ||
210 | "unsupported checksum type: %s", checksumType) | ||
211 | } | ||
212 | |||
213 | // Get the remainder of the value and parse it into bytes | ||
214 | b, err := hex.DecodeString(v[idx+1:]) | ||
215 | if err != nil { | ||
216 | return fmt.Errorf("invalid checksum: %s", err) | ||
217 | } | ||
218 | |||
219 | // Set our value | ||
220 | checksumValue = b | ||
221 | } | 179 | } |
222 | 180 | ||
181 | // Delete the query parameter if we have it. | ||
182 | q.Del("checksum") | ||
183 | u.RawQuery = q.Encode() | ||
184 | |||
223 | if mode == ClientModeAny { | 185 | if mode == ClientModeAny { |
224 | // Ask the getter which client mode to use | 186 | // Ask the getter which client mode to use |
225 | mode, err = g.ClientMode(u) | 187 | mode, err = g.ClientMode(u) |
@@ -248,15 +210,24 @@ func (c *Client) Get() error { | |||
248 | // If we're not downloading a directory, then just download the file | 210 | // If we're not downloading a directory, then just download the file |
249 | // and return. | 211 | // and return. |
250 | if mode == ClientModeFile { | 212 | if mode == ClientModeFile { |
251 | err := g.GetFile(dst, u) | 213 | getFile := true |
252 | if err != nil { | 214 | if checksum != nil { |
253 | return err | 215 | if err := checksum.checksum(dst); err == nil { |
216 | // don't get the file if the checksum of dst is correct | ||
217 | getFile = false | ||
218 | } | ||
254 | } | 219 | } |
255 | 220 | if getFile { | |
256 | if checksumHash != nil { | 221 | err := g.GetFile(dst, u) |
257 | if err := checksum(dst, checksumHash, checksumValue); err != nil { | 222 | if err != nil { |
258 | return err | 223 | return err |
259 | } | 224 | } |
225 | |||
226 | if checksum != nil { | ||
227 | if err := checksum.checksum(dst); err != nil { | ||
228 | return err | ||
229 | } | ||
230 | } | ||
260 | } | 231 | } |
261 | 232 | ||
262 | if decompressor != nil { | 233 | if decompressor != nil { |
@@ -291,7 +262,7 @@ func (c *Client) Get() error { | |||
291 | if decompressor == nil { | 262 | if decompressor == nil { |
292 | // If we're getting a directory, then this is an error. You cannot | 263 | // If we're getting a directory, then this is an error. You cannot |
293 | // checksum a directory. TODO: test | 264 | // checksum a directory. TODO: test |
294 | if checksumHash != nil { | 265 | if checksum != nil { |
295 | return fmt.Errorf( | 266 | return fmt.Errorf( |
296 | "checksum cannot be specified for directory download") | 267 | "checksum cannot be specified for directory download") |
297 | } | 268 | } |
@@ -320,30 +291,7 @@ func (c *Client) Get() error { | |||
320 | return err | 291 | return err |
321 | } | 292 | } |
322 | 293 | ||
323 | return copyDir(realDst, subDir, false) | 294 | return copyDir(c.Ctx, realDst, subDir, false) |
324 | } | ||
325 | |||
326 | return nil | ||
327 | } | ||
328 | |||
329 | // checksum is a simple method to compute the checksum of a source file | ||
330 | // and compare it to the given expected value. | ||
331 | func checksum(source string, h hash.Hash, v []byte) error { | ||
332 | f, err := os.Open(source) | ||
333 | if err != nil { | ||
334 | return fmt.Errorf("Failed to open file for checksum: %s", err) | ||
335 | } | ||
336 | defer f.Close() | ||
337 | |||
338 | if _, err := io.Copy(h, f); err != nil { | ||
339 | return fmt.Errorf("Failed to hash: %s", err) | ||
340 | } | ||
341 | |||
342 | if actual := h.Sum(nil); !bytes.Equal(actual, v) { | ||
343 | return fmt.Errorf( | ||
344 | "Checksums did not match.\nExpected: %s\nGot: %s", | ||
345 | hex.EncodeToString(v), | ||
346 | hex.EncodeToString(actual)) | ||
347 | } | 295 | } |
348 | 296 | ||
349 | return nil | 297 | return nil |