Skip to content

Commit

Permalink
ostree: provide LayerInfosForCopy
Browse files Browse the repository at this point in the history
it enables the copy of compressed images.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Dec 14, 2017
1 parent f2cced4 commit 15961b8
Showing 1 changed file with 69 additions and 6 deletions.
75 changes: 69 additions & 6 deletions ostree/ostree_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"compress/gzip"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/containers/image/types"
"github.com/containers/storage/pkg/ioutils"
"github.com/opencontainers/go-digest"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
glib "github.com/ostreedev/ostree-go/pkg/glibobject"
"github.com/pkg/errors"
"github.com/vbatts/tar-split/tar/asm"
Expand All @@ -34,14 +36,15 @@ import (
import "C"

type ostreeImageSource struct {
ref ostreeReference
tmpDir string
repo *C.struct_OstreeRepo
ref ostreeReference
tmpDir string
repo *C.struct_OstreeRepo
compressed map[digest.Digest]digest.Digest
}

// newImageSource returns an ImageSource for reading from an existing directory.
func newImageSource(ctx *types.SystemContext, tmpDir string, ref ostreeReference) (types.ImageSource, error) {
return &ostreeImageSource{ref: ref, tmpDir: tmpDir}, nil
return &ostreeImageSource{ref: ref, tmpDir: tmpDir, compressed: make(map[digest.Digest]digest.Digest)}, nil
}

// Reference returns the reference used to set up this source.
Expand Down Expand Up @@ -255,7 +258,12 @@ func (s *ostreeImageSource) readSingleFile(commit, path string) (io.ReadCloser,

// GetBlob returns a stream for the specified blob, and the blob's size.
func (s *ostreeImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {

blob := info.Digest.Hex()
compressedBlob, found := s.compressed[info.Digest]
if found {
blob = compressedBlob.Hex()
}
branch := fmt.Sprintf("ociimage/%s", blob)

if s.repo == nil {
Expand Down Expand Up @@ -348,7 +356,62 @@ func (s *ostreeImageSource) GetSignatures(ctx context.Context, instanceDigest *d
return signatures, nil
}

// LayerInfosForCopy() returns updated layer info that should be used when reading, in preference to values in the manifest, if specified.
// LayerInfosForCopy() returns the list of layer blobs that make up the root filesystem of
// the image, after they've been decompressed.
func (s *ostreeImageSource) LayerInfosForCopy() []types.BlobInfo {
return nil
updatedBlobInfos := []types.BlobInfo{}
manifestBlob, manifestType, err := s.GetManifest(nil)
if err != nil {
return nil
}

var schema manifestSchema
if err := json.Unmarshal(manifestBlob, &schema); err != nil {
return nil
}

uncompressedLayerType := ""
switch manifestType {
case imgspecv1.MediaTypeImageManifest:
uncompressedLayerType = imgspecv1.MediaTypeImageLayer
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema2MediaType:
// This is actually a compressed type, but there's no uncompressed type defined
uncompressedLayerType = manifest.DockerV2Schema2LayerMediaType
}

layers := []digest.Digest{}

for _, layer := range schema.LayersDescriptors {
layers = append(layers, layer.Digest)
}
for _, layer := range schema.FSLayers {
layers = append(layers, layer.BlobSum)
}

for _, layer := range layers {
branch := fmt.Sprintf("ociimage/%s", layer.Hex())
found, uncompressedDigestStr, err := readMetadata(s.repo, branch, "docker.uncompressed_digest")
if err != nil || !found {
return nil
}

found, uncompressedSizeStr, err := readMetadata(s.repo, branch, "docker.uncompressed_size")
if err != nil || !found {
return nil
}

uncompressedSize, err := strconv.ParseInt(uncompressedSizeStr, 10, 64)
if err != nil {
return nil
}
uncompressedDigest := digest.Digest(uncompressedDigestStr)
blobInfo := types.BlobInfo{
Digest: uncompressedDigest,
Size: uncompressedSize,
MediaType: uncompressedLayerType,
}
s.compressed[uncompressedDigest] = layer
updatedBlobInfos = append([]types.BlobInfo{blobInfo}, updatedBlobInfos...)
}
return updatedBlobInfos
}

0 comments on commit 15961b8

Please sign in to comment.