예제 #1
0
파일: server.go 프로젝트: Nitron/docker
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, indexEp string, sf *utils.StreamFormatter) error {
	out = utils.NewWriteFlusher(out)
	imgList, err := srv.getImageList(localRepo)
	if err != nil {
		return err
	}
	flattenedImgList := flatten(imgList)
	out.Write(sf.FormatStatus("", "Sending image list"))

	var repoData *registry.RepositoryData
	repoData, err = r.PushImageJSONIndex(indexEp, remoteName, flattenedImgList, false, nil)
	if err != nil {
		return err
	}

	for _, ep := range repoData.Endpoints {
		out.Write(sf.FormatStatus("", "Pushing repository %s (%d tags)", localName, len(localRepo)))
		// This section can not be parallelized (each round depends on the previous one)
		for _, round := range imgList {
			// FIXME: This section can be parallelized
			for _, elem := range round {
				var pushTags func() error
				pushTags = func() error {
					out.Write(sf.FormatStatus("", "Pushing tags for rev [%s] on {%s}", elem.ID, ep+"repositories/"+remoteName+"/tags/"+elem.Tag))
					if err := r.PushRegistryTag(remoteName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
						return err
					}
					return nil
				}
				if _, exists := repoData.ImgList[elem.ID]; exists {
					if err := pushTags(); err != nil {
						return err
					}
					out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", elem.ID))
					continue
				} else if r.LookupRemoteImage(elem.ID, ep, repoData.Tokens) {
					if err := pushTags(); err != nil {
						return err
					}
					out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", elem.ID))
					continue
				}
				if checksum, err := srv.pushImage(r, out, remoteName, elem.ID, ep, repoData.Tokens, sf); err != nil {
					// FIXME: Continue on error?
					return err
				} else {
					elem.Checksum = checksum
				}
				return pushTags()
			}
		}
	}

	if _, err := r.PushImageJSONIndex(indexEp, remoteName, flattenedImgList, true, repoData.Endpoints); err != nil {
		return err
	}

	return nil
}
예제 #2
0
파일: server.go 프로젝트: kmindg/docker
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name string, localRepo map[string]string, indexEp 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
	repoData, err = r.PushImageJSONIndex(indexEp, name, imgList, false, nil)
	if err != nil {
		return err
	}

	for _, ep := range repoData.Endpoints {
		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 r.LookupRemoteImage(elem.ID, ep, 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 _, err := r.PushImageJSONIndex(indexEp, name, imgList, true, repoData.Endpoints); err != nil {
		return err
	}

	return nil
}
예제 #3
0
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, indexEp string, sf *utils.StreamFormatter) error {
	out = utils.NewWriteFlusher(out)

	imgList, err := srv.getImageList(localRepo)
	if err != nil {
		return err
	}
	out.Write(sf.FormatStatus("Sending image list"))

	var repoData *registry.RepositoryData
	repoData, err = r.PushImageJSONIndex(indexEp, remoteName, imgList, false, nil)
	if err != nil {
		return err
	}

	for _, ep := range repoData.Endpoints {
		out.Write(sf.FormatStatus("Pushing repository %s (%d tags)", localName, 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 pushed, skipping", elem.ID))
				continue
			} else if r.LookupRemoteImage(elem.ID, ep, repoData.Tokens) {
				out.Write(sf.FormatStatus("Image %s already pushed, skipping", elem.ID))
				continue
			}
			if checksum, err := srv.pushImage(r, out, remoteName, elem.ID, ep, repoData.Tokens, sf); err != nil {
				// FIXME: Continue on error?
				return err
			} else {
				elem.Checksum = checksum
			}
			out.Write(sf.FormatStatus("Pushing tags for rev [%s] on {%s}", elem.ID, ep+"repositories/"+remoteName+"/tags/"+elem.Tag))
			if err := r.PushRegistryTag(remoteName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
				return err
			}
		}
	}

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

	return nil
}
예제 #4
0
파일: server.go 프로젝트: sjbalaji/docker
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
}