github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/commands/helpers/cache_extractor.go (about) 1 package helpers 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "path/filepath" 10 "time" 11 12 "github.com/Sirupsen/logrus" 13 "github.com/codegangsta/cli" 14 15 "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" 16 "gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers/archives" 17 "gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers/formatter" 18 ) 19 20 type CacheExtractorCommand struct { 21 retryHelper 22 File string `long:"file" description:"The file containing your cache artifacts"` 23 URL string `long:"url" description:"Download artifacts instead of uploading them"` 24 } 25 26 func (c *CacheExtractorCommand) download() (bool, error) { 27 os.MkdirAll(filepath.Dir(c.File), 0600) 28 29 file, err := ioutil.TempFile(filepath.Dir(c.File), "cache") 30 if err != nil { 31 return false, err 32 } 33 defer file.Close() 34 defer os.Remove(file.Name()) 35 36 resp, err := http.Get(c.URL) 37 if err != nil { 38 return true, err 39 } 40 defer resp.Body.Close() 41 42 if resp.StatusCode == 404 { 43 return false, os.ErrNotExist 44 } else if resp.StatusCode/100 != 2 { 45 // Retry on server errors 46 retry := resp.StatusCode/100 == 5 47 return retry, fmt.Errorf("Received: %s", resp.Status) 48 } 49 50 fi, _ := os.Lstat(c.File) 51 date, _ := time.Parse(http.TimeFormat, resp.Header.Get("Last-Modified")) 52 if fi != nil && !date.After(fi.ModTime()) { 53 logrus.Infoln(filepath.Base(c.File), "is up to date") 54 return false, nil 55 } 56 57 logrus.Infoln("Downloading", filepath.Base(c.File)) 58 _, err = io.Copy(file, resp.Body) 59 if err != nil { 60 return true, err 61 } 62 os.Chtimes(file.Name(), time.Now(), date) 63 64 err = os.Rename(file.Name(), c.File) 65 if err != nil { 66 return false, err 67 } 68 return false, nil 69 } 70 71 func (c *CacheExtractorCommand) Execute(context *cli.Context) { 72 formatter.SetRunnerFormatter() 73 74 if len(c.File) == 0 { 75 logrus.Fatalln("Missing cache file") 76 } 77 78 if c.URL != "" { 79 err := c.doRetry(c.download) 80 if err != nil && !os.IsNotExist(err) { 81 logrus.Warningln(err) 82 } 83 } 84 85 err := archives.ExtractZipFile(c.File) 86 if err != nil && !os.IsNotExist(err) { 87 logrus.Fatalln(err) 88 } 89 } 90 91 func init() { 92 common.RegisterCommand2("cache-extractor", "download and extract cache artifacts (internal)", &CacheExtractorCommand{ 93 retryHelper: retryHelper{ 94 Retry: 2, 95 RetryTime: time.Second, 96 }, 97 }) 98 }