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 }