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  }