Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New image manifest format #18785

Merged
merged 9 commits into from
Jan 11, 2016
Merged

New image manifest format #18785

merged 9 commits into from
Jan 11, 2016

Conversation

aaronlehmann
Copy link
Contributor

This PR adds support for the new manifest format ("schema2") specified in https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md.

The new format allows end-to-end content addressability. The existing v2 manifest format puts image configurations in "v1Compatibility" strings that use the same data model and non-content-addressable ID scheme that the legacy v1 protocol uses. Supporting this format with the content addressable image/layer model in Docker 1.10 involves hacks to do things like generate fake v1 IDs. The new format carries the actual image configuration as a blob, so push/pull transfers an exact copy of the image.

The schema2 format also includes the concept of a "manifest list". This is a kind of meta-manifest that points to the appropriate manifests for different platforms. It will eventually allow pulling the same image name, tag, or digest across different platforms, and getting a version of the image built for the correct platform. The tools to create and push these manifest lists don't exist yet, but assuming this PR is merged for 1.10, 1.10 will support these multi-architecture images.

The transition to the new manifest format preserves backward compatibility. Engines which support the new format will always try to push schema2 manifests; however, if the remote registry doesn't support the format, it will fall back to using the schema1 format. When pulling, the engine indicates in an Accept header if it can accept the new format. If it can't, and it's pulling an image that the manifest has a schema2 manifest for, the registry will transparently convert the manifest to schema1 format (note this is not supported for pull-by-digest).

One nice side effect of this PR is that the hacks described above for assembling legacy manifests are moved out of the engine code into vendored distribution code. The distribution APIs now have a ManifestBuilder interface that abstracts away the job of creating a manifest in either the old or new format.

Support for the new format will be coming soon on Docker Hub. For now, testing push and pull with schema2 manifests requires building registry from the master branch of github.com/docker/distribution.

@thaJeztah
Copy link
Member

Tentatively added this to the 1.10 milestone, thanks @aaronlehmann

@@ -126,17 +125,7 @@ func NewV2Repository(ctx context.Context, repoInfo *registry.RepositoryInfo, end
}

