builder: implement PullParent option with buildkit
Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
parent
b6242da4ee
commit
7c1c8f1fe2
2 changed files with 61 additions and 15 deletions
|
@ -42,8 +42,6 @@ import (
|
|||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
const preferLocal = true // FIXME: make this optional from the op
|
||||
|
||||
// SourceOpt is options for creating the image source
|
||||
type SourceOpt struct {
|
||||
SessionManager *session.Manager
|
||||
|
@ -114,32 +112,61 @@ func (is *imageSource) resolveLocal(refStr string) ([]byte, error) {
|
|||
return img.RawJSON(), nil
|
||||
}
|
||||
|
||||
func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, opt gw.ResolveImageConfigOpt) (digest.Digest, []byte, error) {
|
||||
if preferLocal {
|
||||
dt, err := is.resolveLocal(ref)
|
||||
if err == nil {
|
||||
return "", dt, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (is *imageSource) resolveRemote(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) {
|
||||
type t struct {
|
||||
dgst digest.Digest
|
||||
dt []byte
|
||||
}
|
||||
res, err := is.g.Do(ctx, ref, func(ctx context.Context) (interface{}, error) {
|
||||
dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, opt.Platform)
|
||||
dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &t{dgst: dgst, dt: dt}, nil
|
||||
})
|
||||
var typed *t
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
typed := res.(*t)
|
||||
typed = res.(*t)
|
||||
return typed.dgst, typed.dt, nil
|
||||
}
|
||||
|
||||
func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, opt gw.ResolveImageConfigOpt) (digest.Digest, []byte, error) {
|
||||
resolveMode, err := source.ParseImageResolveMode(opt.ResolveMode)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
switch resolveMode {
|
||||
case source.ResolveModeForcePull:
|
||||
dgst, dt, err := is.resolveRemote(ctx, ref, opt.Platform)
|
||||
// TODO: pull should fallback to local in case of failure to allow offline behavior
|
||||
// the fallback doesn't work currently
|
||||
return dgst, dt, err
|
||||
/*
|
||||
if err == nil {
|
||||
return dgst, dt, err
|
||||
}
|
||||
// fallback to local
|
||||
dt, err = is.resolveLocal(ref)
|
||||
return "", dt, err
|
||||
*/
|
||||
|
||||
case source.ResolveModeDefault:
|
||||
// default == prefer local, but in the future could be smarter
|
||||
fallthrough
|
||||
case source.ResolveModePreferLocal:
|
||||
dt, err := is.resolveLocal(ref)
|
||||
if err == nil {
|
||||
return "", dt, err
|
||||
}
|
||||
// fallback to remote
|
||||
return is.resolveRemote(ctx, ref, opt.Platform)
|
||||
}
|
||||
// should never happen
|
||||
return "", nil, fmt.Errorf("builder cannot resolve image %s: invalid mode %q", ref, opt.ResolveMode)
|
||||
}
|
||||
|
||||
func (is *imageSource) Resolve(ctx context.Context, id source.Identifier) (source.SourceInstance, error) {
|
||||
imageIdentifier, ok := id.(*source.ImageIdentifier)
|
||||
if !ok {
|
||||
|
@ -213,7 +240,7 @@ func (p *puller) resolveLocal() {
|
|||
}
|
||||
}
|
||||
|
||||
if preferLocal {
|
||||
if p.src.ResolveMode == source.ResolveModeDefault || p.src.ResolveMode == source.ResolveModePreferLocal {
|
||||
dt, err := p.is.resolveLocal(p.src.Reference.String())
|
||||
if err == nil {
|
||||
p.config = dt
|
||||
|
@ -257,8 +284,7 @@ func (p *puller) resolve(ctx context.Context) error {
|
|||
resolveProgressDone(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, dt, err := p.is.ResolveImageConfig(ctx, ref.String(), gw.ResolveImageConfigOpt{Platform: &p.platform})
|
||||
_, dt, err := p.is.ResolveImageConfig(ctx, ref.String(), gw.ResolveImageConfigOpt{Platform: &p.platform, ResolveMode: resolveModeToString(p.src.ResolveMode)})
|
||||
if err != nil {
|
||||
p.resolveErr = err
|
||||
resolveProgressDone(err)
|
||||
|
@ -732,3 +758,17 @@ func cacheKeyFromConfig(dt []byte) digest.Digest {
|
|||
}
|
||||
return identity.ChainID(img.RootFS.DiffIDs)
|
||||
}
|
||||
|
||||
// resolveModeToString is the equivalent of github.com/moby/buildkit/solver/llb.ResolveMode.String()
|
||||
// FIXME: add String method on source.ResolveMode
|
||||
func resolveModeToString(rm source.ResolveMode) string {
|
||||
switch rm {
|
||||
case source.ResolveModeDefault:
|
||||
return "default"
|
||||
case source.ResolveModeForcePull:
|
||||
return "pull"
|
||||
case source.ResolveModePreferLocal:
|
||||
return "local"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -209,6 +209,12 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.
|
|||
frontendAttrs["no-cache"] = ""
|
||||
}
|
||||
|
||||
if opt.Options.PullParent {
|
||||
frontendAttrs["image-resolve-mode"] = "pull"
|
||||
} else {
|
||||
frontendAttrs["image-resolve-mode"] = "default"
|
||||
}
|
||||
|
||||
if opt.Options.Platform != "" {
|
||||
// same as in newBuilder in builder/dockerfile.builder.go
|
||||
// TODO: remove once opt.Options.Platform is of type specs.Platform
|
||||
|
|
Loading…
Reference in a new issue