Skip to content

Commit df20b5c

Browse files
committed
Merge pull request moby#21002 from tonistiigi/fix-id-noprefix
Fix docker run for 64 byte hex ID
2 parents 8e74cf5 + 16e4c4e commit df20b5c

File tree

5 files changed

+55
-26
lines changed

5 files changed

+55
-26
lines changed

api/client/create.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,30 @@ func (cli *DockerCli) createContainer(config *container.Config, hostConfig *cont
9292
defer containerIDFile.Close()
9393
}
9494

95-
ref, err := reference.ParseNamed(config.Image)
95+
var trustedRef reference.Canonical
96+
_, ref, err := reference.ParseIDOrReference(config.Image)
9697
if err != nil {
9798
return nil, err
9899
}
99-
ref = reference.WithDefaultTag(ref)
100-
101-
var trustedRef reference.Canonical
100+
if ref != nil {
101+
ref = reference.WithDefaultTag(ref)
102102

103-
if ref, ok := ref.(reference.NamedTagged); ok && isTrusted() {
104-
var err error
105-
trustedRef, err = cli.trustedReference(ref)
106-
if err != nil {
107-
return nil, err
103+
if ref, ok := ref.(reference.NamedTagged); ok && isTrusted() {
104+
var err error
105+
trustedRef, err = cli.trustedReference(ref)
106+
if err != nil {
107+
return nil, err
108+
}
109+
config.Image = trustedRef.String()
108110
}
109-
config.Image = trustedRef.String()
110111
}
111112

112113
//create the container
113114
response, err := cli.client.ContainerCreate(config, hostConfig, networkingConfig, name)
114115

115116
//if image not found try to pull it
116117
if err != nil {
117-
if client.IsErrImageNotFound(err) {
118+
if client.IsErrImageNotFound(err) && ref != nil {
118119
fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", ref.String())
119120

120121
// we don't want to write to stdout anything apart from container.ID

daemon/daemon.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"time"
2121

2222
"github.com/Sirupsen/logrus"
23-
"github.com/docker/distribution/digest"
2423
"github.com/docker/docker/api"
2524
"github.com/docker/docker/builder"
2625
"github.com/docker/docker/container"
@@ -1268,25 +1267,25 @@ func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
12681267
// GetImageID returns an image ID corresponding to the image referred to by
12691268
// refOrID.
12701269
func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
1271-
// Treat as an ID
1272-
if id, err := digest.ParseDigest(refOrID); err == nil {
1270+
id, ref, err := reference.ParseIDOrReference(refOrID)
1271+
if err != nil {
1272+
return "", err
1273+
}
1274+
if id != "" {
12731275
if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
12741276
return "", ErrImageDoesNotExist{refOrID}
12751277
}
12761278
return image.ID(id), nil
12771279
}
12781280

1279-
// Treat it as a possible tag or digest reference
1280-
if ref, err := reference.ParseNamed(refOrID); err == nil {
1281-
if id, err := daemon.referenceStore.Get(ref); err == nil {
1282-
return id, nil
1283-
}
1284-
if tagged, ok := ref.(reference.NamedTagged); ok {
1285-
if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
1286-
for _, namedRef := range daemon.referenceStore.References(id) {
1287-
if namedRef.Name() == ref.Name() {
1288-
return id, nil
1289-
}
1281+
if id, err := daemon.referenceStore.Get(ref); err == nil {
1282+
return id, nil
1283+
}
1284+
if tagged, ok := ref.(reference.NamedTagged); ok {
1285+
if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
1286+
for _, namedRef := range daemon.referenceStore.References(id) {
1287+
if namedRef.Name() == ref.Name() {
1288+
return id, nil
12901289
}
12911290
}
12921291
}

image/tarexport/save.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,18 @@ func (l *tarexporter) parseNames(names []string) (map[image.ID]*imageDescriptor,
7070
}
7171

7272
for _, name := range names {
73-
ref, err := reference.ParseNamed(name)
73+
id, ref, err := reference.ParseIDOrReference(name)
7474
if err != nil {
7575
return nil, err
7676
}
77+
if id != "" {
78+
_, err := l.is.Get(image.ID(id))
79+
if err != nil {
80+
return nil, err
81+
}
82+
addAssoc(image.ID(id), nil)
83+
continue
84+
}
7785
if ref.Name() == string(digest.Canonical) {
7886
imgID, err := l.is.Search(name)
7987
if err != nil {

integration-cli/docker_cli_create_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,11 @@ func (s *DockerSuite) TestCreateWithInvalidLogOpts(c *check.C) {
450450
out, _ = dockerCmd(c, "ps", "-a")
451451
c.Assert(out, checker.Not(checker.Contains), name)
452452
}
453+
454+
// #20972
455+
func (s *DockerSuite) TestCreate64ByteHexID(c *check.C) {
456+
out := inspectField(c, "busybox", "Id")
457+
imageID := strings.TrimPrefix(strings.TrimSpace(string(out)), "sha256:")
458+
459+
dockerCmd(c, "create", imageID)
460+
}

reference/reference.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,19 @@ func IsNameOnly(ref Named) bool {
155155
return true
156156
}
157157

158+
// ParseIDOrReference parses string for a image ID or a reference. ID can be
159+
// without a default prefix.
160+
func ParseIDOrReference(idOrRef string) (digest.Digest, Named, error) {
161+
if err := v1.ValidateID(idOrRef); err == nil {
162+
idOrRef = "sha256:" + idOrRef
163+
}
164+
if dgst, err := digest.ParseDigest(idOrRef); err == nil {
165+
return dgst, nil, nil
166+
}
167+
ref, err := ParseNamed(idOrRef)
168+
return "", ref, err
169+
}
170+
158171
// splitHostname splits a repository name to hostname and remotename string.
159172
// If no valid hostname is found, the default hostname is used. Repository name
160173
// needs to be already validated before.

0 commit comments

Comments
 (0)