Skip to content

Commit

Permalink
Merge pull request #305 from nalind/storage-update
Browse files Browse the repository at this point in the history
Rework how we use containers/storage
  • Loading branch information
runcom authored Dec 14, 2017
2 parents c8bcd6a + 2ad3ecd commit 1744973
Show file tree
Hide file tree
Showing 37 changed files with 1,959 additions and 988 deletions.
11 changes: 10 additions & 1 deletion copy/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,15 @@ func (ic *imageCopier) copyLayers() error {
srcInfos := ic.src.LayerInfos()
destInfos := []types.BlobInfo{}
diffIDs := []digest.Digest{}
updatedSrcInfos := ic.src.LayerInfosForCopy()
srcInfosUpdated := false
if updatedSrcInfos != nil && !reflect.DeepEqual(srcInfos, updatedSrcInfos) {
if !ic.canModifyManifest {
return errors.Errorf("Internal error: copyLayers() needs to use an updated manifest but that was known to be forbidden")
}
srcInfos = updatedSrcInfos
srcInfosUpdated = true
}
for _, srcLayer := range srcInfos {
var (
destInfo types.BlobInfo
Expand Down Expand Up @@ -396,7 +405,7 @@ func (ic *imageCopier) copyLayers() error {
if ic.diffIDsAreNeeded {
ic.manifestUpdates.InformationOnly.LayerDiffIDs = diffIDs
}
if layerDigestsDiffer(srcInfos, destInfos) {
if srcInfosUpdated || layerDigestsDiffer(srcInfos, destInfos) {
ic.manifestUpdates.LayerInfos = destInfos
}
return nil
Expand Down
3 changes: 3 additions & 0 deletions copy/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func (f fakeImageSource) OCIConfig() (*v1.Image, error) {
func (f fakeImageSource) LayerInfos() []types.BlobInfo {
panic("Unexpected call to a mock function")
}
func (f fakeImageSource) LayerInfosForCopy() []types.BlobInfo {
panic("Unexpected call to a mock function")
}
func (f fakeImageSource) EmbeddedDockerReferenceConflicts(ref reference.Named) bool {
panic("Unexpected call to a mock function")
}
Expand Down
5 changes: 5 additions & 0 deletions directory/directory_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *dige
}
return signatures, nil
}

// LayerInfosForCopy() returns updated layer info that should be used when copying, in preference to values in the manifest, if specified.
func (s *dirImageSource) LayerInfosForCopy() []types.BlobInfo {
return nil
}
5 changes: 5 additions & 0 deletions docker/archive/src.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ func (s *archiveImageSource) Reference() types.ImageReference {
func (s *archiveImageSource) Close() error {
return nil
}

// LayerInfosForCopy() returns updated layer info that should be used when reading, in preference to values in the manifest, if specified.
func (s *archiveImageSource) LayerInfosForCopy() []types.BlobInfo {
return nil
}
5 changes: 5 additions & 0 deletions docker/daemon/daemon_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ func (s *daemonImageSource) Reference() types.ImageReference {
func (s *daemonImageSource) Close() error {
return os.Remove(s.tarCopyPath)
}

// LayerInfosForCopy() returns updated layer info that should be used when reading, in preference to values in the manifest, if specified.
func (s *daemonImageSource) LayerInfosForCopy() []types.BlobInfo {
return nil
}
5 changes: 5 additions & 0 deletions docker/docker_image_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ func (s *dockerImageSource) Close() error {
return nil
}

// LayerInfosForCopy() returns updated layer info that should be used when reading, in preference to values in the manifest, if specified.
func (s *dockerImageSource) LayerInfosForCopy() []types.BlobInfo {
return nil
}

// simplifyContentType drops parameters from a HTTP media type (see https://tools.ietf.org/html/rfc7231#section-3.1.1.1)
// Alternatively, an empty string is returned unchanged, and invalid values are "simplified" to an empty string.
func simplifyContentType(contentType string) string {
Expand Down
6 changes: 3 additions & 3 deletions docker/tarfile/dest.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (d *Destination) ReapplyBlob(info types.BlobInfo) (types.BlobInfo, error) {
func (d *Destination) PutManifest(m []byte) error {
// We do not bother with types.ManifestTypeRejectedError; our .SupportedManifestMIMETypes() above is already providing only one alternative,
// so the caller trying a different manifest kind would be pointless.
var man schema2Manifest
var man manifest.Schema2
if err := json.Unmarshal(m, &man); err != nil {
return errors.Wrap(err, "Error parsing manifest")
}
Expand All @@ -176,12 +176,12 @@ func (d *Destination) PutManifest(m []byte) error {
}

layerPaths := []string{}
for _, l := range man.Layers {
for _, l := range man.LayersDescriptors {
layerPaths = append(layerPaths, l.Digest.String())
}

items := []ManifestItem{{
Config: man.Config.Digest.String(),
Config: man.ConfigDescriptor.Digest.String(),
RepoTags: []string{d.repoTag},
Layers: layerPaths,
Parent: "",
Expand Down
22 changes: 11 additions & 11 deletions docker/tarfile/src.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ type Source struct {
tarManifest *ManifestItem // nil if not available yet.
configBytes []byte
configDigest digest.Digest
orderedDiffIDList []diffID
knownLayers map[diffID]*layerInfo
orderedDiffIDList []digest.Digest
knownLayers map[digest.Digest]*layerInfo
// Other state
generatedManifest []byte // Private cache for GetManifest(), nil if not set yet.
}
Expand Down Expand Up @@ -156,7 +156,7 @@ func (s *Source) ensureCachedDataIsPresent() error {
if err != nil {
return err
}
var parsedConfig image // Most fields ommitted, we only care about layer DiffIDs.
var parsedConfig manifest.Schema2Image // There's a lot of info there, but we only really care about layer DiffIDs.
if err := json.Unmarshal(configBytes, &parsedConfig); err != nil {
return errors.Wrapf(err, "Error decoding tar config %s", tarManifest[0].Config)
}
Expand Down Expand Up @@ -194,12 +194,12 @@ func (s *Source) LoadTarManifest() ([]ManifestItem, error) {
return s.loadTarManifest()
}

func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *image) (map[diffID]*layerInfo, error) {
func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manifest.Schema2Image) (map[digest.Digest]*layerInfo, error) {
// Collect layer data available in manifest and config.
if len(tarManifest.Layers) != len(parsedConfig.RootFS.DiffIDs) {
return nil, errors.Errorf("Inconsistent layer count: %d in manifest, %d in config", len(tarManifest.Layers), len(parsedConfig.RootFS.DiffIDs))
}
knownLayers := map[diffID]*layerInfo{}
knownLayers := map[digest.Digest]*layerInfo{}
unknownLayerSizes := map[string]*layerInfo{} // Points into knownLayers, a "to do list" of items with unknown sizes.
for i, diffID := range parsedConfig.RootFS.DiffIDs {
if _, ok := knownLayers[diffID]; ok {
Expand Down Expand Up @@ -260,23 +260,23 @@ func (s *Source) GetManifest(instanceDigest *digest.Digest) ([]byte, string, err
if err := s.ensureCachedDataIsPresent(); err != nil {
return nil, "", err
}
m := schema2Manifest{
m := manifest.Schema2{
SchemaVersion: 2,
MediaType: manifest.DockerV2Schema2MediaType,
Config: distributionDescriptor{
ConfigDescriptor: manifest.Schema2Descriptor{
MediaType: manifest.DockerV2Schema2ConfigMediaType,
Size: int64(len(s.configBytes)),
Digest: s.configDigest,
},
Layers: []distributionDescriptor{},
LayersDescriptors: []manifest.Schema2Descriptor{},
}
for _, diffID := range s.orderedDiffIDList {
li, ok := s.knownLayers[diffID]
if !ok {
return nil, "", errors.Errorf("Internal inconsistency: Information about layer %s missing", diffID)
}
m.Layers = append(m.Layers, distributionDescriptor{
Digest: digest.Digest(diffID), // diffID is a digest of the uncompressed tarball
m.LayersDescriptors = append(m.LayersDescriptors, manifest.Schema2Descriptor{
Digest: diffID, // diffID is a digest of the uncompressed tarball
MediaType: manifest.DockerV2Schema2LayerMediaType,
Size: li.size,
})
Expand Down Expand Up @@ -312,7 +312,7 @@ func (s *Source) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {
return ioutil.NopCloser(bytes.NewReader(s.configBytes)), int64(len(s.configBytes)), nil
}

if li, ok := s.knownLayers[diffID(info.Digest)]; ok { // diffID is a digest of the uncompressed tarball,
if li, ok := s.knownLayers[info.Digest]; ok { // diffID is a digest of the uncompressed tarball,
stream, err := s.openTarComponent(li.path)
if err != nil {
return nil, 0, err
Expand Down
38 changes: 6 additions & 32 deletions docker/tarfile/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package tarfile

import "github.com/opencontainers/go-digest"
import (
"github.com/containers/image/manifest"
"github.com/opencontainers/go-digest"
)

// Various data structures.

Expand All @@ -18,37 +21,8 @@ type ManifestItem struct {
Config string
RepoTags []string
Layers []string
Parent imageID `json:",omitempty"`
LayerSources map[diffID]distributionDescriptor `json:",omitempty"`
Parent imageID `json:",omitempty"`
LayerSources map[digest.Digest]manifest.Schema2Descriptor `json:",omitempty"`
}

type imageID string
type diffID digest.Digest

// Based on github.com/docker/distribution/blobs.go
type distributionDescriptor struct {
MediaType string `json:"mediaType,omitempty"`
Size int64 `json:"size,omitempty"`
Digest digest.Digest `json:"digest,omitempty"`
URLs []string `json:"urls,omitempty"`
}

// Based on github.com/docker/distribution/manifest/schema2/manifest.go
// FIXME: We are repeating this all over the place; make a public copy?
type schema2Manifest struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType,omitempty"`
Config distributionDescriptor `json:"config"`
Layers []distributionDescriptor `json:"layers"`
}

// Based on github.com/docker/docker/image/image.go
// MOST CONTENT OMITTED AS UNNECESSARY
type image struct {
RootFS *rootFS `json:"rootfs,omitempty"`
}

type rootFS struct {
Type string `json:"type"`
DiffIDs []diffID `json:"diff_ids,omitempty"`
}
2 changes: 1 addition & 1 deletion image/docker_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type platformSpec struct {

// A manifestDescriptor references a platform-specific manifest.
type manifestDescriptor struct {
descriptor
manifest.Schema2Descriptor
Platform platformSpec `json:"platform"`
}

Expand Down
Loading

0 comments on commit 1744973

Please sign in to comment.