func digestFromManifest(m *schema1.SignedManifest, name reference.Named) (digest.Digest, int, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helper doesn't seem very useful anymore. At least, there is no need to have name as input and err as output.

@aaronlehmann aaronlehmann force-pushed the new-manifest branch 2 times, most recently from fa99803 to 170e191 Compare December 22, 2015 23:25
@dmcgowan
Copy link
Member

design +1, this has already been approved and implemented on the distribution side.

@icecrime
Copy link
Contributor

Design LGTM

@aaronlehmann
Copy link
Contributor Author

I've brought this up to date by rebasing it on top of #18889. When #18889 is merged, the rebase will just involve dropping the first commit.

@thaJeztah
Copy link
Member

ping @aaronlehmann #18889 was merged, so this needs to be rebased

@aaronlehmann
Copy link
Contributor Author

Rebased

# Install two versions of the registry. The first is an older version that
# only supports schema1 manifests. The second is a newer version that supports
# both. This allows integration-cli tests to cover push/pull with both schema1
# and schema1 manifests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and schema2 manifests

@aaronlehmann aaronlehmann force-pushed the new-manifest branch 2 times, most recently from 11fa69e to bde2e44 Compare January 8, 2016 01:10
@aaronlehmann aaronlehmann changed the title New image manifest format - WIP New image manifest format Jan 8, 2016
@aaronlehmann
Copy link
Contributor Author

This is no longer WIP. The distribution bits have been merged upstream and the version vendored here is off the master branch.

@thaJeztah
Copy link
Member

ping @tonistiigi could you review this?

@@ -27,7 +27,7 @@ func (r *RootFS) BaseLayerID() string {

// ChainID returns the ChainID for the top layer in RootFS.
func (r *RootFS) ChainID() layer.ChainID {
baseDiffID, _ := digest.FromBytes([]byte(r.BaseLayerID())) // can never error
baseDiffID := digest.FromBytes([]byte(r.BaseLayerID())) // can never error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

}

// blobSumAlreadyExists checks if the registry already know about any of the
// blobsums passed in the "blobsums" slice. If it finds one that the registry
// knows about, it returns the known digest and "true".
func blobSumAlreadyExists(ctx context.Context, blobsums []digest.Digest, repo distribution.Repository, layersPushed *pushMap) (digest.Digest, bool, error) {
layersPushed.Lock()
for _, dgst := range blobsums {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, why is this block gone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to Upload, line 233.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks!

@icecrime
Copy link
Contributor

LGTM

@vdemeester
Copy link
Member

LGTM 🐹

@icecrime
Copy link
Contributor

I don't think there is any docs impact there: merging \o/

@thaJeztah
Copy link
Member

@aaronlehmann I don't think this has user-facing changes? So docs should be good, but please let us know if we overlooked something there, then we can do a docs follow up

@icecrime
Copy link
Contributor

Mmmm Windows CI is broken again 😢 Ping @jfrazelle @mikedougherty @jhowardmsft: can we merge anyway or do you want to give it look?

@lowenna
Copy link
Member

lowenna commented Jan 11, 2016

Looking now and restarting failing nodes...

@lowenna
Copy link
Member

lowenna commented Jan 11, 2016

@mikedougherty @jfrazelle

This seems a different error to other Windows CI failures. It's consistently hitting this:

09:53:43 + git clone https://github.com/BurntSushi/toml.git /tmp/tmp.7KvnKpADjP/src/github.com/BurntSushi/toml
09:53:43 Cloning into '/tmp/tmp.7KvnKpADjP/src/github.com/BurntSushi/toml'...
09:53:43 Removing intermediate container 63e2e9e2b088
09:53:43 SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
09:53:43 [8] System error: read parent: connection reset by peer

This is happening on multiple nodes, which are working with other PRs. Hence I think it's something in this PR rather than CI itself. Can you guys see anything obvious that I'm missing?

@aaronlehmann
Copy link
Contributor Author

This PR changes the Dockerfile, while most do not. It seems that something goes wrong while doing the initial docker build. However, it fails in a step that's well past my change. I suspect that if you clear the build cache, you would see the same problem with other PRs.

BTW, @tonistiigi has tested this PR manually on Windows.

@lowenna
Copy link
Member

lowenna commented Jan 11, 2016

Re-started on node 1 which I've just cleaned out the build cache on.

@aaronlehmann
Copy link
Contributor Author

icecrime pushed a commit that referenced this pull request Jan 11, 2016
@icecrime icecrime merged commit f11b6a2 into moby:master Jan 11, 2016
@aaronlehmann aaronlehmann deleted the new-manifest branch January 11, 2016 20:02
aaronlehmann added a commit to aaronlehmann/docker that referenced this pull request Mar 1, 2016
Concurrent uploads which share layers worked correctly as of moby#18353,
but unfortunately moby#18785 caused a regression. This PR removed the logic
that shares digests between different push sessions. This overlooked the
case where one session was waiting for another session to upload a
layer.

This commit adds back the ability to propagate this digest information,
using the distribution.Descriptor type because this is what is received
from stats and uploads, and also what is ultimately needed for building
the manifest.

Surprisingly, there was no test covering this case. This commit adds
one. It fails without the fix.

See recent comments on moby#9132.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
tiborvass pushed a commit to tiborvass/docker that referenced this pull request Mar 7, 2016
Concurrent uploads which share layers worked correctly as of moby#18353,
but unfortunately moby#18785 caused a regression. This PR removed the logic
that shares digests between different push sessions. This overlooked the
case where one session was waiting for another session to upload a
layer.

This commit adds back the ability to propagate this digest information,
using the distribution.Descriptor type because this is what is received
from stats and uploads, and also what is ultimately needed for building
the manifest.

Surprisingly, there was no test covering this case. This commit adds
one. It fails without the fix.

See recent comments on moby#9132.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
(cherry picked from commit 5c99eeb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants