Merge pull request #464 from tonistiigi/image-platform
platform support for image and dockerfiledocker-18.09
commit
1b34bd1e31
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/moby/buildkit/util/contentutil"
|
||||
"github.com/moby/buildkit/util/imageutil"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
var defaultImageMetaResolver llb.ImageMetaResolver
|
||||
|
@ -22,12 +23,12 @@ var WithDefault = llb.ImageOptionFunc(func(ii *llb.ImageInfo) {
|
|||
})
|
||||
|
||||
type imageMetaResolverOpts struct {
|
||||
platform string
|
||||
platform *specs.Platform
|
||||
}
|
||||
|
||||
type ImageMetaResolverOpt func(o *imageMetaResolverOpts)
|
||||
|
||||
func WithPlatform(p string) ImageMetaResolverOpt {
|
||||
func WithDefaultPlatform(p *specs.Platform) ImageMetaResolverOpt {
|
||||
return func(o *imageMetaResolverOpts) {
|
||||
o.platform = p
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ func Default() llb.ImageMetaResolver {
|
|||
type imageMetaResolver struct {
|
||||
resolver remotes.Resolver
|
||||
buffer contentutil.Buffer
|
||||
platform string
|
||||
platform *specs.Platform
|
||||
locker *locker.Locker
|
||||
cache map[string]resolveResult
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ type resolveResult struct {
|
|||
dgst digest.Digest
|
||||
}
|
||||
|
||||
func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
||||
func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) {
|
||||
imr.locker.Lock(ref)
|
||||
defer imr.locker.Unlock(ref)
|
||||
|
||||
|
@ -77,7 +78,11 @@ func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string
|
|||
return res.dgst, res.config, nil
|
||||
}
|
||||
|
||||
dgst, config, err := imageutil.Config(ctx, ref, imr.resolver, imr.buffer, imr.platform)
|
||||
if platform == nil {
|
||||
platform = imr.platform
|
||||
}
|
||||
|
||||
dgst, config, err := imageutil.Config(ctx, ref, imr.resolver, imr.buffer, platform)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
func WithMetaResolver(mr ImageMetaResolver) ImageOption {
|
||||
|
@ -13,5 +14,5 @@ func WithMetaResolver(mr ImageMetaResolver) ImageOption {
|
|||
}
|
||||
|
||||
type ImageMetaResolver interface {
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error)
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ func Image(ref string, opts ...ImageOption) State {
|
|||
src.err = err
|
||||
}
|
||||
if info.metaResolver != nil {
|
||||
_, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref)
|
||||
_, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref, info.Constraints.Platform)
|
||||
if err != nil {
|
||||
src.err = err
|
||||
} else {
|
||||
|
|
|
@ -36,8 +36,9 @@ func NewState(o Output) State {
|
|||
}
|
||||
|
||||
type State struct {
|
||||
out Output
|
||||
ctx context.Context
|
||||
out Output
|
||||
ctx context.Context
|
||||
opts []ConstraintsOpt
|
||||
}
|
||||
|
||||
func (s State) ensurePlatform() State {
|
||||
|
@ -62,6 +63,11 @@ func (s State) Value(k interface{}) interface{} {
|
|||
return s.ctx.Value(k)
|
||||
}
|
||||
|
||||
func (s State) SetMarhalDefaults(co ...ConstraintsOpt) State {
|
||||
s.opts = co
|
||||
return s
|
||||
}
|
||||
|
||||
func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) {
|
||||
def := &Definition{
|
||||
Metadata: make(map[digest.Digest]pb.OpMetadata, 0),
|
||||
|
@ -74,7 +80,7 @@ func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) {
|
|||
c := &Constraints{
|
||||
Platform: &defaultPlatform,
|
||||
}
|
||||
for _, o := range co {
|
||||
for _, o := range append(s.opts, co...) {
|
||||
o.SetConstraintsOption(c)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,12 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/docker/builder/dockerignore"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
|
||||
"github.com/moby/buildkit/frontend/gateway/client"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
@ -28,6 +30,7 @@ const (
|
|||
buildArgPrefix = "build-arg:"
|
||||
labelPrefix = "label:"
|
||||
keyNoCache = "no-cache"
|
||||
keyTargetPlatform = "platform"
|
||||
)
|
||||
|
||||
var httpPrefix = regexp.MustCompile("^https?://")
|
||||
|
@ -36,6 +39,17 @@ var gitUrlPathWithFragmentSuffix = regexp.MustCompile("\\.git(?:#.+)?$")
|
|||
func Build(ctx context.Context, c client.Client) error {
|
||||
opts := c.Opts()
|
||||
|
||||
// TODO: read buildPlatforms from workers
|
||||
buildPlatforms := []specs.Platform{platforms.DefaultSpec()}
|
||||
targetPlatform := platforms.DefaultSpec()
|
||||
if v := opts[keyTargetPlatform]; v != "" {
|
||||
var err error
|
||||
targetPlatform, err = platforms.Parse(v)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse target platform %s", v)
|
||||
}
|
||||
}
|
||||
|
||||
filename := opts[keyFilename]
|
||||
if filename == "" {
|
||||
filename = defaultDockerfileName
|
||||
|
@ -166,14 +180,16 @@ func Build(ctx context.Context, c client.Client) error {
|
|||
}
|
||||
|
||||
st, img, err := dockerfile2llb.Dockerfile2LLB(ctx, dtDockerfile, dockerfile2llb.ConvertOpt{
|
||||
Target: opts[keyTarget],
|
||||
MetaResolver: c,
|
||||
BuildArgs: filter(opts, buildArgPrefix),
|
||||
Labels: filter(opts, labelPrefix),
|
||||
SessionID: c.SessionID(),
|
||||
BuildContext: buildContext,
|
||||
Excludes: excludes,
|
||||
IgnoreCache: ignoreCache,
|
||||
Target: opts[keyTarget],
|
||||
MetaResolver: c,
|
||||
BuildArgs: filter(opts, buildArgPrefix),
|
||||
Labels: filter(opts, labelPrefix),
|
||||
SessionID: c.SessionID(),
|
||||
BuildContext: buildContext,
|
||||
Excludes: excludes,
|
||||
IgnoreCache: ignoreCache,
|
||||
TargetPlatform: &targetPlatform,
|
||||
BuildPlatforms: buildPlatforms,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/docker/go-connections/nat"
|
||||
|
@ -20,7 +21,7 @@ import (
|
|||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/shell"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
@ -46,6 +47,8 @@ type ConvertOpt struct {
|
|||
IgnoreCache []string
|
||||
// CacheIDNamespace scopes the IDs for different cache mounts
|
||||
CacheIDNamespace string
|
||||
TargetPlatform *specs.Platform
|
||||
BuildPlatforms []specs.Platform
|
||||
}
|
||||
|
||||
func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, *Image, error) {
|
||||
|
@ -53,6 +56,18 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
return nil, nil, errors.Errorf("the Dockerfile cannot be empty")
|
||||
}
|
||||
|
||||
if opt.TargetPlatform != nil && opt.BuildPlatforms == nil {
|
||||
opt.BuildPlatforms = []specs.Platform{*opt.TargetPlatform}
|
||||
}
|
||||
if len(opt.BuildPlatforms) == 0 {
|
||||
opt.BuildPlatforms = []specs.Platform{platforms.DefaultSpec()}
|
||||
}
|
||||
implicitTargetPlatform := false
|
||||
if opt.TargetPlatform == nil {
|
||||
implicitTargetPlatform = true
|
||||
opt.TargetPlatform = &opt.BuildPlatforms[0]
|
||||
}
|
||||
|
||||
dockerfile, err := parser.Parse(bytes.NewReader(dt))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -92,6 +107,20 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
deps: make(map[*dispatchState]struct{}),
|
||||
ctxPaths: make(map[string]struct{}),
|
||||
}
|
||||
|
||||
if v := st.Platform; v != "" {
|
||||
v, err := shlex.ProcessWord(v, toEnvList(metaArgs, nil))
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "failed to process arguments for platform %s", v)
|
||||
}
|
||||
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "failed to parse platform %s", v)
|
||||
}
|
||||
ds.platform = &p
|
||||
}
|
||||
|
||||
if d, ok := dispatchStatesByName[st.BaseName]; ok {
|
||||
ds.base = d
|
||||
}
|
||||
|
@ -150,7 +179,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
if d.base == nil {
|
||||
if d.stage.BaseName == emptyImageName {
|
||||
d.state = llb.Scratch()
|
||||
d.image = emptyImage()
|
||||
d.image = emptyImage(*opt.TargetPlatform)
|
||||
continue
|
||||
}
|
||||
func(i int, d *dispatchState) {
|
||||
|
@ -159,16 +188,25 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
platform := d.platform
|
||||
if platform == nil {
|
||||
platform = opt.TargetPlatform
|
||||
}
|
||||
d.stage.BaseName = reference.TagNameOnly(ref).String()
|
||||
var isScratch bool
|
||||
if metaResolver != nil && reachable {
|
||||
dgst, dt, err := metaResolver.ResolveImageConfig(ctx, d.stage.BaseName)
|
||||
dgst, dt, err := metaResolver.ResolveImageConfig(ctx, d.stage.BaseName, platform)
|
||||
if err == nil { // handle the error while builder is actually running
|
||||
var img Image
|
||||
if err := json.Unmarshal(dt, &img); err != nil {
|
||||
return err
|
||||
}
|
||||
img.Created = nil
|
||||
// if there is no explicit target platform, try to match based on image config
|
||||
if d.platform == nil && implicitTargetPlatform {
|
||||
p := autoDetectPlatform(img, *platform, opt.BuildPlatforms)
|
||||
platform = &p
|
||||
}
|
||||
d.image = img
|
||||
if dgst != "" {
|
||||
ref, err = reference.WithDigest(ref, dgst)
|
||||
|
@ -186,7 +224,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
if isScratch {
|
||||
d.state = llb.Scratch()
|
||||
} else {
|
||||
d.state = llb.Image(d.stage.BaseName, dfCmd(d.stage.SourceCode))
|
||||
d.state = llb.Image(d.stage.BaseName, dfCmd(d.stage.SourceCode), llb.Platform(*platform))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
@ -242,6 +280,8 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
buildContext: llb.NewState(buildContext),
|
||||
proxyEnv: proxyEnv,
|
||||
cacheIDNamespace: opt.CacheIDNamespace,
|
||||
buildPlatforms: opt.BuildPlatforms,
|
||||
targetPlatform: *opt.TargetPlatform,
|
||||
}
|
||||
|
||||
if err = dispatchOnBuild(d, d.image.Config.OnBuild, opt); err != nil {
|
||||
|
@ -280,7 +320,14 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
}
|
||||
buildContext.Output = bc.Output()
|
||||
|
||||
return &target.state, &target.image, nil
|
||||
st := target.state.SetMarhalDefaults(llb.Platform(*opt.TargetPlatform))
|
||||
|
||||
if !implicitTargetPlatform {
|
||||
target.image.OS = opt.TargetPlatform.OS
|
||||
target.image.Architecture = opt.TargetPlatform.Architecture
|
||||
}
|
||||
|
||||
return &st, &target.image, nil
|
||||
}
|
||||
|
||||
func toCommand(ic instructions.Command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) (command, error) {
|
||||
|
@ -325,6 +372,8 @@ type dispatchOpt struct {
|
|||
buildContext llb.State
|
||||
proxyEnv *llb.ProxyEnv
|
||||
cacheIDNamespace string
|
||||
targetPlatform specs.Platform
|
||||
buildPlatforms []specs.Platform
|
||||
}
|
||||
|
||||
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
|
||||
|
@ -348,7 +397,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
|
|||
case *instructions.WorkdirCommand:
|
||||
err = dispatchWorkdir(d, c, true)
|
||||
case *instructions.AddCommand:
|
||||
err = dispatchCopy(d, c.SourcesAndDest, opt.buildContext, true, c, "")
|
||||
err = dispatchCopy(d, c.SourcesAndDest, opt.buildContext, true, c, "", opt)
|
||||
if err == nil {
|
||||
for _, src := range c.Sources() {
|
||||
d.ctxPaths[path.Join("/", filepath.ToSlash(src))] = struct{}{}
|
||||
|
@ -381,7 +430,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
|
|||
if len(cmd.sources) != 0 {
|
||||
l = cmd.sources[0].state
|
||||
}
|
||||
err = dispatchCopy(d, c.SourcesAndDest, l, false, c, c.Chown)
|
||||
err = dispatchCopy(d, c.SourcesAndDest, l, false, c, c.Chown, opt)
|
||||
if err == nil && len(cmd.sources) == 0 {
|
||||
for _, src := range c.Sources() {
|
||||
d.ctxPaths[path.Join("/", filepath.ToSlash(src))] = struct{}{}
|
||||
|
@ -395,6 +444,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
|
|||
type dispatchState struct {
|
||||
state llb.State
|
||||
image Image
|
||||
platform *specs.Platform
|
||||
stage instructions.Stage
|
||||
base *dispatchState
|
||||
deps map[*dispatchState]struct{}
|
||||
|
@ -490,9 +540,9 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo
|
|||
return nil
|
||||
}
|
||||
|
||||
func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool, cmdToPrint interface{}, chown string) error {
|
||||
func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool, cmdToPrint interface{}, chown string, opt dispatchOpt) error {
|
||||
// TODO: this should use CopyOp instead. Current implementation is inefficient
|
||||
img := llb.Image(CopyImage)
|
||||
img := llb.Image(CopyImage, llb.Platform(opt.buildPlatforms[0]))
|
||||
|
||||
dest := path.Join(".", pathRelativeToWorkingDir(d.state, c.Dest()))
|
||||
if c.Dest() == "." || c.Dest()[len(c.Dest())-1] == filepath.Separator {
|
||||
|
@ -558,12 +608,12 @@ func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState l
|
|||
args = append(args[:1], append([]string{"--unpack"}, args[1:]...)...)
|
||||
}
|
||||
|
||||
opt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint)}
|
||||
runOpt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint)}
|
||||
if d.ignoreCache {
|
||||
opt = append(opt, llb.IgnoreCache)
|
||||
runOpt = append(runOpt, llb.IgnoreCache)
|
||||
}
|
||||
run := img.Run(append(opt, mounts...)...)
|
||||
d.state = run.AddMount("/dest", d.state)
|
||||
run := img.Run(append(runOpt, mounts...)...)
|
||||
d.state = run.AddMount("/dest", d.state).Platform(opt.targetPlatform)
|
||||
|
||||
return commitToHistory(&d.image, commitMessage.String(), true, &d.state)
|
||||
}
|
||||
|
@ -802,7 +852,7 @@ func commitToHistory(img *Image, msg string, withLayer bool, st *llb.State) erro
|
|||
msg += " # buildkit"
|
||||
}
|
||||
|
||||
img.History = append(img.History, ocispec.History{
|
||||
img.History = append(img.History, specs.History{
|
||||
CreatedBy: msg,
|
||||
Comment: historyComment,
|
||||
EmptyLayer: !withLayer,
|
||||
|
@ -934,3 +984,17 @@ func withShell(img Image, args []string) []string {
|
|||
}
|
||||
return append(shell, strings.Join(args, " "))
|
||||
}
|
||||
|
||||
func autoDetectPlatform(img Image, target specs.Platform, supported []specs.Platform) specs.Platform {
|
||||
os := img.OS
|
||||
arch := img.Architecture
|
||||
if target.OS == os && target.Architecture == arch {
|
||||
return target
|
||||
}
|
||||
for _, p := range supported {
|
||||
if p.OS == os && p.Architecture == arch {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package dockerfile2llb
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/moby/buildkit/util/system"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
|
||||
|
@ -31,7 +30,7 @@ type HealthConfig struct {
|
|||
}
|
||||
|
||||
type ImageConfig struct {
|
||||
ocispec.ImageConfig
|
||||
specs.ImageConfig
|
||||
|
||||
Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy
|
||||
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific)
|
||||
|
@ -46,7 +45,7 @@ type ImageConfig struct {
|
|||
// Image is the JSON structure which describes some basic information about the image.
|
||||
// This provides the `application/vnd.oci.image.config.v1+json` mediatype when marshalled to JSON.
|
||||
type Image struct {
|
||||
ocispec.Image
|
||||
specs.Image
|
||||
|
||||
// Config defines the execution parameters which should be used as a base when running a container using the image.
|
||||
Config ImageConfig `json:"config,omitempty"`
|
||||
|
@ -61,11 +60,11 @@ func clone(src Image) Image {
|
|||
return img
|
||||
}
|
||||
|
||||
func emptyImage() Image {
|
||||
func emptyImage(platform specs.Platform) Image {
|
||||
img := Image{
|
||||
Image: ocispec.Image{
|
||||
Architecture: runtime.GOARCH,
|
||||
OS: runtime.GOOS,
|
||||
Image: specs.Image{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
},
|
||||
}
|
||||
img.RootFS.Type = "layers"
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// KeyValuePair represent an arbitrary named value (useful in slice instead of map[string] string to preserve ordering)
|
||||
|
@ -382,7 +381,7 @@ type Stage struct {
|
|||
Commands []Command
|
||||
BaseName string
|
||||
SourceCode string
|
||||
Platform specs.Platform
|
||||
Platform string
|
||||
}
|
||||
|
||||
// AddCommand to the stage
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/command"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -279,13 +278,14 @@ func parseFrom(req parseRequest) (*Stage, error) {
|
|||
if err := req.flags.Parse(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
code := strings.TrimSpace(req.original)
|
||||
return &Stage{
|
||||
BaseName: req.args[0],
|
||||
Name: stageName,
|
||||
SourceCode: code,
|
||||
Commands: []Command{},
|
||||
Platform: *system.ParsePlatform(flPlatform.Value),
|
||||
Platform: flPlatform.Value,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/moby/buildkit/solver"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type Frontend interface {
|
||||
|
@ -17,7 +18,7 @@ type Frontend interface {
|
|||
|
||||
type FrontendLLBBridge interface {
|
||||
Solve(ctx context.Context, req SolveRequest) (solver.CachedResult, map[string][]byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error)
|
||||
Exec(ctx context.Context, meta executor.Meta, rootfs cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@ import (
|
|||
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// TODO: make this take same options as LLBBridge. Add Return()
|
||||
type Client interface {
|
||||
Solve(ctx context.Context, req SolveRequest, exporterAttr map[string][]byte, final bool) (Reference, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error)
|
||||
Opts() map[string]string
|
||||
SessionID() string
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/moby/buildkit/solver"
|
||||
"github.com/moby/buildkit/util/tracing"
|
||||
"github.com/moby/buildkit/worker"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/http2"
|
||||
|
@ -63,7 +63,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
|||
sid := session.FromContext(ctx)
|
||||
|
||||
_, isDevel := opts[keyDevel]
|
||||
var img ocispec.Image
|
||||
var img specs.Image
|
||||
var rootFS cache.ImmutableRef
|
||||
var readonly bool // TODO: try to switch to read-only by default.
|
||||
|
||||
|
@ -95,7 +95,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
dgst, config, err := llbBridge.ResolveImageConfig(ctx, reference.TagNameOnly(sourceRef).String())
|
||||
dgst, config, err := llbBridge.ResolveImageConfig(ctx, reference.TagNameOnly(sourceRef).String(), nil) // TODO:
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -262,7 +262,17 @@ type llbBridgeForwarder struct {
|
|||
|
||||
func (lbf *llbBridgeForwarder) ResolveImageConfig(ctx context.Context, req *pb.ResolveImageConfigRequest) (*pb.ResolveImageConfigResponse, error) {
|
||||
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx)
|
||||
dgst, dt, err := lbf.llbBridge.ResolveImageConfig(ctx, req.Ref)
|
||||
var platform *specs.Platform
|
||||
if p := req.Platform; p != nil {
|
||||
platform = &specs.Platform{
|
||||
OS: p.OS,
|
||||
Architecture: p.Architecture,
|
||||
Variant: p.Variant,
|
||||
OSVersion: p.OSVersion,
|
||||
OSFeatures: p.OSFeatures,
|
||||
}
|
||||
}
|
||||
dgst, dt, err := lbf.llbBridge.ResolveImageConfig(ctx, req.Ref, platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import (
|
|||
|
||||
"github.com/moby/buildkit/frontend/gateway/client"
|
||||
pb "github.com/moby/buildkit/frontend/gateway/pb"
|
||||
opspb "github.com/moby/buildkit/solver/pb"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
@ -63,8 +65,18 @@ func (c *grpcClient) Solve(ctx context.Context, creq client.SolveRequest, export
|
|||
return &reference{id: resp.Ref, c: c}, nil
|
||||
}
|
||||
|
||||
func (c *grpcClient) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
||||
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{Ref: ref})
|
||||
func (c *grpcClient) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) {
|
||||
var p *opspb.Platform
|
||||
if platform != nil {
|
||||
p = &opspb.Platform{
|
||||
OS: platform.OS,
|
||||
Architecture: platform.Architecture,
|
||||
Variant: platform.Variant,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
}
|
||||
}
|
||||
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{Ref: ref, Platform: p})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
|
|
@ -45,7 +45,8 @@ var _ = math.Inf
|
|||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type ResolveImageConfigRequest struct {
|
||||
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
|
||||
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
|
||||
Platform *pb.Platform `protobuf:"bytes,2,opt,name=Platform" json:"Platform,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ResolveImageConfigRequest) Reset() { *m = ResolveImageConfigRequest{} }
|
||||
|
@ -60,6 +61,13 @@ func (m *ResolveImageConfigRequest) GetRef() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *ResolveImageConfigRequest) GetPlatform() *pb.Platform {
|
||||
if m != nil {
|
||||
return m.Platform
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ResolveImageConfigResponse struct {
|
||||
Digest github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=Digest,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"Digest"`
|
||||
Config []byte `protobuf:"bytes,2,opt,name=Config,proto3" json:"Config,omitempty"`
|
||||
|
@ -451,6 +459,16 @@ func (m *ResolveImageConfigRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
i = encodeVarintGateway(dAtA, i, uint64(len(m.Ref)))
|
||||
i += copy(dAtA[i:], m.Ref)
|
||||
}
|
||||
if m.Platform != nil {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGateway(dAtA, i, uint64(m.Platform.Size()))
|
||||
n1, err := m.Platform.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -503,11 +521,11 @@ func (m *SolveRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGateway(dAtA, i, uint64(m.Definition.Size()))
|
||||
n1, err := m.Definition.MarshalTo(dAtA[i:])
|
||||
n2, err := m.Definition.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
i += n2
|
||||
}
|
||||
if len(m.Frontend) > 0 {
|
||||
dAtA[i] = 0x12
|
||||
|
@ -627,11 +645,11 @@ func (m *ReadFileRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
dAtA[i] = 0x1a
|
||||
i++
|
||||
i = encodeVarintGateway(dAtA, i, uint64(m.Range.Size()))
|
||||
n2, err := m.Range.MarshalTo(dAtA[i:])
|
||||
n3, err := m.Range.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n2
|
||||
i += n3
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
@ -740,6 +758,10 @@ func (m *ResolveImageConfigRequest) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovGateway(uint64(l))
|
||||
}
|
||||
if m.Platform != nil {
|
||||
l = m.Platform.Size()
|
||||
n += 1 + l + sovGateway(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -929,6 +951,39 @@ func (m *ResolveImageConfigRequest) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
m.Ref = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGateway
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGateway
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Platform == nil {
|
||||
m.Platform = &pb.Platform{}
|
||||
}
|
||||
if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGateway(dAtA[iNdEx:])
|
||||
|
@ -1998,45 +2053,46 @@ var (
|
|||
func init() { proto.RegisterFile("gateway.proto", fileDescriptorGateway) }
|
||||
|
||||
var fileDescriptorGateway = []byte{
|
||||
// 629 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x40,
|
||||
0x10, 0xad, 0x63, 0x40, 0x64, 0x12, 0x3e, 0xb4, 0xaa, 0x2a, 0xe3, 0x03, 0x44, 0x56, 0x45, 0x2d,
|
||||
0x5a, 0x6c, 0x35, 0x6d, 0x25, 0x44, 0xa5, 0x4a, 0x0d, 0x1f, 0x12, 0x15, 0x12, 0x68, 0x7b, 0xa8,
|
||||
0xc4, 0xcd, 0x4e, 0xc6, 0x66, 0x45, 0xb2, 0xeb, 0xda, 0x1b, 0xda, 0xa8, 0x97, 0xf6, 0xe7, 0xf4,
|
||||
0x9f, 0x70, 0xec, 0x99, 0x03, 0xaa, 0xf8, 0x25, 0x95, 0xd7, 0xeb, 0x60, 0x48, 0x49, 0xe9, 0x6d,
|
||||
0xdf, 0x78, 0xe6, 0xed, 0x9b, 0x79, 0xb3, 0x86, 0x85, 0x38, 0x90, 0xf8, 0x25, 0x18, 0x79, 0x49,
|
||||
0x2a, 0xa4, 0x20, 0x2b, 0x03, 0x11, 0x8e, 0xbc, 0x70, 0xc8, 0xfa, 0xbd, 0x33, 0x26, 0xbd, 0xf3,
|
||||
0x97, 0x5e, 0x94, 0x0a, 0x2e, 0x91, 0xf7, 0xec, 0xcd, 0x98, 0xc9, 0xd3, 0x61, 0xe8, 0x75, 0xc5,
|
||||
0xc0, 0x8f, 0x45, 0x2c, 0x7c, 0x55, 0x11, 0x0e, 0x23, 0x85, 0x14, 0x50, 0xa7, 0x82, 0xc9, 0x7e,
|
||||
0x51, 0x49, 0xcf, 0x49, 0xfd, 0x92, 0xd4, 0xcf, 0x44, 0xff, 0x1c, 0x53, 0x3f, 0x09, 0x7d, 0x91,
|
||||
0x64, 0x45, 0xb6, 0xb3, 0x09, 0x2b, 0x14, 0xd5, 0x87, 0x83, 0x41, 0x10, 0xe3, 0x8e, 0xe0, 0x11,
|
||||
0x8b, 0x29, 0x7e, 0x1e, 0x62, 0x26, 0xc9, 0x32, 0x98, 0x14, 0x23, 0xcb, 0x68, 0x19, 0x6e, 0x9d,
|
||||
0xe6, 0x47, 0xe7, 0xbb, 0x01, 0xf6, 0xdf, 0xf2, 0xb3, 0x44, 0xf0, 0x0c, 0xc9, 0x07, 0x98, 0xdb,
|
||||
0x65, 0x31, 0x66, 0xb2, 0xa8, 0xe9, 0xb4, 0x2f, 0xae, 0xd6, 0x1e, 0x5d, 0x5e, 0xad, 0x6d, 0x54,
|
||||
0x34, 0x89, 0x04, 0x79, 0x57, 0x70, 0x19, 0x30, 0x8e, 0x69, 0xe6, 0xc7, 0x62, 0xb3, 0xa7, 0x4a,
|
||||
0xbc, 0xa2, 0x92, 0x6a, 0x06, 0xf2, 0x04, 0xe6, 0x0a, 0x76, 0xab, 0xd6, 0x32, 0xdc, 0x26, 0xd5,
|
||||
0xc8, 0xb9, 0xac, 0x41, 0xf3, 0x63, 0x2e, 0xa0, 0x54, 0xe9, 0x01, 0xec, 0x62, 0xc4, 0x38, 0x93,
|
||||
0x4c, 0x70, 0x75, 0x71, 0xa3, 0xbd, 0xe8, 0x25, 0xa1, 0x77, 0x13, 0xa5, 0x95, 0x0c, 0x62, 0xc3,
|
||||
0xfc, 0xbe, 0x9e, 0xad, 0xa2, 0xae, 0xd3, 0x31, 0x26, 0x27, 0xd0, 0x28, 0xcf, 0x47, 0x89, 0xb4,
|
||||
0xcc, 0x96, 0xe9, 0x36, 0xda, 0x5b, 0xde, 0xbd, 0xe6, 0x78, 0x55, 0x25, 0x5e, 0xa5, 0x74, 0x8f,
|
||||
0xcb, 0x74, 0x44, 0xab, 0x64, 0xc4, 0x85, 0xa5, 0x83, 0x41, 0x22, 0x52, 0xb9, 0x13, 0x74, 0x4f,
|
||||
0x91, 0x62, 0x94, 0x59, 0x33, 0x2d, 0xd3, 0xad, 0xd3, 0xbb, 0x61, 0xf2, 0x18, 0x66, 0xf7, 0x19,
|
||||
0x0f, 0xfa, 0x16, 0xb4, 0x0c, 0x77, 0x9e, 0x16, 0x80, 0x38, 0xd0, 0xdc, 0xfb, 0x9a, 0x27, 0x62,
|
||||
0xfa, 0x5e, 0xca, 0xd4, 0x6a, 0xa8, 0xb1, 0xdc, 0x8a, 0xd9, 0xef, 0x60, 0xf9, 0xae, 0x88, 0xdc,
|
||||
0xc5, 0x33, 0x1c, 0x95, 0x2e, 0x9e, 0xe1, 0x28, 0xe7, 0x3f, 0x0f, 0xfa, 0x43, 0xd4, 0xed, 0x17,
|
||||
0x60, 0xbb, 0xb6, 0x65, 0x38, 0x7b, 0xb0, 0xa0, 0x3b, 0xd2, 0x8e, 0x4e, 0xac, 0xc0, 0x84, 0x8c,
|
||||
0xda, 0xa4, 0x0c, 0xe7, 0x1b, 0x2c, 0x51, 0x0c, 0x7a, 0xfb, 0xac, 0x8f, 0xf7, 0xee, 0x92, 0xf2,
|
||||
0x81, 0xf5, 0xf1, 0x38, 0x90, 0xa7, 0x63, 0x1f, 0x34, 0x26, 0xdb, 0x30, 0x4b, 0x03, 0x1e, 0xa3,
|
||||
0x65, 0x2a, 0x3b, 0x9f, 0x4e, 0x71, 0x40, 0x5d, 0x92, 0xe7, 0xd2, 0xa2, 0xc4, 0x79, 0x0b, 0xf5,
|
||||
0x71, 0x2c, 0xdf, 0xa2, 0xa3, 0x28, 0xca, 0xb0, 0xd8, 0x48, 0x93, 0x6a, 0x94, 0xc7, 0x0f, 0x91,
|
||||
0xc7, 0xfa, 0x6a, 0x93, 0x6a, 0xe4, 0xac, 0xc3, 0xf2, 0x8d, 0x72, 0x3d, 0x03, 0x02, 0x33, 0xbb,
|
||||
0x81, 0x0c, 0x14, 0x43, 0x93, 0xaa, 0xb3, 0xb3, 0x00, 0x8d, 0x63, 0xc6, 0xcb, 0x97, 0xe2, 0x2c,
|
||||
0x42, 0xf3, 0x58, 0xf0, 0xf1, 0x43, 0x68, 0xff, 0x34, 0xa1, 0x7e, 0x78, 0xd8, 0xe9, 0xa4, 0xac,
|
||||
0x17, 0x23, 0xf9, 0x61, 0x00, 0x99, 0x7c, 0x35, 0xe4, 0xf5, 0x94, 0xae, 0xee, 0x7d, 0x94, 0xf6,
|
||||
0x9b, 0xff, 0xac, 0xd2, 0x4d, 0x9c, 0xc0, 0xac, 0x72, 0x96, 0x3c, 0x7b, 0xe0, 0x36, 0xdb, 0xee,
|
||||
0xbf, 0x13, 0x35, 0x77, 0x17, 0xe6, 0xcb, 0xa1, 0x91, 0x8d, 0xa9, 0xf2, 0x6e, 0xed, 0x84, 0xfd,
|
||||
0xfc, 0x41, 0xb9, 0xfa, 0x92, 0x4f, 0x30, 0x93, 0x4f, 0x9c, 0xac, 0x4f, 0x29, 0xaa, 0x58, 0x62,
|
||||
0x4f, 0xeb, 0xb3, 0xea, 0x55, 0xa7, 0x79, 0x71, 0xbd, 0x6a, 0xfc, 0xba, 0x5e, 0x35, 0x7e, 0x5f,
|
||||
0xaf, 0x1a, 0xe1, 0x9c, 0xfa, 0x2f, 0xbe, 0xfa, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x21, 0xd1,
|
||||
0x98, 0xa0, 0x05, 0x00, 0x00,
|
||||
// 652 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x4a,
|
||||
0x14, 0x7d, 0x8e, 0x01, 0x25, 0x37, 0xe6, 0x43, 0xa3, 0xa7, 0x27, 0xe3, 0x05, 0x44, 0xd6, 0x13,
|
||||
0xcf, 0xe2, 0x15, 0x5b, 0x4d, 0x5b, 0x09, 0x51, 0xa9, 0x52, 0xc3, 0x87, 0x44, 0x85, 0x44, 0x34,
|
||||
0x5d, 0x20, 0xb1, 0x1b, 0x27, 0x63, 0x33, 0xc2, 0x99, 0x71, 0xed, 0x09, 0x6d, 0xd4, 0x4d, 0xfb,
|
||||
0x73, 0xfa, 0x4f, 0x58, 0x76, 0xcd, 0x02, 0x55, 0xfc, 0x92, 0xca, 0xe3, 0x71, 0x30, 0x50, 0x52,
|
||||
0xba, 0x9b, 0x73, 0x7d, 0xef, 0x99, 0x73, 0xe7, 0xdc, 0x6b, 0x58, 0x8c, 0x89, 0xa4, 0x1f, 0xc9,
|
||||
0xc4, 0x4f, 0x33, 0x21, 0x05, 0x5a, 0x1d, 0x89, 0x70, 0xe2, 0x87, 0x63, 0x96, 0x0c, 0xcf, 0x99,
|
||||
0xf4, 0x2f, 0x9e, 0xfb, 0x51, 0x26, 0xb8, 0xa4, 0x7c, 0xe8, 0x6c, 0xc5, 0x4c, 0x9e, 0x8d, 0x43,
|
||||
0x7f, 0x20, 0x46, 0x41, 0x2c, 0x62, 0x11, 0xa8, 0x8a, 0x70, 0x1c, 0x29, 0xa4, 0x80, 0x3a, 0x95,
|
||||
0x4c, 0xce, 0xb3, 0x5a, 0x7a, 0x41, 0x1a, 0x54, 0xa4, 0x41, 0x2e, 0x92, 0x0b, 0x9a, 0x05, 0x69,
|
||||
0x18, 0x88, 0x34, 0x2f, 0xb3, 0xdd, 0x13, 0x58, 0xc5, 0x54, 0x7d, 0x38, 0x1c, 0x91, 0x98, 0xee,
|
||||
0x0a, 0x1e, 0xb1, 0x18, 0xd3, 0x0f, 0x63, 0x9a, 0x4b, 0xb4, 0x02, 0x26, 0xa6, 0x91, 0x6d, 0x74,
|
||||
0x0c, 0xaf, 0x85, 0x8b, 0x23, 0xf2, 0xa0, 0xd9, 0x4f, 0x88, 0x8c, 0x44, 0x36, 0xb2, 0x1b, 0x1d,
|
||||
0xc3, 0x6b, 0x77, 0x2d, 0x3f, 0x0d, 0xfd, 0x2a, 0x86, 0xa7, 0x5f, 0xdd, 0x2f, 0x06, 0x38, 0xbf,
|
||||
0x62, 0xce, 0x53, 0xc1, 0x73, 0x8a, 0xde, 0xc1, 0xc2, 0x1e, 0x8b, 0x69, 0x2e, 0x4b, 0xf6, 0x5e,
|
||||
0xf7, 0xf2, 0x7a, 0xfd, 0xaf, 0xab, 0xeb, 0xf5, 0xcd, 0x9a, 0x7a, 0x91, 0x52, 0x3e, 0x10, 0x5c,
|
||||
0x12, 0xc6, 0x69, 0x96, 0x07, 0xb1, 0xd8, 0x1a, 0xaa, 0x12, 0xbf, 0xac, 0xc4, 0x9a, 0x01, 0xfd,
|
||||
0x03, 0x0b, 0x25, 0xbb, 0x92, 0x64, 0x61, 0x8d, 0xdc, 0xab, 0x06, 0x58, 0xef, 0x0b, 0x01, 0x55,
|
||||
0x3f, 0x3e, 0xc0, 0x1e, 0x8d, 0x18, 0x67, 0x92, 0x09, 0xae, 0x2e, 0x6e, 0x77, 0x97, 0x0a, 0xfd,
|
||||
0xb7, 0x51, 0x5c, 0xcb, 0x40, 0x0e, 0x34, 0x0f, 0xb4, 0x0b, 0x8a, 0xba, 0x85, 0xa7, 0x18, 0x9d,
|
||||
0x42, 0xbb, 0x3a, 0x1f, 0xa7, 0xd2, 0x36, 0x3b, 0xa6, 0xd7, 0xee, 0x6e, 0xfb, 0x8f, 0xda, 0xe8,
|
||||
0xd7, 0x95, 0xf8, 0xb5, 0xd2, 0x7d, 0x2e, 0xb3, 0x09, 0xae, 0x93, 0x21, 0x0f, 0x96, 0x0f, 0x47,
|
||||
0xa9, 0xc8, 0xe4, 0x2e, 0x19, 0x9c, 0x51, 0x4c, 0xa3, 0xdc, 0x9e, 0xeb, 0x98, 0x5e, 0x0b, 0xdf,
|
||||
0x0f, 0xa3, 0xbf, 0x61, 0xfe, 0x80, 0x71, 0x92, 0xd8, 0xd0, 0x31, 0xbc, 0x26, 0x2e, 0x01, 0x72,
|
||||
0xc1, 0xda, 0xff, 0x54, 0x24, 0xd2, 0xec, 0xad, 0x94, 0x99, 0xdd, 0x56, 0xcf, 0x72, 0x27, 0xe6,
|
||||
0xbc, 0x81, 0x95, 0xfb, 0x22, 0x0a, 0xbf, 0xcf, 0xe9, 0xa4, 0xf2, 0xfb, 0x9c, 0x4e, 0x0a, 0xfe,
|
||||
0x0b, 0x92, 0x8c, 0xa9, 0x6e, 0xbf, 0x04, 0x3b, 0x8d, 0x6d, 0xc3, 0xdd, 0x87, 0x45, 0xdd, 0x91,
|
||||
0x76, 0xf4, 0xe1, 0xb0, 0xdc, 0x97, 0xd1, 0x78, 0x28, 0xc3, 0xfd, 0x0c, 0xcb, 0x98, 0x92, 0xe1,
|
||||
0x01, 0x4b, 0xe8, 0xe3, 0x53, 0x57, 0xf8, 0xc0, 0x12, 0xda, 0x27, 0xf2, 0x6c, 0xea, 0x83, 0xc6,
|
||||
0x68, 0x07, 0xe6, 0x31, 0xe1, 0x31, 0xb5, 0x4d, 0x65, 0xe7, 0xbf, 0x33, 0x1c, 0x50, 0x97, 0x14,
|
||||
0xb9, 0xb8, 0x2c, 0x71, 0x5f, 0x43, 0x6b, 0x1a, 0x2b, 0xa6, 0xe8, 0x38, 0x8a, 0x72, 0x5a, 0x4e,
|
||||
0xa4, 0x89, 0x35, 0x2a, 0xe2, 0x47, 0x94, 0xc7, 0xfa, 0x6a, 0x13, 0x6b, 0xe4, 0x6e, 0xc0, 0xca,
|
||||
0xad, 0x72, 0xfd, 0x06, 0x08, 0xe6, 0xf6, 0x88, 0x24, 0x8a, 0xc1, 0xc2, 0xea, 0xec, 0x2e, 0x42,
|
||||
0xbb, 0xcf, 0x78, 0xb5, 0x53, 0xee, 0x12, 0x58, 0x7d, 0xc1, 0xa7, 0x8b, 0xd0, 0xfd, 0x66, 0x42,
|
||||
0xeb, 0xe8, 0xa8, 0xd7, 0xcb, 0xd8, 0x30, 0xa6, 0xe8, 0xab, 0x01, 0xe8, 0xe1, 0xd6, 0xa0, 0x97,
|
||||
0x33, 0xba, 0x7a, 0x74, 0x7d, 0x9d, 0x57, 0x7f, 0x58, 0xa5, 0x9b, 0x38, 0x85, 0x79, 0xe5, 0x2c,
|
||||
0xfa, 0xef, 0x89, 0xd3, 0xec, 0x78, 0xbf, 0x4f, 0xd4, 0xdc, 0x03, 0x68, 0x56, 0x8f, 0x86, 0x36,
|
||||
0x67, 0xca, 0xbb, 0x33, 0x13, 0xce, 0xff, 0x4f, 0xca, 0xd5, 0x97, 0x9c, 0xc0, 0x5c, 0xf1, 0xe2,
|
||||
0x68, 0x63, 0x46, 0x51, 0xcd, 0x12, 0x67, 0x56, 0x9f, 0x75, 0xaf, 0x7a, 0xd6, 0xe5, 0xcd, 0x9a,
|
||||
0xf1, 0xfd, 0x66, 0xcd, 0xf8, 0x71, 0xb3, 0x66, 0x84, 0x0b, 0xea, 0x0f, 0xfa, 0xe2, 0x67, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xbc, 0x68, 0x1b, 0xf0, 0xca, 0x05, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ service LLBBridge {
|
|||
|
||||
message ResolveImageConfigRequest {
|
||||
string Ref = 1;
|
||||
pb.Platform Platform = 2;
|
||||
}
|
||||
|
||||
message ResolveImageConfigResponse {
|
||||
|
|
|
@ -110,12 +110,12 @@ func (s *llbBridge) Exec(ctx context.Context, meta executor.Meta, root cache.Imm
|
|||
return err
|
||||
}
|
||||
|
||||
func (s *llbBridge) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
||||
func (s *llbBridge) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) {
|
||||
w, err := s.resolveWorker()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return w.ResolveImageConfig(ctx, ref)
|
||||
return w.ResolveImageConfig(ctx, ref, platform)
|
||||
}
|
||||
|
||||
type lazyCacheManager struct {
|
||||
|
|
|
@ -14,18 +14,20 @@ import (
|
|||
const sourceCacheType = "buildkit.source.v0"
|
||||
|
||||
type sourceOp struct {
|
||||
mu sync.Mutex
|
||||
op *pb.Op_Source
|
||||
sm *source.Manager
|
||||
src source.SourceInstance
|
||||
w worker.Worker
|
||||
mu sync.Mutex
|
||||
op *pb.Op_Source
|
||||
platform *pb.Platform
|
||||
sm *source.Manager
|
||||
src source.SourceInstance
|
||||
w worker.Worker
|
||||
}
|
||||
|
||||
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, sm *source.Manager, w worker.Worker) (solver.Op, error) {
|
||||
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, w worker.Worker) (solver.Op, error) {
|
||||
return &sourceOp{
|
||||
op: op,
|
||||
sm: sm,
|
||||
w: w,
|
||||
op: op,
|
||||
sm: sm,
|
||||
w: w,
|
||||
platform: platform,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -35,7 +37,7 @@ func (s *sourceOp) instance(ctx context.Context) (source.SourceInstance, error)
|
|||
if s.src != nil {
|
||||
return s.src, nil
|
||||
}
|
||||
id, err := source.FromLLB(s.op)
|
||||
id, err := source.FromLLB(s.op, s.platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige
|
|||
func llbOpName(op *pb.Op) string {
|
||||
switch op := op.Op.(type) {
|
||||
case *pb.Op_Source:
|
||||
if id, err := source.FromLLB(op); err == nil {
|
||||
if id, err := source.FromLLB(op, nil); err == nil {
|
||||
if id, ok := id.(*source.LocalIdentifier); ok {
|
||||
if len(id.IncludePatterns) == 1 {
|
||||
return op.Source.Identifier + " (" + id.IncludePatterns[0] + ")"
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/diff"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/moby/buildkit/cache"
|
||||
"github.com/moby/buildkit/session"
|
||||
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/moby/buildkit/util/pull"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -52,13 +52,13 @@ func (is *imageSource) ID() string {
|
|||
return source.DockerImageScheme
|
||||
}
|
||||
|
||||
func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
||||
func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, platform *specs.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, pull.NewResolver(ctx, is.SessionManager, is.ImageStore), is.ContentStore, "")
|
||||
dgst, dt, err := imageutil.Config(ctx, ref, pull.NewResolver(ctx, is.SessionManager, is.ImageStore), is.ContentStore, platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -77,34 +77,44 @@ func (is *imageSource) Resolve(ctx context.Context, id source.Identifier) (sourc
|
|||
return nil, errors.Errorf("invalid image identifier %v", id)
|
||||
}
|
||||
|
||||
platform := platforms.DefaultSpec()
|
||||
if imageIdentifier.Platform != nil {
|
||||
platform = *imageIdentifier.Platform
|
||||
}
|
||||
|
||||
pullerUtil := &pull.Puller{
|
||||
Snapshotter: is.Snapshotter,
|
||||
ContentStore: is.ContentStore,
|
||||
Applier: is.Applier,
|
||||
Src: imageIdentifier.Reference,
|
||||
Resolver: pull.NewResolver(ctx, is.SessionManager, is.ImageStore),
|
||||
Platform: &platform,
|
||||
}
|
||||
p := &puller{
|
||||
CacheAccessor: is.CacheAccessor,
|
||||
Puller: pullerUtil,
|
||||
Platform: platform,
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
type puller struct {
|
||||
CacheAccessor cache.Accessor
|
||||
Platform specs.Platform
|
||||
*pull.Puller
|
||||
}
|
||||
|
||||
func mainManifestKey(ctx context.Context, desc ocispec.Descriptor) (digest.Digest, error) {
|
||||
func mainManifestKey(ctx context.Context, desc specs.Descriptor, platform specs.Platform) (digest.Digest, error) {
|
||||
dt, err := json.Marshal(struct {
|
||||
Digest digest.Digest
|
||||
OS string
|
||||
Arch string
|
||||
Digest digest.Digest
|
||||
OS string
|
||||
Arch string
|
||||
Variant string `json:",omitempty"`
|
||||
}{
|
||||
Digest: desc.Digest,
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
Digest: desc.Digest,
|
||||
OS: platform.OS,
|
||||
Arch: platform.Architecture,
|
||||
Variant: platform.Variant,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -118,7 +128,7 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error)
|
|||
return "", false, err
|
||||
}
|
||||
if index == 0 || desc.Digest == "" {
|
||||
k, err := mainManifestKey(ctx, desc)
|
||||
k, err := mainManifestKey(ctx, desc, p.Platform)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
@ -132,10 +142,10 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error)
|
|||
if err != nil {
|
||||
return "", false, nil
|
||||
}
|
||||
_, dt, err := imageutil.Config(ctx, ref.String(), p.Resolver, p.ContentStore, "")
|
||||
_, dt, err := imageutil.Config(ctx, ref.String(), p.Resolver, p.ContentStore, nil) // TODO
|
||||
if err != nil {
|
||||
// this happens on schema1 images
|
||||
k, err := mainManifestKey(ctx, desc)
|
||||
k, err := mainManifestKey(ctx, desc, p.Platform)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
@ -158,7 +168,7 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) {
|
|||
// cacheKeyFromConfig returns a stable digest from image config. If image config
|
||||
// is a known oci image we will use chainID of layers.
|
||||
func cacheKeyFromConfig(dt []byte) digest.Digest {
|
||||
var img ocispec.Image
|
||||
var img specs.Image
|
||||
err := json.Unmarshal(dt, &img)
|
||||
if err != nil {
|
||||
return digest.FromBytes(dt)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/containerd/containerd/reference"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -50,11 +51,20 @@ func FromString(s string) (Identifier, error) {
|
|||
return nil, errors.Wrapf(errNotFound, "unknown schema %s", parts[0])
|
||||
}
|
||||
}
|
||||
func FromLLB(op *pb.Op_Source) (Identifier, error) {
|
||||
func FromLLB(op *pb.Op_Source, platform *pb.Platform) (Identifier, error) {
|
||||
id, err := FromString(op.Source.Identifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if id, ok := id.(*ImageIdentifier); ok && platform != nil {
|
||||
id.Platform = &specs.Platform{
|
||||
OS: platform.OS,
|
||||
Architecture: platform.Architecture,
|
||||
Variant: platform.Variant,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
}
|
||||
}
|
||||
if id, ok := id.(*GitIdentifier); ok {
|
||||
for k, v := range op.Source.Attrs {
|
||||
switch k {
|
||||
|
@ -136,6 +146,7 @@ func FromLLB(op *pb.Op_Source) (Identifier, error) {
|
|||
|
||||
type ImageIdentifier struct {
|
||||
Reference reference.Spec
|
||||
Platform *specs.Platform
|
||||
}
|
||||
|
||||
func NewImageIdentifier(str string) (*ImageIdentifier, error) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/containerd/containerd/reference"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -19,16 +19,18 @@ type IngesterProvider interface {
|
|||
content.Provider
|
||||
}
|
||||
|
||||
func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester IngesterProvider, platform string) (digest.Digest, []byte, error) {
|
||||
if platform == "" {
|
||||
platform = platforms.Default()
|
||||
func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester IngesterProvider, platform *specs.Platform) (digest.Digest, []byte, error) {
|
||||
// TODO: fix containerd to take struct instead of string
|
||||
platformStr := platforms.Default()
|
||||
if platform != nil {
|
||||
platformStr = platforms.Format(*platform)
|
||||
}
|
||||
ref, err := reference.Parse(str)
|
||||
if err != nil {
|
||||
return "", nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
desc := ocispec.Descriptor{
|
||||
desc := specs.Descriptor{
|
||||
Digest: ref.Digest(),
|
||||
}
|
||||
if desc.Digest != "" {
|
||||
|
@ -56,12 +58,12 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester
|
|||
|
||||
handlers := []images.Handler{
|
||||
remotes.FetchHandler(ingester, fetcher),
|
||||
childrenConfigHandler(ingester, platform),
|
||||
childrenConfigHandler(ingester, platformStr),
|
||||
}
|
||||
if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
config, err := images.Config(ctx, ingester, desc, platform)
|
||||
config, err := images.Config(ctx, ingester, desc, platformStr)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -75,10 +77,10 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester
|
|||
}
|
||||
|
||||
func childrenConfigHandler(provider content.Provider, platform string) images.HandlerFunc {
|
||||
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||
var descs []ocispec.Descriptor
|
||||
return func(ctx context.Context, desc specs.Descriptor) ([]specs.Descriptor, error) {
|
||||
var descs []specs.Descriptor
|
||||
switch desc.MediaType {
|
||||
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||
case images.MediaTypeDockerSchema2Manifest, specs.MediaTypeImageManifest:
|
||||
p, err := content.ReadBlob(ctx, provider, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -86,19 +88,19 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha
|
|||
|
||||
// TODO(stevvooe): We just assume oci manifest, for now. There may be
|
||||
// subtle differences from the docker version.
|
||||
var manifest ocispec.Manifest
|
||||
var manifest specs.Manifest
|
||||
if err := json.Unmarshal(p, &manifest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
descs = append(descs, manifest.Config)
|
||||
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
||||
case images.MediaTypeDockerSchema2ManifestList, specs.MediaTypeImageIndex:
|
||||
p, err := content.ReadBlob(ctx, provider, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var index ocispec.Index
|
||||
var index specs.Index
|
||||
if err := json.Unmarshal(p, &index); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha
|
|||
} else {
|
||||
descs = append(descs, index.Manifests...)
|
||||
}
|
||||
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
|
||||
case images.MediaTypeDockerSchema2Config, specs.MediaTypeImageConfig:
|
||||
// childless data types.
|
||||
return nil, nil
|
||||
default:
|
||||
|
@ -129,7 +131,7 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha
|
|||
}
|
||||
}
|
||||
|
||||
// ocispec.MediaTypeImageManifest, // TODO: detect schema1/manifest-list
|
||||
// specs.MediaTypeImageManifest, // TODO: detect schema1/manifest-list
|
||||
func DetectManifestMediaType(ra content.ReaderAt) (string, error) {
|
||||
// TODO: schema1
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ type Puller struct {
|
|||
ContentStore content.Store
|
||||
Applier diff.Applier
|
||||
Src reference.Spec
|
||||
Platform *ocispec.Platform
|
||||
// See NewResolver()
|
||||
Resolver remotes.Resolver
|
||||
resolveOnce sync.Once
|
||||
|
@ -86,6 +87,11 @@ func (p *Puller) Pull(ctx context.Context) (*Pulled, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
platformStr := platforms.Default()
|
||||
if p.Platform != nil {
|
||||
platformStr = platforms.Format(*p.Platform)
|
||||
}
|
||||
|
||||
ongoing := newJobs(p.ref)
|
||||
|
||||
pctx, stopProgress := context.WithCancel(ctx)
|
||||
|
@ -117,7 +123,7 @@ func (p *Puller) Pull(ctx context.Context) (*Pulled, error) {
|
|||
// Set any children labels for that content
|
||||
childrenHandler = images.SetChildrenLabels(p.ContentStore, childrenHandler)
|
||||
// Filter the childen by the platform
|
||||
childrenHandler = images.FilterPlatforms(childrenHandler, platforms.Default())
|
||||
childrenHandler = images.FilterPlatforms(childrenHandler, platformStr)
|
||||
|
||||
handlers = append(handlers,
|
||||
remotes.FetchHandler(p.ContentStore, fetcher),
|
||||
|
@ -155,7 +161,7 @@ func (p *Puller) Pull(ctx context.Context) (*Pulled, error) {
|
|||
delete(allBlobs, desc.Digest)
|
||||
return nil, nil
|
||||
}),
|
||||
images.FilterPlatforms(images.ChildrenHandler(p.ContentStore), platforms.Default()),
|
||||
images.FilterPlatforms(images.ChildrenHandler(p.ContentStore), platformStr),
|
||||
}
|
||||
|
||||
if err := images.Dispatch(ctx, images.Handlers(handlers...), p.desc); err != nil {
|
||||
|
@ -209,7 +215,7 @@ func (p *Puller) Pull(ctx context.Context) (*Pulled, error) {
|
|||
defer release()
|
||||
|
||||
unpackProgressDone := oneOffProgress(ctx, "unpacking "+p.Src.String())
|
||||
chainid, err := unpack(ctx, p.desc, p.ContentStore, csh, p.Snapshotter, p.Applier)
|
||||
chainid, err := unpack(ctx, p.desc, p.ContentStore, csh, p.Snapshotter, p.Applier, platformStr)
|
||||
if err != nil {
|
||||
return nil, unpackProgressDone(err)
|
||||
}
|
||||
|
@ -222,8 +228,8 @@ func (p *Puller) Pull(ctx context.Context) (*Pulled, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func unpack(ctx context.Context, desc ocispec.Descriptor, cs content.Store, csh ctdsnapshot.Snapshotter, s snapshot.Snapshotter, applier diff.Applier) (digest.Digest, error) {
|
||||
layers, err := getLayers(ctx, cs, desc)
|
||||
func unpack(ctx context.Context, desc ocispec.Descriptor, cs content.Store, csh ctdsnapshot.Snapshotter, s snapshot.Snapshotter, applier diff.Applier, platform string) (digest.Digest, error) {
|
||||
layers, err := getLayers(ctx, cs, desc, platform)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -263,13 +269,13 @@ func fillBlobMapping(ctx context.Context, s snapshot.Snapshotter, layers []rootf
|
|||
return nil
|
||||
}
|
||||
|
||||
func getLayers(ctx context.Context, provider content.Provider, desc ocispec.Descriptor) ([]rootfs.Layer, error) {
|
||||
manifest, err := images.Manifest(ctx, provider, desc, platforms.Default())
|
||||
func getLayers(ctx context.Context, provider content.Provider, desc ocispec.Descriptor, platform string) ([]rootfs.Layer, error) {
|
||||
manifest, err := images.Manifest(ctx, provider, desc, platform)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
image := images.Image{Target: desc}
|
||||
diffIDs, err := image.RootFS(ctx, provider, platforms.Default())
|
||||
diffIDs, err := image.RootFS(ctx, provider, platform)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to resolve rootfs")
|
||||
}
|
||||
|
|
|
@ -211,11 +211,10 @@ func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) {
|
|||
}
|
||||
|
||||
func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) {
|
||||
// TODO: update this to send full op
|
||||
if op, ok := v.Sys().(*pb.Op); ok {
|
||||
switch op := op.Op.(type) {
|
||||
if baseOp, ok := v.Sys().(*pb.Op); ok {
|
||||
switch op := baseOp.Op.(type) {
|
||||
case *pb.Op_Source:
|
||||
return ops.NewSourceOp(v, op, w.SourceManager, w)
|
||||
return ops.NewSourceOp(v, op, baseOp.Platform, w.SourceManager, w)
|
||||
case *pb.Op_Exec:
|
||||
return ops.NewExecOp(v, op, w.CacheManager, w.MetadataStore, w.Executor, w)
|
||||
case *pb.Op_Build:
|
||||
|
@ -225,17 +224,17 @@ func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solve
|
|||
return nil, errors.Errorf("could not resolve %v", v)
|
||||
}
|
||||
|
||||
func (w *Worker) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
||||
func (w *Worker) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) {
|
||||
// ImageSource is typically source/containerimage
|
||||
resolveImageConfig, ok := w.ImageSource.(resolveImageConfig)
|
||||
if !ok {
|
||||
return "", nil, errors.Errorf("worker %q does not implement ResolveImageConfig", w.ID())
|
||||
}
|
||||
return resolveImageConfig.ResolveImageConfig(ctx, ref)
|
||||
return resolveImageConfig.ResolveImageConfig(ctx, ref, platform)
|
||||
}
|
||||
|
||||
type resolveImageConfig interface {
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error)
|
||||
}
|
||||
|
||||
func (w *Worker) Exec(ctx context.Context, meta executor.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
|
||||
|
|
|
@ -22,7 +22,7 @@ type Worker interface {
|
|||
LoadRef(id string) (cache.ImmutableRef, error)
|
||||
// ResolveOp resolves Vertex.Sys() to Op implementation.
|
||||
ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
|
||||
ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error)
|
||||
// Exec is similar to executor.Exec but without []mount.Mount
|
||||
Exec(ctx context.Context, meta executor.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error
|
||||
DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error)
|
||||
|
|
Loading…
Reference in New Issue