func (srv *Server) pullImage(out io.Writer, imgId, registry string, token []string, json bool) error { history, err := srv.registry.GetRemoteHistory(imgId, registry, token) if err != nil { return err } // FIXME: Try to stream the images? // FIXME: Launch the getRemoteImage() in goroutines for _, id := range history { if !srv.runtime.graph.Exists(id) { fmt.Fprintf(out, utils.FormatStatus("Pulling %s metadata", json), id) imgJson, err := srv.registry.GetRemoteImageJson(id, registry, token) if err != nil { // FIXME: Keep goging in case of error? return err } img, err := NewImgJson(imgJson) if err != nil { return fmt.Errorf("Failed to parse json: %s", err) } // Get the layer fmt.Fprintf(out, utils.FormatStatus("Pulling %s fs layer", json), id) layer, contentLength, err := srv.registry.GetRemoteImageLayer(img.Id, registry, token) if err != nil { return err } if err := srv.runtime.graph.Register(utils.ProgressReader(layer, contentLength, out, utils.FormatProgress("%v/%v (%v)", json), json), false, img); err != nil { return err } } } return nil }
func (srv *Server) pullRepository(out io.Writer, remote, askedTag string, json bool) error { fmt.Fprintf(out, utils.FormatStatus("Pulling repository %s from %s", json), remote, auth.IndexServerAddress()) repoData, err := srv.registry.GetRepositoryData(remote) if err != nil { return err } utils.Debugf("Updating checksums") // Reload the json file to make sure not to overwrite faster sums if err := srv.runtime.graph.UpdateChecksums(repoData.ImgList); err != nil { return err } utils.Debugf("Retrieving the tag list") tagsList, err := srv.registry.GetRemoteTags(repoData.Endpoints, remote, repoData.Tokens) if err != nil { return err } utils.Debugf("Registering tags") // If not specific tag have been asked, take all if askedTag == "" { for tag, id := range tagsList { repoData.ImgList[id].Tag = tag } } else { // Otherwise, check that the tag exists and use only that one if id, exists := tagsList[askedTag]; !exists { return fmt.Errorf("Tag %s not found in repositoy %s", askedTag, remote) } else { repoData.ImgList[id].Tag = askedTag } } for _, img := range repoData.ImgList { if askedTag != "" && img.Tag != askedTag { utils.Debugf("(%s) does not match %s (id: %s), skipping", img.Tag, askedTag, img.Id) continue } fmt.Fprintf(out, utils.FormatStatus("Pulling image %s (%s) from %s", json), img.Id, img.Tag, remote) success := false for _, ep := range repoData.Endpoints { if err := srv.pullImage(out, img.Id, "https://"+ep+"/v1", repoData.Tokens, json); err != nil { fmt.Fprintf(out, utils.FormatStatus("Error while retrieving image for tag: %s (%s); checking next endpoint\n", json), askedTag, err) continue } success = true break } if !success { return fmt.Errorf("Could not find repository on any of the indexed registries.") } } for tag, id := range tagsList { if askedTag != "" && tag != askedTag { continue } if err := srv.runtime.repositories.Set(remote, tag, id, true); err != nil { return err } } if err := srv.runtime.repositories.Save(); err != nil { return err } return nil }