github.com/alloyci/alloy-runner@v1.0.1-0.20180222164613-925503ccafd6/commands/helpers/cache_archiver.go (about)

     1  package helpers
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"os"
     7  	"path/filepath"
     8  	"time"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/urfave/cli"
    12  
    13  	"gitlab.com/gitlab-org/gitlab-runner/common"
    14  	"gitlab.com/gitlab-org/gitlab-runner/helpers/archives"
    15  	"gitlab.com/gitlab-org/gitlab-runner/helpers/url"
    16  )
    17  
    18  type CacheArchiverCommand struct {
    19  	fileArchiver
    20  	retryHelper
    21  	File    string `long:"file" description:"The path to file"`
    22  	URL     string `long:"url" description:"URL of remote cache resource"`
    23  	Timeout int    `long:"timeout" description:"Overall timeout for cache uploading request (in minutes)"`
    24  
    25  	client *CacheClient
    26  }
    27  
    28  func (c *CacheArchiverCommand) getClient() *CacheClient {
    29  	if c.client == nil {
    30  		c.client = NewCacheClient(c.Timeout)
    31  	}
    32  
    33  	return c.client
    34  }
    35  
    36  func (c *CacheArchiverCommand) upload() (bool, error) {
    37  	logrus.Infoln("Uploading", filepath.Base(c.File), "to", url_helpers.CleanURL(c.URL))
    38  
    39  	file, err := os.Open(c.File)
    40  	if err != nil {
    41  		return false, err
    42  	}
    43  	defer file.Close()
    44  
    45  	fi, err := file.Stat()
    46  	if err != nil {
    47  		return false, err
    48  	}
    49  
    50  	req, err := http.NewRequest("PUT", c.URL, file)
    51  	if err != nil {
    52  		return true, err
    53  	}
    54  	req.Header.Set("Content-Type", "application/octet-stream")
    55  	req.Header.Set("Last-Modified", fi.ModTime().Format(http.TimeFormat))
    56  	req.ContentLength = fi.Size()
    57  
    58  	resp, err := c.getClient().Do(req)
    59  	if err != nil {
    60  		return true, err
    61  	}
    62  	defer resp.Body.Close()
    63  
    64  	if resp.StatusCode/100 != 2 {
    65  		// Retry on server errors
    66  		retry := resp.StatusCode/100 == 5
    67  		return retry, fmt.Errorf("Received: %s", resp.Status)
    68  	}
    69  
    70  	return false, nil
    71  }
    72  
    73  func (c *CacheArchiverCommand) Execute(*cli.Context) {
    74  	if c.File == "" {
    75  		logrus.Fatalln("Missing --file")
    76  	}
    77  
    78  	// Enumerate files
    79  	err := c.enumerate()
    80  	if err != nil {
    81  		logrus.Fatalln(err)
    82  	}
    83  
    84  	// Check if list of files changed
    85  	if !c.isFileChanged(c.File) {
    86  		logrus.Infoln("Archive is up to date!")
    87  		return
    88  	}
    89  
    90  	// Create archive
    91  	err = archives.CreateZipFile(c.File, c.sortedFiles())
    92  	if err != nil {
    93  		logrus.Fatalln(err)
    94  	}
    95  
    96  	// Upload archive if needed
    97  	if c.URL != "" {
    98  		err := c.doRetry(c.upload)
    99  		if err != nil {
   100  			logrus.Fatalln(err)
   101  		}
   102  	}
   103  }
   104  
   105  func init() {
   106  	common.RegisterCommand2("cache-archiver", "create and upload cache artifacts (internal)", &CacheArchiverCommand{
   107  		retryHelper: retryHelper{
   108  			Retry:     2,
   109  			RetryTime: time.Second,
   110  		},
   111  	})
   112  }