Get downloads the configured source to the destination.
(ctx context.Context, req *Request)
| 45 | |
| 46 | // Get downloads the configured source to the destination. |
| 47 | func (c *Client) Get(ctx context.Context, req *Request) (*GetResult, error) { |
| 48 | if err := c.configure(); err != nil { |
| 49 | return nil, err |
| 50 | } |
| 51 | |
| 52 | // Pass along the configured Getter client in the context for usage with the X-Terraform-Get feature. |
| 53 | ctx = NewContextWithClient(ctx, c) |
| 54 | |
| 55 | // Store this locally since there are cases we swap this |
| 56 | if req.GetMode == ModeInvalid { |
| 57 | req.GetMode = ModeAny |
| 58 | } |
| 59 | |
| 60 | // Client setting takes precedence for all requests |
| 61 | if c.DisableSymlinks { |
| 62 | req.DisableSymlinks = true |
| 63 | } |
| 64 | |
| 65 | // If there is a subdir component, then we download the root separately |
| 66 | // and then copy over the proper subdir. |
| 67 | req.Src, req.subDir = SourceDirSubdir(req.Src) |
| 68 | |
| 69 | if req.subDir != "" { |
| 70 | // Check if the subdirectory is attempting to traverse upwards, outside of |
| 71 | // the cloned repository path. |
| 72 | req.subDir = filepath.Clean(req.subDir) |
| 73 | if containsDotDot(req.subDir) { |
| 74 | return nil, fmt.Errorf("subdirectory component contain path traversal out of the repository") |
| 75 | } |
| 76 | |
| 77 | // Prevent absolute paths, remove a leading path separator from the subdirectory |
| 78 | if req.subDir[0] == os.PathSeparator { |
| 79 | req.subDir = req.subDir[1:] |
| 80 | } |
| 81 | |
| 82 | td, tdcloser, err := safetemp.Dir("", "getter") |
| 83 | if err != nil { |
| 84 | return nil, err |
| 85 | } |
| 86 | defer tdcloser.Close() |
| 87 | |
| 88 | req.realDst = req.Dst |
| 89 | req.Dst = td |
| 90 | } |
| 91 | |
| 92 | var multierr []error |
| 93 | for _, g := range c.Getters { |
| 94 | shouldDownload, err := Detect(req, g) |
| 95 | if err != nil { |
| 96 | return nil, err |
| 97 | } |
| 98 | if !shouldDownload { |
| 99 | // the request should not be processed by that getter |
| 100 | continue |
| 101 | } |
| 102 | |
| 103 | result, getErr := c.get(ctx, req, g) |
| 104 | if getErr != nil { |