func (u *Updater) update() error { up := update.New() if err := up.CanUpdate(); err != nil { return err } if err := os.MkdirAll(updateDir, 0755); err != nil { return err } local, err := tuf.FileLocalStore(filepath.Join(updateDir, "tuf.db")) if err != nil { return err } plat := fmt.Sprintf("%s-%s", runtime.GOOS, runtime.GOARCH) opts := &tuf.HTTPRemoteOptions{ UserAgent: fmt.Sprintf("flynn-cli/%s %s", version.String(), plat), Retries: tuf.DefaultHTTPRetries, } remote, err := tuf.HTTPRemoteStore(u.repo, opts) if err != nil { return err } client := tuf.NewClient(local, remote) if err := u.updateTUFClient(client); err != nil { return err } name := fmt.Sprintf("/flynn-%s.gz", plat) latestVersion, err := tufutil.GetVersion(client, name) if err != nil { return err } if latestVersion == version.String() { return nil } bin := &tufBuffer{} if err := client.Download(name, bin); err != nil { return err } gr, err := gzip.NewReader(bin) if err != nil { return err } err, errRecover := up.FromStream(gr) if errRecover != nil { return fmt.Errorf("update and recovery errors: %q %q", err, errRecover) } if err != nil { return err } log.Printf("Updated %s -> %s.", version.String(), latestVersion) return nil }
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 }