github.com/replicatedhq/ship@v0.55.0/pkg/util/http_upload.go (about) 1 package util 2 3 import ( 4 "io/ioutil" 5 "net/http" 6 "os" 7 "path" 8 9 "github.com/go-kit/kit/log" 10 "github.com/go-kit/kit/log/level" 11 "github.com/mholt/archiver" 12 "github.com/pkg/errors" 13 ) 14 15 type AssetUploader interface { 16 UploadAssets(target string) error 17 } 18 19 type assetUploader struct { 20 logger log.Logger 21 tar archiver.Archiver 22 client *http.Client 23 } 24 25 func NewAssetUploader( 26 logger log.Logger, 27 client *http.Client, 28 ) AssetUploader { 29 return &assetUploader{ 30 logger: log.With(logger, "struct", "assetUploader"), 31 client: client, 32 } 33 34 } 35 36 // i need tests 37 func (a *assetUploader) UploadAssets(target string) error { 38 debug := log.With(level.Debug(a.logger), "method", "UploadAssets") 39 currentWorkingDir, err := os.Getwd() 40 if err != nil { 41 return errors.Wrapf(err, "get working directory") 42 } 43 44 debug.Log("event", "tmpdir.create") 45 // need a real tmpdir because archiver library doesn't support Afero 46 tmpdir, err := ioutil.TempDir("", "ship-archive") 47 if err != nil { 48 return errors.Wrapf(err, "create temp dir") 49 } 50 defer os.RemoveAll(tmpdir) 51 52 // in normal use this means that the targz archiver will be used, but tests can set something else if needed 53 if a.tar == nil { 54 a.tar = archiver.TarGz 55 } 56 57 debug.Log("event", "archive.create") 58 archivePath := path.Join(tmpdir, "assets.tar.gz") 59 err = a.tar.Make(archivePath, []string{currentWorkingDir}) 60 if err != nil { 61 return errors.Wrapf(err, "create archive at ") 62 } 63 64 debug.Log("event", "archive.open") 65 archive, err := os.Open(archivePath) 66 if err != nil { 67 return errors.Wrap(err, "open archive") 68 } 69 70 debug.Log("event", "request.create") 71 request, err := http.NewRequest("PUT", target, archive) 72 if err != nil { 73 return errors.Wrap(err, "create request") 74 } 75 76 stat, err := archive.Stat() 77 if err != nil { 78 return errors.Wrap(err, "get archive info") 79 } 80 request.ContentLength = stat.Size() 81 82 debug.Log("event", "request.send") 83 resp, err := a.client.Do(request) 84 if err != nil { 85 return errors.Wrap(err, "send request") 86 } else if resp == nil { 87 return errors.Errorf("request returned no error, but was nil") 88 } 89 if resp.StatusCode > 299 { 90 if resp.Body != nil { 91 body, err := ioutil.ReadAll(resp.Body) 92 if err == nil { 93 return errors.Errorf("request returned status code %d and body %q", resp.StatusCode, string(body)) 94 } 95 } 96 return errors.Errorf("request returned status code %d", resp.StatusCode) 97 } 98 return nil 99 }