summaryrefslogtreecommitdiff
path: root/builder
diff options
context:
space:
mode:
authorBrian Goff <cpuguy83@gmail.com>2020-03-05 22:09:10 -0800
committerBrian Goff <cpuguy83@gmail.com>2020-03-05 22:46:46 -0800
commited033adb2cc287b513102e15fc47ddd60c51171d (patch)
treef6ba68d0b063ba5a4148ee815232c6ba05f59c7d /builder
parentcc2d166cfd6185059c729173f33db13eeab00695 (diff)
downloaddocker-ed033adb2cc287b513102e15fc47ddd60c51171d.tar.gz
Builder: Check remote when local img platform doesn't match
This fixes an issue where if a build requests an image that already exists in Docker's image store but does not match the specified build platform, instead of building using the wrong platform go ahead and check the remote for the correct platform. Steps to reproduce issue: ```terminal $ docker pull --platform=amd64 debian:buster <output supressed> $ cat Dockerfile FROM debian:buster RUN echo hello $ docker build --platform=armhf -< Dockerfile <output supressed> ``` Without this fix, the build invokcation will build using the amd64 image since it is already tagged locally, but this is clearly not what we want. With the fix the local image is not used and instead we pull the correct image. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Diffstat (limited to 'builder')
-rw-r--r--builder/builder-next/adapters/containerimage/pull.go29
1 files changed, 23 insertions, 6 deletions
diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go
index a7e25d4ee0..589e0c4b69 100644
--- a/builder/builder-next/adapters/containerimage/pull.go
+++ b/builder/builder-next/adapters/containerimage/pull.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "path"
"runtime"
"sync"
"sync/atomic"
@@ -41,6 +42,7 @@ import (
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/time/rate"
)
@@ -114,7 +116,7 @@ func (is *imageSource) getCredentialsFromSession(ctx context.Context, sm *sessio
}
}
-func (is *imageSource) resolveLocal(refStr string) ([]byte, error) {
+func (is *imageSource) resolveLocal(refStr string) (*image.Image, error) {
ref, err := distreference.ParseNormalizedNamed(refStr)
if err != nil {
return nil, err
@@ -127,7 +129,7 @@ func (is *imageSource) resolveLocal(refStr string) ([]byte, error) {
if err != nil {
return nil, err
}
- return img.RawJSON(), nil
+ return img, nil
}
func (is *imageSource) resolveRemote(ctx context.Context, ref string, platform *ocispec.Platform, sm *session.Manager) (digest.Digest, []byte, error) {
@@ -174,9 +176,16 @@ func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, opt l
// default == prefer local, but in the future could be smarter
fallthrough
case source.ResolveModePreferLocal:
- dt, err := is.resolveLocal(ref)
+ img, err := is.resolveLocal(ref)
if err == nil {
- return "", dt, err
+ if img.Architecture != opt.Platform.Architecture || img.Variant != opt.Platform.Variant || img.OS != opt.Platform.OS {
+ logrus.WithField("ref", ref).Debugf("Requested build platform %s does not match local image platform %s, checking remote",
+ path.Join(opt.Platform.OS, opt.Platform.Architecture, opt.Platform.Variant),
+ path.Join(img.OS, img.Architecture, img.Variant),
+ )
+ } else {
+ return "", img.RawJSON(), err
+ }
}
// fallback to remote
return is.resolveRemote(ctx, ref, opt.Platform, sm)
@@ -261,9 +270,17 @@ func (p *puller) resolveLocal() {
}
if p.src.ResolveMode == source.ResolveModeDefault || p.src.ResolveMode == source.ResolveModePreferLocal {
- dt, err := p.is.resolveLocal(p.src.Reference.String())
+ ref := p.src.Reference.String()
+ img, err := p.is.resolveLocal(ref)
if err == nil {
- p.config = dt
+ if img.Architecture != p.platform.Architecture || img.Variant != p.platform.Variant || img.OS != p.platform.OS {
+ logrus.WithField("ref", ref).Debugf("Requested build platform %s does not match local image platform %s, not resolving",
+ path.Join(p.platform.OS, p.platform.Architecture, p.platform.Variant),
+ path.Join(img.OS, img.Architecture, img.Variant),
+ )
+ } else {
+ p.config = img.RawJSON()
+ }
}
}
})