|
@@ -438,7 +438,7 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgID, endpoin
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
defer layer.Close()
|
|
defer layer.Close()
|
|
- if err := srv.runtime.graph.Register(utils.ProgressReader(layer, imgSize, out, sf.FormatProgress(utils.TruncateID(id), "Downloading", "%8v/%v (%v)"), sf), false, img); err != nil {
|
|
|
|
|
|
+ if err := srv.runtime.graph.Register(imgJSON, utils.ProgressReader(layer, imgSize, out, sf.FormatProgress(utils.TruncateID(id), "Downloading", "%8v/%v (%v)"), sf), img); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -454,12 +454,6 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName
|
|
return err
|
|
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")
|
|
utils.Debugf("Retrieving the tag list")
|
|
tagsList, err := r.GetRemoteTags(repoData.Endpoints, remoteName, repoData.Tokens)
|
|
tagsList, err := r.GetRemoteTags(repoData.Endpoints, remoteName, repoData.Tokens)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -618,41 +612,6 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-// Retrieve the checksum of an image
|
|
|
|
-// Priority:
|
|
|
|
-// - Check on the stored checksums
|
|
|
|
-// - Check if the archive exists, if it does not, ask the registry
|
|
|
|
-// - If the archive does exists, process the checksum from it
|
|
|
|
-// - If the archive does not exists and not found on registry, process checksum from layer
|
|
|
|
-func (srv *Server) getChecksum(imageID string) (string, error) {
|
|
|
|
- // FIXME: Use in-memory map instead of reading the file each time
|
|
|
|
- if sums, err := srv.runtime.graph.getStoredChecksums(); err != nil {
|
|
|
|
- return "", err
|
|
|
|
- } else if checksum, exists := sums[imageID]; exists {
|
|
|
|
- return checksum, nil
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- img, err := srv.runtime.graph.Get(imageID)
|
|
|
|
- if err != nil {
|
|
|
|
- return "", err
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if _, err := os.Stat(layerArchivePath(srv.runtime.graph.imageRoot(imageID))); err != nil {
|
|
|
|
- if os.IsNotExist(err) {
|
|
|
|
- // TODO: Ask the registry for the checksum
|
|
|
|
- // As the archive is not there, it is supposed to come from a pull.
|
|
|
|
- } else {
|
|
|
|
- return "", err
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- checksum, err := img.Checksum()
|
|
|
|
- if err != nil {
|
|
|
|
- return "", err
|
|
|
|
- }
|
|
|
|
- return checksum, nil
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// Retrieve the all the images to be uploaded in the correct order
|
|
// Retrieve the all the images to be uploaded in the correct order
|
|
// Note: we can't use a map as it is not ordered
|
|
// Note: we can't use a map as it is not ordered
|
|
func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgData, error) {
|
|
func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgData, error) {
|
|
@@ -669,14 +628,10 @@ func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgDat
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
imageSet[img.ID] = struct{}{}
|
|
imageSet[img.ID] = struct{}{}
|
|
- checksum, err := srv.getChecksum(img.ID)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
imgList = append([]*registry.ImgData{{
|
|
imgList = append([]*registry.ImgData{{
|
|
- ID: img.ID,
|
|
|
|
- Checksum: checksum,
|
|
|
|
- Tag: tag,
|
|
|
|
|
|
+ ID: img.ID,
|
|
|
|
+ Tag: tag,
|
|
}}, imgList...)
|
|
}}, imgList...)
|
|
return nil
|
|
return nil
|
|
})
|
|
})
|
|
@@ -686,7 +641,6 @@ func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgDat
|
|
|
|
|
|
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, indexEp string, sf *utils.StreamFormatter) error {
|
|
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)
|
|
out = utils.NewWriteFlusher(out)
|
|
- out.Write(sf.FormatStatus("", "Processing checksums"))
|
|
|
|
imgList, err := srv.getImageList(localRepo)
|
|
imgList, err := srv.getImageList(localRepo)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -710,9 +664,11 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName
|
|
out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", elem.ID))
|
|
out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", elem.ID))
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
- if err := srv.pushImage(r, out, remoteName, elem.ID, ep, repoData.Tokens, sf); err != nil {
|
|
|
|
|
|
+ if checksum, err := srv.pushImage(r, out, remoteName, elem.ID, ep, repoData.Tokens, sf); err != nil {
|
|
// FIXME: Continue on error?
|
|
// FIXME: Continue on error?
|
|
return err
|
|
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))
|
|
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 {
|
|
if err := r.PushRegistryTag(remoteName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
|
|
@@ -728,64 +684,45 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID, ep string, token []string, sf *utils.StreamFormatter) error {
|
|
|
|
|
|
+func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID, ep string, token []string, sf *utils.StreamFormatter) (checksum string, err error) {
|
|
out = utils.NewWriteFlusher(out)
|
|
out = utils.NewWriteFlusher(out)
|
|
jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
|
|
jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
|
|
if err != nil {
|
|
if err != nil {
|
|
- return fmt.Errorf("Error while retreiving the path for {%s}: %s", imgID, err)
|
|
|
|
|
|
+ return "", fmt.Errorf("Error while retreiving the path for {%s}: %s", imgID, err)
|
|
}
|
|
}
|
|
out.Write(sf.FormatStatus("", "Pushing %s", imgID))
|
|
out.Write(sf.FormatStatus("", "Pushing %s", imgID))
|
|
|
|
|
|
- // Make sure we have the image's checksum
|
|
|
|
- checksum, err := srv.getChecksum(imgID)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
imgData := ®istry.ImgData{
|
|
imgData := ®istry.ImgData{
|
|
- ID: imgID,
|
|
|
|
- Checksum: checksum,
|
|
|
|
|
|
+ ID: imgID,
|
|
}
|
|
}
|
|
|
|
|
|
// Send the json
|
|
// Send the json
|
|
if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil {
|
|
if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil {
|
|
if err == registry.ErrAlreadyExists {
|
|
if err == registry.ErrAlreadyExists {
|
|
out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", imgData.ID))
|
|
out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", imgData.ID))
|
|
- return nil
|
|
|
|
|
|
+ return "", nil
|
|
}
|
|
}
|
|
- return err
|
|
|
|
|
|
+ return "", err
|
|
}
|
|
}
|
|
|
|
|
|
- // Retrieve the tarball to be sent
|
|
|
|
- var layerData *TempArchive
|
|
|
|
- // If the archive exists, use it
|
|
|
|
- file, err := os.Open(layerArchivePath(srv.runtime.graph.imageRoot(imgID)))
|
|
|
|
|
|
+ layerData, err := srv.runtime.graph.TempLayerArchive(imgID, Uncompressed, sf, out)
|
|
if err != nil {
|
|
if err != nil {
|
|
- if os.IsNotExist(err) {
|
|
|
|
- // If the archive does not exist, create one from the layer
|
|
|
|
- layerData, err = srv.runtime.graph.TempLayerArchive(imgID, Xz, sf, out)
|
|
|
|
- if err != nil {
|
|
|
|
- return fmt.Errorf("Failed to generate layer archive: %s", err)
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- defer file.Close()
|
|
|
|
- st, err := file.Stat()
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- layerData = &TempArchive{
|
|
|
|
- File: file,
|
|
|
|
- Size: st.Size(),
|
|
|
|
- }
|
|
|
|
|
|
+ return "", fmt.Errorf("Failed to generate layer archive: %s", err)
|
|
}
|
|
}
|
|
|
|
|
|
// Send the layer
|
|
// Send the layer
|
|
- if err := r.PushImageLayerRegistry(imgData.ID, utils.ProgressReader(layerData, int(layerData.Size), out, sf.FormatProgress("", "Pushing", "%8v/%v (%v)"), sf), ep, token); err != nil {
|
|
|
|
- return err
|
|
|
|
|
|
+ if checksum, err := r.PushImageLayerRegistry(imgData.ID, utils.ProgressReader(layerData, int(layerData.Size), out, sf.FormatProgress("", "Pushing", "%8v/%v (%v)"), sf), ep, token, jsonRaw); err != nil {
|
|
|
|
+ return "", err
|
|
|
|
+ } else {
|
|
|
|
+ imgData.Checksum = checksum
|
|
}
|
|
}
|
|
- return nil
|
|
|
|
|
|
+
|
|
|
|
+ // Send the checksum
|
|
|
|
+ if err := r.PushImageChecksumRegistry(imgData, ep, token); err != nil {
|
|
|
|
+ return "", err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return imgData.Checksum, nil
|
|
}
|
|
}
|
|
|
|
|
|
// FIXME: Allow to interupt current push when new push of same image is done.
|
|
// FIXME: Allow to interupt current push when new push of same image is done.
|
|
@@ -823,7 +760,7 @@ func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFo
|
|
|
|
|
|
var token []string
|
|
var token []string
|
|
out.Write(sf.FormatStatus("", "The push refers to an image: [%s]", localName))
|
|
out.Write(sf.FormatStatus("", "The push refers to an image: [%s]", localName))
|
|
- if err := srv.pushImage(r, out, remoteName, img.ID, endpoint, token, sf); err != nil {
|
|
|
|
|
|
+ if _, err := srv.pushImage(r, out, remoteName, img.ID, endpoint, token, sf); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|