From 35193c0e7dc301e1d2f6ea96e0ce34ffd2d4b88d Mon Sep 17 00:00:00 2001 From: John Howard Date: Fri, 23 Feb 2018 15:29:26 -0800 Subject: [PATCH 1/9] LCOW: Auto-select OS Signed-off-by: John Howard Addresses https://github.com/moby/moby/pull/35089#issuecomment-367802698. This change enables the daemon to automatically select an image under LCOW that can be used if the API doesn't specify an explicit platform. For example: FROM supertest2014/nyan ADD Dockerfile / And docker build . will download the linux image (not a multi-manifest image) And similarly docker pull ubuntu will match linux/amd64 --- builder/dockerfile/dispatchers.go | 6 +++--- daemon/images/image_builder.go | 2 +- daemon/images/image_pull.go | 6 ------ distribution/pull.go | 6 ------ distribution/pull_v2.go | 31 ++++++++++++++++++++++++------- distribution/pull_v2_unix.go | 6 +++--- distribution/pull_v2_windows.go | 25 ++++++++++++++----------- image/store.go | 3 ++- pkg/system/lcow.go | 4 ++-- 9 files changed, 49 insertions(+), 40 deletions(-) diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 4d47c208b73a0..4a71b6765ecee 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -228,7 +228,7 @@ func (d *dispatchRequest) getOsFromFlagsAndStage(stageOS string) string { // multi-arch aware yet, it is guaranteed to only hold the OS part here. return d.builder.options.Platform default: - return runtime.GOOS + return "" // Auto-select } } @@ -247,9 +247,9 @@ func (d *dispatchRequest) getImageOrStage(name string, stageOS string) (builder. imageImage.OS = runtime.GOOS if runtime.GOOS == "windows" { switch os { - case "windows", "": + case "windows": return nil, errors.New("Windows does not support FROM scratch") - case "linux": + case "linux", "": if !system.LCOWSupported() { return nil, errors.New("Linux containers are not supported on this system") } diff --git a/daemon/images/image_builder.go b/daemon/images/image_builder.go index ca7d0fda4ace9..b792721ee4502 100644 --- a/daemon/images/image_builder.go +++ b/daemon/images/image_builder.go @@ -166,7 +166,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf // Every call to GetImageAndReleasableLayer MUST call releasableLayer.Release() to prevent // leaking of layers. func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { - if refOrID == "" { + if refOrID == "" { // ie FROM scratch if !system.IsOSSupported(opts.OS) { return nil, nil, system.ErrNotSupportedOperatingSystem } diff --git a/daemon/images/image_pull.go b/daemon/images/image_pull.go index 238c38b6b399d..ed8ecb9abeb96 100644 --- a/daemon/images/image_pull.go +++ b/daemon/images/image_pull.go @@ -3,7 +3,6 @@ package images // import "github.com/docker/docker/daemon/images" import ( "context" "io" - "runtime" "strings" "time" @@ -65,11 +64,6 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference close(writesDone) }() - // Default to the host OS platform in case it hasn't been populated with an explicit value. - if os == "" { - os = runtime.GOOS - } - imagePullConfig := &distribution.ImagePullConfig{ Config: distribution.Config{ MetaHeaders: metaHeaders, diff --git a/distribution/pull.go b/distribution/pull.go index 0240eb05f7b5c..0c5237f6c068e 100644 --- a/distribution/pull.go +++ b/distribution/pull.go @@ -3,7 +3,6 @@ package distribution // import "github.com/docker/docker/distribution" import ( "context" "fmt" - "runtime" "github.com/docker/distribution/reference" "github.com/docker/docker/api" @@ -115,11 +114,6 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo continue } - // Make sure we default the OS if it hasn't been supplied - if imagePullConfig.OS == "" { - imagePullConfig.OS = runtime.GOOS - } - if err := puller.Pull(ctx, ref, imagePullConfig.OS); err != nil { // Was this pull cancelled? If so, don't try to fall // back. diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go index 60a894b1c3a8b..9e07c88d19d4f 100644 --- a/distribution/pull_v2.go +++ b/distribution/pull_v2.go @@ -509,6 +509,14 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv } } + // In the situation that the API call didn't specify an OS explicitly, but + // we support the operating system, switch to that operating system. + // eg FROM supertest2014/nyan with no platform specifier, and docker build + // with no --platform= flag under LCOW. + if requestedOS == "" && system.IsOSSupported(configOS) { + requestedOS = configOS + } + // Early bath if the requested OS doesn't match that of the configuration. // This avoids doing the download, only to potentially fail later. if !strings.EqualFold(configOS, requestedOS) { @@ -618,9 +626,10 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s // Early bath if the requested OS doesn't match that of the configuration. // This avoids doing the download, only to potentially fail later. - if !strings.EqualFold(configPlatform.OS, requestedOS) { + if !system.IsOSSupported(configPlatform.OS) { return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, requestedOS) } + requestedOS = configPlatform.OS // Populate diff ids in descriptors to avoid downloading foreign layers // which have been side loaded @@ -629,6 +638,10 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s } } + if requestedOS == "" { + requestedOS = runtime.GOOS + } + if p.config.DownloadManager != nil { go func() { var ( @@ -722,18 +735,22 @@ func receiveConfig(s ImageConfigStore, configChan <-chan []byte, errChan <-chan // pullManifestList handles "manifest lists" which point to various // platform-specific manifests. -func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, os string) (id digest.Digest, manifestListDigest digest.Digest, err error) { +func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, requestedOS string) (id digest.Digest, manifestListDigest digest.Digest, err error) { manifestListDigest, err = schema2ManifestDigest(ref, mfstList) if err != nil { return "", "", err } - logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a %s/%s match", ref, len(mfstList.Manifests), os, runtime.GOARCH) + logOS := requestedOS // May be "" indicating any OS + if logOS == "" { + logOS = "*" + } + logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a %s/%s match", ref, len(mfstList.Manifests), logOS, runtime.GOARCH) - manifestMatches := filterManifests(mfstList.Manifests, os) + manifestMatches := filterManifests(mfstList.Manifests, requestedOS) if len(manifestMatches) == 0 { - errMsg := fmt.Sprintf("no matching manifest for %s/%s in the manifest list entries", os, runtime.GOARCH) + errMsg := fmt.Sprintf("no matching manifest for %s/%s in the manifest list entries", logOS, runtime.GOARCH) logrus.Debugf(errMsg) return "", "", errors.New(errMsg) } @@ -764,12 +781,12 @@ func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mf switch v := manifest.(type) { case *schema1.SignedManifest: - id, _, err = p.pullSchema1(ctx, manifestRef, v, os) + id, _, err = p.pullSchema1(ctx, manifestRef, v, manifestMatches[0].Platform.OS) if err != nil { return "", "", err } case *schema2.DeserializedManifest: - id, _, err = p.pullSchema2(ctx, manifestRef, v, os) + id, _, err = p.pullSchema2(ctx, manifestRef, v, manifestMatches[0].Platform.OS) if err != nil { return "", "", err } diff --git a/distribution/pull_v2_unix.go b/distribution/pull_v2_unix.go index 0be8a032428e5..65c9594386727 100644 --- a/distribution/pull_v2_unix.go +++ b/distribution/pull_v2_unix.go @@ -16,13 +16,13 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo return blobs.Open(ctx, ld.digest) } -func filterManifests(manifests []manifestlist.ManifestDescriptor, os string) []manifestlist.ManifestDescriptor { +func filterManifests(manifests []manifestlist.ManifestDescriptor, _ string) []manifestlist.ManifestDescriptor { var matches []manifestlist.ManifestDescriptor for _, manifestDescriptor := range manifests { - if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == os { + if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == runtime.GOOS { matches = append(matches, manifestDescriptor) - logrus.Debugf("found match for %s/%s with media type %s, digest %s", os, runtime.GOARCH, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) + logrus.Debugf("found match for %s/%s with media type %s, digest %s", runtime.GOOS, runtime.GOARCH, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) } } return matches diff --git a/distribution/pull_v2_windows.go b/distribution/pull_v2_windows.go index 432a36119d4c9..fc736e336d51a 100644 --- a/distribution/pull_v2_windows.go +++ b/distribution/pull_v2_windows.go @@ -62,24 +62,27 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo return rsc, err } -func filterManifests(manifests []manifestlist.ManifestDescriptor, os string) []manifestlist.ManifestDescriptor { - osVersion := "" - if os == "windows" { - version := system.GetOSVersion() - osVersion = fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build) - logrus.Debugf("will prefer entries with version %s", osVersion) - } +func filterManifests(manifests []manifestlist.ManifestDescriptor, requestedOS string) []manifestlist.ManifestDescriptor { + version := system.GetOSVersion() + osVersion := fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build) + logrus.Debugf("will prefer Windows entries with version %s", osVersion) var matches []manifestlist.ManifestDescriptor + foundWindowsMatch := false for _, manifestDescriptor := range manifests { - if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == os { + if (manifestDescriptor.Platform.Architecture == runtime.GOARCH) && + ((requestedOS != "" && manifestDescriptor.Platform.OS == requestedOS) || // Explicit user request for an OS we know we support + (requestedOS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support matches = append(matches, manifestDescriptor) - logrus.Debugf("found match for %s/%s %s with media type %s, digest %s", os, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) + logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) + if strings.EqualFold("windows", manifestDescriptor.Platform.OS) { + foundWindowsMatch = true + } } else { - logrus.Debugf("ignoring %s/%s %s with media type %s, digest %s", os, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) + logrus.Debugf("ignoring %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, manifestDescriptor.Platform.Architecture, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) } } - if os == "windows" { + if foundWindowsMatch { sort.Stable(manifestsByVersion{osVersion, matches}) } return matches diff --git a/image/store.go b/image/store.go index 9fd7d7dcf3737..1a8a8a24516c2 100644 --- a/image/store.go +++ b/image/store.go @@ -76,7 +76,8 @@ func (is *store) restore() error { var l layer.Layer if chainID := img.RootFS.ChainID(); chainID != "" { if !system.IsOSSupported(img.OperatingSystem()) { - return system.ErrNotSupportedOperatingSystem + logrus.Errorf("not restoring image with unsupported operating system %v, %v, %s", dgst, chainID, img.OperatingSystem()) + return nil } l, err = is.lss[img.OperatingSystem()].Get(chainID) if err != nil { diff --git a/pkg/system/lcow.go b/pkg/system/lcow.go index 5c3fbfe6f4a76..dc8ef9f96dfde 100644 --- a/pkg/system/lcow.go +++ b/pkg/system/lcow.go @@ -59,10 +59,10 @@ func ParsePlatform(in string) *specs.Platform { // IsOSSupported determines if an operating system is supported by the host func IsOSSupported(os string) bool { - if runtime.GOOS == os { + if strings.EqualFold(runtime.GOOS, os) { return true } - if LCOWSupported() && os == "linux" { + if LCOWSupported() && strings.EqualFold(os, "linux") { return true } return false From 7f334d3acfd7bfde900e16e393662587b9ff74a1 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Tue, 26 Jun 2018 15:39:25 +0800 Subject: [PATCH 2/9] Initial support for OCI multi-platform image Add the OCI spec compatible image support in client side. Signed-off-by: Dennis Chen --- api/server/router/build/build_routes.go | 12 +++--- api/server/router/image/image_routes.go | 12 +++--- api/types/client.go | 3 +- builder/dockerfile/builder.go | 7 ---- builder/dockerfile/copy.go | 7 ++-- builder/dockerfile/dispatchers.go | 9 +++-- builder/dockerfile/internals.go | 2 +- image/tarexport/load.go | 4 +- pkg/system/lcow.go | 53 ------------------------- 9 files changed, 28 insertions(+), 81 deletions(-) diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 2d73e9b1f3449..0dd2b1d8f9d3b 100644 --- a/api/server/router/build/build_routes.go +++ b/api/server/router/build/build_routes.go @@ -14,6 +14,7 @@ import ( "strings" "sync" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" @@ -23,7 +24,6 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" - "github.com/docker/docker/pkg/system" "github.com/docker/go-units" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -72,11 +72,13 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui options.RemoteContext = r.FormValue("remote") if versions.GreaterThanOrEqualTo(version, "1.32") { apiPlatform := r.FormValue("platform") - p := system.ParsePlatform(apiPlatform) - if err := system.ValidatePlatform(p); err != nil { - return nil, errdefs.InvalidParameter(errors.Errorf("invalid platform: %s", err)) + if len(strings.TrimSpace(apiPlatform)) != 0 { + sp, err := platforms.Parse(apiPlatform) + if err != nil { + return nil, err + } + options.Platform = sp } - options.Platform = p.OS } if r.Form.Get("shmsize") != "" { diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 8e32d0292ed8e..f359df27f8ec0 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -4,11 +4,11 @@ import ( "context" "encoding/base64" "encoding/json" - "fmt" "net/http" "strconv" "strings" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -16,7 +16,6 @@ import ( "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/streamformatter" - "github.com/docker/docker/pkg/system" "github.com/docker/docker/registry" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -45,9 +44,12 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite version := httputils.VersionFromContext(ctx) if versions.GreaterThanOrEqualTo(version, "1.32") { apiPlatform := r.FormValue("platform") - platform = system.ParsePlatform(apiPlatform) - if err = system.ValidatePlatform(platform); err != nil { - err = fmt.Errorf("invalid platform: %s", err) + if len(strings.TrimSpace(apiPlatform)) != 0 { + sp, err := platforms.Parse(apiPlatform) + if err != nil { + return err + } + platform = &sp } } diff --git a/api/types/client.go b/api/types/client.go index 3df8d23368419..cc10a98a58e22 100644 --- a/api/types/client.go +++ b/api/types/client.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/go-units" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // CheckpointCreateOptions holds parameters to create a checkpoint from a container @@ -180,7 +181,7 @@ type ImageBuildOptions struct { ExtraHosts []string // List of extra hosts Target string SessionID string - Platform string + Platform specs.Platform // Version specifies the version of the unerlying builder to use Version BuilderVersion // BuildID is an optional identifier that can be passed together with the diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go index d5d2de818024c..b58534707916d 100644 --- a/builder/dockerfile/builder.go +++ b/builder/dockerfile/builder.go @@ -104,13 +104,6 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) ( source = src } - os := "" - apiPlatform := system.ParsePlatform(config.Options.Platform) - if apiPlatform.OS != "" { - os = apiPlatform.OS - } - config.Options.Platform = os - builderOptions := builderOptions{ Options: config.Options, ProgressWriter: config.ProgressWriter, diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go index 43f40b62f99ca..17d2b5bde9e3e 100644 --- a/builder/dockerfile/copy.go +++ b/builder/dockerfile/copy.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/urlutil" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -72,7 +73,7 @@ type copier struct { source builder.Source pathCache pathCache download sourceDownloader - platform string + platform specs.Platform // for cleanup. TODO: having copier.cleanup() is error prone and hard to // follow. Code calling performCopy should manage the lifecycle of its params. // Copier should take override source as input, not imageMount. @@ -95,8 +96,8 @@ func (o *copier) createCopyInstruction(args []string, cmdName string) (copyInstr last := len(args) - 1 // Work in platform-specific filepath semantics - inst.dest = fromSlash(args[last], o.platform) - separator := string(separator(o.platform)) + inst.dest = fromSlash(args[last], o.platform.OS) + separator := string(separator(o.platform.OS)) infos, err := o.getCopyInfosForSourcePaths(args[0:last], inst.dest) if err != nil { return inst, errors.Wrapf(err, "%s failed", cmdName) diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 4a71b6765ecee..65d93139f18b7 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -14,6 +14,7 @@ import ( "sort" "strings" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" @@ -151,9 +152,11 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error // func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { d.builder.imageProber.Reset() - if err := system.ValidatePlatform(&cmd.Platform); err != nil { + //TODO(@arm64b): Leave the sanity check of the spec platform to the containerd code + if err := platforms.ValidatePlatform(&cmd.Platform); err != nil { return err } + image, err := d.getFromImage(d.shlex, cmd.BaseName, cmd.Platform.OS) if err != nil { return err @@ -223,10 +226,10 @@ func (d *dispatchRequest) getOsFromFlagsAndStage(stageOS string) string { switch { case stageOS != "": return stageOS - case d.builder.options.Platform != "": + case d.builder.options.Platform.OS != "": // Note this is API "platform", but by this point, as the daemon is not // multi-arch aware yet, it is guaranteed to only hold the OS part here. - return d.builder.options.Platform + return d.builder.options.Platform.OS default: return "" // Auto-select } diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go index 88e75a2179bed..e23c3280016ef 100644 --- a/builder/dockerfile/internals.go +++ b/builder/dockerfile/internals.go @@ -456,7 +456,7 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf // is too small for builder scenarios where many users are // using RUN statements to install large amounts of data. // Use 127GB as that's the default size of a VHD in Hyper-V. - if runtime.GOOS == "windows" && options.Platform == "windows" { + if runtime.GOOS == "windows" && options.Platform.OS == "windows" { hc.StorageOpt = make(map[string]string) hc.StorageOpt["size"] = "127GB" } diff --git a/image/tarexport/load.go b/image/tarexport/load.go index c89dd08f93ca4..0416e28b81b78 100644 --- a/image/tarexport/load.go +++ b/image/tarexport/load.go @@ -422,8 +422,6 @@ func checkCompatibleOS(imageOS string) error { return fmt.Errorf("cannot load %s image on %s", imageOS, runtime.GOOS) } // Finally, check the image OS is supported for the platform. - if err := system.ValidatePlatform(system.ParsePlatform(imageOS)); err != nil { - return fmt.Errorf("cannot load %s image on %s: %s", imageOS, runtime.GOOS, err) - } + // TODO(@arm64b): Leave this sanity check to the containerd code in the future return nil } diff --git a/pkg/system/lcow.go b/pkg/system/lcow.go index dc8ef9f96dfde..786811df7460c 100644 --- a/pkg/system/lcow.go +++ b/pkg/system/lcow.go @@ -1,62 +1,9 @@ package system // import "github.com/docker/docker/pkg/system" import ( - "fmt" "runtime" - "strings" - - specs "github.com/opencontainers/image-spec/specs-go/v1" ) -// ValidatePlatform determines if a platform structure is valid. -// TODO This is a temporary function - can be replaced by parsing from -// https://github.com/containerd/containerd/pull/1403/files at a later date. -// @jhowardmsft -func ValidatePlatform(platform *specs.Platform) error { - platform.Architecture = strings.ToLower(platform.Architecture) - platform.OS = strings.ToLower(platform.OS) - // Based on https://github.com/moby/moby/pull/34642#issuecomment-330375350, do - // not support anything except operating system. - if platform.Architecture != "" { - return fmt.Errorf("invalid platform architecture %q", platform.Architecture) - } - if platform.OS != "" { - if !(platform.OS == runtime.GOOS || (LCOWSupported() && platform.OS == "linux")) { - return fmt.Errorf("invalid platform os %q", platform.OS) - } - } - if len(platform.OSFeatures) != 0 { - return fmt.Errorf("invalid platform osfeatures %q", platform.OSFeatures) - } - if platform.OSVersion != "" { - return fmt.Errorf("invalid platform osversion %q", platform.OSVersion) - } - if platform.Variant != "" { - return fmt.Errorf("invalid platform variant %q", platform.Variant) - } - return nil -} - -// ParsePlatform parses a platform string in the format os[/arch[/variant] -// into an OCI image-spec platform structure. -// TODO This is a temporary function - can be replaced by parsing from -// https://github.com/containerd/containerd/pull/1403/files at a later date. -// @jhowardmsft -func ParsePlatform(in string) *specs.Platform { - p := &specs.Platform{} - elements := strings.SplitN(strings.ToLower(in), "/", 3) - if len(elements) == 3 { - p.Variant = elements[2] - } - if len(elements) >= 2 { - p.Architecture = elements[1] - } - if len(elements) >= 1 { - p.OS = elements[0] - } - return p -} - // IsOSSupported determines if an operating system is supported by the host func IsOSSupported(os string) bool { if strings.EqualFold(runtime.GOOS, os) { From 360d2f2ce7cba28fc5427bc346ea37aee7fe78f6 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 26 Jun 2018 10:59:57 -0700 Subject: [PATCH 3/9] vendor: update buildkit to cce2080ddb Signed-off-by: Tonis Tiigi --- vendor.conf | 2 +- .../api/services/control/control.pb.go | 214 +++-- .../api/services/control/control.proto | 1 + .../github.com/moby/buildkit/cache/manager.go | 10 +- .../github.com/moby/buildkit/client/client.go | 6 +- .../moby/buildkit/client/llb/exec.go | 88 +- .../client/llb/imagemetaresolver/resolver.go | 15 +- .../moby/buildkit/client/llb/marshal.go | 62 +- .../moby/buildkit/client/llb/meta.go | 26 +- .../moby/buildkit/client/llb/resolver.go | 3 +- .../moby/buildkit/client/llb/source.go | 65 +- .../moby/buildkit/client/llb/state.go | 181 ++-- .../moby/buildkit/client/workers.go | 26 +- .../moby/buildkit/control/control.go | 26 +- .../frontend/dockerfile/builder/build.go | 34 +- .../dockerfile/dockerfile2llb/convert.go | 102 ++- .../dockerfile2llb/convert_norunmount.go | 4 +- .../dockerfile2llb/convert_runmount.go | 20 +- .../dockerfile/dockerfile2llb/image.go | 15 +- .../dockerfile/instructions/commands.go | 3 +- .../instructions/commands_runmount.go | 34 +- .../frontend/dockerfile/instructions/parse.go | 4 +- .../moby/buildkit/frontend/frontend.go | 3 +- .../frontend/gateway/client/client.go | 3 +- .../moby/buildkit/frontend/gateway/gateway.go | 32 +- .../frontend/gateway/pb/gateway.pb.go | 148 +++- .../frontend/gateway/pb/gateway.proto | 1 + .../moby/buildkit/solver/llbsolver/bridge.go | 8 +- .../buildkit/solver/llbsolver/ops/exec.go | 94 +- .../buildkit/solver/llbsolver/ops/source.go | 22 +- .../moby/buildkit/solver/llbsolver/solver.go | 14 +- .../moby/buildkit/solver/llbsolver/vertex.go | 47 +- .../moby/buildkit/solver/pb/ops.pb.go | 819 ++++++++++++++---- .../moby/buildkit/solver/pb/ops.proto | 37 +- .../moby/buildkit/source/identifier.go | 13 +- .../moby/buildkit/util/imageutil/config.go | 32 +- vendor/github.com/moby/buildkit/vendor.conf | 2 +- .../github.com/moby/buildkit/worker/worker.go | 6 +- 38 files changed, 1637 insertions(+), 585 deletions(-) diff --git a/vendor.conf b/vendor.conf index 25f74900d0982..627a856505593 100644 --- a/vendor.conf +++ b/vendor.conf @@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.5 golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 # buildkit -github.com/moby/buildkit dbf67a691ce77023a0a5ce9b005298631f8bbb4e +github.com/moby/buildkit cce2080ddbe4698912f2290892b247c83627efa8 github.com/tonistiigi/fsutil 8abad97ee3969cdf5e9c367f46adba2c212b3ddb github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 diff --git a/vendor/github.com/moby/buildkit/api/services/control/control.pb.go b/vendor/github.com/moby/buildkit/api/services/control/control.pb.go index e92bd7f04d7ab..5feffaf9deb57 100644 --- a/vendor/github.com/moby/buildkit/api/services/control/control.pb.go +++ b/vendor/github.com/moby/buildkit/api/services/control/control.pb.go @@ -542,8 +542,9 @@ func (m *ListWorkersResponse) GetRecord() []*WorkerRecord { } type WorkerRecord struct { - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Labels map[string]string `protobuf:"bytes,2,rep,name=Labels" json:"Labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + Labels map[string]string `protobuf:"bytes,2,rep,name=Labels" json:"Labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Platforms []pb.Platform `protobuf:"bytes,3,rep,name=platforms" json:"platforms"` } func (m *WorkerRecord) Reset() { *m = WorkerRecord{} } @@ -565,6 +566,13 @@ func (m *WorkerRecord) GetLabels() map[string]string { return nil } +func (m *WorkerRecord) GetPlatforms() []pb.Platform { + if m != nil { + return m.Platforms + } + return nil +} + func init() { proto.RegisterType((*PruneRequest)(nil), "moby.buildkit.v1.PruneRequest") proto.RegisterType((*DiskUsageRequest)(nil), "moby.buildkit.v1.DiskUsageRequest") @@ -1650,6 +1658,18 @@ func (m *WorkerRecord) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], v) } } + if len(m.Platforms) > 0 { + for _, msg := range m.Platforms { + dAtA[i] = 0x1a + i++ + i = encodeVarintControl(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -1979,6 +1999,12 @@ func (m *WorkerRecord) Size() (n int) { n += mapEntrySize + 1 + sovControl(uint64(mapEntrySize)) } } + if len(m.Platforms) > 0 { + for _, e := range m.Platforms { + l = e.Size() + n += 1 + l + sovControl(uint64(l)) + } + } return n } @@ -4663,6 +4689,37 @@ func (m *WorkerRecord) Unmarshal(dAtA []byte) error { } m.Labels[mapkey] = mapvalue iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Platforms", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowControl + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthControl + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Platforms = append(m.Platforms, pb.Platform{}) + if err := m.Platforms[len(m.Platforms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipControl(dAtA[iNdEx:]) @@ -4792,80 +4849,81 @@ var ( func init() { proto.RegisterFile("control.proto", fileDescriptorControl) } var fileDescriptorControl = []byte{ - // 1192 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0x66, 0x6c, 0xc7, 0x3f, 0x65, 0x27, 0x0a, 0x0d, 0xac, 0x46, 0x03, 0x24, 0x66, 0x00, 0xc9, - 0x8a, 0x76, 0xc7, 0xd9, 0xc0, 0x22, 0xc8, 0x61, 0xb5, 0xeb, 0x78, 0x11, 0x89, 0x12, 0xb1, 0x74, - 0x36, 0xac, 0xc4, 0x6d, 0x6c, 0x77, 0xbc, 0xa3, 0xd8, 0xd3, 0xa6, 0xbb, 0x27, 0xda, 0xf0, 0x14, - 0x1c, 0xb8, 0xf2, 0x14, 0x1c, 0x38, 0x73, 0x40, 0xda, 0x23, 0x67, 0x0e, 0x59, 0x94, 0x3b, 0x3c, - 0x03, 0xea, 0x9f, 0xb1, 0xdb, 0x1e, 0xe7, 0xc7, 0xd9, 0x53, 0xba, 0x3a, 0x5f, 0x7d, 0x53, 0x5d, - 0x5f, 0xb9, 0xaa, 0x60, 0xb9, 0x4b, 0x63, 0xc1, 0xe8, 0x20, 0x18, 0x31, 0x2a, 0x28, 0x5a, 0x1d, - 0xd2, 0xce, 0x59, 0xd0, 0x49, 0xa2, 0x41, 0xef, 0x24, 0x12, 0xc1, 0xe9, 0x7d, 0xef, 0x5e, 0x3f, - 0x12, 0x2f, 0x92, 0x4e, 0xd0, 0xa5, 0xc3, 0x66, 0x9f, 0xf6, 0x69, 0x53, 0x01, 0x3b, 0xc9, 0xb1, - 0xb2, 0x94, 0xa1, 0x4e, 0x9a, 0xc0, 0x5b, 0xef, 0x53, 0xda, 0x1f, 0x90, 0x09, 0x4a, 0x44, 0x43, - 0xc2, 0x45, 0x38, 0x1c, 0x19, 0xc0, 0x5d, 0x8b, 0x4f, 0x7e, 0xac, 0x99, 0x7e, 0xac, 0xc9, 0xe9, - 0xe0, 0x94, 0xb0, 0xe6, 0xa8, 0xd3, 0xa4, 0x23, 0xae, 0xd1, 0xfe, 0x0a, 0xd4, 0x9e, 0xb2, 0x24, - 0x26, 0x98, 0xfc, 0x98, 0x10, 0x2e, 0xfc, 0x0d, 0x58, 0x6d, 0x47, 0xfc, 0xe4, 0x88, 0x87, 0xfd, - 0xf4, 0x0e, 0xdd, 0x81, 0xe2, 0x71, 0x34, 0x10, 0x84, 0xb9, 0x4e, 0xdd, 0x69, 0x54, 0xb0, 0xb1, - 0xfc, 0x3d, 0x78, 0xdb, 0xc2, 0xf2, 0x11, 0x8d, 0x39, 0x41, 0x0f, 0xa0, 0xc8, 0x48, 0x97, 0xb2, - 0x9e, 0xeb, 0xd4, 0xf3, 0x8d, 0xea, 0xd6, 0x87, 0xc1, 0xec, 0x8b, 0x03, 0xe3, 0x20, 0x41, 0xd8, - 0x80, 0xfd, 0x3f, 0x72, 0x50, 0xb5, 0xee, 0xd1, 0x0a, 0xe4, 0x76, 0xdb, 0xe6, 0x7b, 0xb9, 0xdd, - 0x36, 0x72, 0xa1, 0x74, 0x90, 0x88, 0xb0, 0x33, 0x20, 0x6e, 0xae, 0xee, 0x34, 0xca, 0x38, 0x35, - 0xd1, 0xbb, 0xb0, 0xb4, 0x1b, 0x1f, 0x71, 0xe2, 0xe6, 0xd5, 0xbd, 0x36, 0x10, 0x82, 0xc2, 0x61, - 0xf4, 0x13, 0x71, 0x0b, 0x75, 0xa7, 0x91, 0xc7, 0xea, 0x2c, 0xdf, 0xf1, 0x34, 0x64, 0x24, 0x16, - 0xee, 0x92, 0x7e, 0x87, 0xb6, 0x50, 0x0b, 0x2a, 0x3b, 0x8c, 0x84, 0x82, 0xf4, 0x1e, 0x0b, 0xb7, - 0x58, 0x77, 0x1a, 0xd5, 0x2d, 0x2f, 0xd0, 0x69, 0x0e, 0xd2, 0x34, 0x07, 0xcf, 0xd2, 0x34, 0xb7, - 0xca, 0xaf, 0xce, 0xd7, 0xdf, 0xfa, 0xf9, 0xf5, 0xba, 0x83, 0x27, 0x6e, 0xe8, 0x11, 0xc0, 0x7e, - 0xc8, 0xc5, 0x11, 0x57, 0x24, 0xa5, 0x6b, 0x49, 0x0a, 0x8a, 0xc0, 0xf2, 0x41, 0x6b, 0x00, 0x2a, - 0x01, 0x3b, 0x34, 0x89, 0x85, 0x5b, 0x56, 0x71, 0x5b, 0x37, 0xa8, 0x0e, 0xd5, 0x36, 0xe1, 0x5d, - 0x16, 0x8d, 0x44, 0x44, 0x63, 0xb7, 0xa2, 0x9e, 0x60, 0x5f, 0xf9, 0xbf, 0x14, 0xa0, 0x76, 0x28, - 0x35, 0x4e, 0x85, 0x5b, 0x85, 0x3c, 0x26, 0xc7, 0x26, 0x8b, 0xf2, 0x88, 0x02, 0x80, 0x36, 0x39, - 0x8e, 0xe2, 0x48, 0x71, 0xe4, 0x54, 0x98, 0x2b, 0xc1, 0xa8, 0x13, 0x4c, 0x6e, 0xb1, 0x85, 0x40, - 0x1e, 0x94, 0x9f, 0xbc, 0x1c, 0x51, 0x26, 0xc5, 0xcf, 0x2b, 0x9a, 0xb1, 0x8d, 0x9e, 0xc3, 0x72, - 0x7a, 0x7e, 0x2c, 0x04, 0xe3, 0x6e, 0x41, 0x09, 0x7e, 0x3f, 0x2b, 0xb8, 0x1d, 0x54, 0x30, 0xe5, - 0xf3, 0x24, 0x16, 0xec, 0x0c, 0x4f, 0xf3, 0x48, 0xad, 0x0f, 0x09, 0xe7, 0x32, 0x42, 0x2d, 0x54, - 0x6a, 0xca, 0x70, 0xbe, 0x66, 0x34, 0x16, 0x24, 0xee, 0x29, 0xa1, 0x2a, 0x78, 0x6c, 0xcb, 0x70, - 0xd2, 0xb3, 0x0e, 0xa7, 0x74, 0xa3, 0x70, 0xa6, 0x7c, 0x4c, 0x38, 0x53, 0x77, 0x68, 0x1b, 0x96, - 0x76, 0xc2, 0xee, 0x0b, 0xa2, 0x34, 0xa9, 0x6e, 0xad, 0x65, 0x09, 0xd5, 0xbf, 0xbf, 0x55, 0x22, - 0xf0, 0x56, 0x41, 0x96, 0x07, 0xd6, 0x2e, 0xde, 0x23, 0x40, 0xd9, 0xf7, 0x4a, 0x5d, 0x4e, 0xc8, - 0x59, 0xaa, 0xcb, 0x09, 0x39, 0x93, 0x45, 0x7c, 0x1a, 0x0e, 0x12, 0x5d, 0xdc, 0x15, 0xac, 0x8d, - 0xed, 0xdc, 0x97, 0x8e, 0x64, 0xc8, 0x86, 0xb8, 0x08, 0x83, 0xff, 0xda, 0x81, 0x9a, 0x1d, 0x21, - 0xfa, 0x00, 0x2a, 0x3a, 0xa8, 0x49, 0x71, 0x4c, 0x2e, 0x64, 0x1d, 0xee, 0x0e, 0x8d, 0xc1, 0xdd, - 0x5c, 0x3d, 0xdf, 0xa8, 0x60, 0xeb, 0x06, 0x7d, 0x07, 0x55, 0x0d, 0xd6, 0x59, 0xce, 0xab, 0x2c, - 0x37, 0xaf, 0x4e, 0x4a, 0x60, 0x79, 0xe8, 0x1c, 0xdb, 0x1c, 0xde, 0x43, 0x58, 0x9d, 0x05, 0x2c, - 0xf4, 0xc2, 0xdf, 0x1d, 0x58, 0x36, 0xa2, 0x9a, 0x2e, 0x14, 0xa6, 0x8c, 0x84, 0xa5, 0x77, 0xa6, - 0x1f, 0x3d, 0xb8, 0xb4, 0x1e, 0x34, 0x2c, 0x98, 0xf5, 0xd3, 0xf1, 0x66, 0xe8, 0xbc, 0x1d, 0x78, - 0x6f, 0x2e, 0x74, 0xa1, 0xc8, 0x3f, 0x82, 0xe5, 0x43, 0x11, 0x8a, 0x84, 0x5f, 0xfa, 0x93, 0xf5, - 0x7f, 0x73, 0x60, 0x25, 0xc5, 0x98, 0xd7, 0x7d, 0x0e, 0xe5, 0x53, 0xc2, 0x04, 0x79, 0x49, 0xb8, - 0x79, 0x95, 0x9b, 0x7d, 0xd5, 0xf7, 0x0a, 0x81, 0xc7, 0x48, 0xb4, 0x0d, 0x65, 0xae, 0x78, 0x88, - 0x96, 0x75, 0x6e, 0x29, 0x6b, 0x2f, 0xf3, 0xbd, 0x31, 0x1e, 0x35, 0xa1, 0x30, 0xa0, 0xfd, 0x54, - 0xed, 0xf7, 0x2f, 0xf3, 0xdb, 0xa7, 0x7d, 0xac, 0x80, 0xfe, 0x79, 0x0e, 0x8a, 0xfa, 0x0e, 0xed, - 0x41, 0xb1, 0x17, 0xf5, 0x09, 0x17, 0xfa, 0x55, 0xad, 0x2d, 0xf9, 0x03, 0xf9, 0xfb, 0x7c, 0x7d, - 0xc3, 0x1a, 0x54, 0x74, 0x44, 0x62, 0x39, 0x28, 0xc3, 0x28, 0x26, 0x8c, 0x37, 0xfb, 0xf4, 0x9e, - 0x76, 0x09, 0xda, 0xea, 0x0f, 0x36, 0x0c, 0x92, 0x2b, 0x8a, 0x47, 0x89, 0x30, 0x85, 0x79, 0x3b, - 0x2e, 0xcd, 0x20, 0x47, 0x44, 0x1c, 0x0e, 0x89, 0xe9, 0x6b, 0xea, 0x2c, 0x47, 0x44, 0x57, 0xd6, - 0x6d, 0x4f, 0x0d, 0x8e, 0x32, 0x36, 0x16, 0xda, 0x86, 0x12, 0x17, 0x21, 0x13, 0xa4, 0xa7, 0x5a, - 0xd2, 0x4d, 0x7a, 0x7b, 0xea, 0x80, 0x1e, 0x42, 0xa5, 0x4b, 0x87, 0xa3, 0x01, 0x91, 0xde, 0xc5, - 0x1b, 0x7a, 0x4f, 0x5c, 0x64, 0xf5, 0x10, 0xc6, 0x28, 0x53, 0x53, 0xa5, 0x82, 0xb5, 0xe1, 0xff, - 0x97, 0x83, 0x9a, 0x2d, 0x56, 0x66, 0x62, 0xee, 0x41, 0x51, 0x4b, 0xaf, 0xab, 0xee, 0x76, 0xa9, - 0xd2, 0x0c, 0x73, 0x53, 0xe5, 0x42, 0xa9, 0x9b, 0x30, 0x35, 0x4e, 0xf5, 0x90, 0x4d, 0x4d, 0x19, - 0xb0, 0xa0, 0x22, 0x1c, 0xa8, 0x54, 0xe5, 0xb1, 0x36, 0xe4, 0x94, 0x1d, 0xaf, 0x2a, 0x8b, 0x4d, - 0xd9, 0xb1, 0x9b, 0x2d, 0x43, 0xe9, 0x8d, 0x64, 0x28, 0x2f, 0x2c, 0x83, 0xff, 0xa7, 0x03, 0x95, - 0x71, 0x95, 0x5b, 0xd9, 0x75, 0xde, 0x38, 0xbb, 0x53, 0x99, 0xc9, 0xdd, 0x2e, 0x33, 0x77, 0xa0, - 0xc8, 0x05, 0x23, 0xe1, 0x50, 0x69, 0x94, 0xc7, 0xc6, 0x92, 0xfd, 0x64, 0xc8, 0xfb, 0x4a, 0xa1, - 0x1a, 0x96, 0x47, 0xdf, 0x87, 0x5a, 0xeb, 0x4c, 0x10, 0x7e, 0x40, 0xb8, 0x5c, 0x2e, 0xa4, 0xb6, - 0xbd, 0x50, 0x84, 0xea, 0x1d, 0x35, 0xac, 0xce, 0xfe, 0x5d, 0x40, 0xfb, 0x11, 0x17, 0xcf, 0x29, - 0x3b, 0x21, 0x8c, 0xcf, 0xdb, 0x03, 0xf3, 0xd6, 0x1e, 0x78, 0x00, 0xef, 0x4c, 0xa1, 0x4d, 0x97, - 0xfa, 0x62, 0x66, 0x13, 0x9c, 0xd3, 0x6d, 0xb4, 0xcb, 0xcc, 0x2a, 0xf8, 0xab, 0x03, 0x35, 0xfb, - 0x1f, 0x99, 0xca, 0x6e, 0x41, 0x71, 0x3f, 0xec, 0x90, 0x41, 0xda, 0xc6, 0x36, 0xae, 0x26, 0x0e, - 0x34, 0x58, 0xf7, 0x71, 0xe3, 0xe9, 0x7d, 0x05, 0x55, 0xeb, 0x7a, 0x91, 0x9e, 0xbd, 0xf5, 0x6f, - 0x1e, 0x4a, 0x3b, 0x7a, 0xa9, 0x47, 0xcf, 0xa0, 0x32, 0x5e, 0x81, 0x91, 0x9f, 0x8d, 0x63, 0x76, - 0x97, 0xf6, 0x3e, 0xbe, 0x12, 0x63, 0x32, 0xf7, 0x0d, 0x2c, 0xa9, 0xa5, 0x1c, 0xcd, 0x49, 0x99, - 0xbd, 0xad, 0x7b, 0x57, 0x2f, 0xd7, 0x9b, 0x8e, 0x64, 0x52, 0xd3, 0x6d, 0x1e, 0x93, 0xbd, 0x06, - 0x79, 0xeb, 0xd7, 0x8c, 0x45, 0x74, 0x00, 0x45, 0xd3, 0x68, 0xe6, 0x41, 0xed, 0x19, 0xe6, 0xd5, - 0x2f, 0x07, 0x68, 0xb2, 0x4d, 0x07, 0x1d, 0x8c, 0x77, 0xbc, 0x79, 0xa1, 0xd9, 0x05, 0xea, 0x5d, - 0xf3, 0xff, 0x86, 0xb3, 0xe9, 0xa0, 0x1f, 0xa0, 0x6a, 0x95, 0x20, 0xfa, 0x24, 0xeb, 0x92, 0xad, - 0x67, 0xef, 0xd3, 0x6b, 0x50, 0x3a, 0xd8, 0x56, 0xed, 0xd5, 0xc5, 0x9a, 0xf3, 0xd7, 0xc5, 0x9a, - 0xf3, 0xcf, 0xc5, 0x9a, 0xd3, 0x29, 0xaa, 0x5f, 0xe4, 0x67, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, - 0x4d, 0x94, 0x5a, 0xb6, 0xd8, 0x0d, 0x00, 0x00, + // 1214 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x4f, 0x6f, 0x1b, 0x55, + 0x10, 0x67, 0x6d, 0xc7, 0xf6, 0x8e, 0x9d, 0x28, 0x3c, 0xa0, 0x5a, 0x2d, 0x90, 0x98, 0x05, 0x24, + 0xab, 0x6a, 0xd7, 0x69, 0xa0, 0x08, 0x72, 0xa8, 0x5a, 0xc7, 0x45, 0x24, 0x4a, 0x44, 0xd8, 0x34, + 0x54, 0xe2, 0xb6, 0xb6, 0x5f, 0xdc, 0x55, 0xd6, 0xfb, 0x96, 0xf7, 0x9e, 0xa3, 0x86, 0x4f, 0xc1, + 0x81, 0x6f, 0xc2, 0x81, 0x33, 0x07, 0xa4, 0xde, 0xe0, 0xcc, 0x21, 0x45, 0xb9, 0xc3, 0x67, 0x40, + 0xef, 0xcf, 0xda, 0xcf, 0x5e, 0xe7, 0x8f, 0xd3, 0x93, 0xdf, 0xcc, 0xfe, 0xe6, 0xb7, 0xf3, 0x66, + 0x66, 0x67, 0xc6, 0xb0, 0xdc, 0x23, 0x09, 0xa7, 0x24, 0xf6, 0x53, 0x4a, 0x38, 0x41, 0xab, 0x43, + 0xd2, 0x3d, 0xf3, 0xbb, 0xa3, 0x28, 0xee, 0x9f, 0x44, 0xdc, 0x3f, 0x7d, 0xe0, 0xde, 0x1f, 0x44, + 0xfc, 0xc5, 0xa8, 0xeb, 0xf7, 0xc8, 0xb0, 0x35, 0x20, 0x03, 0xd2, 0x92, 0xc0, 0xee, 0xe8, 0x58, + 0x4a, 0x52, 0x90, 0x27, 0x45, 0xe0, 0xae, 0x0f, 0x08, 0x19, 0xc4, 0x78, 0x82, 0xe2, 0xd1, 0x10, + 0x33, 0x1e, 0x0e, 0x53, 0x0d, 0xb8, 0x67, 0xf0, 0x89, 0x97, 0xb5, 0xb2, 0x97, 0xb5, 0x18, 0x89, + 0x4f, 0x31, 0x6d, 0xa5, 0xdd, 0x16, 0x49, 0x99, 0x42, 0x7b, 0x2b, 0x50, 0x3f, 0xa0, 0xa3, 0x04, + 0x07, 0xf8, 0xc7, 0x11, 0x66, 0xdc, 0xbb, 0x0b, 0xab, 0x9d, 0x88, 0x9d, 0x1c, 0xb1, 0x70, 0x90, + 0xe9, 0xd0, 0x1d, 0x28, 0x1f, 0x47, 0x31, 0xc7, 0xd4, 0xb1, 0x1a, 0x56, 0xd3, 0x0e, 0xb4, 0xe4, + 0xed, 0xc2, 0xdb, 0x06, 0x96, 0xa5, 0x24, 0x61, 0x18, 0x3d, 0x84, 0x32, 0xc5, 0x3d, 0x42, 0xfb, + 0x8e, 0xd5, 0x28, 0x36, 0x6b, 0x9b, 0x1f, 0xfa, 0xb3, 0x37, 0xf6, 0xb5, 0x81, 0x00, 0x05, 0x1a, + 0xec, 0xfd, 0x5e, 0x80, 0x9a, 0xa1, 0x47, 0x2b, 0x50, 0xd8, 0xe9, 0xe8, 0xf7, 0x15, 0x76, 0x3a, + 0xc8, 0x81, 0xca, 0xfe, 0x88, 0x87, 0xdd, 0x18, 0x3b, 0x85, 0x86, 0xd5, 0xac, 0x06, 0x99, 0x88, + 0xde, 0x85, 0xa5, 0x9d, 0xe4, 0x88, 0x61, 0xa7, 0x28, 0xf5, 0x4a, 0x40, 0x08, 0x4a, 0x87, 0xd1, + 0x4f, 0xd8, 0x29, 0x35, 0xac, 0x66, 0x31, 0x90, 0x67, 0x71, 0x8f, 0x83, 0x90, 0xe2, 0x84, 0x3b, + 0x4b, 0xea, 0x1e, 0x4a, 0x42, 0x6d, 0xb0, 0xb7, 0x29, 0x0e, 0x39, 0xee, 0x3f, 0xe1, 0x4e, 0xb9, + 0x61, 0x35, 0x6b, 0x9b, 0xae, 0xaf, 0xc2, 0xec, 0x67, 0x61, 0xf6, 0x9f, 0x65, 0x61, 0x6e, 0x57, + 0x5f, 0x9d, 0xaf, 0xbf, 0xf5, 0xf3, 0xeb, 0x75, 0x2b, 0x98, 0x98, 0xa1, 0xc7, 0x00, 0x7b, 0x21, + 0xe3, 0x47, 0x4c, 0x92, 0x54, 0xae, 0x25, 0x29, 0x49, 0x02, 0xc3, 0x06, 0xad, 0x01, 0xc8, 0x00, + 0x6c, 0x93, 0x51, 0xc2, 0x9d, 0xaa, 0xf4, 0xdb, 0xd0, 0xa0, 0x06, 0xd4, 0x3a, 0x98, 0xf5, 0x68, + 0x94, 0xf2, 0x88, 0x24, 0x8e, 0x2d, 0xaf, 0x60, 0xaa, 0xbc, 0x5f, 0x4a, 0x50, 0x3f, 0x14, 0x39, + 0xce, 0x12, 0xb7, 0x0a, 0xc5, 0x00, 0x1f, 0xeb, 0x28, 0x8a, 0x23, 0xf2, 0x01, 0x3a, 0xf8, 0x38, + 0x4a, 0x22, 0xc9, 0x51, 0x90, 0x6e, 0xae, 0xf8, 0x69, 0xd7, 0x9f, 0x68, 0x03, 0x03, 0x81, 0x5c, + 0xa8, 0x3e, 0x7d, 0x99, 0x12, 0x2a, 0x92, 0x5f, 0x94, 0x34, 0x63, 0x19, 0x3d, 0x87, 0xe5, 0xec, + 0xfc, 0x84, 0x73, 0xca, 0x9c, 0x92, 0x4c, 0xf8, 0x83, 0x7c, 0xc2, 0x4d, 0xa7, 0xfc, 0x29, 0x9b, + 0xa7, 0x09, 0xa7, 0x67, 0xc1, 0x34, 0x8f, 0xc8, 0xf5, 0x21, 0x66, 0x4c, 0x78, 0xa8, 0x12, 0x95, + 0x89, 0xc2, 0x9d, 0xaf, 0x29, 0x49, 0x38, 0x4e, 0xfa, 0x32, 0x51, 0x76, 0x30, 0x96, 0x85, 0x3b, + 0xd9, 0x59, 0xb9, 0x53, 0xb9, 0x91, 0x3b, 0x53, 0x36, 0xda, 0x9d, 0x29, 0x1d, 0xda, 0x82, 0xa5, + 0xed, 0xb0, 0xf7, 0x02, 0xcb, 0x9c, 0xd4, 0x36, 0xd7, 0xf2, 0x84, 0xf2, 0xf1, 0xb7, 0x32, 0x09, + 0xac, 0x5d, 0x12, 0xe5, 0x11, 0x28, 0x13, 0xf7, 0x31, 0xa0, 0xfc, 0x7d, 0x45, 0x5e, 0x4e, 0xf0, + 0x59, 0x96, 0x97, 0x13, 0x7c, 0x26, 0x8a, 0xf8, 0x34, 0x8c, 0x47, 0xaa, 0xb8, 0xed, 0x40, 0x09, + 0x5b, 0x85, 0x2f, 0x2d, 0xc1, 0x90, 0x77, 0x71, 0x11, 0x06, 0xef, 0xb5, 0x05, 0x75, 0xd3, 0x43, + 0xf4, 0x01, 0xd8, 0xca, 0xa9, 0x49, 0x71, 0x4c, 0x14, 0xa2, 0x0e, 0x77, 0x86, 0x5a, 0x60, 0x4e, + 0xa1, 0x51, 0x6c, 0xda, 0x81, 0xa1, 0x41, 0xdf, 0x41, 0x4d, 0x81, 0x55, 0x94, 0x8b, 0x32, 0xca, + 0xad, 0xab, 0x83, 0xe2, 0x1b, 0x16, 0x2a, 0xc6, 0x26, 0x87, 0xfb, 0x08, 0x56, 0x67, 0x01, 0x0b, + 0xdd, 0xf0, 0x37, 0x0b, 0x96, 0x75, 0x52, 0x75, 0x17, 0x0a, 0x33, 0x46, 0x4c, 0x33, 0x9d, 0xee, + 0x47, 0x0f, 0x2f, 0xad, 0x07, 0x05, 0xf3, 0x67, 0xed, 0x94, 0xbf, 0x39, 0x3a, 0x77, 0x1b, 0xde, + 0x9b, 0x0b, 0x5d, 0xc8, 0xf3, 0x8f, 0x60, 0xf9, 0x90, 0x87, 0x7c, 0xc4, 0x2e, 0xfd, 0x64, 0xbd, + 0x5f, 0x2d, 0x58, 0xc9, 0x30, 0xfa, 0x76, 0x9f, 0x43, 0xf5, 0x14, 0x53, 0x8e, 0x5f, 0x62, 0xa6, + 0x6f, 0xe5, 0xe4, 0x6f, 0xf5, 0xbd, 0x44, 0x04, 0x63, 0x24, 0xda, 0x82, 0x2a, 0x93, 0x3c, 0x58, + 0xa5, 0x75, 0x6e, 0x29, 0x2b, 0x2b, 0xfd, 0xbe, 0x31, 0x1e, 0xb5, 0xa0, 0x14, 0x93, 0x41, 0x96, + 0xed, 0xf7, 0x2f, 0xb3, 0xdb, 0x23, 0x83, 0x40, 0x02, 0xbd, 0xf3, 0x02, 0x94, 0x95, 0x0e, 0xed, + 0x42, 0xb9, 0x1f, 0x0d, 0x30, 0xe3, 0xea, 0x56, 0xed, 0x4d, 0xf1, 0x81, 0xfc, 0x7d, 0xbe, 0x7e, + 0xd7, 0x18, 0x54, 0x24, 0xc5, 0x89, 0x18, 0x94, 0x61, 0x94, 0x60, 0xca, 0x5a, 0x03, 0x72, 0x5f, + 0x99, 0xf8, 0x1d, 0xf9, 0x13, 0x68, 0x06, 0xc1, 0x15, 0x25, 0xe9, 0x88, 0xeb, 0xc2, 0xbc, 0x1d, + 0x97, 0x62, 0x10, 0x23, 0x22, 0x09, 0x87, 0x58, 0xf7, 0x35, 0x79, 0x16, 0x23, 0xa2, 0x27, 0xea, + 0xb6, 0x2f, 0x07, 0x47, 0x35, 0xd0, 0x12, 0xda, 0x82, 0x0a, 0xe3, 0x21, 0xe5, 0xb8, 0x2f, 0x5b, + 0xd2, 0x4d, 0x7a, 0x7b, 0x66, 0x80, 0x1e, 0x81, 0xdd, 0x23, 0xc3, 0x34, 0xc6, 0xc2, 0xba, 0x7c, + 0x43, 0xeb, 0x89, 0x89, 0xa8, 0x1e, 0x4c, 0x29, 0xa1, 0x72, 0xaa, 0xd8, 0x81, 0x12, 0xbc, 0xff, + 0x0a, 0x50, 0x37, 0x93, 0x95, 0x9b, 0x98, 0xbb, 0x50, 0x56, 0xa9, 0x57, 0x55, 0x77, 0xbb, 0x50, + 0x29, 0x86, 0xb9, 0xa1, 0x72, 0xa0, 0xd2, 0x1b, 0x51, 0x39, 0x4e, 0xd5, 0x90, 0xcd, 0x44, 0xe1, + 0x30, 0x27, 0x3c, 0x8c, 0x65, 0xa8, 0x8a, 0x81, 0x12, 0xc4, 0x94, 0x1d, 0xaf, 0x2a, 0x8b, 0x4d, + 0xd9, 0xb1, 0x99, 0x99, 0x86, 0xca, 0x1b, 0xa5, 0xa1, 0xba, 0x70, 0x1a, 0xbc, 0x3f, 0x2c, 0xb0, + 0xc7, 0x55, 0x6e, 0x44, 0xd7, 0x7a, 0xe3, 0xe8, 0x4e, 0x45, 0xa6, 0x70, 0xbb, 0xc8, 0xdc, 0x81, + 0x32, 0xe3, 0x14, 0x87, 0x43, 0x99, 0xa3, 0x62, 0xa0, 0x25, 0xd1, 0x4f, 0x86, 0x6c, 0x20, 0x33, + 0x54, 0x0f, 0xc4, 0xd1, 0xf3, 0xa0, 0xde, 0x3e, 0xe3, 0x98, 0xed, 0x63, 0x26, 0x96, 0x0b, 0x91, + 0xdb, 0x7e, 0xc8, 0x43, 0x79, 0x8f, 0x7a, 0x20, 0xcf, 0xde, 0x3d, 0x40, 0x7b, 0x11, 0xe3, 0xcf, + 0x09, 0x3d, 0xc1, 0x94, 0xcd, 0xdb, 0x03, 0x8b, 0xc6, 0x1e, 0xb8, 0x0f, 0xef, 0x4c, 0xa1, 0x75, + 0x97, 0xfa, 0x62, 0x66, 0x13, 0x9c, 0xd3, 0x6d, 0x94, 0xc9, 0xcc, 0x2a, 0xf8, 0xa7, 0x05, 0x75, + 0xf3, 0x41, 0xae, 0xb2, 0xdb, 0x50, 0xde, 0x0b, 0xbb, 0x38, 0xce, 0xda, 0xd8, 0xdd, 0xab, 0x89, + 0x7d, 0x05, 0x56, 0x7d, 0x5c, 0x5b, 0xa2, 0x0d, 0xb0, 0xd3, 0x38, 0xe4, 0xc7, 0x84, 0x0e, 0xb3, + 0xae, 0x56, 0x17, 0x7b, 0xd0, 0x81, 0x56, 0xea, 0x31, 0x3e, 0x01, 0xb9, 0x5f, 0x41, 0xcd, 0x20, + 0x5a, 0xa4, 0xcb, 0x6f, 0xfe, 0x5b, 0x84, 0xca, 0xb6, 0xfa, 0x1b, 0x80, 0x9e, 0x81, 0x3d, 0x5e, + 0x9a, 0x91, 0x97, 0xf7, 0x7c, 0x76, 0xfb, 0x76, 0x3f, 0xbe, 0x12, 0xa3, 0x63, 0xfd, 0x0d, 0x2c, + 0xc9, 0x35, 0x1e, 0xcd, 0x09, 0xb2, 0xb9, 0xdf, 0xbb, 0x57, 0xaf, 0xe3, 0x1b, 0x96, 0x60, 0x92, + 0xf3, 0x70, 0x1e, 0x93, 0xb9, 0x38, 0xb9, 0xeb, 0xd7, 0x0c, 0x52, 0xb4, 0x0f, 0x65, 0xdd, 0x9a, + 0xe6, 0x41, 0xcd, 0xa9, 0xe7, 0x36, 0x2e, 0x07, 0x28, 0xb2, 0x0d, 0x0b, 0xed, 0x8f, 0xb7, 0xc2, + 0x79, 0xae, 0x99, 0x25, 0xed, 0x5e, 0xf3, 0xbc, 0x69, 0x6d, 0x58, 0xe8, 0x07, 0xa8, 0x19, 0x45, + 0x8b, 0x3e, 0xc9, 0x9b, 0xe4, 0xbf, 0x00, 0xf7, 0xd3, 0x6b, 0x50, 0xca, 0xd9, 0x76, 0xfd, 0xd5, + 0xc5, 0x9a, 0xf5, 0xd7, 0xc5, 0x9a, 0xf5, 0xcf, 0xc5, 0x9a, 0xd5, 0x2d, 0xcb, 0x6f, 0xf8, 0xb3, + 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x86, 0xd4, 0x0f, 0xa1, 0x0a, 0x0e, 0x00, 0x00, } diff --git a/vendor/github.com/moby/buildkit/api/services/control/control.proto b/vendor/github.com/moby/buildkit/api/services/control/control.proto index 7944ce89a87e2..9768920f7e816 100644 --- a/vendor/github.com/moby/buildkit/api/services/control/control.proto +++ b/vendor/github.com/moby/buildkit/api/services/control/control.proto @@ -118,4 +118,5 @@ message ListWorkersResponse { message WorkerRecord { string ID = 1; map Labels = 2; + repeated pb.Platform platforms = 3 [(gogoproto.nullable) = false]; } diff --git a/vendor/github.com/moby/buildkit/cache/manager.go b/vendor/github.com/moby/buildkit/cache/manager.go index f0ea2e77a9aa3..a10cb9e80680c 100644 --- a/vendor/github.com/moby/buildkit/cache/manager.go +++ b/vendor/github.com/moby/buildkit/cache/manager.go @@ -17,7 +17,7 @@ import ( ) var ( - errLocked = errors.New("locked") + ErrLocked = errors.New("locked") errNotFound = errors.New("not found") errInvalid = errors.New("invalid") ) @@ -122,7 +122,7 @@ func (cm *cacheManager) get(ctx context.Context, id string, fromSnapshotter bool if rec.mutable { if len(rec.refs) != 0 { - return nil, errors.Wrapf(errLocked, "%s is locked", id) + return nil, errors.Wrapf(ErrLocked, "%s is locked", id) } if rec.equalImmutable != nil { return rec.equalImmutable.ref(), nil @@ -279,12 +279,12 @@ func (cm *cacheManager) GetMutable(ctx context.Context, id string) (MutableRef, } if len(rec.refs) != 0 { - return nil, errors.Wrapf(errLocked, "%s is locked", id) + return nil, errors.Wrapf(ErrLocked, "%s is locked", id) } if rec.equalImmutable != nil { if len(rec.equalImmutable.refs) != 0 { - return nil, errors.Wrapf(errLocked, "%s is locked", id) + return nil, errors.Wrapf(ErrLocked, "%s is locked", id) } delete(cm.records, rec.equalImmutable.ID()) if err := rec.equalImmutable.remove(ctx, false); err != nil { @@ -513,7 +513,7 @@ func (cm *cacheManager) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) } func IsLocked(err error) bool { - return errors.Cause(err) == errLocked + return errors.Cause(err) == ErrLocked } func IsNotFound(err error) bool { diff --git a/vendor/github.com/moby/buildkit/client/client.go b/vendor/github.com/moby/buildkit/client/client.go index c71c00c0e2c52..403ed52a8ce3c 100644 --- a/vendor/github.com/moby/buildkit/client/client.go +++ b/vendor/github.com/moby/buildkit/client/client.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "io/ioutil" - "time" "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" controlapi "github.com/moby/buildkit/api/services/control" @@ -23,7 +22,7 @@ type Client struct { type ClientOpt interface{} // New returns a new buildkit client. Address can be empty for the system-default address. -func New(address string, opts ...ClientOpt) (*Client, error) { +func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error) { gopts := []grpc.DialOption{ grpc.WithDialer(dialer), grpc.FailOnNonTempDialError(true), @@ -54,9 +53,6 @@ func New(address string, opts ...ClientOpt) (*Client, error) { address = appdefaults.Address } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - conn, err := grpc.DialContext(ctx, address, gopts...) if err != nil { return nil, errors.Wrapf(err, "failed to dial %q . make sure buildkitd is running", address) diff --git a/vendor/github.com/moby/buildkit/client/llb/exec.go b/vendor/github.com/moby/buildkit/client/llb/exec.go index 98be2653e4583..9dec170f0256d 100644 --- a/vendor/github.com/moby/buildkit/client/llb/exec.go +++ b/vendor/github.com/moby/buildkit/client/llb/exec.go @@ -17,8 +17,8 @@ type Meta struct { ProxyEnv *ProxyEnv } -func NewExecOp(root Output, meta Meta, readOnly bool, md OpMetadata) *ExecOp { - e := &ExecOp{meta: meta, cachedOpMetadata: md} +func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp { + e := &ExecOp{meta: meta, constraints: c} rootMount := &mount{ target: pb.RootMount, source: root, @@ -28,32 +28,35 @@ func NewExecOp(root Output, meta Meta, readOnly bool, md OpMetadata) *ExecOp { if readOnly { e.root = root } else { - e.root = &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} + o := &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} + if p := c.Platform; p != nil { + o.platform = p + } + e.root = o } rootMount.output = e.root - return e } type mount struct { - target string - readonly bool - source Output - output Output - selector string - cacheID string - tmpfs bool + target string + readonly bool + source Output + output Output + selector string + cacheID string + tmpfs bool + cacheSharing CacheMountSharingMode // hasOutput bool } type ExecOp struct { - root Output - mounts []*mount - meta Meta - cachedPBDigest digest.Digest - cachedPB []byte - cachedOpMetadata OpMetadata - isValidated bool + MarshalCache + root Output + mounts []*mount + meta Meta + constraints Constraints + isValidated bool } func (e *ExecOp) AddMount(target string, source Output, opt ...MountOption) Output { @@ -70,9 +73,13 @@ func (e *ExecOp) AddMount(target string, source Output, opt ...MountOption) Outp } else if m.tmpfs { m.output = &output{vertex: e, err: errors.Errorf("tmpfs mount for %s can't be used as a parent", target)} } else { - m.output = &output{vertex: e, getIndex: e.getMountIndexFn(m)} + o := &output{vertex: e, getIndex: e.getMountIndexFn(m)} + if p := e.constraints.Platform; p != nil { + o.platform = p + } + m.output = o } - e.cachedPB = nil + e.Store(nil, nil, nil) e.isValidated = false return m.output } @@ -107,9 +114,9 @@ func (e *ExecOp) Validate() error { return nil } -func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { - if e.cachedPB != nil { - return e.cachedPBDigest, e.cachedPB, &e.cachedOpMetadata, nil +func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { + if e.Cached(c) { + return e.Load() } if err := e.Validate(); err != nil { return "", nil, nil, err @@ -137,10 +144,9 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { } } - pop := &pb.Op{ - Op: &pb.Op_Exec{ - Exec: peo, - }, + pop, md := MarshalConstraints(c, &e.constraints) + pop.Op = &pb.Op_Exec{ + Exec: peo, } outIndex := 0 @@ -150,7 +156,7 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { if m.tmpfs { return "", nil, nil, errors.Errorf("tmpfs mounts must use scratch") } - inp, err := m.source.ToInput() + inp, err := m.source.ToInput(c) if err != nil { return "", nil, nil, err } @@ -190,6 +196,14 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { pm.CacheOpt = &pb.CacheOpt{ ID: m.cacheID, } + switch m.cacheSharing { + case CacheMountShared: + pm.CacheOpt.Sharing = pb.CacheSharingOpt_SHARED + case CacheMountPrivate: + pm.CacheOpt.Sharing = pb.CacheSharingOpt_PRIVATE + case CacheMountLocked: + pm.CacheOpt.Sharing = pb.CacheSharingOpt_LOCKED + } } if m.tmpfs { pm.MountType = pb.MountType_TMPFS @@ -201,9 +215,8 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { if err != nil { return "", nil, nil, err } - e.cachedPBDigest = digest.FromBytes(dt) - e.cachedPB = dt - return e.cachedPBDigest, dt, &e.cachedOpMetadata, nil + e.Store(dt, md, c) + return e.Load() } func (e *ExecOp) Output() Output { @@ -273,9 +286,10 @@ func SourcePath(src string) MountOption { } } -func AsPersistentCacheDir(id string) MountOption { +func AsPersistentCacheDir(id string, sharing CacheMountSharingMode) MountOption { return func(m *mount) { m.cacheID = id + m.cacheSharing = sharing } } @@ -366,7 +380,7 @@ func WithProxy(ps ProxyEnv) RunOption { } type ExecInfo struct { - opMetaWrapper + constraintsWrapper State State Mounts []MountInfo ReadonlyRootFS bool @@ -385,3 +399,11 @@ type ProxyEnv struct { FtpProxy string NoProxy string } + +type CacheMountSharingMode int + +const ( + CacheMountShared CacheMountSharingMode = iota + CacheMountPrivate + CacheMountLocked +) diff --git a/vendor/github.com/moby/buildkit/client/llb/imagemetaresolver/resolver.go b/vendor/github.com/moby/buildkit/client/llb/imagemetaresolver/resolver.go index d7d0d7460fee0..09d4aec1b1a1b 100644 --- a/vendor/github.com/moby/buildkit/client/llb/imagemetaresolver/resolver.go +++ b/vendor/github.com/moby/buildkit/client/llb/imagemetaresolver/resolver.go @@ -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 } diff --git a/vendor/github.com/moby/buildkit/client/llb/marshal.go b/vendor/github.com/moby/buildkit/client/llb/marshal.go index 4d8ad5557a553..65a352fae89c0 100644 --- a/vendor/github.com/moby/buildkit/client/llb/marshal.go +++ b/vendor/github.com/moby/buildkit/client/llb/marshal.go @@ -4,6 +4,7 @@ import ( "io" "io/ioutil" + "github.com/containerd/containerd/platforms" "github.com/moby/buildkit/solver/pb" digest "github.com/opencontainers/go-digest" ) @@ -12,11 +13,11 @@ import ( // Corresponds to the Definition structure defined in solver/pb.Definition. type Definition struct { Def [][]byte - Metadata map[digest.Digest]OpMetadata + Metadata map[digest.Digest]pb.OpMetadata } func (def *Definition) ToPB() *pb.Definition { - md := make(map[digest.Digest]OpMetadata) + md := make(map[digest.Digest]pb.OpMetadata) for k, v := range def.Metadata { md[k] = v } @@ -28,14 +29,12 @@ func (def *Definition) ToPB() *pb.Definition { func (def *Definition) FromPB(x *pb.Definition) { def.Def = x.Def - def.Metadata = make(map[digest.Digest]OpMetadata) + def.Metadata = make(map[digest.Digest]pb.OpMetadata) for k, v := range x.Metadata { def.Metadata[k] = v } } -type OpMetadata = pb.OpMetadata - func WriteTo(def *Definition, w io.Writer) error { b, err := def.ToPB().Marshal() if err != nil { @@ -58,3 +57,56 @@ func ReadFrom(r io.Reader) (*Definition, error) { def.FromPB(&pbDef) return &def, nil } + +func MarshalConstraints(base, override *Constraints) (*pb.Op, *pb.OpMetadata) { + c := *base + c.WorkerConstraints = append([]string{}, c.WorkerConstraints...) + + if p := override.Platform; p != nil { + c.Platform = p + } + + for _, wc := range override.WorkerConstraints { + c.WorkerConstraints = append(c.WorkerConstraints, wc) + } + + c.Metadata = mergeMetadata(c.Metadata, override.Metadata) + + if c.Platform == nil { + defaultPlatform := platforms.Normalize(platforms.DefaultSpec()) + c.Platform = &defaultPlatform + } + + return &pb.Op{ + Platform: &pb.Platform{ + OS: c.Platform.OS, + Architecture: c.Platform.Architecture, + Variant: c.Platform.Variant, + OSVersion: c.Platform.OSVersion, + OSFeatures: c.Platform.OSFeatures, + }, + Constraints: &pb.WorkerConstraints{ + Filter: c.WorkerConstraints, + }, + }, &c.Metadata +} + +type MarshalCache struct { + digest digest.Digest + dt []byte + md *pb.OpMetadata + constraints *Constraints +} + +func (mc *MarshalCache) Cached(c *Constraints) bool { + return mc.dt != nil && mc.constraints == c +} +func (mc *MarshalCache) Load() (digest.Digest, []byte, *pb.OpMetadata, error) { + return mc.digest, mc.dt, mc.md, nil +} +func (mc *MarshalCache) Store(dt []byte, md *pb.OpMetadata, c *Constraints) { + mc.digest = digest.FromBytes(dt) + mc.dt = dt + mc.md = md + mc.constraints = c +} diff --git a/vendor/github.com/moby/buildkit/client/llb/meta.go b/vendor/github.com/moby/buildkit/client/llb/meta.go index 54449ff6062f7..22aea097d482a 100644 --- a/vendor/github.com/moby/buildkit/client/llb/meta.go +++ b/vendor/github.com/moby/buildkit/client/llb/meta.go @@ -4,16 +4,19 @@ import ( "fmt" "path" + "github.com/containerd/containerd/platforms" "github.com/google/shlex" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) type contextKeyT string var ( - keyArgs = contextKeyT("llb.exec.args") - keyDir = contextKeyT("llb.exec.dir") - keyEnv = contextKeyT("llb.exec.env") - keyUser = contextKeyT("llb.exec.user") + keyArgs = contextKeyT("llb.exec.args") + keyDir = contextKeyT("llb.exec.dir") + keyEnv = contextKeyT("llb.exec.env") + keyUser = contextKeyT("llb.exec.user") + keyPlatform = contextKeyT("llb.platform") ) func addEnv(key, value string) StateOption { @@ -106,6 +109,21 @@ func shlexf(str string, v ...interface{}) StateOption { } } +func platform(p specs.Platform) StateOption { + return func(s State) State { + return s.WithValue(keyPlatform, platforms.Normalize(p)) + } +} + +func getPlatform(s State) *specs.Platform { + v := s.Value(keyPlatform) + if v != nil { + p := v.(specs.Platform) + return &p + } + return nil +} + type EnvList []KeyValue type KeyValue struct { diff --git a/vendor/github.com/moby/buildkit/client/llb/resolver.go b/vendor/github.com/moby/buildkit/client/llb/resolver.go index bac738c967321..b539b1159e83e 100644 --- a/vendor/github.com/moby/buildkit/client/llb/resolver.go +++ b/vendor/github.com/moby/buildkit/client/llb/resolver.go @@ -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) } diff --git a/vendor/github.com/moby/buildkit/client/llb/source.go b/vendor/github.com/moby/buildkit/client/llb/source.go index 5b1bf061bf04d..f0f296849984a 100644 --- a/vendor/github.com/moby/buildkit/client/llb/source.go +++ b/vendor/github.com/moby/buildkit/client/llb/source.go @@ -15,22 +15,21 @@ import ( ) type SourceOp struct { - id string - attrs map[string]string - output Output - cachedPBDigest digest.Digest - cachedPB []byte - cachedOpMetadata OpMetadata - err error + MarshalCache + id string + attrs map[string]string + output Output + constraints Constraints + err error } -func NewSource(id string, attrs map[string]string, md OpMetadata) *SourceOp { +func NewSource(id string, attrs map[string]string, c Constraints) *SourceOp { s := &SourceOp{ - id: id, - attrs: attrs, - cachedOpMetadata: md, + id: id, + attrs: attrs, + constraints: c, } - s.output = &output{vertex: s} + s.output = &output{vertex: s, platform: c.Platform} return s } @@ -44,26 +43,26 @@ func (s *SourceOp) Validate() error { return nil } -func (s *SourceOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { - if s.cachedPB != nil { - return s.cachedPBDigest, s.cachedPB, &s.cachedOpMetadata, nil +func (s *SourceOp) Marshal(constraints *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { + if s.Cached(constraints) { + return s.Load() } if err := s.Validate(); err != nil { return "", nil, nil, err } - proto := &pb.Op{ - Op: &pb.Op_Source{ - Source: &pb.SourceOp{Identifier: s.id, Attrs: s.attrs}, - }, + proto, md := MarshalConstraints(constraints, &s.constraints) + + proto.Op = &pb.Op_Source{ + Source: &pb.SourceOp{Identifier: s.id, Attrs: s.attrs}, } dt, err := proto.Marshal() if err != nil { return "", nil, nil, err } - s.cachedPB = dt - s.cachedPBDigest = digest.FromBytes(dt) - return s.cachedPBDigest, dt, &s.cachedOpMetadata, nil + + s.Store(dt, md, constraints) + return s.Load() } func (s *SourceOp) Output() Output { @@ -74,10 +73,6 @@ func (s *SourceOp) Inputs() []Output { return nil } -func Source(id string) State { - return NewState(NewSource(id, nil, OpMetadata{}).Output()) -} - func Image(ref string, opts ...ImageOption) State { r, err := reference.ParseNormalizedNamed(ref) if err == nil { @@ -87,12 +82,12 @@ func Image(ref string, opts ...ImageOption) State { for _, opt := range opts { opt.SetImageOption(&info) } - src := NewSource("docker-image://"+ref, nil, info.Metadata()) // controversial + src := NewSource("docker-image://"+ref, nil, info.Constraints) // controversial if err != nil { 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 { @@ -136,7 +131,7 @@ func (fn ImageOptionFunc) SetImageOption(ii *ImageInfo) { } type ImageInfo struct { - opMetaWrapper + constraintsWrapper metaResolver ImageMetaResolver } @@ -169,7 +164,7 @@ func Git(remote, ref string, opts ...GitOption) State { if url != "" { attrs[pb.AttrFullRemoteURL] = url } - source := NewSource("git://"+id, attrs, gi.Metadata()) + source := NewSource("git://"+id, attrs, gi.Constraints) return NewState(source.Output()) } @@ -183,7 +178,7 @@ func (fn gitOptionFunc) SetGitOption(gi *GitInfo) { } type GitInfo struct { - opMetaWrapper + constraintsWrapper KeepGitDir bool } @@ -220,7 +215,7 @@ func Local(name string, opts ...LocalOption) State { attrs[pb.AttrSharedKeyHint] = gi.SharedKeyHint } - source := NewSource("local://"+name, attrs, gi.Metadata()) + source := NewSource("local://"+name, attrs, gi.Constraints) return NewState(source.Output()) } @@ -280,7 +275,7 @@ func SharedKeyHint(h string) LocalOption { } type LocalInfo struct { - opMetaWrapper + constraintsWrapper SessionID string IncludePatterns string ExcludePatterns string @@ -310,12 +305,12 @@ func HTTP(url string, opts ...HTTPOption) State { attrs[pb.AttrHTTPGID] = strconv.Itoa(hi.GID) } - source := NewSource(url, attrs, hi.Metadata()) + source := NewSource(url, attrs, hi.Constraints) return NewState(source.Output()) } type HTTPInfo struct { - opMetaWrapper + constraintsWrapper Checksum digest.Digest Filename string Perm int diff --git a/vendor/github.com/moby/buildkit/client/llb/state.go b/vendor/github.com/moby/buildkit/client/llb/state.go index a53b212ebbbdd..f9e2138e4256d 100644 --- a/vendor/github.com/moby/buildkit/client/llb/state.go +++ b/vendor/github.com/moby/buildkit/client/llb/state.go @@ -3,21 +3,23 @@ package llb import ( "context" + "github.com/containerd/containerd/platforms" "github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/util/system" digest "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) type StateOption func(State) State type Output interface { - ToInput() (*pb.Input, error) + ToInput(*Constraints) (*pb.Input, error) Vertex() Vertex } type Vertex interface { Validate() error - Marshal() (digest.Digest, []byte, *OpMetadata, error) + Marshal(*Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) Output() Output Inputs() []Output } @@ -29,12 +31,25 @@ func NewState(o Output) State { } s = dir("/")(s) s = addEnv("PATH", system.DefaultPathEnv)(s) + s = s.ensurePlatform() return s } type State struct { - out Output - ctx context.Context + out Output + ctx context.Context + opts []ConstraintsOpt +} + +func (s State) ensurePlatform() State { + if o, ok := s.out.(interface { + Platform() *specs.Platform + }); ok { + if p := o.Platform(); p != nil { + s = platform(*p)(s) + } + } + return s } func (s State) WithValue(k, v interface{}) State { @@ -48,18 +63,32 @@ func (s State) Value(k interface{}) interface{} { return s.ctx.Value(k) } -func (s State) Marshal(md ...MetadataOpt) (*Definition, error) { +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]OpMetadata, 0), + Metadata: make(map[digest.Digest]pb.OpMetadata, 0), } if s.Output() == nil { return def, nil } - def, err := marshal(s.Output().Vertex(), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, md) + + defaultPlatform := platforms.Normalize(platforms.DefaultSpec()) + c := &Constraints{ + Platform: &defaultPlatform, + } + for _, o := range append(s.opts, co...) { + o.SetConstraintsOption(c) + } + + def, err := marshal(s.Output().Vertex(), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, c) if err != nil { return def, err } - inp, err := s.Output().ToInput() + inp, err := s.Output().ToInput(c) if err != nil { return def, err } @@ -72,29 +101,25 @@ func (s State) Marshal(md ...MetadataOpt) (*Definition, error) { return def, nil } -func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, md []MetadataOpt) (*Definition, error) { +func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, c *Constraints) (*Definition, error) { if _, ok := vertexCache[v]; ok { return def, nil } for _, inp := range v.Inputs() { var err error - def, err = marshal(inp.Vertex(), def, cache, vertexCache, md) + def, err = marshal(inp.Vertex(), def, cache, vertexCache, c) if err != nil { return def, err } } - dgst, dt, opMeta, err := v.Marshal() + dgst, dt, opMeta, err := v.Marshal(c) if err != nil { return def, err } vertexCache[v] = struct{}{} if opMeta != nil { - m := mergeMetadata(def.Metadata[dgst], *opMeta) - for _, f := range md { - f.SetMetadataOption(&m) - } - def.Metadata[dgst] = m + def.Metadata[dgst] = mergeMetadata(def.Metadata[dgst], *opMeta) } if _, ok := cache[dgst]; ok { return def, nil @@ -113,14 +138,19 @@ func (s State) Output() Output { } func (s State) WithOutput(o Output) State { - return State{ + s = State{ out: o, ctx: s.ctx, } + s = s.ensurePlatform() + return s } func (s State) Run(ro ...RunOption) ExecState { ei := &ExecInfo{State: s} + if p := s.GetPlatform(); p != nil { + ei.Constraints.Platform = p + } for _, o := range ro { o.SetRunOption(ei) } @@ -132,7 +162,7 @@ func (s State) Run(ro ...RunOption) ExecState { ProxyEnv: ei.ProxyEnv, } - exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Metadata()) + exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Constraints) for _, m := range ei.Mounts { exec.AddMount(m.Target, m.Source, m.Opts...) } @@ -178,6 +208,14 @@ func (s State) User(v string) State { return user(v)(s) } +func (s State) Platform(p specs.Platform) State { + return platform(p)(s) +} + +func (s State) GetPlatform() *specs.Platform { + return getPlatform(s) +} + func (s State) With(so ...StateOption) State { for _, o := range so { s = o(s) @@ -189,9 +227,10 @@ type output struct { vertex Vertex getIndex func() (pb.OutputIndex, error) err error + platform *specs.Platform } -func (o *output) ToInput() (*pb.Input, error) { +func (o *output) ToInput(c *Constraints) (*pb.Input, error) { if o.err != nil { return nil, o.err } @@ -203,7 +242,7 @@ func (o *output) ToInput() (*pb.Input, error) { return nil, err } } - dgst, _, _, err := o.vertex.Marshal() + dgst, _, _, err := o.vertex.Marshal(c) if err != nil { return nil, err } @@ -214,8 +253,12 @@ func (o *output) Vertex() Vertex { return o.vertex } -type MetadataOpt interface { - SetMetadataOption(*OpMetadata) +func (o *output) Platform() *specs.Platform { + return o.platform +} + +type ConstraintsOpt interface { + SetConstraintsOption(*Constraints) RunOption LocalOption HTTPOption @@ -223,33 +266,33 @@ type MetadataOpt interface { GitOption } -type metadataOptFunc func(m *OpMetadata) +type constraintsOptFunc func(m *Constraints) -func (fn metadataOptFunc) SetMetadataOption(m *OpMetadata) { +func (fn constraintsOptFunc) SetConstraintsOption(m *Constraints) { fn(m) } -func (fn metadataOptFunc) SetRunOption(ei *ExecInfo) { - ei.ApplyMetadata(fn) +func (fn constraintsOptFunc) SetRunOption(ei *ExecInfo) { + ei.applyConstraints(fn) } -func (fn metadataOptFunc) SetLocalOption(li *LocalInfo) { - li.ApplyMetadata(fn) +func (fn constraintsOptFunc) SetLocalOption(li *LocalInfo) { + li.applyConstraints(fn) } -func (fn metadataOptFunc) SetHTTPOption(hi *HTTPInfo) { - hi.ApplyMetadata(fn) +func (fn constraintsOptFunc) SetHTTPOption(hi *HTTPInfo) { + hi.applyConstraints(fn) } -func (fn metadataOptFunc) SetImageOption(ii *ImageInfo) { - ii.ApplyMetadata(fn) +func (fn constraintsOptFunc) SetImageOption(ii *ImageInfo) { + ii.applyConstraints(fn) } -func (fn metadataOptFunc) SetGitOption(gi *GitInfo) { - gi.ApplyMetadata(fn) +func (fn constraintsOptFunc) SetGitOption(gi *GitInfo) { + gi.applyConstraints(fn) } -func mergeMetadata(m1, m2 OpMetadata) OpMetadata { +func mergeMetadata(m1, m2 pb.OpMetadata) pb.OpMetadata { if m2.IgnoreCache { m1.IgnoreCache = true } @@ -268,49 +311,77 @@ func mergeMetadata(m1, m2 OpMetadata) OpMetadata { return m1 } -var IgnoreCache = metadataOptFunc(func(md *OpMetadata) { - md.IgnoreCache = true +var IgnoreCache = constraintsOptFunc(func(c *Constraints) { + c.Metadata.IgnoreCache = true }) -func WithDescription(m map[string]string) MetadataOpt { - return metadataOptFunc(func(md *OpMetadata) { - md.Description = m +func WithDescription(m map[string]string) ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { + c.Metadata.Description = m }) } // WithExportCache forces results for this vertex to be exported with the cache -func WithExportCache() MetadataOpt { - return metadataOptFunc(func(md *OpMetadata) { - md.ExportCache = &pb.ExportCache{Value: true} +func WithExportCache() ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { + c.Metadata.ExportCache = &pb.ExportCache{Value: true} }) } // WithoutExportCache sets results for this vertex to be not exported with // the cache -func WithoutExportCache() MetadataOpt { - return metadataOptFunc(func(md *OpMetadata) { +func WithoutExportCache() ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { // ExportCache with value false means to disable exporting - md.ExportCache = &pb.ExportCache{Value: false} + c.Metadata.ExportCache = &pb.ExportCache{Value: false} }) } // WithoutDefaultExportCache resets the cache export for the vertex to use // the default defined by the build configuration. -func WithoutDefaultExportCache() MetadataOpt { - return metadataOptFunc(func(md *OpMetadata) { +func WithoutDefaultExportCache() ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { // nil means no vertex based config has been set - md.ExportCache = nil + c.Metadata.ExportCache = nil }) } -type opMetaWrapper struct { - OpMetadata +type constraintsWrapper struct { + Constraints +} + +func (cw *constraintsWrapper) applyConstraints(f func(c *Constraints)) { + f(&cw.Constraints) } -func (mw *opMetaWrapper) ApplyMetadata(f func(m *OpMetadata)) { - f(&mw.OpMetadata) +type Constraints struct { + Platform *specs.Platform + WorkerConstraints []string + Metadata pb.OpMetadata } -func (mw *opMetaWrapper) Metadata() OpMetadata { - return mw.OpMetadata +func Platform(p specs.Platform) ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { + c.Platform = &p + }) +} + +var ( + LinuxAmd64 = Platform(specs.Platform{OS: "linux", Architecture: "amd64"}) + LinuxArmhf = Platform(specs.Platform{OS: "linux", Architecture: "arm", Variant: "v7"}) + LinuxArm = LinuxArmhf + LinuxArmel = Platform(specs.Platform{OS: "linux", Architecture: "arm", Variant: "v6"}) + LinuxArm64 = Platform(specs.Platform{OS: "linux", Architecture: "arm64"}) + LinuxS390x = Platform(specs.Platform{OS: "linux", Architecture: "s390x"}) + LinuxPpc64le = Platform(specs.Platform{OS: "linux", Architecture: "ppc64le"}) + Darwin = Platform(specs.Platform{OS: "darwin", Architecture: "amd64"}) + Windows = Platform(specs.Platform{OS: "windows", Architecture: "amd64"}) +) + +func Require(filters ...string) ConstraintsOpt { + return constraintsOptFunc(func(c *Constraints) { + for _, f := range filters { + c.WorkerConstraints = append(c.WorkerConstraints, f) + } + }) } diff --git a/vendor/github.com/moby/buildkit/client/workers.go b/vendor/github.com/moby/buildkit/client/workers.go index b4ccb82d4c07a..2645a597ef912 100644 --- a/vendor/github.com/moby/buildkit/client/workers.go +++ b/vendor/github.com/moby/buildkit/client/workers.go @@ -4,12 +4,15 @@ import ( "context" controlapi "github.com/moby/buildkit/api/services/control" + "github.com/moby/buildkit/solver/pb" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) type WorkerInfo struct { - ID string - Labels map[string]string + ID string + Labels map[string]string + Platforms []specs.Platform } func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([]*WorkerInfo, error) { @@ -28,8 +31,9 @@ func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([] for _, w := range resp.Record { wi = append(wi, &WorkerInfo{ - ID: w.ID, - Labels: w.Labels, + ID: w.ID, + Labels: w.Labels, + Platforms: toClientPlatforms(w.Platforms), }) } @@ -47,3 +51,17 @@ func WithWorkerFilter(f []string) ListWorkersOption { wi.Filter = f } } + +func toClientPlatforms(p []pb.Platform) []specs.Platform { + out := make([]specs.Platform, 0, len(p)) + for _, pp := range p { + out = append(out, specs.Platform{ + OS: pp.OS, + Architecture: pp.Architecture, + Variant: pp.Variant, + OSVersion: pp.OSVersion, + OSFeatures: pp.OSFeatures, + }) + } + return out +} diff --git a/vendor/github.com/moby/buildkit/control/control.go b/vendor/github.com/moby/buildkit/control/control.go index ac9060501c1d7..2460df84b6579 100644 --- a/vendor/github.com/moby/buildkit/control/control.go +++ b/vendor/github.com/moby/buildkit/control/control.go @@ -13,7 +13,9 @@ import ( "github.com/moby/buildkit/session/grpchijack" "github.com/moby/buildkit/solver" "github.com/moby/buildkit/solver/llbsolver" + "github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/worker" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" @@ -35,7 +37,10 @@ type Controller struct { // TODO: ControlService } func NewController(opt Opt) (*Controller, error) { - solver := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter) + solver, err := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter) + if err != nil { + return nil, errors.Wrap(err, "failed to create solver") + } c := &Controller{ opt: opt, @@ -265,8 +270,9 @@ func (c *Controller) ListWorkers(ctx context.Context, r *controlapi.ListWorkersR } for _, w := range workers { resp.Record = append(resp.Record, &controlapi.WorkerRecord{ - ID: w.ID(), - Labels: w.Labels(), + ID: w.ID(), + Labels: w.Labels(), + Platforms: toPBPlatforms(w.Platforms()), }) } return resp, nil @@ -290,3 +296,17 @@ func parseCacheExporterOpt(opt map[string]string) solver.CacheExportMode { } return solver.CacheExportModeMin } + +func toPBPlatforms(p []specs.Platform) []pb.Platform { + out := make([]pb.Platform, 0, len(p)) + for _, pp := range p { + out = append(out, pb.Platform{ + OS: pp.OS, + Architecture: pp.Architecture, + Variant: pp.Variant, + OSVersion: pp.OSVersion, + OSFeatures: pp.OSFeatures, + }) + } + return out +} diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go index 9aee2a778dcda..c618f38402a33 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go @@ -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,14 +30,26 @@ const ( buildArgPrefix = "build-arg:" labelPrefix = "label:" keyNoCache = "no-cache" + keyTargetPlatform = "platform" ) var httpPrefix = regexp.MustCompile("^https?://") -var gitUrlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$") +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 { diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go index 756d7e160548b..00e92b3ffae19 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go @@ -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" ) @@ -30,7 +31,7 @@ const ( localNameContext = "context" historyComment = "buildkit.dockerfile.v0" - CopyImage = "tonistiigi/copy:v0.1.3@sha256:87c46e7b413cdd2c2702902b481b390ce263ac9d942253d366f3b1a3c16f96d6" + CopyImage = "tonistiigi/copy:v0.1.3@sha256:e57a3b4d6240f55bac26b655d2cfb751f8b9412d6f7bb1f787e946391fb4b21b" ) type ConvertOpt struct { @@ -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{} @@ -467,7 +517,11 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE opt = append(opt, llb.WithProxy(*proxy)) } - opt = append(opt, dispatchRunMounts(d, c, sources, dopt)...) + runMounts, err := dispatchRunMounts(d, c, sources, dopt) + if err != nil { + return err + } + opt = append(opt, runMounts...) d.state = d.state.Run(opt...).Root() return commitToHistory(&d.image, "RUN "+runCommandString(args, d.buildArgs), true, &d.state) @@ -486,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 { @@ -554,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) } @@ -767,7 +821,7 @@ func getArgValue(arg instructions.ArgCommand) string { return v } -func dfCmd(cmd interface{}) llb.MetadataOpt { +func dfCmd(cmd interface{}) llb.ConstraintsOpt { // TODO: add fmt.Stringer to instructions.Command to remove interface{} var cmdStr string if cmd, ok := cmd.(fmt.Stringer); ok { @@ -798,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, @@ -930,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 +} diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go index b358ee68f330d..a4544e797504e 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go @@ -11,6 +11,6 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState return false } -func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption { - return nil +func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) { + return nil, nil } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go index f1b20293f43b7..61408e1ff00dd 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go @@ -9,6 +9,7 @@ import ( "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/pkg/errors" ) func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool { @@ -40,7 +41,7 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState return false } -func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption { +func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) { var out []llb.RunOption mounts := instructions.GetMounts(c) @@ -61,14 +62,25 @@ func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []* mountOpts = append(mountOpts, llb.Readonly) } if mount.Type == instructions.MountTypeCache { - mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID)) + sharing := llb.CacheMountShared + if mount.CacheSharing == instructions.MountSharingPrivate { + sharing = llb.CacheMountPrivate + } + if mount.CacheSharing == instructions.MountSharingLocked { + sharing = llb.CacheMountLocked + } + mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID, sharing)) + } + target := path.Join("/", mount.Target) + if target == "/" { + return nil, errors.Errorf("invalid mount target %q", mount.Target) } if src := path.Join("/", mount.Source); src != "/" { mountOpts = append(mountOpts, llb.SourcePath(src)) } - out = append(out, llb.AddMount(path.Join("/", mount.Target), st, mountOpts...)) + out = append(out, llb.AddMount(target, st, mountOpts...)) d.ctxPaths[path.Join("/", filepath.ToSlash(mount.Source))] = struct{}{} } - return out + return out, nil } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/image.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/image.go index 59c464a63dd16..6085d1e4d20af 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/image.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/image.go @@ -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" diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go index 3e4617ac918d2..b96010f0b1bd9 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go @@ -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 diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go index 71030fa72b9ad..569c60bc68bba 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go @@ -20,6 +20,16 @@ var allowedMountTypes = map[string]struct{}{ MountTypeTmpfs: {}, } +const MountSharingShared = "shared" +const MountSharingPrivate = "private" +const MountSharingLocked = "locked" + +var allowedSharingTypes = map[string]struct{}{ + MountSharingShared: {}, + MountSharingPrivate: {}, + MountSharingLocked: {}, +} + type mountsKeyT string var mountsKey = mountsKeyT("dockerfile/run/mounts") @@ -76,12 +86,13 @@ type mountState struct { } type Mount struct { - Type string - From string - Source string - Target string - ReadOnly bool - CacheID string + Type string + From string + Source string + Target string + ReadOnly bool + CacheID string + CacheSharing string } func parseMount(value string) (*Mount, error) { @@ -120,7 +131,7 @@ func parseMount(value string) (*Mount, error) { switch key { case "type": if !isValidMountType(strings.ToLower(value)) { - return nil, errors.Errorf("invalid mount type %q", value) + return nil, errors.Errorf("unsupported mount type %q", value) } m.Type = strings.ToLower(value) case "from": @@ -144,6 +155,11 @@ func parseMount(value string) (*Mount, error) { roAuto = false case "id": m.CacheID = value + case "sharing": + if _, ok := allowedSharingTypes[strings.ToLower(value)]; !ok { + return nil, errors.Errorf("unsupported sharing value %q", value) + } + m.CacheSharing = strings.ToLower(value) default: return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field) } @@ -157,5 +173,9 @@ func parseMount(value string) (*Mount, error) { } } + if m.CacheSharing != "" && m.Type != MountTypeCache { + return nil, errors.Errorf("invalid cache sharing set for %v mount", m.Type) + } + return m, nil } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go index 8c8199e1f7256..d84bb43c23b40 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go @@ -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 } diff --git a/vendor/github.com/moby/buildkit/frontend/frontend.go b/vendor/github.com/moby/buildkit/frontend/frontend.go index f522f59964fb4..d76742d7c2e57 100644 --- a/vendor/github.com/moby/buildkit/frontend/frontend.go +++ b/vendor/github.com/moby/buildkit/frontend/frontend.go @@ -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 } diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/client/client.go b/vendor/github.com/moby/buildkit/frontend/gateway/client/client.go index 784925a0b7825..51c11d653339c 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/client/client.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/client/client.go @@ -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 } diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go b/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go index 36726206de670..bc7698a6bc967 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go @@ -8,6 +8,7 @@ import ( "net" "os" "strings" + "sync" "time" "github.com/docker/distribution/reference" @@ -21,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" @@ -62,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. @@ -94,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 } @@ -103,9 +104,11 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten return nil, nil, err } - sourceRef, err = reference.WithDigest(sourceRef, dgst) - if err != nil { - return nil, nil, err + if dgst != "" { + sourceRef, err = reference.WithDigest(sourceRef, dgst) + if err != nil { + return nil, nil, err + } } src := llb.Image(sourceRef.String()) @@ -248,6 +251,7 @@ func (d dummyAddr) String() string { } type llbBridgeForwarder struct { + mu sync.Mutex callCtx context.Context llbBridge frontend.FrontendLLBBridge refs map[string]solver.Result @@ -258,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 } @@ -292,7 +306,9 @@ func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) } id := identity.NewID() + lbf.mu.Lock() lbf.refs[id] = ref + lbf.mu.Unlock() if req.Final { lbf.lastRef = ref lbf.exporterAttr = exp @@ -304,7 +320,9 @@ func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) } func (lbf *llbBridgeForwarder) ReadFile(ctx context.Context, req *pb.ReadFileRequest) (*pb.ReadFileResponse, error) { ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx) + lbf.mu.Lock() ref, ok := lbf.refs[req.Ref] + lbf.mu.Unlock() if !ok { return nil, errors.Errorf("no such ref: %v", req.Ref) } diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go b/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go index eb20999563ec3..bbd8531ea63a0 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.pb.go @@ -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, } diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto b/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto index 55c05e43973df..9ba88bc79ca4e 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto +++ b/vendor/github.com/moby/buildkit/frontend/gateway/pb/gateway.proto @@ -18,6 +18,7 @@ service LLBBridge { message ResolveImageConfigRequest { string Ref = 1; + pb.Platform Platform = 2; } message ResolveImageConfigResponse { diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/bridge.go b/vendor/github.com/moby/buildkit/solver/llbsolver/bridge.go index 98dc2ad5d5c11..8d5f46ec0db93 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/bridge.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/bridge.go @@ -15,6 +15,7 @@ import ( "github.com/moby/buildkit/util/tracing" "github.com/moby/buildkit/worker" digest "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -25,6 +26,7 @@ type llbBridge struct { ci *remotecache.CacheImporter cms map[string]solver.CacheManager cmsMu sync.Mutex + platforms []specs.Platform } func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res solver.CachedResult, exp map[string][]byte, err error) { @@ -59,7 +61,7 @@ func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res s } if req.Definition != nil && req.Definition.Def != nil { - edge, err := Load(req.Definition, WithCacheSources(cms)) + edge, err := Load(req.Definition, WithCacheSources(cms), RuntimePlatforms(b.platforms)) if err != nil { return nil, nil, err } @@ -108,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 { diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go b/vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go index ae5a322c19d9c..b9252275a9439 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go @@ -11,9 +11,11 @@ import ( "sort" "strings" "sync" + "time" "github.com/boltdb/bolt" "github.com/containerd/containerd/mount" + "github.com/docker/docker/pkg/locker" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/executor" @@ -37,16 +39,19 @@ type execOp struct { exec executor.Executor w worker.Worker numInputs int + + cacheMounts map[string]*cacheRefShare } func NewExecOp(v solver.Vertex, op *pb.Op_Exec, cm cache.Manager, md *metadata.Store, exec executor.Executor, w worker.Worker) (solver.Op, error) { return &execOp{ - op: op.Exec, - cm: cm, - md: md, - exec: exec, - numInputs: len(v.Inputs()), - w: w, + op: op.Exec, + cm: cm, + md: md, + exec: exec, + numInputs: len(v.Inputs()), + w: w, + cacheMounts: map[string]*cacheRefShare{}, }, nil } @@ -165,32 +170,72 @@ func (e *execOp) getMountDeps() ([]dep, error) { return deps, nil } -func (e *execOp) getRefCacheDir(ctx context.Context, ref cache.ImmutableRef, id string, m *pb.Mount) (cache.MutableRef, error) { +func (e *execOp) getRefCacheDir(ctx context.Context, ref cache.ImmutableRef, id string, m *pb.Mount, sharing pb.CacheSharingOpt) (mref cache.MutableRef, err error) { key := "cache-dir:" + id if ref != nil { key += ":" + ref.ID() } - return sharedCacheRefs.get(key, func() (cache.MutableRef, error) { - return e.getRefCacheDirNoCache(ctx, key, ref, id, m) - }) + if ref, ok := e.cacheMounts[key]; ok { + return ref.clone(), nil + } + defer func() { + if err == nil { + share := &cacheRefShare{MutableRef: mref, refs: map[*cacheRef]struct{}{}} + e.cacheMounts[key] = share + mref = share.clone() + } + }() + + switch sharing { + case pb.CacheSharingOpt_SHARED: + return sharedCacheRefs.get(key, func() (cache.MutableRef, error) { + return e.getRefCacheDirNoCache(ctx, key, ref, id, m, false) + }) + case pb.CacheSharingOpt_PRIVATE: + return e.getRefCacheDirNoCache(ctx, key, ref, id, m, false) + case pb.CacheSharingOpt_LOCKED: + return e.getRefCacheDirNoCache(ctx, key, ref, id, m, true) + default: + return nil, errors.Errorf("invalid cache sharing option: %s", sharing.String()) + } + } -func (e *execOp) getRefCacheDirNoCache(ctx context.Context, key string, ref cache.ImmutableRef, id string, m *pb.Mount) (cache.MutableRef, error) { +func (e *execOp) getRefCacheDirNoCache(ctx context.Context, key string, ref cache.ImmutableRef, id string, m *pb.Mount, block bool) (cache.MutableRef, error) { makeMutable := func(cache.ImmutableRef) (cache.MutableRef, error) { desc := fmt.Sprintf("cached mount %s from exec %s", m.Dest, strings.Join(e.op.Meta.Args, " ")) return e.cm.New(ctx, ref, cache.WithDescription(desc), cache.CachePolicyRetain) } - sis, err := e.md.Search(key) - if err != nil { - return nil, err - } - for _, si := range sis { - if mRef, err := e.cm.GetMutable(ctx, si.ID()); err == nil { - logrus.Debugf("reusing ref for cache dir: %s", mRef.ID()) - return mRef, nil + cacheRefsLocker.Lock(key) + defer cacheRefsLocker.Unlock(key) + for { + sis, err := e.md.Search(key) + if err != nil { + return nil, err + } + locked := false + for _, si := range sis { + if mRef, err := e.cm.GetMutable(ctx, si.ID()); err == nil { + logrus.Debugf("reusing ref for cache dir: %s", mRef.ID()) + return mRef, nil + } else if errors.Cause(err) == cache.ErrLocked { + locked = true + } + } + if block && locked { + cacheRefsLocker.Unlock(key) + select { + case <-ctx.Done(): + cacheRefsLocker.Lock(key) + return nil, ctx.Err() + case <-time.After(100 * time.Millisecond): + cacheRefsLocker.Lock(key) + } + } else { + break } } mRef, err := makeMutable(ref) @@ -287,7 +332,7 @@ func (e *execOp) Exec(ctx context.Context, inputs []solver.Result) ([]solver.Res if m.CacheOpt == nil { return nil, errors.Errorf("missing cache mount options") } - mRef, err := e.getRefCacheDir(ctx, ref, m.CacheOpt.ID, m) + mRef, err := e.getRefCacheDir(ctx, ref, m.CacheOpt.ID, m, m.CacheOpt.Sharing) if err != nil { return nil, err } @@ -418,6 +463,7 @@ func (m *tmpfsMount) Release() error { return nil } +var cacheRefsLocker = locker.New() var sharedCacheRefs = &cacheRefs{} type cacheRefs struct { @@ -466,9 +512,11 @@ func (r *cacheRefShare) clone() cache.MutableRef { } func (r *cacheRefShare) release(ctx context.Context) error { - r.main.mu.Lock() - defer r.main.mu.Unlock() - delete(r.main.shares, r.key) + if r.main != nil { + r.main.mu.Lock() + defer r.main.mu.Unlock() + delete(r.main.shares, r.key) + } return r.MutableRef.Release(ctx) } diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/ops/source.go b/vendor/github.com/moby/buildkit/solver/llbsolver/ops/source.go index 2133a15463131..722861eeb4f07 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/ops/source.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/ops/source.go @@ -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 } diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/solver.go b/vendor/github.com/moby/buildkit/solver/llbsolver/solver.go index 460d6e1ba1d13..1a03222f1ea70 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/solver.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/solver.go @@ -13,6 +13,7 @@ import ( "github.com/moby/buildkit/solver" "github.com/moby/buildkit/util/progress" "github.com/moby/buildkit/worker" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -30,9 +31,10 @@ type Solver struct { resolveWorker ResolveWorkerFunc frontends map[string]frontend.Frontend ci *remotecache.CacheImporter + platforms []specs.Platform } -func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) *Solver { +func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) (*Solver, error) { s := &Solver{ resolveWorker: defaultResolver(wc), frontends: f, @@ -43,11 +45,18 @@ func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solve cache := solver.NewCacheManager("local", cacheStore, results) + // executing is currently only allowed on default worker + w, err := wc.GetDefault() + if err != nil { + return nil, err + } + s.platforms = w.Platforms() + s.solver = solver.NewSolver(solver.SolverOpt{ ResolveOpFunc: s.resolver(), DefaultCache: cache, }) - return s + return s, nil } func (s *Solver) resolver() solver.ResolveOpFunc { @@ -67,6 +76,7 @@ func (s *Solver) Bridge(b solver.Builder) frontend.FrontendLLBBridge { resolveWorker: s.resolveWorker, ci: s.ci, cms: map[string]solver.CacheManager{}, + platforms: s.platforms, } } diff --git a/vendor/github.com/moby/buildkit/solver/llbsolver/vertex.go b/vendor/github.com/moby/buildkit/solver/llbsolver/vertex.go index f7f17c184fec6..64551caba2053 100644 --- a/vendor/github.com/moby/buildkit/solver/llbsolver/vertex.go +++ b/vendor/github.com/moby/buildkit/solver/llbsolver/vertex.go @@ -3,10 +3,12 @@ package llbsolver import ( "strings" + "github.com/containerd/containerd/platforms" "github.com/moby/buildkit/solver" "github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/source" digest "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -38,11 +40,44 @@ func (v *vertex) Name() string { return v.name } -type LoadOpt func(*solver.VertexOptions) +type LoadOpt func(*pb.Op, *pb.OpMetadata, *solver.VertexOptions) error func WithCacheSources(cms []solver.CacheManager) LoadOpt { - return func(opt *solver.VertexOptions) { + return func(_ *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error { opt.CacheSources = cms + return nil + } +} + +func RuntimePlatforms(p []specs.Platform) LoadOpt { + var defaultPlatform *pb.Platform + for i := range p { + p[i] = platforms.Normalize(p[i]) + } + return func(op *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error { + if op.Platform == nil { + if defaultPlatform == nil { + p := platforms.DefaultSpec() + defaultPlatform = &pb.Platform{ + OS: p.OS, + Architecture: p.Architecture, + } + } + op.Platform = defaultPlatform + } + if _, ok := op.Op.(*pb.Op_Exec); ok { + var found bool + for _, pp := range p { + if pp.OS == op.Platform.OS && pp.Architecture == op.Platform.Architecture && pp.Variant == op.Platform.Variant { + found = true + break + } + } + if !found { + return errors.Errorf("runtime execution on platform %s not supported", platforms.Format(specs.Platform{OS: op.Platform.OS, Architecture: op.Platform.Architecture, Variant: op.Platform.Variant})) + } + } + return nil } } @@ -67,9 +102,11 @@ func newVertex(dgst digest.Digest, op *pb.Op, opMeta *pb.OpMetadata, load func(d } } for _, fn := range opts { - fn(&opt) + if err := fn(op, opMeta, &opt); err != nil { + return nil, err + } } - vtx := &vertex{sys: op.Op, options: opt, digest: dgst, name: llbOpName(op)} + vtx := &vertex{sys: op, options: opt, digest: dgst, name: llbOpName(op)} for _, in := range op.Inputs { sub, err := load(in.Digest) if err != nil { @@ -129,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] + ")" diff --git a/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go b/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go index d6ac7ad9d6488..5806eb7e6b3bd 100644 --- a/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go +++ b/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go @@ -12,6 +12,7 @@ It has these top-level messages: Op + Platform Input ExecOp Meta @@ -25,7 +26,7 @@ OpMetadata ExportCache ProxyEnv - WorkerConstraint + WorkerConstraints Definition */ package pb @@ -50,6 +51,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package +// MountType defines a type of a mount from a supported set type MountType int32 const ( @@ -80,6 +82,34 @@ func (x MountType) String() string { } func (MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorOps, []int{0} } +// CacheSharingOpt defines different sharing modes for cache mount +type CacheSharingOpt int32 + +const ( + // SHARED cache mount can be used concurrently by multiple writers + CacheSharingOpt_SHARED CacheSharingOpt = 0 + // PRIVATE creates a new mount if there are multiple writers + CacheSharingOpt_PRIVATE CacheSharingOpt = 1 + // LOCKED pauses second writer until first one releases the mount + CacheSharingOpt_LOCKED CacheSharingOpt = 2 +) + +var CacheSharingOpt_name = map[int32]string{ + 0: "SHARED", + 1: "PRIVATE", + 2: "LOCKED", +} +var CacheSharingOpt_value = map[string]int32{ + "SHARED": 0, + "PRIVATE": 1, + "LOCKED": 2, +} + +func (x CacheSharingOpt) String() string { + return proto.EnumName(CacheSharingOpt_name, int32(x)) +} +func (CacheSharingOpt) EnumDescriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } + // Op represents a vertex of the LLB DAG. type Op struct { // inputs is a set of input edges. @@ -89,7 +119,9 @@ type Op struct { // *Op_Source // *Op_Copy // *Op_Build - Op isOp_Op `protobuf_oneof:"op"` + Op isOp_Op `protobuf_oneof:"op"` + Platform *Platform `protobuf:"bytes,10,opt,name=platform" json:"platform,omitempty"` + Constraints *WorkerConstraints `protobuf:"bytes,11,opt,name=constraints" json:"constraints,omitempty"` } func (m *Op) Reset() { *m = Op{} } @@ -163,6 +195,20 @@ func (m *Op) GetBuild() *BuildOp { return nil } +func (m *Op) GetPlatform() *Platform { + if m != nil { + return m.Platform + } + return nil +} + +func (m *Op) GetConstraints() *WorkerConstraints { + if m != nil { + return m.Constraints + } + return nil +} + // XXX_OneofFuncs is for the internal use of the proto package. func (*Op) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _Op_OneofMarshaler, _Op_OneofUnmarshaler, _Op_OneofSizer, []interface{}{ @@ -275,6 +321,55 @@ func _Op_OneofSizer(msg proto.Message) (n int) { return n } +// Platform is github.com/opencontainers/image-spec/specs-go/v1.Platform +type Platform struct { + Architecture string `protobuf:"bytes,1,opt,name=Architecture,proto3" json:"Architecture,omitempty"` + OS string `protobuf:"bytes,2,opt,name=OS,proto3" json:"OS,omitempty"` + Variant string `protobuf:"bytes,3,opt,name=Variant,proto3" json:"Variant,omitempty"` + OSVersion string `protobuf:"bytes,4,opt,name=OSVersion,proto3" json:"OSVersion,omitempty"` + OSFeatures []string `protobuf:"bytes,5,rep,name=OSFeatures" json:"OSFeatures,omitempty"` +} + +func (m *Platform) Reset() { *m = Platform{} } +func (m *Platform) String() string { return proto.CompactTextString(m) } +func (*Platform) ProtoMessage() {} +func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } + +func (m *Platform) GetArchitecture() string { + if m != nil { + return m.Architecture + } + return "" +} + +func (m *Platform) GetOS() string { + if m != nil { + return m.OS + } + return "" +} + +func (m *Platform) GetVariant() string { + if m != nil { + return m.Variant + } + return "" +} + +func (m *Platform) GetOSVersion() string { + if m != nil { + return m.OSVersion + } + return "" +} + +func (m *Platform) GetOSFeatures() []string { + if m != nil { + return m.OSFeatures + } + return nil +} + // Input represents an input edge for an Op. type Input struct { // digest of the marshaled input Op @@ -286,7 +381,7 @@ type Input struct { func (m *Input) Reset() { *m = Input{} } func (m *Input) String() string { return proto.CompactTextString(m) } func (*Input) ProtoMessage() {} -func (*Input) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } +func (*Input) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{2} } // ExecOp executes a command in a container. type ExecOp struct { @@ -297,7 +392,7 @@ type ExecOp struct { func (m *ExecOp) Reset() { *m = ExecOp{} } func (m *ExecOp) String() string { return proto.CompactTextString(m) } func (*ExecOp) ProtoMessage() {} -func (*ExecOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{2} } +func (*ExecOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{3} } func (m *ExecOp) GetMeta() *Meta { if m != nil { @@ -327,7 +422,7 @@ type Meta struct { func (m *Meta) Reset() { *m = Meta{} } func (m *Meta) String() string { return proto.CompactTextString(m) } func (*Meta) ProtoMessage() {} -func (*Meta) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{3} } +func (*Meta) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{4} } func (m *Meta) GetArgs() []string { if m != nil { @@ -378,7 +473,7 @@ type Mount struct { func (m *Mount) Reset() { *m = Mount{} } func (m *Mount) String() string { return proto.CompactTextString(m) } func (*Mount) ProtoMessage() {} -func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{4} } +func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{5} } func (m *Mount) GetSelector() string { if m != nil { @@ -415,14 +510,18 @@ func (m *Mount) GetCacheOpt() *CacheOpt { return nil } +// CacheOpt defines options specific to cache mounts type CacheOpt struct { + // ID is an optional namespace for the mount ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + // Sharing is the sharing mode for the mount + Sharing CacheSharingOpt `protobuf:"varint,2,opt,name=sharing,proto3,enum=pb.CacheSharingOpt" json:"sharing,omitempty"` } func (m *CacheOpt) Reset() { *m = CacheOpt{} } func (m *CacheOpt) String() string { return proto.CompactTextString(m) } func (*CacheOpt) ProtoMessage() {} -func (*CacheOpt) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{5} } +func (*CacheOpt) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{6} } func (m *CacheOpt) GetID() string { if m != nil { @@ -431,6 +530,13 @@ func (m *CacheOpt) GetID() string { return "" } +func (m *CacheOpt) GetSharing() CacheSharingOpt { + if m != nil { + return m.Sharing + } + return CacheSharingOpt_SHARED +} + // CopyOp copies files across Ops. type CopyOp struct { Src []*CopySource `protobuf:"bytes,1,rep,name=src" json:"src,omitempty"` @@ -440,7 +546,7 @@ type CopyOp struct { func (m *CopyOp) Reset() { *m = CopyOp{} } func (m *CopyOp) String() string { return proto.CompactTextString(m) } func (*CopyOp) ProtoMessage() {} -func (*CopyOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{6} } +func (*CopyOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{7} } func (m *CopyOp) GetSrc() []*CopySource { if m != nil { @@ -465,7 +571,7 @@ type CopySource struct { func (m *CopySource) Reset() { *m = CopySource{} } func (m *CopySource) String() string { return proto.CompactTextString(m) } func (*CopySource) ProtoMessage() {} -func (*CopySource) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{7} } +func (*CopySource) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{8} } func (m *CopySource) GetSelector() string { if m != nil { @@ -486,7 +592,7 @@ type SourceOp struct { func (m *SourceOp) Reset() { *m = SourceOp{} } func (m *SourceOp) String() string { return proto.CompactTextString(m) } func (*SourceOp) ProtoMessage() {} -func (*SourceOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{8} } +func (*SourceOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{9} } func (m *SourceOp) GetIdentifier() string { if m != nil { @@ -513,7 +619,7 @@ type BuildOp struct { func (m *BuildOp) Reset() { *m = BuildOp{} } func (m *BuildOp) String() string { return proto.CompactTextString(m) } func (*BuildOp) ProtoMessage() {} -func (*BuildOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{9} } +func (*BuildOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{10} } func (m *BuildOp) GetInputs() map[string]*BuildInput { if m != nil { @@ -544,22 +650,23 @@ type BuildInput struct { func (m *BuildInput) Reset() { *m = BuildInput{} } func (m *BuildInput) String() string { return proto.CompactTextString(m) } func (*BuildInput) ProtoMessage() {} -func (*BuildInput) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{10} } +func (*BuildInput) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{11} } // OpMetadata is a per-vertex metadata entry, which can be defined for arbitrary Op vertex and overridable on the run time. type OpMetadata struct { // ignore_cache specifies to ignore the cache for this Op. IgnoreCache bool `protobuf:"varint,1,opt,name=ignore_cache,json=ignoreCache,proto3" json:"ignore_cache,omitempty"` // Description can be used for keeping any text fields that builder doesn't parse - Description map[string]string `protobuf:"bytes,2,rep,name=description" json:"description,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - WorkerConstraint *WorkerConstraint `protobuf:"bytes,3,opt,name=worker_constraint,json=workerConstraint" json:"worker_constraint,omitempty"` - ExportCache *ExportCache `protobuf:"bytes,4,opt,name=export_cache,json=exportCache" json:"export_cache,omitempty"` + Description map[string]string `protobuf:"bytes,2,rep,name=description" json:"description,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // index 3 reserved for WorkerConstraint in previous versions + // WorkerConstraint worker_constraint = 3; + ExportCache *ExportCache `protobuf:"bytes,4,opt,name=export_cache,json=exportCache" json:"export_cache,omitempty"` } func (m *OpMetadata) Reset() { *m = OpMetadata{} } func (m *OpMetadata) String() string { return proto.CompactTextString(m) } func (*OpMetadata) ProtoMessage() {} -func (*OpMetadata) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{11} } +func (*OpMetadata) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{12} } func (m *OpMetadata) GetIgnoreCache() bool { if m != nil { @@ -575,13 +682,6 @@ func (m *OpMetadata) GetDescription() map[string]string { return nil } -func (m *OpMetadata) GetWorkerConstraint() *WorkerConstraint { - if m != nil { - return m.WorkerConstraint - } - return nil -} - func (m *OpMetadata) GetExportCache() *ExportCache { if m != nil { return m.ExportCache @@ -596,7 +696,7 @@ type ExportCache struct { func (m *ExportCache) Reset() { *m = ExportCache{} } func (m *ExportCache) String() string { return proto.CompactTextString(m) } func (*ExportCache) ProtoMessage() {} -func (*ExportCache) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{12} } +func (*ExportCache) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{13} } func (m *ExportCache) GetValue() bool { if m != nil { @@ -615,7 +715,7 @@ type ProxyEnv struct { func (m *ProxyEnv) Reset() { *m = ProxyEnv{} } func (m *ProxyEnv) String() string { return proto.CompactTextString(m) } func (*ProxyEnv) ProtoMessage() {} -func (*ProxyEnv) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{13} } +func (*ProxyEnv) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{14} } func (m *ProxyEnv) GetHttpProxy() string { if m != nil { @@ -645,17 +745,17 @@ func (m *ProxyEnv) GetNoProxy() string { return "" } -// WorkerConstraint is experimental and likely to be changed. -type WorkerConstraint struct { +// WorkerConstraints defines conditions for the worker +type WorkerConstraints struct { Filter []string `protobuf:"bytes,1,rep,name=filter" json:"filter,omitempty"` } -func (m *WorkerConstraint) Reset() { *m = WorkerConstraint{} } -func (m *WorkerConstraint) String() string { return proto.CompactTextString(m) } -func (*WorkerConstraint) ProtoMessage() {} -func (*WorkerConstraint) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{14} } +func (m *WorkerConstraints) Reset() { *m = WorkerConstraints{} } +func (m *WorkerConstraints) String() string { return proto.CompactTextString(m) } +func (*WorkerConstraints) ProtoMessage() {} +func (*WorkerConstraints) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{15} } -func (m *WorkerConstraint) GetFilter() []string { +func (m *WorkerConstraints) GetFilter() []string { if m != nil { return m.Filter } @@ -674,7 +774,7 @@ type Definition struct { func (m *Definition) Reset() { *m = Definition{} } func (m *Definition) String() string { return proto.CompactTextString(m) } func (*Definition) ProtoMessage() {} -func (*Definition) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{15} } +func (*Definition) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{16} } func (m *Definition) GetDef() [][]byte { if m != nil { @@ -692,6 +792,7 @@ func (m *Definition) GetMetadata() map[github_com_opencontainers_go_digest.Diges func init() { proto.RegisterType((*Op)(nil), "pb.Op") + proto.RegisterType((*Platform)(nil), "pb.Platform") proto.RegisterType((*Input)(nil), "pb.Input") proto.RegisterType((*ExecOp)(nil), "pb.ExecOp") proto.RegisterType((*Meta)(nil), "pb.Meta") @@ -705,9 +806,10 @@ func init() { proto.RegisterType((*OpMetadata)(nil), "pb.OpMetadata") proto.RegisterType((*ExportCache)(nil), "pb.ExportCache") proto.RegisterType((*ProxyEnv)(nil), "pb.ProxyEnv") - proto.RegisterType((*WorkerConstraint)(nil), "pb.WorkerConstraint") + proto.RegisterType((*WorkerConstraints)(nil), "pb.WorkerConstraints") proto.RegisterType((*Definition)(nil), "pb.Definition") proto.RegisterEnum("pb.MountType", MountType_name, MountType_value) + proto.RegisterEnum("pb.CacheSharingOpt", CacheSharingOpt_name, CacheSharingOpt_value) } func (m *Op) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -743,6 +845,26 @@ func (m *Op) MarshalTo(dAtA []byte) (int, error) { } i += nn1 } + if m.Platform != nil { + dAtA[i] = 0x52 + i++ + i = encodeVarintOps(dAtA, i, uint64(m.Platform.Size())) + n2, err := m.Platform.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Constraints != nil { + dAtA[i] = 0x5a + i++ + i = encodeVarintOps(dAtA, i, uint64(m.Constraints.Size())) + n3, err := m.Constraints.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } return i, nil } @@ -752,11 +874,11 @@ func (m *Op_Exec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintOps(dAtA, i, uint64(m.Exec.Size())) - n2, err := m.Exec.MarshalTo(dAtA[i:]) + n4, err := m.Exec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n4 } return i, nil } @@ -766,11 +888,11 @@ func (m *Op_Source) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintOps(dAtA, i, uint64(m.Source.Size())) - n3, err := m.Source.MarshalTo(dAtA[i:]) + n5, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n5 } return i, nil } @@ -780,11 +902,11 @@ func (m *Op_Copy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintOps(dAtA, i, uint64(m.Copy.Size())) - n4, err := m.Copy.MarshalTo(dAtA[i:]) + n6, err := m.Copy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n6 } return i, nil } @@ -794,14 +916,71 @@ func (m *Op_Build) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintOps(dAtA, i, uint64(m.Build.Size())) - n5, err := m.Build.MarshalTo(dAtA[i:]) + n7, err := m.Build.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n7 + } + return i, nil +} +func (m *Platform) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Platform) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Architecture) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintOps(dAtA, i, uint64(len(m.Architecture))) + i += copy(dAtA[i:], m.Architecture) + } + if len(m.OS) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintOps(dAtA, i, uint64(len(m.OS))) + i += copy(dAtA[i:], m.OS) + } + if len(m.Variant) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintOps(dAtA, i, uint64(len(m.Variant))) + i += copy(dAtA[i:], m.Variant) + } + if len(m.OSVersion) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintOps(dAtA, i, uint64(len(m.OSVersion))) + i += copy(dAtA[i:], m.OSVersion) + } + if len(m.OSFeatures) > 0 { + for _, s := range m.OSFeatures { + dAtA[i] = 0x2a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } } return i, nil } + func (m *Input) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -850,11 +1029,11 @@ func (m *ExecOp) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintOps(dAtA, i, uint64(m.Meta.Size())) - n6, err := m.Meta.MarshalTo(dAtA[i:]) + n8, err := m.Meta.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n8 } if len(m.Mounts) > 0 { for _, msg := range m.Mounts { @@ -932,11 +1111,11 @@ func (m *Meta) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintOps(dAtA, i, uint64(m.ProxyEnv.Size())) - n7, err := m.ProxyEnv.MarshalTo(dAtA[i:]) + n9, err := m.ProxyEnv.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n9 } return i, nil } @@ -999,11 +1178,11 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintOps(dAtA, i, uint64(m.CacheOpt.Size())) - n8, err := m.CacheOpt.MarshalTo(dAtA[i:]) + n10, err := m.CacheOpt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n10 } return i, nil } @@ -1029,6 +1208,11 @@ func (m *CacheOpt) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintOps(dAtA, i, uint64(len(m.ID))) i += copy(dAtA[i:], m.ID) } + if m.Sharing != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintOps(dAtA, i, uint64(m.Sharing)) + } return i, nil } @@ -1178,11 +1362,11 @@ func (m *BuildOp) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintOps(dAtA, i, uint64(v.Size())) - n9, err := v.MarshalTo(dAtA[i:]) + n11, err := v.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n11 } } } @@ -1190,11 +1374,11 @@ func (m *BuildOp) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintOps(dAtA, i, uint64(m.Def.Size())) - n10, err := m.Def.MarshalTo(dAtA[i:]) + n12, err := m.Def.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n12 } if len(m.Attrs) > 0 { for k, _ := range m.Attrs { @@ -1281,25 +1465,15 @@ func (m *OpMetadata) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], v) } } - if m.WorkerConstraint != nil { - dAtA[i] = 0x1a - i++ - i = encodeVarintOps(dAtA, i, uint64(m.WorkerConstraint.Size())) - n11, err := m.WorkerConstraint.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n11 - } if m.ExportCache != nil { dAtA[i] = 0x22 i++ i = encodeVarintOps(dAtA, i, uint64(m.ExportCache.Size())) - n12, err := m.ExportCache.MarshalTo(dAtA[i:]) + n13, err := m.ExportCache.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n13 } return i, nil } @@ -1374,7 +1548,7 @@ func (m *ProxyEnv) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *WorkerConstraint) Marshal() (dAtA []byte, err error) { +func (m *WorkerConstraints) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -1384,7 +1558,7 @@ func (m *WorkerConstraint) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *WorkerConstraint) MarshalTo(dAtA []byte) (int, error) { +func (m *WorkerConstraints) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -1449,11 +1623,11 @@ func (m *Definition) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintOps(dAtA, i, uint64((&v).Size())) - n13, err := (&v).MarshalTo(dAtA[i:]) + n14, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n14 } } return i, nil @@ -1480,6 +1654,14 @@ func (m *Op) Size() (n int) { if m.Op != nil { n += m.Op.Size() } + if m.Platform != nil { + l = m.Platform.Size() + n += 1 + l + sovOps(uint64(l)) + } + if m.Constraints != nil { + l = m.Constraints.Size() + n += 1 + l + sovOps(uint64(l)) + } return n } @@ -1519,6 +1701,34 @@ func (m *Op_Build) Size() (n int) { } return n } +func (m *Platform) Size() (n int) { + var l int + _ = l + l = len(m.Architecture) + if l > 0 { + n += 1 + l + sovOps(uint64(l)) + } + l = len(m.OS) + if l > 0 { + n += 1 + l + sovOps(uint64(l)) + } + l = len(m.Variant) + if l > 0 { + n += 1 + l + sovOps(uint64(l)) + } + l = len(m.OSVersion) + if l > 0 { + n += 1 + l + sovOps(uint64(l)) + } + if len(m.OSFeatures) > 0 { + for _, s := range m.OSFeatures { + l = len(s) + n += 1 + l + sovOps(uint64(l)) + } + } + return n +} + func (m *Input) Size() (n int) { var l int _ = l @@ -1615,6 +1825,9 @@ func (m *CacheOpt) Size() (n int) { if l > 0 { n += 1 + l + sovOps(uint64(l)) } + if m.Sharing != 0 { + n += 1 + sovOps(uint64(m.Sharing)) + } return n } @@ -1722,10 +1935,6 @@ func (m *OpMetadata) Size() (n int) { n += mapEntrySize + 1 + sovOps(uint64(mapEntrySize)) } } - if m.WorkerConstraint != nil { - l = m.WorkerConstraint.Size() - n += 1 + l + sovOps(uint64(l)) - } if m.ExportCache != nil { l = m.ExportCache.Size() n += 1 + l + sovOps(uint64(l)) @@ -1764,7 +1973,7 @@ func (m *ProxyEnv) Size() (n int) { return n } -func (m *WorkerConstraint) Size() (n int) { +func (m *WorkerConstraints) Size() (n int) { var l int _ = l if len(m.Filter) > 0 { @@ -1998,6 +2207,267 @@ func (m *Op) Unmarshal(dAtA []byte) error { } m.Op = &Op_Build{v} iNdEx = postIndex + case 10: + 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 ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Platform == nil { + m.Platform = &Platform{} + } + if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Constraints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Constraints == nil { + m.Constraints = &WorkerConstraints{} + } + if err := m.Constraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOps(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthOps + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Platform) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Platform: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Platform: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Architecture", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Architecture = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OS", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OS = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Variant", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Variant = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OSVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OSVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OSFeatures", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOps + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OSFeatures = append(m.OSFeatures, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipOps(dAtA[iNdEx:]) @@ -2706,6 +3176,25 @@ func (m *CacheOpt) Unmarshal(dAtA []byte) error { } m.ID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sharing", wireType) + } + m.Sharing = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOps + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sharing |= (CacheSharingOpt(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipOps(dAtA[iNdEx:]) @@ -3711,39 +4200,6 @@ func (m *OpMetadata) Unmarshal(dAtA []byte) error { } m.Description[mapkey] = mapvalue iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WorkerConstraint", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowOps - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthOps - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.WorkerConstraint == nil { - m.WorkerConstraint = &WorkerConstraint{} - } - if err := m.WorkerConstraint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ExportCache", wireType) @@ -4034,7 +4490,7 @@ func (m *ProxyEnv) Unmarshal(dAtA []byte) error { } return nil } -func (m *WorkerConstraint) Unmarshal(dAtA []byte) error { +func (m *WorkerConstraints) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4057,10 +4513,10 @@ func (m *WorkerConstraint) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: WorkerConstraint: wiretype end group for non-group") + return fmt.Errorf("proto: WorkerConstraints: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: WorkerConstraint: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: WorkerConstraints: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4423,72 +4879,81 @@ var ( func init() { proto.RegisterFile("ops.proto", fileDescriptorOps) } var fileDescriptorOps = []byte{ - // 1062 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, - 0x17, 0xcf, 0xae, 0x3f, 0xb2, 0x7b, 0x36, 0xed, 0xdf, 0xff, 0x21, 0x2a, 0xc6, 0x94, 0xc4, 0x6c, - 0x11, 0x72, 0xd3, 0xc6, 0x91, 0x8c, 0x84, 0x2a, 0x2e, 0x2a, 0xe2, 0x0f, 0x14, 0x83, 0x42, 0xaa, - 0x49, 0x04, 0x97, 0x91, 0xbd, 0x1e, 0x3b, 0xab, 0x3a, 0x3b, 0xab, 0xdd, 0xd9, 0x24, 0xbe, 0x00, - 0x89, 0x3e, 0x01, 0x12, 0x4f, 0xc1, 0x43, 0xc0, 0x75, 0x2f, 0xb9, 0x85, 0x8b, 0x82, 0xc2, 0x8b, - 0xa0, 0x73, 0x66, 0xbc, 0xeb, 0x86, 0x22, 0xb5, 0x82, 0x2b, 0xcf, 0x9c, 0xf3, 0x3b, 0x67, 0xce, - 0xf9, 0x9d, 0x8f, 0x35, 0xb8, 0x32, 0x4e, 0xdb, 0x71, 0x22, 0x95, 0x64, 0x76, 0x3c, 0x6e, 0xec, - 0xce, 0x42, 0x75, 0x96, 0x8d, 0xdb, 0x81, 0x3c, 0xdf, 0x9b, 0xc9, 0x99, 0xdc, 0x23, 0xd5, 0x38, - 0x9b, 0xd2, 0x8d, 0x2e, 0x74, 0xd2, 0x26, 0xfe, 0xcf, 0x16, 0xd8, 0x47, 0x31, 0x7b, 0x1f, 0xaa, - 0x61, 0x14, 0x67, 0x2a, 0xad, 0x5b, 0xcd, 0x52, 0xcb, 0xeb, 0xb8, 0xed, 0x78, 0xdc, 0x1e, 0xa2, - 0x84, 0x1b, 0x05, 0x6b, 0x42, 0x59, 0x5c, 0x89, 0xa0, 0x6e, 0x37, 0xad, 0x96, 0xd7, 0x01, 0x04, - 0x0c, 0xae, 0x44, 0x70, 0x14, 0x1f, 0xac, 0x71, 0xd2, 0xb0, 0x0f, 0xa1, 0x9a, 0xca, 0x2c, 0x09, - 0x44, 0xbd, 0x44, 0x98, 0x0d, 0xc4, 0x1c, 0x93, 0x84, 0x50, 0x46, 0x8b, 0x9e, 0x02, 0x19, 0x2f, - 0xea, 0xe5, 0xc2, 0x53, 0x4f, 0xc6, 0x0b, 0xed, 0x09, 0x35, 0xec, 0x1e, 0x54, 0xc6, 0x59, 0x38, - 0x9f, 0xd4, 0x2b, 0x04, 0xf1, 0x10, 0xd2, 0x45, 0x01, 0x61, 0xb4, 0xae, 0x5b, 0x06, 0x5b, 0xc6, - 0xfe, 0xb7, 0x50, 0xa1, 0x38, 0xd9, 0xe7, 0x50, 0x9d, 0x84, 0x33, 0x91, 0xaa, 0xba, 0xd5, 0xb4, - 0x5a, 0x6e, 0xb7, 0xf3, 0xfc, 0xc5, 0xf6, 0xda, 0x6f, 0x2f, 0xb6, 0x77, 0x56, 0x08, 0x91, 0xb1, - 0x88, 0x02, 0x19, 0xa9, 0x51, 0x18, 0x89, 0x24, 0xdd, 0x9b, 0xc9, 0x5d, 0x6d, 0xd2, 0xee, 0xd3, - 0x0f, 0x37, 0x1e, 0xd8, 0x7d, 0xa8, 0x84, 0xd1, 0x44, 0x5c, 0x51, 0xb2, 0xa5, 0xee, 0x5b, 0xc6, - 0x95, 0x77, 0x94, 0xa9, 0x38, 0x53, 0x43, 0x54, 0x71, 0x8d, 0xf0, 0x87, 0x50, 0xd5, 0x34, 0xb0, - 0xbb, 0x50, 0x3e, 0x17, 0x6a, 0x44, 0xcf, 0x7b, 0x1d, 0x07, 0x63, 0x3e, 0x14, 0x6a, 0xc4, 0x49, - 0x8a, 0x0c, 0x9f, 0xcb, 0x2c, 0x52, 0x69, 0xdd, 0x2e, 0x18, 0x3e, 0x44, 0x09, 0x37, 0x0a, 0xff, - 0x1b, 0x28, 0xa3, 0x01, 0x63, 0x50, 0x1e, 0x25, 0x33, 0x5d, 0x0a, 0x97, 0xd3, 0x99, 0xd5, 0xa0, - 0x24, 0xa2, 0x0b, 0xb2, 0x75, 0x39, 0x1e, 0x51, 0x12, 0x5c, 0x4e, 0x88, 0x6a, 0x97, 0xe3, 0x11, - 0xed, 0xb2, 0x54, 0x24, 0xc4, 0xab, 0xcb, 0xe9, 0xcc, 0xee, 0x83, 0x1b, 0x27, 0xf2, 0x6a, 0x71, - 0x8a, 0xd6, 0x95, 0xa2, 0x2c, 0x4f, 0x50, 0x38, 0x88, 0x2e, 0xb8, 0x13, 0x9b, 0x93, 0xff, 0x9d, - 0x0d, 0x15, 0x0a, 0x88, 0xb5, 0x30, 0xfd, 0x38, 0xd3, 0x4c, 0x96, 0xba, 0xcc, 0xa4, 0x0f, 0x44, - 0x74, 0x9e, 0x3d, 0x92, 0xde, 0x00, 0x27, 0x15, 0x73, 0x11, 0x28, 0x99, 0x10, 0x57, 0x2e, 0xcf, - 0xef, 0x18, 0xce, 0x04, 0xcb, 0xa1, 0x23, 0xa4, 0x33, 0x7b, 0x00, 0x55, 0x49, 0x1c, 0x52, 0x90, - 0xff, 0xc0, 0xac, 0x81, 0xa0, 0xf3, 0x44, 0x8c, 0x26, 0x32, 0x9a, 0x2f, 0x28, 0x74, 0x87, 0xe7, - 0x77, 0xf6, 0x00, 0x5c, 0x62, 0xed, 0x64, 0x11, 0x8b, 0x7a, 0xb5, 0x69, 0xb5, 0x6e, 0x77, 0x6e, - 0xe5, 0x8c, 0xa2, 0x90, 0x17, 0x7a, 0xd6, 0x02, 0x27, 0x18, 0x05, 0x67, 0xe2, 0x28, 0x56, 0xf5, - 0xcd, 0x82, 0x83, 0x9e, 0x91, 0xf1, 0x5c, 0xeb, 0x37, 0xc0, 0x59, 0x4a, 0xd9, 0x6d, 0xb0, 0x87, - 0x7d, 0xdd, 0x4c, 0xdc, 0x1e, 0xf6, 0xfd, 0xc7, 0x50, 0xd5, 0x6d, 0xca, 0x9a, 0x50, 0x4a, 0x93, - 0xc0, 0x8c, 0xca, 0xed, 0x65, 0xff, 0xea, 0x4e, 0xe7, 0xa8, 0xca, 0x73, 0xb7, 0x8b, 0xdc, 0x7d, - 0x0e, 0x50, 0xc0, 0xfe, 0x1b, 0x8e, 0xfd, 0x1f, 0x2c, 0x70, 0x96, 0x13, 0xc6, 0xb6, 0x00, 0xc2, - 0x89, 0x88, 0x54, 0x38, 0x0d, 0x45, 0x62, 0x02, 0x5f, 0x91, 0xb0, 0x5d, 0xa8, 0x8c, 0x94, 0x4a, - 0x96, 0x1d, 0xf8, 0xf6, 0xea, 0x78, 0xb6, 0xf7, 0x51, 0x33, 0x88, 0x54, 0xb2, 0xe0, 0x1a, 0xd5, - 0x78, 0x04, 0x50, 0x08, 0xb1, 0xdd, 0x9e, 0x8a, 0x85, 0xf1, 0x8a, 0x47, 0xb6, 0x09, 0x95, 0x8b, - 0xd1, 0x3c, 0x13, 0x26, 0x28, 0x7d, 0xf9, 0xc4, 0x7e, 0x64, 0xf9, 0x3f, 0xd9, 0xb0, 0x6e, 0xc6, - 0x95, 0x3d, 0x84, 0x75, 0x1a, 0x57, 0x13, 0xd1, 0xab, 0x33, 0x5d, 0x42, 0xd8, 0x5e, 0xbe, 0x87, - 0x56, 0x62, 0x34, 0xae, 0xf4, 0x3e, 0x32, 0x31, 0x16, 0x5b, 0xa9, 0x34, 0x11, 0x53, 0xb3, 0x70, - 0xa8, 0x14, 0x7d, 0x31, 0x0d, 0xa3, 0x50, 0x85, 0x32, 0xe2, 0xa8, 0x62, 0x0f, 0x97, 0x59, 0x97, - 0xc9, 0xe3, 0x9d, 0x55, 0x8f, 0x7f, 0x4f, 0x7a, 0x08, 0xde, 0xca, 0x33, 0xaf, 0xc8, 0xfa, 0x83, - 0xd5, 0xac, 0xcd, 0x93, 0xe4, 0x4e, 0x6f, 0xcb, 0x82, 0x85, 0x7f, 0xc1, 0xdf, 0xc7, 0x00, 0x85, - 0xcb, 0xd7, 0xef, 0x14, 0xff, 0x47, 0x1b, 0xe0, 0x28, 0xc6, 0x1d, 0x32, 0x19, 0xd1, 0xca, 0xd9, - 0x08, 0x67, 0x91, 0x4c, 0xc4, 0x29, 0xf5, 0x37, 0xd9, 0x3b, 0xdc, 0xd3, 0x32, 0x6a, 0x73, 0xb6, - 0x0f, 0xde, 0x44, 0xa4, 0x41, 0x12, 0xc6, 0x48, 0x98, 0x21, 0x7d, 0x1b, 0x73, 0x2a, 0xfc, 0xb4, - 0xfb, 0x05, 0x42, 0x73, 0xb5, 0x6a, 0xc3, 0xf6, 0xe1, 0xff, 0x97, 0x32, 0x79, 0x2a, 0x92, 0xd3, - 0x40, 0x46, 0xa9, 0x4a, 0x46, 0x61, 0xa4, 0x4c, 0x3d, 0x36, 0xd1, 0xd1, 0xd7, 0xa4, 0xec, 0xe5, - 0x3a, 0x5e, 0xbb, 0xbc, 0x21, 0x61, 0x1d, 0xd8, 0x10, 0x57, 0xb1, 0x4c, 0x94, 0x09, 0x54, 0x7f, - 0x18, 0xfe, 0xa7, 0x3f, 0x31, 0x28, 0xa7, 0x60, 0xb9, 0x27, 0x8a, 0x4b, 0xe3, 0x31, 0xd4, 0x6e, - 0xc6, 0xf5, 0x46, 0x1c, 0xdf, 0x03, 0x6f, 0xc5, 0x37, 0x02, 0xbf, 0x22, 0xa0, 0x26, 0x49, 0x5f, - 0xfc, 0x67, 0x16, 0x38, 0xcb, 0x4d, 0xc9, 0xde, 0x03, 0x38, 0x53, 0x2a, 0x3e, 0xa5, 0x85, 0x69, - 0x1e, 0x71, 0x51, 0x42, 0x08, 0xb6, 0x0d, 0x1e, 0x5e, 0x52, 0xa3, 0xd7, 0x0f, 0x92, 0x45, 0xaa, - 0x01, 0xef, 0x82, 0x3b, 0xcd, 0xcd, 0xf5, 0x52, 0x74, 0xa6, 0x4b, 0xeb, 0x77, 0xc0, 0x89, 0xa4, - 0xd1, 0xe9, 0xfd, 0xbd, 0x1e, 0x49, 0x52, 0xf9, 0x3b, 0x50, 0xbb, 0xc9, 0x21, 0xbb, 0x03, 0xd5, - 0x69, 0x38, 0x57, 0x34, 0x54, 0xf8, 0x45, 0x30, 0x37, 0xff, 0x57, 0x0b, 0xa0, 0x18, 0x00, 0x24, - 0x04, 0xa7, 0x03, 0x31, 0x1b, 0x7a, 0x1a, 0xe6, 0xe0, 0x9c, 0x9b, 0xba, 0x9a, 0x6a, 0xdf, 0x7d, - 0x79, 0x68, 0xda, 0xcb, 0xb2, 0x13, 0xa5, 0xfa, 0x2b, 0xfa, 0xec, 0xf7, 0x37, 0xfa, 0x8a, 0xe6, - 0x2f, 0x34, 0xbe, 0x80, 0x5b, 0x2f, 0xb9, 0x7b, 0xcd, 0x79, 0x2a, 0x7a, 0x6f, 0xa5, 0x62, 0x3b, - 0x9f, 0x82, 0x9b, 0x6f, 0x77, 0xe6, 0x40, 0xb9, 0x3b, 0xfc, 0xb2, 0x5f, 0x5b, 0x63, 0x00, 0xd5, - 0xe3, 0x41, 0x8f, 0x0f, 0x4e, 0x6a, 0x16, 0x5b, 0x87, 0xd2, 0xf1, 0xf1, 0x41, 0xcd, 0x66, 0x2e, - 0x54, 0x7a, 0xfb, 0xbd, 0x83, 0x41, 0xad, 0x84, 0xc7, 0x93, 0xc3, 0x27, 0x9f, 0x1d, 0xd7, 0xca, - 0xdd, 0xda, 0xf3, 0xeb, 0x2d, 0xeb, 0x97, 0xeb, 0x2d, 0xeb, 0x8f, 0xeb, 0x2d, 0xeb, 0xfb, 0x3f, - 0xb7, 0xd6, 0xc6, 0x55, 0xfa, 0x17, 0xf4, 0xd1, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x76, - 0x25, 0x54, 0x45, 0x09, 0x00, 0x00, + // 1203 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4d, 0x8f, 0x1b, 0x45, + 0x13, 0xde, 0x19, 0x7f, 0xcd, 0xd4, 0x6c, 0x36, 0x7e, 0x3b, 0x79, 0x83, 0x59, 0xc2, 0xae, 0x99, + 0x20, 0xe4, 0x7c, 0xac, 0x57, 0x32, 0x52, 0x88, 0x38, 0x44, 0xac, 0x3f, 0xa2, 0x35, 0x21, 0x38, + 0x6a, 0xaf, 0x96, 0x63, 0x34, 0x1e, 0xb7, 0xbd, 0xa3, 0x78, 0xa7, 0x47, 0x3d, 0xed, 0xb0, 0x3e, + 0x80, 0x44, 0x7e, 0x01, 0x12, 0x12, 0x77, 0x7e, 0x08, 0xf7, 0x1c, 0xb9, 0xc2, 0x21, 0xa0, 0x20, + 0xf1, 0x3b, 0x50, 0x75, 0xb7, 0x67, 0x66, 0x93, 0x20, 0x25, 0x82, 0x93, 0xbb, 0xab, 0x9e, 0x7a, + 0xba, 0xea, 0xe9, 0x9a, 0x6a, 0x83, 0xcb, 0x93, 0xb4, 0x9d, 0x08, 0x2e, 0x39, 0xb1, 0x93, 0xc9, + 0xf6, 0xde, 0x3c, 0x92, 0x27, 0xcb, 0x49, 0x3b, 0xe4, 0xa7, 0xfb, 0x73, 0x3e, 0xe7, 0xfb, 0xca, + 0x35, 0x59, 0xce, 0xd4, 0x4e, 0x6d, 0xd4, 0x4a, 0x87, 0xf8, 0x3f, 0xd9, 0x60, 0x8f, 0x12, 0xf2, + 0x01, 0x54, 0xa3, 0x38, 0x59, 0xca, 0xb4, 0x61, 0x35, 0x4b, 0x2d, 0xaf, 0xe3, 0xb6, 0x93, 0x49, + 0x7b, 0x88, 0x16, 0x6a, 0x1c, 0xa4, 0x09, 0x65, 0x76, 0xc6, 0xc2, 0x86, 0xdd, 0xb4, 0x5a, 0x5e, + 0x07, 0x10, 0x30, 0x38, 0x63, 0xe1, 0x28, 0x39, 0xdc, 0xa0, 0xca, 0x43, 0x3e, 0x82, 0x6a, 0xca, + 0x97, 0x22, 0x64, 0x8d, 0x92, 0xc2, 0x6c, 0x22, 0x66, 0xac, 0x2c, 0x0a, 0x65, 0xbc, 0xc8, 0x14, + 0xf2, 0x64, 0xd5, 0x28, 0xe7, 0x4c, 0x3d, 0x9e, 0xac, 0x34, 0x13, 0x7a, 0xc8, 0x35, 0xa8, 0x4c, + 0x96, 0xd1, 0x62, 0xda, 0xa8, 0x28, 0x88, 0x87, 0x90, 0x2e, 0x1a, 0x14, 0x46, 0xfb, 0x48, 0x0b, + 0x9c, 0x64, 0x11, 0xc8, 0x19, 0x17, 0xa7, 0x0d, 0xc8, 0x0f, 0x7c, 0x68, 0x6c, 0x34, 0xf3, 0x92, + 0x4f, 0xc0, 0x0b, 0x79, 0x9c, 0x4a, 0x11, 0x44, 0xb1, 0x4c, 0x1b, 0x9e, 0x02, 0xff, 0x1f, 0xc1, + 0x5f, 0x71, 0xf1, 0x98, 0x89, 0x5e, 0xee, 0xa4, 0x45, 0x64, 0xb7, 0x0c, 0x36, 0x4f, 0xfc, 0x1f, + 0x2d, 0x70, 0xd6, 0xac, 0xc4, 0x87, 0xcd, 0x03, 0x11, 0x9e, 0x44, 0x92, 0x85, 0x72, 0x29, 0x58, + 0xc3, 0x6a, 0x5a, 0x2d, 0x97, 0x9e, 0xb3, 0x91, 0x2d, 0xb0, 0x47, 0x63, 0x25, 0x94, 0x4b, 0xed, + 0xd1, 0x98, 0x34, 0xa0, 0x76, 0x1c, 0x88, 0x28, 0x88, 0xa5, 0x52, 0xc6, 0xa5, 0xeb, 0x2d, 0xb9, + 0x0a, 0xee, 0x68, 0x7c, 0xcc, 0x44, 0x1a, 0xf1, 0x58, 0xe9, 0xe1, 0xd2, 0xdc, 0x40, 0x76, 0x00, + 0x46, 0xe3, 0x7b, 0x2c, 0x40, 0xd2, 0xb4, 0x51, 0x69, 0x96, 0x5a, 0x2e, 0x2d, 0x58, 0xfc, 0x6f, + 0xa1, 0xa2, 0xee, 0x88, 0x7c, 0x0e, 0xd5, 0x69, 0x34, 0x67, 0xa9, 0xd4, 0xe9, 0x74, 0x3b, 0xcf, + 0x9e, 0xef, 0x6e, 0xfc, 0xf6, 0x7c, 0xf7, 0x46, 0xa1, 0x19, 0x78, 0xc2, 0xe2, 0x90, 0xc7, 0x32, + 0x88, 0x62, 0x26, 0xd2, 0xfd, 0x39, 0xdf, 0xd3, 0x21, 0xed, 0xbe, 0xfa, 0xa1, 0x86, 0x81, 0x5c, + 0x87, 0x4a, 0x14, 0x4f, 0xd9, 0x99, 0xca, 0xbf, 0xd4, 0xbd, 0x64, 0xa8, 0xbc, 0xd1, 0x52, 0x26, + 0x4b, 0x39, 0x44, 0x17, 0xd5, 0x08, 0x7f, 0x08, 0x55, 0xdd, 0x02, 0xe4, 0x2a, 0x94, 0x4f, 0x99, + 0x0c, 0xd4, 0xf1, 0x5e, 0xc7, 0x41, 0x69, 0x1f, 0x30, 0x19, 0x50, 0x65, 0xc5, 0xee, 0x3a, 0xe5, + 0x4b, 0x94, 0xde, 0xce, 0xbb, 0xeb, 0x01, 0x5a, 0xa8, 0x71, 0xf8, 0xdf, 0x40, 0x19, 0x03, 0x08, + 0x81, 0x72, 0x20, 0xe6, 0xba, 0x0d, 0x5d, 0xaa, 0xd6, 0xa4, 0x0e, 0x25, 0x16, 0x3f, 0x51, 0xb1, + 0x2e, 0xc5, 0x25, 0x5a, 0xc2, 0xaf, 0xa7, 0x46, 0x4c, 0x5c, 0x62, 0xdc, 0x32, 0x65, 0xc2, 0x68, + 0xa8, 0xd6, 0xe4, 0x3a, 0xb8, 0x89, 0xe0, 0x67, 0xab, 0x47, 0x18, 0x5d, 0x29, 0x74, 0x08, 0x1a, + 0x07, 0xf1, 0x13, 0xea, 0x24, 0x66, 0xe5, 0x7f, 0x67, 0x43, 0x45, 0x25, 0x44, 0x5a, 0x58, 0x7e, + 0xb2, 0xd4, 0x4a, 0x96, 0xba, 0xc4, 0x94, 0x0f, 0x4a, 0xe8, 0xac, 0x7a, 0x14, 0x7d, 0x1b, 0x9c, + 0x94, 0x2d, 0x58, 0x28, 0xb9, 0x30, 0x77, 0x9d, 0xed, 0x31, 0x9d, 0x29, 0x5e, 0x87, 0xce, 0x50, + 0xad, 0xc9, 0x4d, 0xa8, 0x72, 0xa5, 0xa1, 0x4a, 0xf2, 0x1f, 0x94, 0x35, 0x10, 0x24, 0x17, 0x2c, + 0x98, 0xf2, 0x78, 0xb1, 0x52, 0xa9, 0x3b, 0x34, 0xdb, 0x93, 0x9b, 0xe0, 0x2a, 0xd5, 0x8e, 0x56, + 0x09, 0x6b, 0x54, 0x9b, 0x56, 0x6b, 0xab, 0x73, 0x21, 0x53, 0x14, 0x8d, 0x34, 0xf7, 0xe3, 0x57, + 0x12, 0x06, 0xe1, 0x09, 0x1b, 0x25, 0xb2, 0x71, 0x39, 0xd7, 0xa0, 0x67, 0x6c, 0x34, 0xf3, 0xfa, + 0x43, 0x70, 0xd6, 0x56, 0xec, 0xe0, 0x61, 0xdf, 0xf4, 0xb6, 0x3d, 0xec, 0x93, 0x3d, 0xa8, 0xa5, + 0x27, 0x81, 0x88, 0xe2, 0xb9, 0x2a, 0x75, 0xab, 0x73, 0x29, 0x23, 0x19, 0x6b, 0x3b, 0x72, 0xad, + 0x31, 0xfe, 0x5d, 0xa8, 0xea, 0x2f, 0x9a, 0x34, 0xa1, 0x94, 0x8a, 0xd0, 0x4c, 0x95, 0xad, 0xf5, + 0xa7, 0xae, 0x87, 0x02, 0x45, 0x57, 0x26, 0x95, 0x9d, 0x4b, 0xe5, 0x53, 0x80, 0x1c, 0xf6, 0xdf, + 0x5c, 0x89, 0xff, 0x83, 0x05, 0xce, 0x7a, 0x18, 0xe1, 0x97, 0x15, 0x4d, 0x59, 0x2c, 0xa3, 0x59, + 0xc4, 0x84, 0xa9, 0xb3, 0x60, 0x21, 0x7b, 0x50, 0x09, 0xa4, 0x14, 0xeb, 0x86, 0x7d, 0xa7, 0x38, + 0xc9, 0xda, 0x07, 0xe8, 0x19, 0xc4, 0x52, 0xac, 0xa8, 0x46, 0x6d, 0xdf, 0x01, 0xc8, 0x8d, 0xd8, + 0x9d, 0x8f, 0xd9, 0xca, 0xb0, 0xe2, 0x92, 0x5c, 0x86, 0xca, 0x93, 0x60, 0xb1, 0x64, 0x26, 0x29, + 0xbd, 0xf9, 0xd4, 0xbe, 0x63, 0xf9, 0x3f, 0xdb, 0x50, 0x33, 0x93, 0x8d, 0xdc, 0x82, 0x9a, 0x9a, + 0x6c, 0x26, 0xa3, 0xd7, 0x57, 0xba, 0x86, 0x90, 0xfd, 0x6c, 0x64, 0x17, 0x72, 0x34, 0x54, 0x7a, + 0x74, 0x9b, 0x1c, 0xf3, 0x01, 0x5e, 0x9a, 0xb2, 0x99, 0x99, 0xcd, 0xea, 0x2a, 0xfa, 0x6c, 0x16, + 0xc5, 0x91, 0x8c, 0x78, 0x4c, 0xd1, 0x45, 0x6e, 0xad, 0xab, 0x2e, 0x2b, 0xc6, 0x2b, 0x45, 0xc6, + 0x57, 0x8b, 0x1e, 0x82, 0x57, 0x38, 0xe6, 0x35, 0x55, 0x7f, 0x58, 0xac, 0xda, 0x1c, 0xa9, 0xe8, + 0xf4, 0xc3, 0x92, 0xab, 0xf0, 0x2f, 0xf4, 0xbb, 0x0d, 0x90, 0x53, 0xbe, 0x79, 0xa7, 0xf8, 0x7f, + 0x59, 0x00, 0xa3, 0x04, 0x47, 0xce, 0x34, 0x50, 0x13, 0x6a, 0x33, 0x9a, 0xc7, 0x5c, 0xb0, 0x47, + 0xea, 0x73, 0x50, 0xf1, 0x0e, 0xf5, 0xb4, 0x4d, 0xb5, 0x39, 0x39, 0x00, 0x6f, 0xca, 0xd2, 0x50, + 0x44, 0x09, 0x0a, 0x66, 0x44, 0xdf, 0xc5, 0x9a, 0x72, 0x9e, 0x76, 0x3f, 0x47, 0x68, 0xad, 0x8a, + 0x31, 0xa4, 0x03, 0x9b, 0xec, 0x2c, 0xe1, 0x42, 0x9a, 0x53, 0xf4, 0x03, 0x78, 0x51, 0x3f, 0xa5, + 0x68, 0x57, 0x27, 0x51, 0x8f, 0xe5, 0x9b, 0xed, 0xbb, 0x50, 0x7f, 0x99, 0xf4, 0xad, 0x04, 0xba, + 0x06, 0x5e, 0x81, 0x1b, 0x81, 0xc7, 0x0a, 0xa8, 0x2b, 0xd4, 0x1b, 0xff, 0x29, 0xbe, 0x70, 0x66, + 0x16, 0x92, 0xf7, 0x01, 0x4e, 0xa4, 0x4c, 0x1e, 0xa9, 0xe1, 0x68, 0x0e, 0x71, 0xd1, 0xa2, 0x10, + 0x64, 0x17, 0x3c, 0xdc, 0xa4, 0xc6, 0xaf, 0x0f, 0x54, 0x11, 0xa9, 0x06, 0xbc, 0x07, 0xee, 0x2c, + 0x0b, 0xd7, 0x03, 0xd0, 0x99, 0xad, 0xa3, 0xdf, 0x05, 0x27, 0xe6, 0xc6, 0xa7, 0x67, 0x75, 0x2d, + 0xe6, 0xca, 0xe5, 0xdf, 0x84, 0xff, 0xbd, 0xf2, 0x1c, 0x93, 0x2b, 0x50, 0x9d, 0x45, 0x0b, 0xa9, + 0x3e, 0x09, 0x1c, 0xff, 0x66, 0xe7, 0xff, 0x6a, 0x01, 0xe4, 0xed, 0x8b, 0x8a, 0x60, 0x6f, 0x23, + 0x66, 0x53, 0xf7, 0xf2, 0x02, 0x9c, 0x53, 0x73, 0x2b, 0xe6, 0xae, 0xae, 0x9e, 0x6f, 0xf9, 0xf6, + 0xfa, 0xd2, 0x94, 0xa6, 0xfa, 0xc9, 0x7c, 0xfa, 0xfb, 0x5b, 0x3d, 0x99, 0xd9, 0x09, 0xdb, 0xf7, + 0xe1, 0xc2, 0x39, 0xba, 0x37, 0xfc, 0x1a, 0xf2, 0xce, 0x29, 0x5c, 0xd9, 0x8d, 0xcf, 0xc0, 0xcd, + 0x46, 0x39, 0x71, 0xa0, 0xdc, 0x1d, 0x7e, 0xd9, 0xaf, 0x6f, 0x10, 0x80, 0xea, 0x78, 0xd0, 0xa3, + 0x83, 0xa3, 0xba, 0x45, 0x6a, 0x50, 0x1a, 0x8f, 0x0f, 0xeb, 0x36, 0x71, 0xa1, 0xd2, 0x3b, 0xe8, + 0x1d, 0x0e, 0xea, 0x25, 0x5c, 0x1e, 0x3d, 0x78, 0x78, 0x6f, 0x5c, 0x2f, 0xdf, 0xb8, 0x0d, 0x17, + 0x5f, 0x9a, 0xcd, 0x2a, 0xfa, 0xf0, 0x80, 0x0e, 0x90, 0xc9, 0x83, 0xda, 0x43, 0x3a, 0x3c, 0x3e, + 0x38, 0x1a, 0xd4, 0x2d, 0x74, 0x7c, 0x31, 0xea, 0xdd, 0x1f, 0xf4, 0xeb, 0x76, 0xb7, 0xfe, 0xec, + 0xc5, 0x8e, 0xf5, 0xcb, 0x8b, 0x1d, 0xeb, 0x8f, 0x17, 0x3b, 0xd6, 0xf7, 0x7f, 0xee, 0x6c, 0x4c, + 0xaa, 0xea, 0x6f, 0xe2, 0xc7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x42, 0x80, 0x11, 0x1b, 0x66, + 0x0a, 0x00, 0x00, } diff --git a/vendor/github.com/moby/buildkit/solver/pb/ops.proto b/vendor/github.com/moby/buildkit/solver/pb/ops.proto index 8b7af2d40467a..6f0a5248054dc 100644 --- a/vendor/github.com/moby/buildkit/solver/pb/ops.proto +++ b/vendor/github.com/moby/buildkit/solver/pb/ops.proto @@ -15,7 +15,18 @@ message Op { SourceOp source = 3; CopyOp copy = 4; BuildOp build = 5; - } + } + Platform platform = 10; + WorkerConstraints constraints = 11; +} + +// Platform is github.com/opencontainers/image-spec/specs-go/v1.Platform +message Platform { + string Architecture = 1; + string OS = 2; + string Variant = 3; + string OSVersion = 4; // unused + repeated string OSFeatures = 5; // unused } // Input represents an input edge for an Op. @@ -54,6 +65,7 @@ message Mount { CacheOpt cacheOpt = 20; } +// MountType defines a type of a mount from a supported set enum MountType { BIND = 0; SECRET = 1; @@ -62,8 +74,22 @@ enum MountType { TMPFS = 4; } +// CacheOpt defines options specific to cache mounts message CacheOpt { + // ID is an optional namespace for the mount string ID = 1; + // Sharing is the sharing mode for the mount + CacheSharingOpt sharing = 2; +} + +// CacheSharingOpt defines different sharing modes for cache mount +enum CacheSharingOpt { + // SHARED cache mount can be used concurrently by multiple writers + SHARED = 0; + // PRIVATE creates a new mount if there are multiple writers + PRIVATE = 1; + // LOCKED pauses second writer until first one releases the mount + LOCKED = 2; } // CopyOp copies files across Ops. @@ -106,8 +132,9 @@ message OpMetadata { // ignore_cache specifies to ignore the cache for this Op. bool ignore_cache = 1; // Description can be used for keeping any text fields that builder doesn't parse - map description = 2; - WorkerConstraint worker_constraint = 3; + map description = 2; + // index 3 reserved for WorkerConstraint in previous versions + // WorkerConstraint worker_constraint = 3; ExportCache export_cache = 4; } @@ -122,8 +149,8 @@ message ProxyEnv { string no_proxy = 4; } -// WorkerConstraint is experimental and likely to be changed. -message WorkerConstraint { +// WorkerConstraints defines conditions for the worker +message WorkerConstraints { repeated string filter = 1; // containerd-style filter } diff --git a/vendor/github.com/moby/buildkit/source/identifier.go b/vendor/github.com/moby/buildkit/source/identifier.go index ae6814c6f0a2d..a4d9f5a01bd13 100644 --- a/vendor/github.com/moby/buildkit/source/identifier.go +++ b/vendor/github.com/moby/buildkit/source/identifier.go @@ -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) { diff --git a/vendor/github.com/moby/buildkit/util/imageutil/config.go b/vendor/github.com/moby/buildkit/util/imageutil/config.go index c9d5e391ff4ef..2c2e18ba53a3f 100644 --- a/vendor/github.com/moby/buildkit/util/imageutil/config.go +++ b/vendor/github.com/moby/buildkit/util/imageutil/config.go @@ -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 diff --git a/vendor/github.com/moby/buildkit/vendor.conf b/vendor/github.com/moby/buildkit/vendor.conf index 1bfc41ba9e3e4..26d6a3b6d5a29 100644 --- a/vendor/github.com/moby/buildkit/vendor.conf +++ b/vendor/github.com/moby/buildkit/vendor.conf @@ -6,7 +6,7 @@ github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 -github.com/containerd/containerd 63522d9eaa5a0443d225642c4b6f4f5fdedf932b +github.com/containerd/containerd 08f7ee9828af1783dc98cc5cc1739e915697c667 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/sirupsen/logrus v1.0.0 diff --git a/vendor/github.com/moby/buildkit/worker/worker.go b/vendor/github.com/moby/buildkit/worker/worker.go index 84fec1f8d4fa4..cd29d5ea667d6 100644 --- a/vendor/github.com/moby/buildkit/worker/worker.go +++ b/vendor/github.com/moby/buildkit/worker/worker.go @@ -11,16 +11,18 @@ import ( "github.com/moby/buildkit/frontend" "github.com/moby/buildkit/solver" digest "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) type Worker interface { // ID needs to be unique in the cluster ID() string Labels() map[string]string + Platforms() []specs.Platform 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) @@ -33,8 +35,6 @@ type Worker interface { // Pre-defined label keys const ( labelPrefix = "org.mobyproject.buildkit.worker." - LabelOS = labelPrefix + "os" // GOOS - LabelArch = labelPrefix + "arch" // GOARCH LabelExecutor = labelPrefix + "executor" // "oci" or "containerd" LabelSnapshotter = labelPrefix + "snapshotter" // containerd snapshotter name ("overlay", "native", ...) LabelHostname = labelPrefix + "hostname" From 48b93419dcc3dc71584d674f045c30793b890395 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 26 Jun 2018 11:30:19 -0700 Subject: [PATCH 4/9] builder: buildkit rebase update Signed-off-by: Tonis Tiigi --- .../adapters/containerimage/pull.go | 2 +- builder/builder-next/worker/worker.go | 32 ++++++++++++------- builder/dockerfile/dispatchers.go | 21 +++++++++--- pkg/system/lcow.go | 1 + 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go index b84d2e8589a75..dd23304951649 100644 --- a/builder/builder-next/adapters/containerimage/pull.go +++ b/builder/builder-next/adapters/containerimage/pull.go @@ -126,7 +126,7 @@ func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (dige 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, "") + dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, nil) if err != nil { return nil, err } diff --git a/builder/builder-next/worker/worker.go b/builder/builder-next/worker/worker.go index 28e16368ce29c..29e8095c328db 100644 --- a/builder/builder-next/worker/worker.go +++ b/builder/builder-next/worker/worker.go @@ -10,6 +10,7 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/rootfs" "github.com/docker/docker/distribution" distmetadata "github.com/docker/docker/distribution/metadata" @@ -122,6 +123,12 @@ func (w *Worker) Labels() map[string]string { return w.Opt.Labels } +// Platforms returns one or more platforms supported by the image. +func (w *Worker) Platforms() []ocispec.Platform { + // does not handle lcow + return []ocispec.Platform{platforms.DefaultSpec()} +} + // LoadRef loads a reference by ID func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) { return w.CacheManager.Get(context.TODO(), id) @@ -129,26 +136,27 @@ func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) { // ResolveOp converts a LLB vertex into a LLB operation func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) { - switch op := v.Sys().(type) { - case *pb.Op_Source: - return ops.NewSourceOp(v, op, w.SourceManager, w) - case *pb.Op_Exec: - return ops.NewExecOp(v, op, w.CacheManager, w.MetadataStore, w.Executor, w) - case *pb.Op_Build: - return ops.NewBuildOp(v, op, s, w) - default: - return nil, errors.Errorf("could not resolve %v", v) + if baseOp, ok := v.Sys().(*pb.Op); ok { + switch op := baseOp.Op.(type) { + case *pb.Op_Source: + 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: + return ops.NewBuildOp(v, op, s, w) + } } + return nil, errors.Errorf("could not resolve %v", v) } // ResolveImageConfig returns image config for an image -func (w *Worker) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { +func (w *Worker) ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.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) } // Exec executes a process directly on a worker @@ -319,5 +327,5 @@ func oneOffProgress(ctx context.Context, id string) func(err error) error { } type resolveImageConfig interface { - ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) + ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) } diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 65d93139f18b7..c30c010eceff9 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -152,12 +152,23 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error // func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { d.builder.imageProber.Reset() - //TODO(@arm64b): Leave the sanity check of the spec platform to the containerd code - if err := platforms.ValidatePlatform(&cmd.Platform); err != nil { - return err - } - image, err := d.getFromImage(d.shlex, cmd.BaseName, cmd.Platform.OS) + // TODO: pass *platform instead, allow autodetect + platform := platforms.DefaultSpec() + if v := cmd.Platform; v != "" { + // TODO: + // 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 errors.Wrapf(err, "failed to parse platform %s", v) + } + platform = p + } + image, err := d.getFromImage(d.shlex, cmd.BaseName, platform.OS) if err != nil { return err } diff --git a/pkg/system/lcow.go b/pkg/system/lcow.go index 786811df7460c..630e9731456cf 100644 --- a/pkg/system/lcow.go +++ b/pkg/system/lcow.go @@ -2,6 +2,7 @@ package system // import "github.com/docker/docker/pkg/system" import ( "runtime" + "strings" ) // IsOSSupported determines if an operating system is supported by the host From 81f862a1fe6f24fea70b1278a4292eefc4029a03 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 26 Jun 2018 13:04:35 -0700 Subject: [PATCH 5/9] api: fix platform type Signed-off-by: Tonis Tiigi --- api/server/router/build/build_routes.go | 4 ++-- api/server/router/image/image_routes.go | 2 +- api/types/client.go | 2 +- builder/dockerfile/copy.go | 2 +- client/image_build.go | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 0dd2b1d8f9d3b..52ba13216dc54 100644 --- a/api/server/router/build/build_routes.go +++ b/api/server/router/build/build_routes.go @@ -72,12 +72,12 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui options.RemoteContext = r.FormValue("remote") if versions.GreaterThanOrEqualTo(version, "1.32") { apiPlatform := r.FormValue("platform") - if len(strings.TrimSpace(apiPlatform)) != 0 { + if apiPlatform != "" { sp, err := platforms.Parse(apiPlatform) if err != nil { return nil, err } - options.Platform = sp + options.Platform = &sp } } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index f359df27f8ec0..42db0a14e77a2 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -44,7 +44,7 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite version := httputils.VersionFromContext(ctx) if versions.GreaterThanOrEqualTo(version, "1.32") { apiPlatform := r.FormValue("platform") - if len(strings.TrimSpace(apiPlatform)) != 0 { + if apiPlatform != "" { sp, err := platforms.Parse(apiPlatform) if err != nil { return err diff --git a/api/types/client.go b/api/types/client.go index cc10a98a58e22..33bc98e0bb401 100644 --- a/api/types/client.go +++ b/api/types/client.go @@ -181,7 +181,7 @@ type ImageBuildOptions struct { ExtraHosts []string // List of extra hosts Target string SessionID string - Platform specs.Platform + Platform *specs.Platform // Version specifies the version of the unerlying builder to use Version BuilderVersion // BuildID is an optional identifier that can be passed together with the diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go index 17d2b5bde9e3e..37ee4006dfe78 100644 --- a/builder/dockerfile/copy.go +++ b/builder/dockerfile/copy.go @@ -73,7 +73,7 @@ type copier struct { source builder.Source pathCache pathCache download sourceDownloader - platform specs.Platform + platform *specs.Platform // for cleanup. TODO: having copier.cleanup() is error prone and hard to // follow. Code calling performCopy should manage the lifecycle of its params. // Copier should take override source as input, not imageMount. diff --git a/client/image_build.go b/client/image_build.go index dff19b989f0fc..e5013176a2f96 100644 --- a/client/image_build.go +++ b/client/image_build.go @@ -8,8 +8,8 @@ import ( "net/http" "net/url" "strconv" - "strings" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" ) @@ -30,11 +30,11 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio } headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) - if options.Platform != "" { + if options.Platform != nil { if err := cli.NewVersionError("1.32", "platform"); err != nil { return types.ImageBuildResponse{}, err } - query.Set("platform", options.Platform) + query.Set("platform", platforms.Format(*options.Platform)) } headers.Set("Content-Type", "application/x-tar") @@ -130,8 +130,8 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur if options.SessionID != "" { query.Set("session", options.SessionID) } - if options.Platform != "" { - query.Set("platform", strings.ToLower(options.Platform)) + if options.Platform != nil { + query.Set("platform", platforms.Format(*options.Platform)) } if options.BuildID != "" { query.Set("buildid", options.BuildID) From 337ba71fc1124603302e28d94e2f08674e31a756 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 26 Jun 2018 14:49:33 -0700 Subject: [PATCH 6/9] distribution: fix passing platform struct to puller Signed-off-by: Tonis Tiigi --- api/server/router/image/backend.go | 3 +- api/server/router/image/image_routes.go | 10 ++- api/types/backend/build.go | 3 +- builder/dockerfile/copy.go | 10 ++- builder/dockerfile/dispatchers.go | 84 +++++++++----------- builder/dockerfile/dispatchers_test.go | 7 +- builder/dockerfile/imagecontext.go | 11 +-- builder/dockerfile/internals.go | 7 +- daemon/cluster/executor/backend.go | 3 +- daemon/cluster/executor/container/adapter.go | 4 +- daemon/images/image_builder.go | 16 ++-- daemon/images/image_pull.go | 9 ++- distribution/config.go | 7 +- distribution/pull.go | 5 +- distribution/pull_v1.go | 3 +- distribution/pull_v2.go | 82 +++++++++++-------- distribution/pull_v2_unix.go | 60 ++++++++++++-- distribution/pull_v2_windows.go | 7 +- distribution/registry_unit_test.go | 3 +- 19 files changed, 207 insertions(+), 127 deletions(-) diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index 93c47cf638987..5837f9a9bcdfd 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/registry" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // Backend is all the methods that need to be implemented @@ -34,7 +35,7 @@ type importExportBackend interface { } type registryBackend interface { - PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error + PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 42db0a14e77a2..9490d7926f9a3 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -35,7 +35,7 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite message = r.Form.Get("message") err error output = ioutils.NewWriteFlusher(w) - platform = &specs.Platform{} + platform *specs.Platform ) defer output.Close() @@ -72,13 +72,17 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite authConfig = &types.AuthConfig{} } } - err = s.backend.PullImage(ctx, image, tag, platform.OS, metaHeaders, authConfig, output) + err = s.backend.PullImage(ctx, image, tag, platform, metaHeaders, authConfig, output) } else { //import src := r.Form.Get("fromSrc") // 'err' MUST NOT be defined within this block, we need any error // generated from the download to be available to the output // stream processing below - err = s.backend.ImportImage(src, repo, platform.OS, tag, message, r.Body, output, r.Form["changes"]) + os := "" + if platform != nil { + os = platform.OS + } + err = s.backend.ImportImage(src, repo, os, tag, message, r.Body, output, r.Form["changes"]) } } if err != nil { diff --git a/api/types/backend/build.go b/api/types/backend/build.go index 31e00ec6ceb9b..1a2e59f2f7c88 100644 --- a/api/types/backend/build.go +++ b/api/types/backend/build.go @@ -5,6 +5,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/streamformatter" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // PullOption defines different modes for accessing images @@ -40,5 +41,5 @@ type GetImageAndLayerOptions struct { PullOption PullOption AuthConfig map[string]types.AuthConfig Output io.Writer - OS string + Platform *specs.Platform } diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go index 37ee4006dfe78..7e9dc6036a460 100644 --- a/builder/dockerfile/copy.go +++ b/builder/dockerfile/copy.go @@ -96,8 +96,14 @@ func (o *copier) createCopyInstruction(args []string, cmdName string) (copyInstr last := len(args) - 1 // Work in platform-specific filepath semantics - inst.dest = fromSlash(args[last], o.platform.OS) - separator := string(separator(o.platform.OS)) + // TODO: This OS switch for paths is NOT correct and should not be supported. + // Maintained for backwards compatibility + pathOS := runtime.GOOS + if o.platform != nil { + pathOS = o.platform.OS + } + inst.dest = fromSlash(args[last], pathOS) + separator := string(separator(pathOS)) infos, err := o.getCopyInfosForSourcePaths(args[0:last], inst.dest) if err != nil { return inst, errors.Wrapf(err, "%s failed", cmdName) diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index c30c010eceff9..5372d2f0f886d 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -28,6 +28,7 @@ import ( "github.com/moby/buildkit/frontend/dockerfile/instructions" "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/moby/buildkit/frontend/dockerfile/shell" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -103,7 +104,7 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error { copyInstruction.chownStr = c.Chown copyInstruction.allowLocalDecompression = true - return d.builder.performCopy(d.state, copyInstruction) + return d.builder.performCopy(d, copyInstruction) } // COPY foo /path @@ -127,7 +128,7 @@ func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error { } copyInstruction.chownStr = c.Chown - return d.builder.performCopy(d.state, copyInstruction) + return d.builder.performCopy(d, copyInstruction) } func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error) { @@ -145,7 +146,7 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error imageRefOrID = stage.Image localOnly = true } - return d.builder.imageSources.Get(imageRefOrID, localOnly, d.state.operatingSystem) + return d.builder.imageSources.Get(imageRefOrID, localOnly, d.builder.options.Platform) } // FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name] @@ -153,22 +154,21 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { d.builder.imageProber.Reset() - // TODO: pass *platform instead, allow autodetect - platform := platforms.DefaultSpec() + var platform *specs.Platform if v := cmd.Platform; v != "" { - // TODO: - // 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) - // } + v, err := d.getExpandedString(d.shlex, v) + if err != nil { + return errors.Wrapf(err, "failed to process arguments for platform %s", v) + } p, err := platforms.Parse(v) if err != nil { return errors.Wrapf(err, "failed to parse platform %s", v) } - platform = p + platform = &p } - image, err := d.getFromImage(d.shlex, cmd.BaseName, platform.OS) + + image, err := d.getFromImage(d.shlex, cmd.BaseName, platform) if err != nil { return err } @@ -214,82 +214,72 @@ func dispatchTriggeredOnBuild(d dispatchRequest, triggers []string) error { return nil } -func (d *dispatchRequest) getExpandedImageName(shlex *shell.Lex, name string) (string, error) { +func (d *dispatchRequest) getExpandedString(shlex *shell.Lex, str string) (string, error) { substitutionArgs := []string{} for key, value := range d.state.buildArgs.GetAllMeta() { substitutionArgs = append(substitutionArgs, key+"="+value) } - name, err := shlex.ProcessWord(name, substitutionArgs) + name, err := shlex.ProcessWord(str, substitutionArgs) if err != nil { return "", err } return name, nil } -// getOsFromFlagsAndStage calculates the operating system if we need to pull an image. -// stagePlatform contains the value supplied by optional `--platform=` on -// a current FROM statement. b.builder.options.Platform contains the operating -// system part of the optional flag passed in the API call (or CLI flag -// through `docker build --platform=...`). Precedence is for an explicit -// platform indication in the FROM statement. -func (d *dispatchRequest) getOsFromFlagsAndStage(stageOS string) string { - switch { - case stageOS != "": - return stageOS - case d.builder.options.Platform.OS != "": - // Note this is API "platform", but by this point, as the daemon is not - // multi-arch aware yet, it is guaranteed to only hold the OS part here. - return d.builder.options.Platform.OS - default: - return "" // Auto-select - } -} - -func (d *dispatchRequest) getImageOrStage(name string, stageOS string) (builder.Image, error) { +func (d *dispatchRequest) getImageOrStage(name string, platform *specs.Platform) (builder.Image, error) { var localOnly bool if im, ok := d.stages.getByName(name); ok { name = im.Image localOnly = true } - os := d.getOsFromFlagsAndStage(stageOS) + if platform == nil { + platform = d.builder.options.Platform + } // Windows cannot support a container with no base image unless it is LCOW. if name == api.NoBaseImageSpecifier { + p := platforms.DefaultSpec() + if platform != nil { + p = *platform + } imageImage := &image.Image{} - imageImage.OS = runtime.GOOS + imageImage.OS = p.OS + + // old windows scratch handling + // TODO: scratch should not have an os. It should be nil image. + // Windows supports scratch. What is not supported is running containers + // from it. if runtime.GOOS == "windows" { - switch os { - case "windows": - return nil, errors.New("Windows does not support FROM scratch") - case "linux", "": + if platform == nil || platform.OS == "linux" { if !system.LCOWSupported() { return nil, errors.New("Linux containers are not supported on this system") } imageImage.OS = "linux" - default: - return nil, errors.Errorf("operating system %q is not supported", os) + } else if platform.OS == "windows" { + return nil, errors.New("Windows does not support FROM scratch") + } else { + return nil, errors.Errorf("platform %s is not supported", platforms.Format(p)) } } return builder.Image(imageImage), nil } - imageMount, err := d.builder.imageSources.Get(name, localOnly, os) + imageMount, err := d.builder.imageSources.Get(name, localOnly, platform) if err != nil { return nil, err } return imageMount.Image(), nil } -func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, stageOS string) (builder.Image, error) { - name, err := d.getExpandedImageName(shlex, name) +func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, platform *specs.Platform) (builder.Image, error) { + name, err := d.getExpandedString(shlex, name) if err != nil { return nil, err } - return d.getImageOrStage(name, stageOS) + return d.getImageOrStage(name, platform) } func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error { - d.state.runConfig.OnBuild = append(d.state.runConfig.OnBuild, c.Expression) return d.builder.commit(d.state, "ONBUILD "+c.Expression) } diff --git a/builder/dockerfile/dispatchers_test.go b/builder/dockerfile/dispatchers_test.go index 36d20a1a82bdf..047a8742e8300 100644 --- a/builder/dockerfile/dispatchers_test.go +++ b/builder/dockerfile/dispatchers_test.go @@ -6,6 +6,7 @@ import ( "runtime" "testing" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" "github.com/docker/docker/api/types/container" @@ -22,15 +23,17 @@ import ( func newBuilderWithMockBackend() *Builder { mockBackend := &MockBackend{} + defaultPlatform := platforms.DefaultSpec() + opts := &types.ImageBuildOptions{Platform: &defaultPlatform} ctx := context.Background() b := &Builder{ - options: &types.ImageBuildOptions{Platform: runtime.GOOS}, + options: opts, docker: mockBackend, Stdout: new(bytes.Buffer), clientCtx: ctx, disableCommit: true, imageSources: newImageSources(ctx, builderOptions{ - Options: &types.ImageBuildOptions{Platform: runtime.GOOS}, + Options: opts, Backend: mockBackend, }), imageProber: newImageProber(mockBackend, nil, false), diff --git a/builder/dockerfile/imagecontext.go b/builder/dockerfile/imagecontext.go index 53a4b9774b5bd..08cb396a2bdfb 100644 --- a/builder/dockerfile/imagecontext.go +++ b/builder/dockerfile/imagecontext.go @@ -7,11 +7,12 @@ import ( "github.com/docker/docker/api/types/backend" "github.com/docker/docker/builder" dockerimage "github.com/docker/docker/image" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -type getAndMountFunc func(string, bool, string) (builder.Image, builder.ROLayer, error) +type getAndMountFunc func(string, bool, *specs.Platform) (builder.Image, builder.ROLayer, error) // imageSources mounts images and provides a cache for mounted images. It tracks // all images so they can be unmounted at the end of the build. @@ -22,7 +23,7 @@ type imageSources struct { } func newImageSources(ctx context.Context, options builderOptions) *imageSources { - getAndMount := func(idOrRef string, localOnly bool, osForPull string) (builder.Image, builder.ROLayer, error) { + getAndMount := func(idOrRef string, localOnly bool, platform *specs.Platform) (builder.Image, builder.ROLayer, error) { pullOption := backend.PullOptionNoPull if !localOnly { if options.Options.PullParent { @@ -35,7 +36,7 @@ func newImageSources(ctx context.Context, options builderOptions) *imageSources PullOption: pullOption, AuthConfig: options.Options.AuthConfigs, Output: options.ProgressWriter.Output, - OS: osForPull, + Platform: platform, }) } @@ -45,12 +46,12 @@ func newImageSources(ctx context.Context, options builderOptions) *imageSources } } -func (m *imageSources) Get(idOrRef string, localOnly bool, osForPull string) (*imageMount, error) { +func (m *imageSources) Get(idOrRef string, localOnly bool, platform *specs.Platform) (*imageMount, error) { if im, ok := m.byImageID[idOrRef]; ok { return im, nil } - image, layer, err := m.getImage(idOrRef, localOnly, osForPull) + image, layer, err := m.getImage(idOrRef, localOnly, platform) if err != nil { return nil, err } diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go index e23c3280016ef..5e2c286d75453 100644 --- a/builder/dockerfile/internals.go +++ b/builder/dockerfile/internals.go @@ -150,7 +150,8 @@ func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, paren return nil } -func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error { +func (b *Builder) performCopy(req dispatchRequest, inst copyInstruction) error { + state := req.state srcHash := getSourceHashFromInfos(inst.infos) var chownComment string @@ -168,7 +169,7 @@ func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error return err } - imageMount, err := b.imageSources.Get(state.imageID, true, state.operatingSystem) + imageMount, err := b.imageSources.Get(state.imageID, true, req.builder.options.Platform) if err != nil { return errors.Wrapf(err, "failed to get destination image %q", state.imageID) } @@ -456,7 +457,7 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf // is too small for builder scenarios where many users are // using RUN statements to install large amounts of data. // Use 127GB as that's the default size of a VHD in Hyper-V. - if runtime.GOOS == "windows" && options.Platform.OS == "windows" { + if runtime.GOOS == "windows" && options.Platform != nil && options.Platform.OS == "windows" { hc.StorageOpt = make(map[string]string) hc.StorageOpt["size"] = "127GB" } diff --git a/daemon/cluster/executor/backend.go b/daemon/cluster/executor/backend.go index 1f2312ab4011c..cfbc86ce366da 100644 --- a/daemon/cluster/executor/backend.go +++ b/daemon/cluster/executor/backend.go @@ -23,6 +23,7 @@ import ( "github.com/docker/libnetwork/cluster" networktypes "github.com/docker/libnetwork/types" "github.com/docker/swarmkit/agent/exec" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // Backend defines the executor component for a swarm agent. @@ -69,7 +70,7 @@ type VolumeBackend interface { // ImageBackend is used by an executor to perform image operations type ImageBackend interface { - PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error + PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, bool, error) LookupImage(name string) (*types.ImageInspect, error) } diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go index fdf1ee2ec75bb..6b222f202de2a 100644 --- a/daemon/cluster/executor/container/adapter.go +++ b/daemon/cluster/executor/container/adapter.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "os" - "runtime" "strings" "syscall" "time" @@ -97,8 +96,7 @@ func (c *containerAdapter) pullImage(ctx context.Context) error { go func() { // TODO @jhowardmsft LCOW Support: This will need revisiting as // the stack is built up to include LCOW support for swarm. - platform := runtime.GOOS - err := c.imageBackend.PullImage(ctx, c.container.image(), "", platform, metaHeaders, authConfig, pw) + err := c.imageBackend.PullImage(ctx, c.container.image(), "", nil, metaHeaders, authConfig, pw) pw.CloseWithError(err) }() diff --git a/daemon/images/image_builder.go b/daemon/images/image_builder.go index b792721ee4502..cdf951c6f5649 100644 --- a/daemon/images/image_builder.go +++ b/daemon/images/image_builder.go @@ -3,6 +3,7 @@ package images // import "github.com/docker/docker/daemon/images" import ( "context" "io" + "runtime" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" @@ -14,6 +15,7 @@ import ( "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/system" "github.com/docker/docker/registry" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -137,7 +139,7 @@ func newROLayerForImage(img *image.Image, layerStore layer.Store) (builder.ROLay } // TODO: could this use the regular daemon PullImage ? -func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer, os string) (*image.Image, error) { +func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer, platform *specs.Platform) (*image.Image, error) { ref, err := reference.ParseNormalizedNamed(name) if err != nil { return nil, err @@ -156,7 +158,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf pullRegistryAuth = &resolvedConfig } - if err := i.pullImageWithReference(ctx, ref, os, nil, pullRegistryAuth, output); err != nil { + if err := i.pullImageWithReference(ctx, ref, platform, nil, pullRegistryAuth, output); err != nil { return nil, err } return i.GetImage(name) @@ -167,10 +169,14 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf // leaking of layers. func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { if refOrID == "" { // ie FROM scratch - if !system.IsOSSupported(opts.OS) { + os := runtime.GOOS + if opts.Platform != nil { + os = opts.Platform.OS + } + if !system.IsOSSupported(os) { return nil, nil, system.ErrNotSupportedOperatingSystem } - layer, err := newROLayerForImage(nil, i.layerStores[opts.OS]) + layer, err := newROLayerForImage(nil, i.layerStores[os]) return nil, layer, err } @@ -189,7 +195,7 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s } } - image, err := i.pullForBuilder(ctx, refOrID, opts.AuthConfig, opts.Output, opts.OS) + image, err := i.pullForBuilder(ctx, refOrID, opts.AuthConfig, opts.Output, opts.Platform) if err != nil { return nil, nil, err } diff --git a/daemon/images/image_pull.go b/daemon/images/image_pull.go index ed8ecb9abeb96..3e6b4330373b9 100644 --- a/daemon/images/image_pull.go +++ b/daemon/images/image_pull.go @@ -15,11 +15,12 @@ import ( "github.com/docker/docker/pkg/progress" "github.com/docker/docker/registry" "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // PullImage initiates a pull operation. image is the repository name to pull, and // tag may be either empty, or indicate a specific tag to pull. -func (i *ImageService) PullImage(ctx context.Context, image, tag, os string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { +func (i *ImageService) PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { start := time.Now() // Special case: "pull -a" may send an image name with a // trailing :. This is ugly, but let's not break API @@ -45,12 +46,12 @@ func (i *ImageService) PullImage(ctx context.Context, image, tag, os string, met } } - err = i.pullImageWithReference(ctx, ref, os, metaHeaders, authConfig, outStream) + err = i.pullImageWithReference(ctx, ref, platform, metaHeaders, authConfig, outStream) imageActions.WithValues("pull").UpdateSince(start) return err } -func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, os string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { +func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { // Include a buffer so that slow client connections don't affect // transfer performance. progressChan := make(chan progress.Progress, 100) @@ -77,7 +78,7 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference }, DownloadManager: i.downloadManager, Schema2Types: distribution.ImageTypes, - OS: os, + Platform: platform, } err := distribution.Pull(ctx, ref, imagePullConfig) diff --git a/distribution/config.go b/distribution/config.go index 55f1f8c2df3ba..438051c296e27 100644 --- a/distribution/config.go +++ b/distribution/config.go @@ -60,9 +60,8 @@ type ImagePullConfig struct { // Schema2Types is the valid schema2 configuration types allowed // by the pull operation. Schema2Types []string - // OS is the requested operating system of the image being pulled to ensure it can be validated - // when the host OS supports multiple image operating systems. - OS string + // Platform is the requested platform of the image being pulled + Platform *specs.Platform } // ImagePushConfig stores push configuration. @@ -171,7 +170,7 @@ func (s *imageConfigStore) PlatformFromConfig(c []byte) (*specs.Platform, error) if !system.IsOSSupported(os) { return nil, system.ErrNotSupportedOperatingSystem } - return &specs.Platform{OS: os, OSVersion: unmarshalledConfig.OSVersion}, nil + return &specs.Platform{OS: os, Architecture: unmarshalledConfig.Architecture, OSVersion: unmarshalledConfig.OSVersion}, nil } type storeLayerProvider struct { diff --git a/distribution/pull.go b/distribution/pull.go index 0c5237f6c068e..5de73ae99ac39 100644 --- a/distribution/pull.go +++ b/distribution/pull.go @@ -11,6 +11,7 @@ import ( refstore "github.com/docker/docker/reference" "github.com/docker/docker/registry" "github.com/opencontainers/go-digest" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -20,7 +21,7 @@ type Puller interface { // Pull tries to pull the image referenced by `tag` // Pull returns an error if any, as well as a boolean that determines whether to retry Pull on the next configured endpoint. // - Pull(ctx context.Context, ref reference.Named, os string) error + Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) error } // newPuller returns a Puller interface that will pull from either a v1 or v2 @@ -114,7 +115,7 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo continue } - if err := puller.Pull(ctx, ref, imagePullConfig.OS); err != nil { + if err := puller.Pull(ctx, ref, imagePullConfig.Platform); err != nil { // Was this pull cancelled? If so, don't try to fall // back. fallback := false diff --git a/distribution/pull_v1.go b/distribution/pull_v1.go index c26d881223f0a..c2c897dc1c31c 100644 --- a/distribution/pull_v1.go +++ b/distribution/pull_v1.go @@ -25,6 +25,7 @@ import ( "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/registry" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -36,7 +37,7 @@ type v1Puller struct { session *registry.Session } -func (p *v1Puller) Pull(ctx context.Context, ref reference.Named, os string) error { +func (p *v1Puller) Pull(ctx context.Context, ref reference.Named, _ *specs.Platform) error { if _, isCanonical := ref.(reference.Canonical); isCanonical { // Allowing fallback, because HTTPS v1 is before HTTP v2 return fallbackError{err: ErrNoSupport{Err: errors.New("Cannot pull by digest with v1 registry")}} diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go index 9e07c88d19d4f..8f05cfa0b289b 100644 --- a/distribution/pull_v2.go +++ b/distribution/pull_v2.go @@ -11,6 +11,7 @@ import ( "runtime" "strings" + "github.com/containerd/containerd/platforms" "github.com/docker/distribution" "github.com/docker/distribution/manifest/manifestlist" "github.com/docker/distribution/manifest/schema1" @@ -63,7 +64,7 @@ type v2Puller struct { confirmedV2 bool } -func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (err error) { +func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) { // TODO(tiborvass): was ReceiveTimeout p.repo, p.confirmedV2, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull") if err != nil { @@ -71,7 +72,7 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (er return err } - if err = p.pullV2Repository(ctx, ref, os); err != nil { + if err = p.pullV2Repository(ctx, ref, platform); err != nil { if _, ok := err.(fallbackError); ok { return err } @@ -86,10 +87,10 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (er return err } -func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, os string) (err error) { +func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) { var layersDownloaded bool if !reference.IsNameOnly(ref) { - layersDownloaded, err = p.pullV2Tag(ctx, ref, os) + layersDownloaded, err = p.pullV2Tag(ctx, ref, platform) if err != nil { return err } @@ -111,7 +112,7 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, os if err != nil { return err } - pulledNew, err := p.pullV2Tag(ctx, tagRef, os) + pulledNew, err := p.pullV2Tag(ctx, tagRef, platform) if err != nil { // Since this is the pull-all-tags case, don't // allow an error pulling a particular tag to @@ -327,7 +328,7 @@ func (ld *v2LayerDescriptor) Registered(diffID layer.DiffID) { ld.V2MetadataService.Add(diffID, metadata.V2Metadata{Digest: ld.digest, SourceRepository: ld.repoInfo.Name.Name()}) } -func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string) (tagUpdated bool, err error) { +func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform *specs.Platform) (tagUpdated bool, err error) { manSvc, err := p.repo.Manifests(ctx) if err != nil { return false, err @@ -391,17 +392,17 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string if p.config.RequireSchema2 { return false, fmt.Errorf("invalid manifest: not schema2") } - id, manifestDigest, err = p.pullSchema1(ctx, ref, v, os) + id, manifestDigest, err = p.pullSchema1(ctx, ref, v, platform) if err != nil { return false, err } case *schema2.DeserializedManifest: - id, manifestDigest, err = p.pullSchema2(ctx, ref, v, os) + id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform) if err != nil { return false, err } case *manifestlist.DeserializedManifestList: - id, manifestDigest, err = p.pullManifestList(ctx, ref, v, os) + id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform) if err != nil { return false, err } @@ -437,7 +438,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string return true, nil } -func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest, requestedOS string) (id digest.Digest, manifestDigest digest.Digest, err error) { +func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest, platform *specs.Platform) (id digest.Digest, manifestDigest digest.Digest, err error) { var verifiedManifest *schema1.Manifest verifiedManifest, err = verifySchema1Manifest(unverifiedManifest, ref) if err != nil { @@ -513,7 +514,10 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv // we support the operating system, switch to that operating system. // eg FROM supertest2014/nyan with no platform specifier, and docker build // with no --platform= flag under LCOW. - if requestedOS == "" && system.IsOSSupported(configOS) { + requestedOS := "" + if platform != nil { + requestedOS = platform.OS + } else if system.IsOSSupported(configOS) { requestedOS = configOS } @@ -544,7 +548,7 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv return imageID, manifestDigest, nil } -func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest, requestedOS string) (id digest.Digest, manifestDigest digest.Digest, err error) { +func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest, platform *specs.Platform) (id digest.Digest, manifestDigest digest.Digest, err error) { manifestDigest, err = schema2ManifestDigest(ref, mfst) if err != nil { return "", "", err @@ -600,6 +604,11 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s configPlatform *specs.Platform // for LCOW when registering downloaded layers ) + layerStoreOS := runtime.GOOS + if platform != nil { + layerStoreOS = platform.OS + } + // https://github.com/docker/docker/issues/24766 - Err on the side of caution, // explicitly blocking images intended for linux from the Windows daemon. On // Windows, we do this before the attempt to download, effectively serialising @@ -623,13 +632,14 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s if len(descriptors) != len(configRootFS.DiffIDs) { return "", "", errRootFSMismatch } - - // Early bath if the requested OS doesn't match that of the configuration. - // This avoids doing the download, only to potentially fail later. - if !system.IsOSSupported(configPlatform.OS) { - return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, requestedOS) + if platform == nil { + // Early bath if the requested OS doesn't match that of the configuration. + // This avoids doing the download, only to potentially fail later. + if !system.IsOSSupported(configPlatform.OS) { + return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, layerStoreOS) + } + layerStoreOS = configPlatform.OS } - requestedOS = configPlatform.OS // Populate diff ids in descriptors to avoid downloading foreign layers // which have been side loaded @@ -638,10 +648,6 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s } } - if requestedOS == "" { - requestedOS = runtime.GOOS - } - if p.config.DownloadManager != nil { go func() { var ( @@ -649,7 +655,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s rootFS image.RootFS ) downloadRootFS := *image.NewRootFS() - rootFS, release, err = p.config.DownloadManager.Download(ctx, downloadRootFS, requestedOS, descriptors, p.config.ProgressOutput) + rootFS, release, err = p.config.DownloadManager.Download(ctx, downloadRootFS, layerStoreOS, descriptors, p.config.ProgressOutput) if err != nil { // Intentionally do not cancel the config download here // as the error from config download (if there is one) @@ -735,22 +741,22 @@ func receiveConfig(s ImageConfigStore, configChan <-chan []byte, errChan <-chan // pullManifestList handles "manifest lists" which point to various // platform-specific manifests. -func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, requestedOS string) (id digest.Digest, manifestListDigest digest.Digest, err error) { +func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, pp *specs.Platform) (id digest.Digest, manifestListDigest digest.Digest, err error) { manifestListDigest, err = schema2ManifestDigest(ref, mfstList) if err != nil { return "", "", err } - logOS := requestedOS // May be "" indicating any OS - if logOS == "" { - logOS = "*" + var platform specs.Platform + if pp != nil { + platform = *pp } - logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a %s/%s match", ref, len(mfstList.Manifests), logOS, runtime.GOARCH) + logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a %s/%s match", ref, len(mfstList.Manifests), platforms.Format(platform), runtime.GOARCH) - manifestMatches := filterManifests(mfstList.Manifests, requestedOS) + manifestMatches := filterManifests(mfstList.Manifests, platform) if len(manifestMatches) == 0 { - errMsg := fmt.Sprintf("no matching manifest for %s/%s in the manifest list entries", logOS, runtime.GOARCH) + errMsg := fmt.Sprintf("no matching manifest for %s in the manifest list entries", platforms.Format(platform)) logrus.Debugf(errMsg) return "", "", errors.New(errMsg) } @@ -781,12 +787,14 @@ func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mf switch v := manifest.(type) { case *schema1.SignedManifest: - id, _, err = p.pullSchema1(ctx, manifestRef, v, manifestMatches[0].Platform.OS) + platform := toOCIPlatform(manifestMatches[0].Platform) + id, _, err = p.pullSchema1(ctx, manifestRef, v, &platform) if err != nil { return "", "", err } case *schema2.DeserializedManifest: - id, _, err = p.pullSchema2(ctx, manifestRef, v, manifestMatches[0].Platform.OS) + platform := toOCIPlatform(manifestMatches[0].Platform) + id, _, err = p.pullSchema2(ctx, manifestRef, v, &platform) if err != nil { return "", "", err } @@ -956,3 +964,13 @@ func fixManifestLayers(m *schema1.Manifest) error { func createDownloadFile() (*os.File, error) { return ioutil.TempFile("", "GetImageBlob") } + +func toOCIPlatform(p manifestlist.PlatformSpec) specs.Platform { + return specs.Platform{ + OS: p.OS, + Architecture: p.Architecture, + Variant: p.Variant, + OSFeatures: p.OSFeatures, + OSVersion: p.OSVersion, + } +} diff --git a/distribution/pull_v2_unix.go b/distribution/pull_v2_unix.go index 65c9594386727..8d2c311f76f9e 100644 --- a/distribution/pull_v2_unix.go +++ b/distribution/pull_v2_unix.go @@ -4,10 +4,11 @@ package distribution // import "github.com/docker/docker/distribution" import ( "context" - "runtime" + "github.com/containerd/containerd/platforms" "github.com/docker/distribution" "github.com/docker/distribution/manifest/manifestlist" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -16,15 +17,27 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo return blobs.Open(ctx, ld.digest) } -func filterManifests(manifests []manifestlist.ManifestDescriptor, _ string) []manifestlist.ManifestDescriptor { +func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platform) []manifestlist.ManifestDescriptor { + p = withDefault(p) var matches []manifestlist.ManifestDescriptor - for _, manifestDescriptor := range manifests { - if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == runtime.GOOS { - matches = append(matches, manifestDescriptor) + for _, desc := range manifests { + if compareNormalized(toOCIPlatform(desc.Platform), p) { + matches = append(matches, desc) + logrus.Debugf("found match for %s with media type %s, digest %s", platforms.Format(p), desc.MediaType, desc.Digest.String()) + } + } - logrus.Debugf("found match for %s/%s with media type %s, digest %s", runtime.GOOS, runtime.GOARCH, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) + // deprecated: backwards compatibility with older versions that didn't compare variant + if len(matches) == 0 && p.Architecture == "arm" { + p = normalize(p) + for _, desc := range manifests { + if desc.Platform.OS == p.OS && desc.Platform.Architecture == p.Architecture { + matches = append(matches, desc) + logrus.Debugf("found deprecated partial match for %s with media type %s, digest %s", platforms.Format(p), desc.MediaType, desc.Digest.String()) + } } } + return matches } @@ -32,3 +45,38 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, _ string) []ma func checkImageCompatibility(imageOS, imageOSVersion string) error { return nil } + +func withDefault(p specs.Platform) specs.Platform { + def := platforms.DefaultSpec() + if p.OS == "" { + p.OS = def.OS + } + if p.Architecture == "" { + p.Architecture = def.Architecture + p.Variant = def.Variant + } + return p +} + +func compareNormalized(p1, p2 specs.Platform) bool { + // remove after https://github.com/containerd/containerd/pull/2414 + return p1.OS == p2.OS && + p1.Architecture == p2.Architecture && + p1.Variant == p2.Variant +} + +func normalize(p specs.Platform) specs.Platform { + p = platforms.Normalize(p) + // remove after https://github.com/containerd/containerd/pull/2414 + if p.Architecture == "arm" { + if p.Variant == "" { + p.Variant = "v7" + } + } + if p.Architecture == "arm64" { + if p.Variant == "" { + p.Variant = "v8" + } + } + return p +} diff --git a/distribution/pull_v2_windows.go b/distribution/pull_v2_windows.go index fc736e336d51a..3c9645883f3a5 100644 --- a/distribution/pull_v2_windows.go +++ b/distribution/pull_v2_windows.go @@ -16,6 +16,7 @@ import ( "github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/registry/client/transport" "github.com/docker/docker/pkg/system" + specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/sirupsen/logrus" ) @@ -62,7 +63,7 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo return rsc, err } -func filterManifests(manifests []manifestlist.ManifestDescriptor, requestedOS string) []manifestlist.ManifestDescriptor { +func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platform) []manifestlist.ManifestDescriptor { version := system.GetOSVersion() osVersion := fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build) logrus.Debugf("will prefer Windows entries with version %s", osVersion) @@ -71,8 +72,8 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, requestedOS st foundWindowsMatch := false for _, manifestDescriptor := range manifests { if (manifestDescriptor.Platform.Architecture == runtime.GOARCH) && - ((requestedOS != "" && manifestDescriptor.Platform.OS == requestedOS) || // Explicit user request for an OS we know we support - (requestedOS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support + ((p.OS != "" && manifestDescriptor.Platform.OS == p.OS) || // Explicit user request for an OS we know we support + (p.OS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support matches = append(matches, manifestDescriptor) logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) if strings.EqualFold("windows", manifestDescriptor.Platform.OS) { diff --git a/distribution/registry_unit_test.go b/distribution/registry_unit_test.go index 5ae529d23dab4..3651c4688bde5 100644 --- a/distribution/registry_unit_test.go +++ b/distribution/registry_unit_test.go @@ -5,7 +5,6 @@ import ( "net/http" "net/http/httptest" "net/url" - "runtime" "strings" "testing" @@ -84,7 +83,7 @@ func testTokenPassThru(t *testing.T, ts *httptest.Server) { logrus.Debug("About to pull") // We expect it to fail, since we haven't mock'd the full registry exchange in our handler above tag, _ := reference.WithTag(n, "tag_goes_here") - _ = p.pullV2Repository(ctx, tag, runtime.GOOS) + _ = p.pullV2Repository(ctx, tag, nil) } func TestTokenPassThru(t *testing.T) { From 0b50d6c315a41025de98617bd6cc79c3925838d5 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 26 Jun 2018 16:17:28 -0700 Subject: [PATCH 7/9] builder: update platform support to puller Signed-off-by: Tonis Tiigi --- .../adapters/containerimage/pull.go | 33 ++++++++++++------- builder/builder-next/builder.go | 5 +++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go index dd23304951649..f76ac5a1aa4e4 100644 --- a/builder/builder-next/adapters/containerimage/pull.go +++ b/builder/builder-next/adapters/containerimage/pull.go @@ -113,7 +113,7 @@ func (is *imageSource) resolveLocal(refStr string) ([]byte, error) { return img.RawJSON(), nil } -func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { +func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) { if preferLocal { dt, err := is.resolveLocal(ref) if err == nil { @@ -126,7 +126,7 @@ func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (dige 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, nil) + dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, platform) if err != nil { return nil, err } @@ -145,10 +145,16 @@ 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 + } + p := &puller{ src: imageIdentifier, is: is, resolver: is.getResolver(ctx), + platform: platform, } return p, nil } @@ -163,17 +169,20 @@ type puller struct { resolveErr error resolver remotes.Resolver config []byte + platform ocispec.Platform } -func (p *puller) mainManifestKey(dgst digest.Digest) (digest.Digest, error) { +func (p *puller) mainManifestKey(dgst digest.Digest, platform ocispec.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: p.desc.Digest, - OS: runtime.GOOS, - Arch: runtime.GOARCH, + Digest: p.desc.Digest, + OS: platform.OS, + Arch: platform.Architecture, + Variant: platform.Variant, }) if err != nil { return "", err @@ -248,7 +257,7 @@ func (p *puller) resolve(ctx context.Context) error { return } - _, dt, err := p.is.ResolveImageConfig(ctx, ref.String()) + _, dt, err := p.is.ResolveImageConfig(ctx, ref.String(), &p.platform) if err != nil { p.resolveErr = err resolveProgressDone(err) @@ -266,7 +275,7 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error) p.resolveLocal() if p.desc.Digest != "" && index == 0 { - dgst, err := p.mainManifestKey(p.desc.Digest) + dgst, err := p.mainManifestKey(p.desc.Digest, p.platform) if err != nil { return "", false, err } @@ -282,7 +291,7 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error) } if p.desc.Digest != "" && index == 0 { - dgst, err := p.mainManifestKey(p.desc.Digest) + dgst, err := p.mainManifestKey(p.desc.Digest, p.platform) if err != nil { return "", false, err } diff --git a/builder/builder-next/builder.go b/builder/builder-next/builder.go index 8c48d9abbf6a1..5a82cddf444ea 100644 --- a/builder/builder-next/builder.go +++ b/builder/builder-next/builder.go @@ -9,6 +9,7 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" "github.com/docker/docker/builder" @@ -208,6 +209,10 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder. frontendAttrs["no-cache"] = "" } + if opt.Options.Platform != nil { + frontendAttrs["platform"] = platforms.Format(*opt.Options.Platform) + } + exporterAttrs := map[string]string{} if len(opt.Options.Tags) > 0 { From f0997716651b6e6c2b07e3d514bf8452114a1433 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 27 Jun 2018 11:53:20 -0700 Subject: [PATCH 8/9] system: add back lcow validation function Signed-off-by: Tonis Tiigi --- api/server/router/build/build_routes.go | 4 ++++ api/server/router/image/image_routes.go | 4 ++++ builder/dockerfile/dispatchers.go | 3 +++ image/tarexport/load.go | 11 ++++++++--- pkg/system/lcow.go | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 52ba13216dc54..071402ae70a9b 100644 --- a/api/server/router/build/build_routes.go +++ b/api/server/router/build/build_routes.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" + "github.com/docker/docker/pkg/system" "github.com/docker/go-units" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -77,6 +78,9 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui if err != nil { return nil, err } + if err := system.ValidatePlatform(sp); err != nil { + return nil, err + } options.Platform = &sp } } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 9490d7926f9a3..85707c06d2ce3 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/streamformatter" + "github.com/docker/docker/pkg/system" "github.com/docker/docker/registry" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -49,6 +50,9 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite if err != nil { return err } + if err := system.ValidatePlatform(sp); err != nil { + return err + } platform = &sp } } diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 5372d2f0f886d..1032c6cdada89 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -165,6 +165,9 @@ func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { if err != nil { return errors.Wrapf(err, "failed to parse platform %s", v) } + if err := system.ValidatePlatform(p); err != nil { + return err + } platform = &p } diff --git a/image/tarexport/load.go b/image/tarexport/load.go index 0416e28b81b78..786214383eaf3 100644 --- a/image/tarexport/load.go +++ b/image/tarexport/load.go @@ -11,6 +11,7 @@ import ( "reflect" "runtime" + "github.com/containerd/containerd/platforms" "github.com/docker/distribution" "github.com/docker/distribution/reference" "github.com/docker/docker/image" @@ -421,7 +422,11 @@ func checkCompatibleOS(imageOS string) error { if runtime.GOOS != "windows" && imageOS == "windows" { return fmt.Errorf("cannot load %s image on %s", imageOS, runtime.GOOS) } - // Finally, check the image OS is supported for the platform. - // TODO(@arm64b): Leave this sanity check to the containerd code in the future - return nil + + p, err := platforms.Parse(imageOS) + if err != nil { + return err + } + + return system.ValidatePlatform(p) } diff --git a/pkg/system/lcow.go b/pkg/system/lcow.go index 630e9731456cf..5be3e2182ba08 100644 --- a/pkg/system/lcow.go +++ b/pkg/system/lcow.go @@ -3,6 +3,9 @@ package system // import "github.com/docker/docker/pkg/system" import ( "runtime" "strings" + + specs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" ) // IsOSSupported determines if an operating system is supported by the host @@ -15,3 +18,15 @@ func IsOSSupported(os string) bool { } return false } + +// ValidatePlatform determines if a platform structure is valid. +// TODO This is a temporary windows-only function, should be replaced by +// comparison of worker capabilities +func ValidatePlatform(platform specs.Platform) error { + if runtime.GOOS == "windows" { + if !(platform.OS == runtime.GOOS || (LCOWSupported() && platform.OS == "linux")) { + return errors.Errorf("unsupported os %s", platform.OS) + } + } + return nil +} From 951faaed664dd51d2aacfdb782534f4c46bd9e23 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 27 Jun 2018 15:21:16 -0700 Subject: [PATCH 9/9] distribution: remove custom matcher code Signed-off-by: Tonis Tiigi --- distribution/pull_v2_unix.go | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/distribution/pull_v2_unix.go b/distribution/pull_v2_unix.go index 8d2c311f76f9e..adbaf41451280 100644 --- a/distribution/pull_v2_unix.go +++ b/distribution/pull_v2_unix.go @@ -18,10 +18,11 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo } func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platform) []manifestlist.ManifestDescriptor { - p = withDefault(p) + p = platforms.Normalize(withDefault(p)) + m := platforms.NewMatcher(p) var matches []manifestlist.ManifestDescriptor for _, desc := range manifests { - if compareNormalized(toOCIPlatform(desc.Platform), p) { + if m.Match(toOCIPlatform(desc.Platform)) { matches = append(matches, desc) logrus.Debugf("found match for %s with media type %s, digest %s", platforms.Format(p), desc.MediaType, desc.Digest.String()) } @@ -29,7 +30,7 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platfo // deprecated: backwards compatibility with older versions that didn't compare variant if len(matches) == 0 && p.Architecture == "arm" { - p = normalize(p) + p = platforms.Normalize(p) for _, desc := range manifests { if desc.Platform.OS == p.OS && desc.Platform.Architecture == p.Architecture { matches = append(matches, desc) @@ -57,26 +58,3 @@ func withDefault(p specs.Platform) specs.Platform { } return p } - -func compareNormalized(p1, p2 specs.Platform) bool { - // remove after https://github.com/containerd/containerd/pull/2414 - return p1.OS == p2.OS && - p1.Architecture == p2.Architecture && - p1.Variant == p2.Variant -} - -func normalize(p specs.Platform) specs.Platform { - p = platforms.Normalize(p) - // remove after https://github.com/containerd/containerd/pull/2414 - if p.Architecture == "arm" { - if p.Variant == "" { - p.Variant = "v7" - } - } - if p.Architecture == "arm64" { - if p.Variant == "" { - p.Variant = "v8" - } - } - return p -}