image/save: Derive Descriptor from actual tar archive
Layer size is the sum of the individual files count, not the tar archive. Use the total bytes read returned by `io.Copy` to populate the `Size` field. Also set the digest to the actual digest of the tar archive. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
3eba4216e0
commit
c58acf06c2
2 changed files with 29 additions and 13 deletions
|
@ -38,6 +38,7 @@ type saveSession struct {
|
|||
images map[image.ID]*imageDescriptor
|
||||
savedLayers map[string]struct{}
|
||||
diffIDPaths map[layer.DiffID]string // cache every diffID blob to avoid duplicates
|
||||
diffIDDescs map[layer.DiffID]distribution.Descriptor
|
||||
}
|
||||
|
||||
func (l *tarexporter) Save(names []string, outStream io.Writer) error {
|
||||
|
@ -180,6 +181,7 @@ func (l *tarexporter) releaseLayerReferences(imgDescr map[image.ID]*imageDescrip
|
|||
func (s *saveSession) save(outStream io.Writer) error {
|
||||
s.savedLayers = make(map[string]struct{})
|
||||
s.diffIDPaths = make(map[layer.DiffID]string)
|
||||
s.diffIDDescs = make(map[layer.DiffID]distribution.Descriptor)
|
||||
|
||||
// get image json
|
||||
tempDir, err := os.MkdirTemp("", "docker-export-")
|
||||
|
@ -502,7 +504,11 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat
|
|||
}
|
||||
defer arch.Close()
|
||||
|
||||
if _, err := io.Copy(tarFile, arch); err != nil {
|
||||
digester := digest.Canonical.Digester()
|
||||
digestedArch := io.TeeReader(arch, digester.Hash())
|
||||
|
||||
tarSize, err := io.Copy(tarFile, digestedArch)
|
||||
if err != nil {
|
||||
return distribution.Descriptor{}, err
|
||||
}
|
||||
|
||||
|
@ -517,19 +523,21 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat
|
|||
|
||||
s.diffIDPaths[l.DiffID()] = layerPath
|
||||
s.savedLayers[legacyImg.ID] = struct{}{}
|
||||
}
|
||||
|
||||
var src distribution.Descriptor
|
||||
if fs, ok := l.(distribution.Describable); ok {
|
||||
src = fs.Descriptor()
|
||||
}
|
||||
|
||||
if src.Digest == "" {
|
||||
src = distribution.Descriptor{
|
||||
MediaType: ocispec.MediaTypeImageLayer,
|
||||
Digest: lDgst,
|
||||
Size: l.Size(),
|
||||
var desc distribution.Descriptor
|
||||
if fs, ok := l.(distribution.Describable); ok {
|
||||
desc = fs.Descriptor()
|
||||
}
|
||||
|
||||
if desc.Digest == "" {
|
||||
desc.Digest = digester.Digest()
|
||||
desc.Size = tarSize
|
||||
}
|
||||
if desc.MediaType == "" {
|
||||
desc.MediaType = ocispec.MediaTypeImageLayer
|
||||
}
|
||||
s.diffIDDescs[l.DiffID()] = desc
|
||||
}
|
||||
return src, nil
|
||||
|
||||
return s.diffIDDescs[l.DiffID()], nil
|
||||
}
|
||||
|
|
|
@ -119,6 +119,14 @@ func TestSaveCheckManifestLayers(t *testing.T) {
|
|||
assert.NilError(t, json.Unmarshal(manifestData, &manifest))
|
||||
|
||||
assert.Check(t, is.Len(manifest.Layers, len(img.RootFS.Layers)))
|
||||
for _, l := range manifest.Layers {
|
||||
stat, err := fs.Stat(tarfs, "blobs/sha256/"+l.Digest.Encoded())
|
||||
if !assert.Check(t, err) {
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Check(t, is.Equal(l.Size, stat.Size()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveRepoWithMultipleImages(t *testing.T) {
|
||||
|
|
Loading…
Add table
Reference in a new issue