func (d *Downloader) DownloadImages(dir string, info chan *ct.ImagePullInfo) error { defer close(info) path := filepath.Join(d.version, "images.json.gz") tmp, err := tufutil.Download(d.client, path) if err != nil { return err } defer tmp.Close() gz, err := gzip.NewReader(tmp) if err != nil { return err } defer gz.Close() out, err := os.Create(filepath.Join(dir, "images."+d.version+".json")) if err != nil { return err } defer out.Close() var images map[string]*ct.Artifact if err := json.NewDecoder(io.TeeReader(gz, out)).Decode(&images); err != nil { return err } for _, image := range images { if err := d.downloadImage(image, info); err != nil { return err } } return nil }
func (d *Downloader) downloadSquashfsLayer(layer *ct.ImageLayer, layerURL string, meta map[string]string) error { if vol := d.vman.GetVolume(layer.ID); vol != nil { return nil } u, err := url.Parse(layerURL) if err != nil { return err } target := u.Query().Get("target") if target == "" { return fmt.Errorf("missing target param in URL: %s", layerURL) } tmp, err := tufutil.Download(d.client, target) if err != nil { return err } defer tmp.Close() _, err = d.vman.ImportFilesystem("default", &volume.Filesystem{ ID: layer.ID, Data: tmp, Size: layer.Length, Type: volume.VolumeTypeSquashfs, MountFlags: syscall.MS_RDONLY, Meta: meta, }) return err }
// updateAndExecLatest updates the tuf DB, downloads the latest flynn-host // binary to a temp file and execs it. // // Latest snapshot errors are ignored because, even though we may have the // latest snapshot, the cluster may not be fully up to date (a previous update // may have failed). func updateAndExecLatest(configDir string, client *tuf.Client, log log15.Logger) error { log.Info("updating TUF data") if _, err := client.Update(); err != nil && !tuf.IsLatestSnapshot(err) { log.Error("error updating TUF client", "err", err) return err } version, err := getChannelVersion(configDir, client, log) if err != nil { return err } log.Info(fmt.Sprintf("downloading %s flynn-host binary", version)) gzTmp, err := tufutil.Download(client, path.Join(version, "flynn-host.gz")) if err != nil { log.Error("error downloading latest flynn-host binary", "err", err) return err } defer gzTmp.Close() gz, err := gzip.NewReader(gzTmp) if err != nil { log.Error("error creating gzip reader", "err", err) return err } defer gz.Close() tmp, err := ioutil.TempFile("", "flynn-host") if err != nil { log.Error("error creating temp file", "err", err) return err } _, err = io.Copy(tmp, gz) tmp.Close() if err != nil { log.Error("error decompressing gzipped flynn-host binary", "err", err) return err } if err := os.Chmod(tmp.Name(), 0755); err != nil { log.Error("error setting executable bit on tmp file", "err", err) return err } log.Info("executing latest flynn-host binary") argv := []string{tmp.Name()} argv = append(argv, os.Args[1:]...) argv = append(argv, "--is-latest") argv = append(argv, "--is-tempfile") return syscall.Exec(tmp.Name(), argv, os.Environ()) }
func downloadGzippedFile(client *tuf.Client, path, dir string, versionSuffix bool) (string, error) { gzPath := path + ".gz" dst := filepath.Join(dir, path) if versionSuffix { version, err := tufutil.GetVersion(client, gzPath) if err != nil { return "", err } dst = dst + "." + version } file, err := tufutil.Download(client, gzPath) if err != nil { return "", err } defer file.Close() // unlink the destination file in case it is in use os.Remove(dst) out, err := os.Create(dst) if err != nil { return "", err } defer out.Close() gz, err := gzip.NewReader(file) if err != nil { return "", err } defer gz.Close() _, err = io.Copy(out, gz) if err != nil { return "", err } if versionSuffix { // symlink the non-versioned path to the versioned path // e.g. flynn-host -> flynn-host.v20150726.0 link := filepath.Join(dir, path) if err := symlink(filepath.Base(dst), link); err != nil { return "", err } } return dst, nil }
func PullImagesWithClient(client *tuf.Client, repository, driver, root, version string, progress chan<- layer.PullInfo) error { path := filepath.Join(version, "version.json.gz") tmp, err := tufutil.Download(client, path) if err != nil { return err } defer tmp.Close() gz, err := gzip.NewReader(tmp) if err != nil { return err } defer gz.Close() var versions map[string]string if err := json.NewDecoder(gz).Decode(&versions); err != nil { return err } ctx, err := BuildContext(driver, root) if err != nil { return err } var wg sync.WaitGroup wg.Add(len(versions)) for name, id := range versions { info := make(chan layer.PullInfo) go func() { for l := range info { progress <- l } wg.Done() }() url := fmt.Sprintf("%s?name=%s&id=%s", repository, name, id) if err := ctx.PullTUF(url, client, info); err != nil { return err } } wg.Wait() close(progress) return nil }
func downloadGzippedFile(client *tuf.Client, path, dir string) (string, error) { file, err := tufutil.Download(client, path+".gz") if err != nil { return "", err } defer file.Close() dst := filepath.Join(dir, path) // unlink the destination file in case it is in use os.Remove(dst) out, err := os.Create(dst) if err != nil { return "", err } gz, err := gzip.NewReader(file) if err != nil { return "", err } defer gz.Close() _, err = io.Copy(out, gz) return dst, err }