Skip to content

Commit

Permalink
Make docker pull detect plugin content and error out.
Browse files Browse the repository at this point in the history
Signed-off-by: Anusha Ragunathan <anusha@docker.com>
  • Loading branch information
anusha-ragunathan committed Aug 20, 2016
1 parent 09e1de2 commit 9b6dcc8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
14 changes: 11 additions & 3 deletions api/client/image/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package image
import (
"errors"
"fmt"
"strings"

"golang.org/x/net/context"

Expand Down Expand Up @@ -77,9 +78,16 @@ func runPull(dockerCli *client.DockerCli, opts pullOptions) error {

if client.IsTrusted() && !registryRef.HasDigest() {
// Check if tag is digest
return dockerCli.TrustedPull(ctx, repoInfo, registryRef, authConfig, requestPrivilege)
err = dockerCli.TrustedPull(ctx, repoInfo, registryRef, authConfig, requestPrivilege)
} else {
err = dockerCli.ImagePullPrivileged(ctx, authConfig, distributionRef.String(), requestPrivilege, opts.all)
}
if err != nil {
if strings.Contains(err.Error(), "target is a plugin") {
return errors.New(err.Error() + " - Use `docker plugin install`")
}
return err
}

return dockerCli.ImagePullPrivileged(ctx, authConfig, distributionRef.String(), requestPrivilege, opts.all)

return nil
}
16 changes: 15 additions & 1 deletion distribution/pull_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ import (
"golang.org/x/net/context"
)

var errRootFSMismatch = errors.New("layers from manifest don't match image configuration")
var (
errRootFSMismatch = errors.New("layers from manifest don't match image configuration")
errMediaTypePlugin = errors.New("target is a plugin")
errRootFSInvalid = errors.New("invalid rootfs in image configuration")
)

// ImageConfigPullError is an error pulling the image config blob
// (only applies to schema2).
Expand Down Expand Up @@ -356,6 +360,12 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
return false, fmt.Errorf("image manifest does not exist for tag or digest %q", tagOrDigest)
}

if m, ok := manifest.(*schema2.DeserializedManifest); ok {
if m.Manifest.Config.MediaType == schema2.MediaTypePluginConfig {
return false, errMediaTypePlugin
}
}

// If manSvc.Get succeeded, we can be confident that the registry on
// the other side speaks the v2 protocol.
p.confirmedV2 = true
Expand Down Expand Up @@ -574,6 +584,10 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
}
}

if unmarshalledConfig.RootFS == nil {
return "", "", errRootFSInvalid
}

// The DiffIDs returned in rootFS MUST match those in the config.
// Otherwise the image config could be referencing layers that aren't
// included in the manifest.
Expand Down
2 changes: 1 addition & 1 deletion plugin/distribution/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func Pull(name string, rs registry.Service, metaheader http.Header, authConfig *
logrus.Debugf("pull.go: error in json.Unmarshal(): %v", err)
return nil, err
}
if m.Config.MediaType != MediaTypeConfig {
if m.Config.MediaType != schema2.MediaTypePluginConfig {
return nil, ErrUnsupportedMediaType
}

Expand Down
4 changes: 2 additions & 2 deletions plugin/distribution/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ func Push(name string, rs registry.Service, metaHeader http.Header, authConfig *
return "", err
}
f.Close()
mt := MediaTypeLayer
mt := schema2.MediaTypeLayer
if i == 0 {
mt = MediaTypeConfig
mt = schema2.MediaTypePluginConfig
}
// Commit completes the write process to the BlobService.
// The descriptor arg to Commit is called the "provisional" descriptor and
Expand Down
9 changes: 2 additions & 7 deletions plugin/distribution/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,5 @@ var ErrUnsupportedRegistry = errors.New("only V2 repositories are supported for
// ErrUnsupportedMediaType indicates we are pulling content that's not a plugin
var ErrUnsupportedMediaType = errors.New("content is not a plugin")

// Plugin related media types
const (
MediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json"
MediaTypeConfig = "application/vnd.docker.plugin.v0+json"
MediaTypeLayer = "application/vnd.docker.image.rootfs.diff.tar.gzip"
DefaultTag = "latest"
)
// DefaultTag is the default tag for plugins
const DefaultTag = "latest"

0 comments on commit 9b6dcc8

Please sign in to comment.