Esempio n. 1
0
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name, registryEp string, localRepo map[string]string, sf *utils.StreamFormatter) error {
	out = utils.NewWriteFlusher(out)
	out.Write(sf.FormatStatus("Processing checksums"))
	imgList, err := srv.getImageList(localRepo)
	if err != nil {
		return err
	}
	out.Write(sf.FormatStatus("Sending image list"))
	srvName := name
	parts := strings.Split(name, "/")
	if len(parts) > 2 {
		srvName = fmt.Sprintf("src/%s", url.QueryEscape(strings.Join(parts, "/")))
	}

	var repoData *registry.RepositoryData
	if registryEp == "" {
		repoData, err = r.PushImageJSONIndex(name, imgList, false, nil)
		if err != nil {
			return err
		}
	} else {
		repoData = &registry.RepositoryData{
			ImgList:   make(map[string]*registry.ImgData),
			Tokens:    []string{},
			Endpoints: []string{registryEp},
		}
		tagsList, err := r.GetRemoteTags(repoData.Endpoints, name, repoData.Tokens)
		if err != nil && err.Error() != "Repository not found" {
			return err
		} else if err == nil {
			for tag, id := range tagsList {
				repoData.ImgList[id] = &registry.ImgData{
					ID:       id,
					Tag:      tag,
					Checksum: "",
				}
			}
		}
	}

	for _, ep := range repoData.Endpoints {
		if !(strings.HasPrefix(ep, "http://") || strings.HasPrefix(ep, "https://")) {
			ep = fmt.Sprintf("%s://%s", registry.UrlScheme(), ep)
		}
		out.Write(sf.FormatStatus("Pushing repository %s to %s (%d tags)", name, ep, len(localRepo)))
		// For each image within the repo, push them
		for _, elem := range imgList {
			if _, exists := repoData.ImgList[elem.ID]; exists {
				out.Write(sf.FormatStatus("Image %s already on registry, skipping", name))
				continue
			} else if registryEp != "" && r.LookupRemoteImage(elem.ID, registryEp, repoData.Tokens) {
				fmt.Fprintf(out, "Image %s already on registry, skipping\n", name)
				continue
			}
			if err := srv.pushImage(r, out, name, elem.ID, ep, repoData.Tokens, sf); err != nil {
				// FIXME: Continue on error?
				return err
			}
			out.Write(sf.FormatStatus("Pushing tags for rev [%s] on {%s}", elem.ID, ep+"/repositories/"+srvName+"/tags/"+elem.Tag))
			if err := r.PushRegistryTag(srvName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
				return err
			}
		}
	}

	if registryEp == "" {
		if _, err := r.PushImageJSONIndex(name, imgList, true, repoData.Endpoints); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 2
0
func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, local, remote, askedTag, registryEp string, sf *utils.StreamFormatter) error {
	out.Write(sf.FormatStatus("Pulling repository %s from %s", local, auth.IndexServerAddress()))

	var repoData *registry.RepositoryData
	var err error
	if registryEp == "" {
		repoData, err = r.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
		}
	} else {
		repoData = &registry.RepositoryData{
			Tokens:    []string{},
			ImgList:   make(map[string]*registry.ImgData),
			Endpoints: []string{registryEp},
		}
	}

	utils.Debugf("Retrieving the tag list")
	tagsList, err := r.GetRemoteTags(repoData.Endpoints, remote, repoData.Tokens)
	if err != nil {
		utils.Debugf("%v", err)
		return err
	}

	if registryEp != "" {
		for tag, id := range tagsList {
			repoData.ImgList[id] = &registry.ImgData{
				ID:       id,
				Tag:      tag,
				Checksum: "",
			}
		}
	}

	utils.Debugf("Registering tags")
	// If no tag has been specified, pull them 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
		id, exists := tagsList[askedTag]
		if !exists {
			return fmt.Errorf("Tag %s not found in repositoy %s", askedTag, local)
		}
		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
		}
		out.Write(sf.FormatStatus("Pulling image %s (%s) from %s", img.ID, img.Tag, remote))
		success := false
		for _, ep := range repoData.Endpoints {
			if !(strings.HasPrefix(ep, "http://") || strings.HasPrefix(ep, "https://")) {
				ep = fmt.Sprintf("%s://%s", registry.UrlScheme(), ep)
			}
			if err := srv.pullImage(r, out, img.ID, ep+"/v1", repoData.Tokens, sf); err != nil {
				out.Write(sf.FormatStatus("Error while retrieving image for tag: %s (%s); checking next endpoint", 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(local, tag, id, true); err != nil {
			return err
		}
	}
	if err := srv.runtime.repositories.Save(); err != nil {
		return err
	}

	return nil
}