diff --git a/registry/registry.go b/registry/registry.go index c565c29989..5d642b392f 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -56,20 +56,19 @@ func (r *Registry) GetRemoteHistory(imgId, registry string, token []string) ([]s } // Check if an image exists in the Registry -func (r *Registry) LookupRemoteImage(imgId, registry string, authConfig *auth.AuthConfig) bool { +func (r *Registry) LookupRemoteImage(imgId, registry string, token []string) bool { rt := &http.Transport{Proxy: http.ProxyFromEnvironment} req, err := http.NewRequest("GET", registry+"/images/"+imgId+"/json", nil) if err != nil { return false } - req.SetBasicAuth(authConfig.Username, authConfig.Password) res, err := rt.RoundTrip(req) if err != nil { return false } res.Body.Close() - return res.StatusCode == 307 + return res.StatusCode == 200 } func (r *Registry) getImagesInRepository(repository string, authConfig *auth.AuthConfig) ([]map[string]string, error) { diff --git a/server.go b/server.go index cdc01c6b09..615881cf78 100644 --- a/server.go +++ b/server.go @@ -351,17 +351,32 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgId, endpoin return nil } -func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, local, remote, askedTag string, sf *utils.StreamFormatter) error { +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())) 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 + var repoData *registry.RepositoryData + var err error + if registryEp == "" { + 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 + } + } else { + repoData = ®istry.RepositoryData{ + Tokens: []string{}, + ImgList: make(map[string]*registry.ImgData), + Endpoints: []string{registryEp}, + } } utils.Debugf("Retrieving the tag list") @@ -369,8 +384,19 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, local, re if err != nil { return err } + + if registryEp != "" { + for tag, id := range tagsList { + repoData.ImgList[id] = ®istry.ImgData{ + Id: id, + Tag: tag, + Checksum: "", + } + } + } + utils.Debugf("Registering tags") - // If not specific tag have been asked, take all + // If no tag has been specified, pull them all if askedTag == "" { for tag, id := range tagsList { repoData.ImgList[id].Tag = tag @@ -547,7 +573,7 @@ func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgDat return imgList, nil } -func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name string, localRepo map[string]string, sf *utils.StreamFormatter) error { +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) @@ -555,16 +581,35 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri 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, "/"))) } - repoData, err := r.PushImageJSONIndex(srvName, imgList, false, nil) - if err != nil { - return err + var repoData *registry.RepositoryData + if registryEp == "" { + repoData, err = srv.registry.PushImageJsonIndex(name, imgList, false) + if err != nil { + return err + } + } else { + repoData = ®istry.RepositoryData{ + ImgList: make(map[string]*registry.ImgData), + Tokens: []string{}, + Endpoints: []string{registryEp}, + } + tagsList, err := srv.registry.GetRemoteTags(repoData.Endpoints, name, repoData.Tokens) + if err != nil { + return err + } + for tag, id := range tagsList { + repoData.ImgList[id] = ®istry.ImgData{ + Id: id, + Tag: tag, + Checksum: "", + } + } } for _, ep := range repoData.Endpoints { @@ -574,6 +619,9 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri if _, exists := repoData.ImgList[elem.ID]; exists { out.Write(sf.FormatStatus("Image %s already on registry, skipping", name)) continue + } else if registryEp != "" && srv.registry.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? @@ -586,9 +634,12 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri } } - if _, err := r.PushImageJSONIndex(srvName, imgList, true, repoData.Endpoints); err != nil { - return err + if registryEp == "" { + if _, err := srv.registry.PushImageJsonIndex(name, imgList, true); err != nil { + return err + } } + return nil } @@ -669,7 +720,7 @@ func (srv *Server) ImagePush(name, endpoint string, out io.Writer, sf *utils.Str out.Write(sf.FormatStatus("The push refers to a repository [%s] (len: %d)", name, len(srv.runtime.repositories.Repositories[name]))) // If it fails, try to get the repository if localRepo, exists := srv.runtime.repositories.Repositories[name]; exists { - if err := srv.pushRepository(r, out, name, localRepo, sf); err != nil { + if err := srv.pushRepository(r, out, name, registry, localRepo, sf); err != nil { return err } return nil