func (h *jobAPI) PullBinariesAndConfig(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { log := h.host.log.New("fn", "PullBinariesAndConfig") log.Info("extracting TUF database") tufDB, err := extractTufDB(r) if err != nil { log.Error("error extracting TUF database", "err", err) httphelper.Error(w, err) return } defer os.Remove(tufDB) query := r.URL.Query() log.Info("creating local TUF store") local, err := tuf.FileLocalStore(tufDB) if err != nil { log.Error("error creating local TUF store", "err", err) httphelper.Error(w, err) return } opts := &tuf.HTTPRemoteOptions{ UserAgent: fmt.Sprintf("flynn-host/%s %s-%s pull", version.String(), runtime.GOOS, runtime.GOARCH), Retries: tuf.DefaultHTTPRetries, } log.Info("creating remote TUF store") remote, err := tuf.HTTPRemoteStore(query.Get("repository"), opts) if err != nil { log.Error("error creating remote TUF store", "err", err) httphelper.Error(w, err) return } client := tuf.NewClient(local, remote) d := downloader.New(client, query.Get("version")) log.Info("downloading binaries") paths, err := d.DownloadBinaries(query.Get("bin-dir")) if err != nil { log.Error("error downloading binaries", "err", err) httphelper.Error(w, err) return } log.Info("downloading config") configs, err := d.DownloadConfig(query.Get("config-dir")) if err != nil { log.Error("error downloading config", "err", err) httphelper.Error(w, err) return } for k, v := range configs { paths[k] = v } httphelper.JSON(w, 200, paths) }
func (h *jobAPI) PullBinariesAndConfig(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { log := h.host.log.New("fn", "PullBinariesAndConfig") log.Info("extracting TUF database") tufDB, err := extractTufDB(r) if err != nil { log.Error("error extracting TUF database", "err", err) httphelper.Error(w, err) return } defer os.Remove(tufDB) query := r.URL.Query() log.Info("initializing TUF client") client, err := newTufClient(tufDB, query.Get("repository")) if err != nil { log.Error("error initializing TUF client", "err", err) httphelper.Error(w, err) return } d := downloader.New(client, h.host.vman, query.Get("version")) log.Info("downloading binaries") paths, err := d.DownloadBinaries(query.Get("bin-dir")) if err != nil { log.Error("error downloading binaries", "err", err) httphelper.Error(w, err) return } log.Info("downloading config") configs, err := d.DownloadConfig(query.Get("config-dir")) if err != nil { log.Error("error downloading config", "err", err) httphelper.Error(w, err) return } for k, v := range configs { paths[k] = v } httphelper.JSON(w, 200, paths) }
func (h *jobAPI) PullImages(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { log := h.host.log.New("fn", "PullImages") log.Info("extracting TUF database") tufDB, err := extractTufDB(r) if err != nil { log.Error("error extracting TUF database", "err", err) httphelper.Error(w, err) return } defer os.Remove(tufDB) query := r.URL.Query() log.Info("initializing TUF client") client, err := newTufClient(tufDB, query.Get("repository")) if err != nil { log.Error("error initializing TUF client", "err", err) httphelper.Error(w, err) return } info := make(chan *ct.ImagePullInfo) stream := sse.NewStream(w, info, nil) go stream.Serve() d := downloader.New(client, h.host.vman, query.Get("version")) log.Info("pulling images") if err := d.DownloadImages(query.Get("config-dir"), info); err != nil { log.Error("error pulling images", "err", err) stream.CloseWithError(err) return } stream.Wait() }
func runDownload(args *docopt.Args) error { if err := os.MkdirAll(args.String["--root"], 0755); err != nil { return fmt.Errorf("error creating root dir: %s", err) } log := log15.New() // create a TUF client and update it log.Info("initializing TUF client") tufDB := args.String["--tuf-db"] local, err := tuf.FileLocalStore(tufDB) if err != nil { log.Error("error creating local TUF client", "err", err) return err } remote, err := tuf.HTTPRemoteStore(args.String["--repository"], tufHTTPOpts("downloader")) if err != nil { log.Error("error creating remote TUF client", "err", err) return err } client := tuf.NewClient(local, remote) if err := updateTUFClient(client); err != nil { log.Error("error updating TUF client", "err", err) return err } configDir := args.String["--config-dir"] version := os.Getenv("FLYNN_VERSION") if version == "" { version, err = getChannelVersion(configDir, client, log) if err != nil { return err } } log.Info(fmt.Sprintf("downloading components with version %s", version)) log.Info("downloading images") if err := pinkerton.PullImagesWithClient( client, args.String["--repository"], args.String["--driver"], args.String["--root"], version, pinkerton.InfoPrinter(false), ); err != nil { return err } d := downloader.New(client, version) log.Info(fmt.Sprintf("downloading config to %s", configDir)) if _, err := d.DownloadConfig(configDir); err != nil { log.Error("error downloading config", "err", err) return err } binDir := args.String["--bin-dir"] log.Info(fmt.Sprintf("downloading binaries to %s", binDir)) if _, err := d.DownloadBinaries(binDir); err != nil { log.Error("error downloading binaries", "err", err) return err } log.Info("download complete") return nil }
func runDownload(args *docopt.Args) error { log := log15.New() log.Info("initializing ZFS volumes") volPath := args.String["--volpath"] volDB := filepath.Join(volPath, "volumes.bolt") volMan := volumemanager.New(volDB, log, func() (volume.Provider, error) { return zfs.NewProvider(&zfs.ProviderConfig{ DatasetName: zfs.DefaultDatasetName, Make: zfs.DefaultMakeDev(volPath, log), WorkingDir: filepath.Join(volPath, "zfs"), }) }) if err := volMan.OpenDB(); err != nil { log.Error("error opening volume database, make sure flynn-host is not running", "err", err) return err } // create a TUF client and update it log.Info("initializing TUF client") tufDB := args.String["--tuf-db"] local, err := tuf.FileLocalStore(tufDB) if err != nil { log.Error("error creating local TUF client", "err", err) return err } remote, err := tuf.HTTPRemoteStore(args.String["--repository"], tufHTTPOpts("downloader")) if err != nil { log.Error("error creating remote TUF client", "err", err) return err } client := tuf.NewClient(local, remote) if err := updateTUFClient(client); err != nil { log.Error("error updating TUF client", "err", err) return err } configDir := args.String["--config-dir"] requestedVersion := os.Getenv("FLYNN_VERSION") if requestedVersion == "" { requestedVersion, err = getChannelVersion(configDir, client, log) if err != nil { return err } } log.Info(fmt.Sprintf("downloading components with version %s", requestedVersion)) d := downloader.New(client, volMan, requestedVersion) binDir := args.String["--bin-dir"] log.Info(fmt.Sprintf("downloading binaries to %s", binDir)) if _, err := d.DownloadBinaries(binDir); err != nil { log.Error("error downloading binaries", "err", err) return err } // use the requested version of flynn-host to download the images as // the format changed in v20161106 if version.String() != requestedVersion { log.Info(fmt.Sprintf("executing %s flynn-host binary", requestedVersion)) binPath := filepath.Join(binDir, "flynn-host") argv := append([]string{binPath}, os.Args[1:]...) return syscall.Exec(binPath, argv, os.Environ()) } log.Info("downloading images") ch := make(chan *ct.ImagePullInfo) go func() { for info := range ch { switch info.Type { case ct.ImagePullTypeImage: log.Info(fmt.Sprintf("pulling %s image", info.Name)) case ct.ImagePullTypeLayer: log.Info(fmt.Sprintf("pulling %s layer %s (%s)", info.Name, info.Layer.ID, units.BytesSize(float64(info.Layer.Length)))) } } }() if err := d.DownloadImages(configDir, ch); err != nil { log.Error("error downloading images", "err", err) return err } log.Info(fmt.Sprintf("downloading config to %s", configDir)) if _, err := d.DownloadConfig(configDir); err != nil { log.Error("error downloading config", "err", err) return err } log.Info("download complete") return nil }