Fix platform struct passing
Tibor Vass authored on 2018/06/28 11:23:27... | ... |
@@ -14,6 +14,7 @@ import ( |
14 | 14 |
"strings" |
15 | 15 |
"sync" |
16 | 16 |
|
17 |
+ "github.com/containerd/containerd/platforms" |
|
17 | 18 |
"github.com/docker/docker/api/server/httputils" |
18 | 19 |
"github.com/docker/docker/api/types" |
19 | 20 |
"github.com/docker/docker/api/types/backend" |
... | ... |
@@ -72,11 +73,16 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui |
72 | 72 |
options.RemoteContext = r.FormValue("remote") |
73 | 73 |
if versions.GreaterThanOrEqualTo(version, "1.32") { |
74 | 74 |
apiPlatform := r.FormValue("platform") |
75 |
- p := system.ParsePlatform(apiPlatform) |
|
76 |
- if err := system.ValidatePlatform(p); err != nil { |
|
77 |
- return nil, errdefs.InvalidParameter(errors.Errorf("invalid platform: %s", err)) |
|
75 |
+ if apiPlatform != "" { |
|
76 |
+ sp, err := platforms.Parse(apiPlatform) |
|
77 |
+ if err != nil { |
|
78 |
+ return nil, err |
|
79 |
+ } |
|
80 |
+ if err := system.ValidatePlatform(sp); err != nil { |
|
81 |
+ return nil, err |
|
82 |
+ } |
|
83 |
+ options.Platform = &sp |
|
78 | 84 |
} |
79 |
- options.Platform = p.OS |
|
80 | 85 |
} |
81 | 86 |
|
82 | 87 |
if r.Form.Get("shmsize") != "" { |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"github.com/docker/docker/api/types/filters" |
9 | 9 |
"github.com/docker/docker/api/types/image" |
10 | 10 |
"github.com/docker/docker/api/types/registry" |
11 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
11 | 12 |
) |
12 | 13 |
|
13 | 14 |
// Backend is all the methods that need to be implemented |
... | ... |
@@ -34,7 +35,7 @@ type importExportBackend interface { |
34 | 34 |
} |
35 | 35 |
|
36 | 36 |
type registryBackend interface { |
37 |
- PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error |
|
37 |
+ PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error |
|
38 | 38 |
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error |
39 | 39 |
SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) |
40 | 40 |
} |
... | ... |
@@ -4,11 +4,11 @@ import ( |
4 | 4 |
"context" |
5 | 5 |
"encoding/base64" |
6 | 6 |
"encoding/json" |
7 |
- "fmt" |
|
8 | 7 |
"net/http" |
9 | 8 |
"strconv" |
10 | 9 |
"strings" |
11 | 10 |
|
11 |
+ "github.com/containerd/containerd/platforms" |
|
12 | 12 |
"github.com/docker/docker/api/server/httputils" |
13 | 13 |
"github.com/docker/docker/api/types" |
14 | 14 |
"github.com/docker/docker/api/types/filters" |
... | ... |
@@ -36,7 +36,7 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite |
36 | 36 |
message = r.Form.Get("message") |
37 | 37 |
err error |
38 | 38 |
output = ioutils.NewWriteFlusher(w) |
39 |
- platform = &specs.Platform{} |
|
39 |
+ platform *specs.Platform |
|
40 | 40 |
) |
41 | 41 |
defer output.Close() |
42 | 42 |
|
... | ... |
@@ -45,9 +45,15 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite |
45 | 45 |
version := httputils.VersionFromContext(ctx) |
46 | 46 |
if versions.GreaterThanOrEqualTo(version, "1.32") { |
47 | 47 |
apiPlatform := r.FormValue("platform") |
48 |
- platform = system.ParsePlatform(apiPlatform) |
|
49 |
- if err = system.ValidatePlatform(platform); err != nil { |
|
50 |
- err = fmt.Errorf("invalid platform: %s", err) |
|
48 |
+ if apiPlatform != "" { |
|
49 |
+ sp, err := platforms.Parse(apiPlatform) |
|
50 |
+ if err != nil { |
|
51 |
+ return err |
|
52 |
+ } |
|
53 |
+ if err := system.ValidatePlatform(sp); err != nil { |
|
54 |
+ return err |
|
55 |
+ } |
|
56 |
+ platform = &sp |
|
51 | 57 |
} |
52 | 58 |
} |
53 | 59 |
|
... | ... |
@@ -70,13 +76,17 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite |
70 | 70 |
authConfig = &types.AuthConfig{} |
71 | 71 |
} |
72 | 72 |
} |
73 |
- err = s.backend.PullImage(ctx, image, tag, platform.OS, metaHeaders, authConfig, output) |
|
73 |
+ err = s.backend.PullImage(ctx, image, tag, platform, metaHeaders, authConfig, output) |
|
74 | 74 |
} else { //import |
75 | 75 |
src := r.Form.Get("fromSrc") |
76 | 76 |
// 'err' MUST NOT be defined within this block, we need any error |
77 | 77 |
// generated from the download to be available to the output |
78 | 78 |
// stream processing below |
79 |
- err = s.backend.ImportImage(src, repo, platform.OS, tag, message, r.Body, output, r.Form["changes"]) |
|
79 |
+ os := "" |
|
80 |
+ if platform != nil { |
|
81 |
+ os = platform.OS |
|
82 |
+ } |
|
83 |
+ err = s.backend.ImportImage(src, repo, os, tag, message, r.Body, output, r.Form["changes"]) |
|
80 | 84 |
} |
81 | 85 |
} |
82 | 86 |
if err != nil { |
... | ... |
@@ -5,6 +5,7 @@ import ( |
5 | 5 |
|
6 | 6 |
"github.com/docker/docker/api/types" |
7 | 7 |
"github.com/docker/docker/pkg/streamformatter" |
8 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
8 | 9 |
) |
9 | 10 |
|
10 | 11 |
// PullOption defines different modes for accessing images |
... | ... |
@@ -40,5 +41,5 @@ type GetImageAndLayerOptions struct { |
40 | 40 |
PullOption PullOption |
41 | 41 |
AuthConfig map[string]types.AuthConfig |
42 | 42 |
Output io.Writer |
43 |
- OS string |
|
43 |
+ Platform *specs.Platform |
|
44 | 44 |
} |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"github.com/docker/docker/api/types/container" |
9 | 9 |
"github.com/docker/docker/api/types/filters" |
10 | 10 |
"github.com/docker/go-units" |
11 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
11 | 12 |
) |
12 | 13 |
|
13 | 14 |
// CheckpointCreateOptions holds parameters to create a checkpoint from a container |
... | ... |
@@ -180,7 +181,7 @@ type ImageBuildOptions struct { |
180 | 180 |
ExtraHosts []string // List of extra hosts |
181 | 181 |
Target string |
182 | 182 |
SessionID string |
183 |
- Platform string |
|
183 |
+ Platform *specs.Platform |
|
184 | 184 |
// Version specifies the version of the unerlying builder to use |
185 | 185 |
Version BuilderVersion |
186 | 186 |
// BuildID is an optional identifier that can be passed together with the |
... | ... |
@@ -113,7 +113,7 @@ func (is *imageSource) resolveLocal(refStr string) ([]byte, error) { |
113 | 113 |
return img.RawJSON(), nil |
114 | 114 |
} |
115 | 115 |
|
116 |
-func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { |
|
116 |
+func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) { |
|
117 | 117 |
if preferLocal { |
118 | 118 |
dt, err := is.resolveLocal(ref) |
119 | 119 |
if err == nil { |
... | ... |
@@ -126,7 +126,7 @@ func (is *imageSource) ResolveImageConfig(ctx context.Context, ref string) (dige |
126 | 126 |
dt []byte |
127 | 127 |
} |
128 | 128 |
res, err := is.g.Do(ctx, ref, func(ctx context.Context) (interface{}, error) { |
129 |
- dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, "") |
|
129 |
+ dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx), is.ContentStore, platform) |
|
130 | 130 |
if err != nil { |
131 | 131 |
return nil, err |
132 | 132 |
} |
... | ... |
@@ -145,10 +145,16 @@ func (is *imageSource) Resolve(ctx context.Context, id source.Identifier) (sourc |
145 | 145 |
return nil, errors.Errorf("invalid image identifier %v", id) |
146 | 146 |
} |
147 | 147 |
|
148 |
+ platform := platforms.DefaultSpec() |
|
149 |
+ if imageIdentifier.Platform != nil { |
|
150 |
+ platform = *imageIdentifier.Platform |
|
151 |
+ } |
|
152 |
+ |
|
148 | 153 |
p := &puller{ |
149 | 154 |
src: imageIdentifier, |
150 | 155 |
is: is, |
151 | 156 |
resolver: is.getResolver(ctx), |
157 |
+ platform: platform, |
|
152 | 158 |
} |
153 | 159 |
return p, nil |
154 | 160 |
} |
... | ... |
@@ -163,17 +169,20 @@ type puller struct { |
163 | 163 |
resolveErr error |
164 | 164 |
resolver remotes.Resolver |
165 | 165 |
config []byte |
166 |
+ platform ocispec.Platform |
|
166 | 167 |
} |
167 | 168 |
|
168 |
-func (p *puller) mainManifestKey(dgst digest.Digest) (digest.Digest, error) { |
|
169 |
+func (p *puller) mainManifestKey(dgst digest.Digest, platform ocispec.Platform) (digest.Digest, error) { |
|
169 | 170 |
dt, err := json.Marshal(struct { |
170 |
- Digest digest.Digest |
|
171 |
- OS string |
|
172 |
- Arch string |
|
171 |
+ Digest digest.Digest |
|
172 |
+ OS string |
|
173 |
+ Arch string |
|
174 |
+ Variant string `json:",omitempty"` |
|
173 | 175 |
}{ |
174 |
- Digest: p.desc.Digest, |
|
175 |
- OS: runtime.GOOS, |
|
176 |
- Arch: runtime.GOARCH, |
|
176 |
+ Digest: p.desc.Digest, |
|
177 |
+ OS: platform.OS, |
|
178 |
+ Arch: platform.Architecture, |
|
179 |
+ Variant: platform.Variant, |
|
177 | 180 |
}) |
178 | 181 |
if err != nil { |
179 | 182 |
return "", err |
... | ... |
@@ -248,7 +257,7 @@ func (p *puller) resolve(ctx context.Context) error { |
248 | 248 |
return |
249 | 249 |
} |
250 | 250 |
|
251 |
- _, dt, err := p.is.ResolveImageConfig(ctx, ref.String()) |
|
251 |
+ _, dt, err := p.is.ResolveImageConfig(ctx, ref.String(), &p.platform) |
|
252 | 252 |
if err != nil { |
253 | 253 |
p.resolveErr = err |
254 | 254 |
resolveProgressDone(err) |
... | ... |
@@ -266,7 +275,7 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error) |
266 | 266 |
p.resolveLocal() |
267 | 267 |
|
268 | 268 |
if p.desc.Digest != "" && index == 0 { |
269 |
- dgst, err := p.mainManifestKey(p.desc.Digest) |
|
269 |
+ dgst, err := p.mainManifestKey(p.desc.Digest, p.platform) |
|
270 | 270 |
if err != nil { |
271 | 271 |
return "", false, err |
272 | 272 |
} |
... | ... |
@@ -282,7 +291,7 @@ func (p *puller) CacheKey(ctx context.Context, index int) (string, bool, error) |
282 | 282 |
} |
283 | 283 |
|
284 | 284 |
if p.desc.Digest != "" && index == 0 { |
285 |
- dgst, err := p.mainManifestKey(p.desc.Digest) |
|
285 |
+ dgst, err := p.mainManifestKey(p.desc.Digest, p.platform) |
|
286 | 286 |
if err != nil { |
287 | 287 |
return "", false, err |
288 | 288 |
} |
... | ... |
@@ -9,6 +9,7 @@ import ( |
9 | 9 |
"time" |
10 | 10 |
|
11 | 11 |
"github.com/containerd/containerd/content" |
12 |
+ "github.com/containerd/containerd/platforms" |
|
12 | 13 |
"github.com/docker/docker/api/types" |
13 | 14 |
"github.com/docker/docker/api/types/backend" |
14 | 15 |
"github.com/docker/docker/builder" |
... | ... |
@@ -208,6 +209,10 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder. |
208 | 208 |
frontendAttrs["no-cache"] = "" |
209 | 209 |
} |
210 | 210 |
|
211 |
+ if opt.Options.Platform != nil { |
|
212 |
+ frontendAttrs["platform"] = platforms.Format(*opt.Options.Platform) |
|
213 |
+ } |
|
214 |
+ |
|
211 | 215 |
exporterAttrs := map[string]string{} |
212 | 216 |
|
213 | 217 |
if len(opt.Options.Tags) > 0 { |
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
"time" |
11 | 11 |
|
12 | 12 |
"github.com/containerd/containerd/content" |
13 |
+ "github.com/containerd/containerd/platforms" |
|
13 | 14 |
"github.com/containerd/containerd/rootfs" |
14 | 15 |
"github.com/docker/docker/distribution" |
15 | 16 |
distmetadata "github.com/docker/docker/distribution/metadata" |
... | ... |
@@ -122,6 +123,12 @@ func (w *Worker) Labels() map[string]string { |
122 | 122 |
return w.Opt.Labels |
123 | 123 |
} |
124 | 124 |
|
125 |
+// Platforms returns one or more platforms supported by the image. |
|
126 |
+func (w *Worker) Platforms() []ocispec.Platform { |
|
127 |
+ // does not handle lcow |
|
128 |
+ return []ocispec.Platform{platforms.DefaultSpec()} |
|
129 |
+} |
|
130 |
+ |
|
125 | 131 |
// LoadRef loads a reference by ID |
126 | 132 |
func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) { |
127 | 133 |
return w.CacheManager.Get(context.TODO(), id) |
... | ... |
@@ -129,26 +136,27 @@ func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) { |
129 | 129 |
|
130 | 130 |
// ResolveOp converts a LLB vertex into a LLB operation |
131 | 131 |
func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) { |
132 |
- switch op := v.Sys().(type) { |
|
133 |
- case *pb.Op_Source: |
|
134 |
- return ops.NewSourceOp(v, op, w.SourceManager, w) |
|
135 |
- case *pb.Op_Exec: |
|
136 |
- return ops.NewExecOp(v, op, w.CacheManager, w.MetadataStore, w.Executor, w) |
|
137 |
- case *pb.Op_Build: |
|
138 |
- return ops.NewBuildOp(v, op, s, w) |
|
139 |
- default: |
|
140 |
- return nil, errors.Errorf("could not resolve %v", v) |
|
132 |
+ if baseOp, ok := v.Sys().(*pb.Op); ok { |
|
133 |
+ switch op := baseOp.Op.(type) { |
|
134 |
+ case *pb.Op_Source: |
|
135 |
+ return ops.NewSourceOp(v, op, baseOp.Platform, w.SourceManager, w) |
|
136 |
+ case *pb.Op_Exec: |
|
137 |
+ return ops.NewExecOp(v, op, w.CacheManager, w.MetadataStore, w.Executor, w) |
|
138 |
+ case *pb.Op_Build: |
|
139 |
+ return ops.NewBuildOp(v, op, s, w) |
|
140 |
+ } |
|
141 | 141 |
} |
142 |
+ return nil, errors.Errorf("could not resolve %v", v) |
|
142 | 143 |
} |
143 | 144 |
|
144 | 145 |
// ResolveImageConfig returns image config for an image |
145 |
-func (w *Worker) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { |
|
146 |
+func (w *Worker) ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) { |
|
146 | 147 |
// ImageSource is typically source/containerimage |
147 | 148 |
resolveImageConfig, ok := w.ImageSource.(resolveImageConfig) |
148 | 149 |
if !ok { |
149 | 150 |
return "", nil, errors.Errorf("worker %q does not implement ResolveImageConfig", w.ID()) |
150 | 151 |
} |
151 |
- return resolveImageConfig.ResolveImageConfig(ctx, ref) |
|
152 |
+ return resolveImageConfig.ResolveImageConfig(ctx, ref, platform) |
|
152 | 153 |
} |
153 | 154 |
|
154 | 155 |
// Exec executes a process directly on a worker |
... | ... |
@@ -319,5 +327,5 @@ func oneOffProgress(ctx context.Context, id string) func(err error) error { |
319 | 319 |
} |
320 | 320 |
|
321 | 321 |
type resolveImageConfig interface { |
322 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
322 |
+ ResolveImageConfig(ctx context.Context, ref string, platform *ocispec.Platform) (digest.Digest, []byte, error) |
|
323 | 323 |
} |
... | ... |
@@ -104,13 +104,6 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) ( |
104 | 104 |
source = src |
105 | 105 |
} |
106 | 106 |
|
107 |
- os := "" |
|
108 |
- apiPlatform := system.ParsePlatform(config.Options.Platform) |
|
109 |
- if apiPlatform.OS != "" { |
|
110 |
- os = apiPlatform.OS |
|
111 |
- } |
|
112 |
- config.Options.Platform = os |
|
113 |
- |
|
114 | 107 |
builderOptions := builderOptions{ |
115 | 108 |
Options: config.Options, |
116 | 109 |
ProgressWriter: config.ProgressWriter, |
... | ... |
@@ -24,6 +24,7 @@ import ( |
24 | 24 |
"github.com/docker/docker/pkg/streamformatter" |
25 | 25 |
"github.com/docker/docker/pkg/system" |
26 | 26 |
"github.com/docker/docker/pkg/urlutil" |
27 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
27 | 28 |
"github.com/pkg/errors" |
28 | 29 |
) |
29 | 30 |
|
... | ... |
@@ -72,7 +73,7 @@ type copier struct { |
72 | 72 |
source builder.Source |
73 | 73 |
pathCache pathCache |
74 | 74 |
download sourceDownloader |
75 |
- platform string |
|
75 |
+ platform *specs.Platform |
|
76 | 76 |
// for cleanup. TODO: having copier.cleanup() is error prone and hard to |
77 | 77 |
// follow. Code calling performCopy should manage the lifecycle of its params. |
78 | 78 |
// Copier should take override source as input, not imageMount. |
... | ... |
@@ -95,8 +96,14 @@ func (o *copier) createCopyInstruction(args []string, cmdName string) (copyInstr |
95 | 95 |
last := len(args) - 1 |
96 | 96 |
|
97 | 97 |
// Work in platform-specific filepath semantics |
98 |
- inst.dest = fromSlash(args[last], o.platform) |
|
99 |
- separator := string(separator(o.platform)) |
|
98 |
+ // TODO: This OS switch for paths is NOT correct and should not be supported. |
|
99 |
+ // Maintained for backwards compatibility |
|
100 |
+ pathOS := runtime.GOOS |
|
101 |
+ if o.platform != nil { |
|
102 |
+ pathOS = o.platform.OS |
|
103 |
+ } |
|
104 |
+ inst.dest = fromSlash(args[last], pathOS) |
|
105 |
+ separator := string(separator(pathOS)) |
|
100 | 106 |
infos, err := o.getCopyInfosForSourcePaths(args[0:last], inst.dest) |
101 | 107 |
if err != nil { |
102 | 108 |
return inst, errors.Wrapf(err, "%s failed", cmdName) |
... | ... |
@@ -14,6 +14,7 @@ import ( |
14 | 14 |
"sort" |
15 | 15 |
"strings" |
16 | 16 |
|
17 |
+ "github.com/containerd/containerd/platforms" |
|
17 | 18 |
"github.com/docker/docker/api" |
18 | 19 |
"github.com/docker/docker/api/types/container" |
19 | 20 |
"github.com/docker/docker/api/types/strslice" |
... | ... |
@@ -27,6 +28,7 @@ import ( |
27 | 27 |
"github.com/moby/buildkit/frontend/dockerfile/instructions" |
28 | 28 |
"github.com/moby/buildkit/frontend/dockerfile/parser" |
29 | 29 |
"github.com/moby/buildkit/frontend/dockerfile/shell" |
30 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
30 | 31 |
"github.com/pkg/errors" |
31 | 32 |
) |
32 | 33 |
|
... | ... |
@@ -102,7 +104,7 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error { |
102 | 102 |
copyInstruction.chownStr = c.Chown |
103 | 103 |
copyInstruction.allowLocalDecompression = true |
104 | 104 |
|
105 |
- return d.builder.performCopy(d.state, copyInstruction) |
|
105 |
+ return d.builder.performCopy(d, copyInstruction) |
|
106 | 106 |
} |
107 | 107 |
|
108 | 108 |
// COPY foo /path |
... | ... |
@@ -126,7 +128,7 @@ func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error { |
126 | 126 |
} |
127 | 127 |
copyInstruction.chownStr = c.Chown |
128 | 128 |
|
129 |
- return d.builder.performCopy(d.state, copyInstruction) |
|
129 |
+ return d.builder.performCopy(d, copyInstruction) |
|
130 | 130 |
} |
131 | 131 |
|
132 | 132 |
func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error) { |
... | ... |
@@ -144,17 +146,32 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error |
144 | 144 |
imageRefOrID = stage.Image |
145 | 145 |
localOnly = true |
146 | 146 |
} |
147 |
- return d.builder.imageSources.Get(imageRefOrID, localOnly, d.state.operatingSystem) |
|
147 |
+ return d.builder.imageSources.Get(imageRefOrID, localOnly, d.builder.options.Platform) |
|
148 | 148 |
} |
149 | 149 |
|
150 | 150 |
// FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name] |
151 | 151 |
// |
152 | 152 |
func initializeStage(d dispatchRequest, cmd *instructions.Stage) error { |
153 | 153 |
d.builder.imageProber.Reset() |
154 |
- if err := system.ValidatePlatform(&cmd.Platform); err != nil { |
|
155 |
- return err |
|
154 |
+ |
|
155 |
+ var platform *specs.Platform |
|
156 |
+ if v := cmd.Platform; v != "" { |
|
157 |
+ v, err := d.getExpandedString(d.shlex, v) |
|
158 |
+ if err != nil { |
|
159 |
+ return errors.Wrapf(err, "failed to process arguments for platform %s", v) |
|
160 |
+ } |
|
161 |
+ |
|
162 |
+ p, err := platforms.Parse(v) |
|
163 |
+ if err != nil { |
|
164 |
+ return errors.Wrapf(err, "failed to parse platform %s", v) |
|
165 |
+ } |
|
166 |
+ if err := system.ValidatePlatform(p); err != nil { |
|
167 |
+ return err |
|
168 |
+ } |
|
169 |
+ platform = &p |
|
156 | 170 |
} |
157 |
- image, err := d.getFromImage(d.shlex, cmd.BaseName, cmd.Platform.OS) |
|
171 |
+ |
|
172 |
+ image, err := d.getFromImage(d.shlex, cmd.BaseName, platform) |
|
158 | 173 |
if err != nil { |
159 | 174 |
return err |
160 | 175 |
} |
... | ... |
@@ -200,82 +217,72 @@ func dispatchTriggeredOnBuild(d dispatchRequest, triggers []string) error { |
200 | 200 |
return nil |
201 | 201 |
} |
202 | 202 |
|
203 |
-func (d *dispatchRequest) getExpandedImageName(shlex *shell.Lex, name string) (string, error) { |
|
203 |
+func (d *dispatchRequest) getExpandedString(shlex *shell.Lex, str string) (string, error) { |
|
204 | 204 |
substitutionArgs := []string{} |
205 | 205 |
for key, value := range d.state.buildArgs.GetAllMeta() { |
206 | 206 |
substitutionArgs = append(substitutionArgs, key+"="+value) |
207 | 207 |
} |
208 | 208 |
|
209 |
- name, err := shlex.ProcessWord(name, substitutionArgs) |
|
209 |
+ name, err := shlex.ProcessWord(str, substitutionArgs) |
|
210 | 210 |
if err != nil { |
211 | 211 |
return "", err |
212 | 212 |
} |
213 | 213 |
return name, nil |
214 | 214 |
} |
215 | 215 |
|
216 |
-// getOsFromFlagsAndStage calculates the operating system if we need to pull an image. |
|
217 |
-// stagePlatform contains the value supplied by optional `--platform=` on |
|
218 |
-// a current FROM statement. b.builder.options.Platform contains the operating |
|
219 |
-// system part of the optional flag passed in the API call (or CLI flag |
|
220 |
-// through `docker build --platform=...`). Precedence is for an explicit |
|
221 |
-// platform indication in the FROM statement. |
|
222 |
-func (d *dispatchRequest) getOsFromFlagsAndStage(stageOS string) string { |
|
223 |
- switch { |
|
224 |
- case stageOS != "": |
|
225 |
- return stageOS |
|
226 |
- case d.builder.options.Platform != "": |
|
227 |
- // Note this is API "platform", but by this point, as the daemon is not |
|
228 |
- // multi-arch aware yet, it is guaranteed to only hold the OS part here. |
|
229 |
- return d.builder.options.Platform |
|
230 |
- default: |
|
231 |
- return runtime.GOOS |
|
232 |
- } |
|
233 |
-} |
|
234 |
- |
|
235 |
-func (d *dispatchRequest) getImageOrStage(name string, stageOS string) (builder.Image, error) { |
|
216 |
+func (d *dispatchRequest) getImageOrStage(name string, platform *specs.Platform) (builder.Image, error) { |
|
236 | 217 |
var localOnly bool |
237 | 218 |
if im, ok := d.stages.getByName(name); ok { |
238 | 219 |
name = im.Image |
239 | 220 |
localOnly = true |
240 | 221 |
} |
241 | 222 |
|
242 |
- os := d.getOsFromFlagsAndStage(stageOS) |
|
223 |
+ if platform == nil { |
|
224 |
+ platform = d.builder.options.Platform |
|
225 |
+ } |
|
243 | 226 |
|
244 | 227 |
// Windows cannot support a container with no base image unless it is LCOW. |
245 | 228 |
if name == api.NoBaseImageSpecifier { |
229 |
+ p := platforms.DefaultSpec() |
|
230 |
+ if platform != nil { |
|
231 |
+ p = *platform |
|
232 |
+ } |
|
246 | 233 |
imageImage := &image.Image{} |
247 |
- imageImage.OS = runtime.GOOS |
|
234 |
+ imageImage.OS = p.OS |
|
235 |
+ |
|
236 |
+ // old windows scratch handling |
|
237 |
+ // TODO: scratch should not have an os. It should be nil image. |
|
238 |
+ // Windows supports scratch. What is not supported is running containers |
|
239 |
+ // from it. |
|
248 | 240 |
if runtime.GOOS == "windows" { |
249 |
- switch os { |
|
250 |
- case "windows", "": |
|
251 |
- return nil, errors.New("Windows does not support FROM scratch") |
|
252 |
- case "linux": |
|
241 |
+ if platform == nil || platform.OS == "linux" { |
|
253 | 242 |
if !system.LCOWSupported() { |
254 | 243 |
return nil, errors.New("Linux containers are not supported on this system") |
255 | 244 |
} |
256 | 245 |
imageImage.OS = "linux" |
257 |
- default: |
|
258 |
- return nil, errors.Errorf("operating system %q is not supported", os) |
|
246 |
+ } else if platform.OS == "windows" { |
|
247 |
+ return nil, errors.New("Windows does not support FROM scratch") |
|
248 |
+ } else { |
|
249 |
+ return nil, errors.Errorf("platform %s is not supported", platforms.Format(p)) |
|
259 | 250 |
} |
260 | 251 |
} |
261 | 252 |
return builder.Image(imageImage), nil |
262 | 253 |
} |
263 |
- imageMount, err := d.builder.imageSources.Get(name, localOnly, os) |
|
254 |
+ imageMount, err := d.builder.imageSources.Get(name, localOnly, platform) |
|
264 | 255 |
if err != nil { |
265 | 256 |
return nil, err |
266 | 257 |
} |
267 | 258 |
return imageMount.Image(), nil |
268 | 259 |
} |
269 |
-func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, stageOS string) (builder.Image, error) { |
|
270 |
- name, err := d.getExpandedImageName(shlex, name) |
|
260 |
+func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, platform *specs.Platform) (builder.Image, error) { |
|
261 |
+ name, err := d.getExpandedString(shlex, name) |
|
271 | 262 |
if err != nil { |
272 | 263 |
return nil, err |
273 | 264 |
} |
274 |
- return d.getImageOrStage(name, stageOS) |
|
265 |
+ return d.getImageOrStage(name, platform) |
|
275 | 266 |
} |
276 | 267 |
|
277 | 268 |
func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error { |
278 |
- |
|
279 | 269 |
d.state.runConfig.OnBuild = append(d.state.runConfig.OnBuild, c.Expression) |
280 | 270 |
return d.builder.commit(d.state, "ONBUILD "+c.Expression) |
281 | 271 |
} |
... | ... |
@@ -6,6 +6,7 @@ import ( |
6 | 6 |
"runtime" |
7 | 7 |
"testing" |
8 | 8 |
|
9 |
+ "github.com/containerd/containerd/platforms" |
|
9 | 10 |
"github.com/docker/docker/api/types" |
10 | 11 |
"github.com/docker/docker/api/types/backend" |
11 | 12 |
"github.com/docker/docker/api/types/container" |
... | ... |
@@ -22,15 +23,17 @@ import ( |
22 | 22 |
|
23 | 23 |
func newBuilderWithMockBackend() *Builder { |
24 | 24 |
mockBackend := &MockBackend{} |
25 |
+ defaultPlatform := platforms.DefaultSpec() |
|
26 |
+ opts := &types.ImageBuildOptions{Platform: &defaultPlatform} |
|
25 | 27 |
ctx := context.Background() |
26 | 28 |
b := &Builder{ |
27 |
- options: &types.ImageBuildOptions{Platform: runtime.GOOS}, |
|
29 |
+ options: opts, |
|
28 | 30 |
docker: mockBackend, |
29 | 31 |
Stdout: new(bytes.Buffer), |
30 | 32 |
clientCtx: ctx, |
31 | 33 |
disableCommit: true, |
32 | 34 |
imageSources: newImageSources(ctx, builderOptions{ |
33 |
- Options: &types.ImageBuildOptions{Platform: runtime.GOOS}, |
|
35 |
+ Options: opts, |
|
34 | 36 |
Backend: mockBackend, |
35 | 37 |
}), |
36 | 38 |
imageProber: newImageProber(mockBackend, nil, false), |
... | ... |
@@ -7,11 +7,12 @@ import ( |
7 | 7 |
"github.com/docker/docker/api/types/backend" |
8 | 8 |
"github.com/docker/docker/builder" |
9 | 9 |
dockerimage "github.com/docker/docker/image" |
10 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
10 | 11 |
"github.com/pkg/errors" |
11 | 12 |
"github.com/sirupsen/logrus" |
12 | 13 |
) |
13 | 14 |
|
14 |
-type getAndMountFunc func(string, bool, string) (builder.Image, builder.ROLayer, error) |
|
15 |
+type getAndMountFunc func(string, bool, *specs.Platform) (builder.Image, builder.ROLayer, error) |
|
15 | 16 |
|
16 | 17 |
// imageSources mounts images and provides a cache for mounted images. It tracks |
17 | 18 |
// all images so they can be unmounted at the end of the build. |
... | ... |
@@ -22,7 +23,7 @@ type imageSources struct { |
22 | 22 |
} |
23 | 23 |
|
24 | 24 |
func newImageSources(ctx context.Context, options builderOptions) *imageSources { |
25 |
- getAndMount := func(idOrRef string, localOnly bool, osForPull string) (builder.Image, builder.ROLayer, error) { |
|
25 |
+ getAndMount := func(idOrRef string, localOnly bool, platform *specs.Platform) (builder.Image, builder.ROLayer, error) { |
|
26 | 26 |
pullOption := backend.PullOptionNoPull |
27 | 27 |
if !localOnly { |
28 | 28 |
if options.Options.PullParent { |
... | ... |
@@ -35,7 +36,7 @@ func newImageSources(ctx context.Context, options builderOptions) *imageSources |
35 | 35 |
PullOption: pullOption, |
36 | 36 |
AuthConfig: options.Options.AuthConfigs, |
37 | 37 |
Output: options.ProgressWriter.Output, |
38 |
- OS: osForPull, |
|
38 |
+ Platform: platform, |
|
39 | 39 |
}) |
40 | 40 |
} |
41 | 41 |
|
... | ... |
@@ -45,12 +46,12 @@ func newImageSources(ctx context.Context, options builderOptions) *imageSources |
45 | 45 |
} |
46 | 46 |
} |
47 | 47 |
|
48 |
-func (m *imageSources) Get(idOrRef string, localOnly bool, osForPull string) (*imageMount, error) { |
|
48 |
+func (m *imageSources) Get(idOrRef string, localOnly bool, platform *specs.Platform) (*imageMount, error) { |
|
49 | 49 |
if im, ok := m.byImageID[idOrRef]; ok { |
50 | 50 |
return im, nil |
51 | 51 |
} |
52 | 52 |
|
53 |
- image, layer, err := m.getImage(idOrRef, localOnly, osForPull) |
|
53 |
+ image, layer, err := m.getImage(idOrRef, localOnly, platform) |
|
54 | 54 |
if err != nil { |
55 | 55 |
return nil, err |
56 | 56 |
} |
... | ... |
@@ -150,7 +150,8 @@ func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, paren |
150 | 150 |
return nil |
151 | 151 |
} |
152 | 152 |
|
153 |
-func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error { |
|
153 |
+func (b *Builder) performCopy(req dispatchRequest, inst copyInstruction) error { |
|
154 |
+ state := req.state |
|
154 | 155 |
srcHash := getSourceHashFromInfos(inst.infos) |
155 | 156 |
|
156 | 157 |
var chownComment string |
... | ... |
@@ -168,7 +169,7 @@ func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error |
168 | 168 |
return err |
169 | 169 |
} |
170 | 170 |
|
171 |
- imageMount, err := b.imageSources.Get(state.imageID, true, state.operatingSystem) |
|
171 |
+ imageMount, err := b.imageSources.Get(state.imageID, true, req.builder.options.Platform) |
|
172 | 172 |
if err != nil { |
173 | 173 |
return errors.Wrapf(err, "failed to get destination image %q", state.imageID) |
174 | 174 |
} |
... | ... |
@@ -456,7 +457,7 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf |
456 | 456 |
// is too small for builder scenarios where many users are |
457 | 457 |
// using RUN statements to install large amounts of data. |
458 | 458 |
// Use 127GB as that's the default size of a VHD in Hyper-V. |
459 |
- if runtime.GOOS == "windows" && options.Platform == "windows" { |
|
459 |
+ if runtime.GOOS == "windows" && options.Platform != nil && options.Platform.OS == "windows" { |
|
460 | 460 |
hc.StorageOpt = make(map[string]string) |
461 | 461 |
hc.StorageOpt["size"] = "127GB" |
462 | 462 |
} |
... | ... |
@@ -8,8 +8,8 @@ import ( |
8 | 8 |
"net/http" |
9 | 9 |
"net/url" |
10 | 10 |
"strconv" |
11 |
- "strings" |
|
12 | 11 |
|
12 |
+ "github.com/containerd/containerd/platforms" |
|
13 | 13 |
"github.com/docker/docker/api/types" |
14 | 14 |
"github.com/docker/docker/api/types/container" |
15 | 15 |
) |
... | ... |
@@ -30,11 +30,11 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio |
30 | 30 |
} |
31 | 31 |
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) |
32 | 32 |
|
33 |
- if options.Platform != "" { |
|
33 |
+ if options.Platform != nil { |
|
34 | 34 |
if err := cli.NewVersionError("1.32", "platform"); err != nil { |
35 | 35 |
return types.ImageBuildResponse{}, err |
36 | 36 |
} |
37 |
- query.Set("platform", options.Platform) |
|
37 |
+ query.Set("platform", platforms.Format(*options.Platform)) |
|
38 | 38 |
} |
39 | 39 |
headers.Set("Content-Type", "application/x-tar") |
40 | 40 |
|
... | ... |
@@ -130,8 +130,8 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur |
130 | 130 |
if options.SessionID != "" { |
131 | 131 |
query.Set("session", options.SessionID) |
132 | 132 |
} |
133 |
- if options.Platform != "" { |
|
134 |
- query.Set("platform", strings.ToLower(options.Platform)) |
|
133 |
+ if options.Platform != nil { |
|
134 |
+ query.Set("platform", platforms.Format(*options.Platform)) |
|
135 | 135 |
} |
136 | 136 |
if options.BuildID != "" { |
137 | 137 |
query.Set("buildid", options.BuildID) |
... | ... |
@@ -23,6 +23,7 @@ import ( |
23 | 23 |
"github.com/docker/libnetwork/cluster" |
24 | 24 |
networktypes "github.com/docker/libnetwork/types" |
25 | 25 |
"github.com/docker/swarmkit/agent/exec" |
26 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
26 | 27 |
) |
27 | 28 |
|
28 | 29 |
// Backend defines the executor component for a swarm agent. |
... | ... |
@@ -69,7 +70,7 @@ type VolumeBackend interface { |
69 | 69 |
|
70 | 70 |
// ImageBackend is used by an executor to perform image operations |
71 | 71 |
type ImageBackend interface { |
72 |
- PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error |
|
72 |
+ PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error |
|
73 | 73 |
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, bool, error) |
74 | 74 |
LookupImage(name string) (*types.ImageInspect, error) |
75 | 75 |
} |
... | ... |
@@ -8,7 +8,6 @@ import ( |
8 | 8 |
"fmt" |
9 | 9 |
"io" |
10 | 10 |
"os" |
11 |
- "runtime" |
|
12 | 11 |
"strings" |
13 | 12 |
"syscall" |
14 | 13 |
"time" |
... | ... |
@@ -97,8 +96,7 @@ func (c *containerAdapter) pullImage(ctx context.Context) error { |
97 | 97 |
go func() { |
98 | 98 |
// TODO @jhowardmsft LCOW Support: This will need revisiting as |
99 | 99 |
// the stack is built up to include LCOW support for swarm. |
100 |
- platform := runtime.GOOS |
|
101 |
- err := c.imageBackend.PullImage(ctx, c.container.image(), "", platform, metaHeaders, authConfig, pw) |
|
100 |
+ err := c.imageBackend.PullImage(ctx, c.container.image(), "", nil, metaHeaders, authConfig, pw) |
|
102 | 101 |
pw.CloseWithError(err) |
103 | 102 |
}() |
104 | 103 |
|
... | ... |
@@ -3,6 +3,7 @@ package images // import "github.com/docker/docker/daemon/images" |
3 | 3 |
import ( |
4 | 4 |
"context" |
5 | 5 |
"io" |
6 |
+ "runtime" |
|
6 | 7 |
|
7 | 8 |
"github.com/docker/distribution/reference" |
8 | 9 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -14,6 +15,7 @@ import ( |
14 | 14 |
"github.com/docker/docker/pkg/stringid" |
15 | 15 |
"github.com/docker/docker/pkg/system" |
16 | 16 |
"github.com/docker/docker/registry" |
17 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
17 | 18 |
"github.com/pkg/errors" |
18 | 19 |
) |
19 | 20 |
|
... | ... |
@@ -137,7 +139,7 @@ func newROLayerForImage(img *image.Image, layerStore layer.Store) (builder.ROLay |
137 | 137 |
} |
138 | 138 |
|
139 | 139 |
// TODO: could this use the regular daemon PullImage ? |
140 |
-func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer, os string) (*image.Image, error) { |
|
140 |
+func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer, platform *specs.Platform) (*image.Image, error) { |
|
141 | 141 |
ref, err := reference.ParseNormalizedNamed(name) |
142 | 142 |
if err != nil { |
143 | 143 |
return nil, err |
... | ... |
@@ -156,7 +158,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf |
156 | 156 |
pullRegistryAuth = &resolvedConfig |
157 | 157 |
} |
158 | 158 |
|
159 |
- if err := i.pullImageWithReference(ctx, ref, os, nil, pullRegistryAuth, output); err != nil { |
|
159 |
+ if err := i.pullImageWithReference(ctx, ref, platform, nil, pullRegistryAuth, output); err != nil { |
|
160 | 160 |
return nil, err |
161 | 161 |
} |
162 | 162 |
return i.GetImage(name) |
... | ... |
@@ -166,11 +168,15 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf |
166 | 166 |
// Every call to GetImageAndReleasableLayer MUST call releasableLayer.Release() to prevent |
167 | 167 |
// leaking of layers. |
168 | 168 |
func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { |
169 |
- if refOrID == "" { |
|
170 |
- if !system.IsOSSupported(opts.OS) { |
|
169 |
+ if refOrID == "" { // ie FROM scratch |
|
170 |
+ os := runtime.GOOS |
|
171 |
+ if opts.Platform != nil { |
|
172 |
+ os = opts.Platform.OS |
|
173 |
+ } |
|
174 |
+ if !system.IsOSSupported(os) { |
|
171 | 175 |
return nil, nil, system.ErrNotSupportedOperatingSystem |
172 | 176 |
} |
173 |
- layer, err := newROLayerForImage(nil, i.layerStores[opts.OS]) |
|
177 |
+ layer, err := newROLayerForImage(nil, i.layerStores[os]) |
|
174 | 178 |
return nil, layer, err |
175 | 179 |
} |
176 | 180 |
|
... | ... |
@@ -189,7 +195,7 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s |
189 | 189 |
} |
190 | 190 |
} |
191 | 191 |
|
192 |
- image, err := i.pullForBuilder(ctx, refOrID, opts.AuthConfig, opts.Output, opts.OS) |
|
192 |
+ image, err := i.pullForBuilder(ctx, refOrID, opts.AuthConfig, opts.Output, opts.Platform) |
|
193 | 193 |
if err != nil { |
194 | 194 |
return nil, nil, err |
195 | 195 |
} |
... | ... |
@@ -3,7 +3,6 @@ package images // import "github.com/docker/docker/daemon/images" |
3 | 3 |
import ( |
4 | 4 |
"context" |
5 | 5 |
"io" |
6 |
- "runtime" |
|
7 | 6 |
"strings" |
8 | 7 |
"time" |
9 | 8 |
|
... | ... |
@@ -16,11 +15,12 @@ import ( |
16 | 16 |
"github.com/docker/docker/pkg/progress" |
17 | 17 |
"github.com/docker/docker/registry" |
18 | 18 |
"github.com/opencontainers/go-digest" |
19 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
19 | 20 |
) |
20 | 21 |
|
21 | 22 |
// PullImage initiates a pull operation. image is the repository name to pull, and |
22 | 23 |
// tag may be either empty, or indicate a specific tag to pull. |
23 |
-func (i *ImageService) PullImage(ctx context.Context, image, tag, os string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { |
|
24 |
+func (i *ImageService) PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { |
|
24 | 25 |
start := time.Now() |
25 | 26 |
// Special case: "pull -a" may send an image name with a |
26 | 27 |
// trailing :. This is ugly, but let's not break API |
... | ... |
@@ -46,12 +46,12 @@ func (i *ImageService) PullImage(ctx context.Context, image, tag, os string, met |
46 | 46 |
} |
47 | 47 |
} |
48 | 48 |
|
49 |
- err = i.pullImageWithReference(ctx, ref, os, metaHeaders, authConfig, outStream) |
|
49 |
+ err = i.pullImageWithReference(ctx, ref, platform, metaHeaders, authConfig, outStream) |
|
50 | 50 |
imageActions.WithValues("pull").UpdateSince(start) |
51 | 51 |
return err |
52 | 52 |
} |
53 | 53 |
|
54 |
-func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, os string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { |
|
54 |
+func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference.Named, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { |
|
55 | 55 |
// Include a buffer so that slow client connections don't affect |
56 | 56 |
// transfer performance. |
57 | 57 |
progressChan := make(chan progress.Progress, 100) |
... | ... |
@@ -65,11 +65,6 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference |
65 | 65 |
close(writesDone) |
66 | 66 |
}() |
67 | 67 |
|
68 |
- // Default to the host OS platform in case it hasn't been populated with an explicit value. |
|
69 |
- if os == "" { |
|
70 |
- os = runtime.GOOS |
|
71 |
- } |
|
72 |
- |
|
73 | 68 |
imagePullConfig := &distribution.ImagePullConfig{ |
74 | 69 |
Config: distribution.Config{ |
75 | 70 |
MetaHeaders: metaHeaders, |
... | ... |
@@ -83,7 +78,7 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference |
83 | 83 |
}, |
84 | 84 |
DownloadManager: i.downloadManager, |
85 | 85 |
Schema2Types: distribution.ImageTypes, |
86 |
- OS: os, |
|
86 |
+ Platform: platform, |
|
87 | 87 |
} |
88 | 88 |
|
89 | 89 |
err := distribution.Pull(ctx, ref, imagePullConfig) |
... | ... |
@@ -60,9 +60,8 @@ type ImagePullConfig struct { |
60 | 60 |
// Schema2Types is the valid schema2 configuration types allowed |
61 | 61 |
// by the pull operation. |
62 | 62 |
Schema2Types []string |
63 |
- // OS is the requested operating system of the image being pulled to ensure it can be validated |
|
64 |
- // when the host OS supports multiple image operating systems. |
|
65 |
- OS string |
|
63 |
+ // Platform is the requested platform of the image being pulled |
|
64 |
+ Platform *specs.Platform |
|
66 | 65 |
} |
67 | 66 |
|
68 | 67 |
// ImagePushConfig stores push configuration. |
... | ... |
@@ -171,7 +170,7 @@ func (s *imageConfigStore) PlatformFromConfig(c []byte) (*specs.Platform, error) |
171 | 171 |
if !system.IsOSSupported(os) { |
172 | 172 |
return nil, system.ErrNotSupportedOperatingSystem |
173 | 173 |
} |
174 |
- return &specs.Platform{OS: os, OSVersion: unmarshalledConfig.OSVersion}, nil |
|
174 |
+ return &specs.Platform{OS: os, Architecture: unmarshalledConfig.Architecture, OSVersion: unmarshalledConfig.OSVersion}, nil |
|
175 | 175 |
} |
176 | 176 |
|
177 | 177 |
type storeLayerProvider struct { |
... | ... |
@@ -3,7 +3,6 @@ package distribution // import "github.com/docker/docker/distribution" |
3 | 3 |
import ( |
4 | 4 |
"context" |
5 | 5 |
"fmt" |
6 |
- "runtime" |
|
7 | 6 |
|
8 | 7 |
"github.com/docker/distribution/reference" |
9 | 8 |
"github.com/docker/docker/api" |
... | ... |
@@ -12,6 +11,7 @@ import ( |
12 | 12 |
refstore "github.com/docker/docker/reference" |
13 | 13 |
"github.com/docker/docker/registry" |
14 | 14 |
"github.com/opencontainers/go-digest" |
15 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
15 | 16 |
"github.com/pkg/errors" |
16 | 17 |
"github.com/sirupsen/logrus" |
17 | 18 |
) |
... | ... |
@@ -21,7 +21,7 @@ type Puller interface { |
21 | 21 |
// Pull tries to pull the image referenced by `tag` |
22 | 22 |
// Pull returns an error if any, as well as a boolean that determines whether to retry Pull on the next configured endpoint. |
23 | 23 |
// |
24 |
- Pull(ctx context.Context, ref reference.Named, os string) error |
|
24 |
+ Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) error |
|
25 | 25 |
} |
26 | 26 |
|
27 | 27 |
// newPuller returns a Puller interface that will pull from either a v1 or v2 |
... | ... |
@@ -115,12 +115,7 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo |
115 | 115 |
continue |
116 | 116 |
} |
117 | 117 |
|
118 |
- // Make sure we default the OS if it hasn't been supplied |
|
119 |
- if imagePullConfig.OS == "" { |
|
120 |
- imagePullConfig.OS = runtime.GOOS |
|
121 |
- } |
|
122 |
- |
|
123 |
- if err := puller.Pull(ctx, ref, imagePullConfig.OS); err != nil { |
|
118 |
+ if err := puller.Pull(ctx, ref, imagePullConfig.Platform); err != nil { |
|
124 | 119 |
// Was this pull cancelled? If so, don't try to fall |
125 | 120 |
// back. |
126 | 121 |
fallback := false |
... | ... |
@@ -25,6 +25,7 @@ import ( |
25 | 25 |
"github.com/docker/docker/pkg/progress" |
26 | 26 |
"github.com/docker/docker/pkg/stringid" |
27 | 27 |
"github.com/docker/docker/registry" |
28 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
28 | 29 |
"github.com/sirupsen/logrus" |
29 | 30 |
) |
30 | 31 |
|
... | ... |
@@ -36,7 +37,7 @@ type v1Puller struct { |
36 | 36 |
session *registry.Session |
37 | 37 |
} |
38 | 38 |
|
39 |
-func (p *v1Puller) Pull(ctx context.Context, ref reference.Named, os string) error { |
|
39 |
+func (p *v1Puller) Pull(ctx context.Context, ref reference.Named, _ *specs.Platform) error { |
|
40 | 40 |
if _, isCanonical := ref.(reference.Canonical); isCanonical { |
41 | 41 |
// Allowing fallback, because HTTPS v1 is before HTTP v2 |
42 | 42 |
return fallbackError{err: ErrNoSupport{Err: errors.New("Cannot pull by digest with v1 registry")}} |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
"runtime" |
12 | 12 |
"strings" |
13 | 13 |
|
14 |
+ "github.com/containerd/containerd/platforms" |
|
14 | 15 |
"github.com/docker/distribution" |
15 | 16 |
"github.com/docker/distribution/manifest/manifestlist" |
16 | 17 |
"github.com/docker/distribution/manifest/schema1" |
... | ... |
@@ -63,7 +64,7 @@ type v2Puller struct { |
63 | 63 |
confirmedV2 bool |
64 | 64 |
} |
65 | 65 |
|
66 |
-func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (err error) { |
|
66 |
+func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) { |
|
67 | 67 |
// TODO(tiborvass): was ReceiveTimeout |
68 | 68 |
p.repo, p.confirmedV2, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull") |
69 | 69 |
if err != nil { |
... | ... |
@@ -71,7 +72,7 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (er |
71 | 71 |
return err |
72 | 72 |
} |
73 | 73 |
|
74 |
- if err = p.pullV2Repository(ctx, ref, os); err != nil { |
|
74 |
+ if err = p.pullV2Repository(ctx, ref, platform); err != nil { |
|
75 | 75 |
if _, ok := err.(fallbackError); ok { |
76 | 76 |
return err |
77 | 77 |
} |
... | ... |
@@ -86,10 +87,10 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, os string) (er |
86 | 86 |
return err |
87 | 87 |
} |
88 | 88 |
|
89 |
-func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, os string) (err error) { |
|
89 |
+func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) { |
|
90 | 90 |
var layersDownloaded bool |
91 | 91 |
if !reference.IsNameOnly(ref) { |
92 |
- layersDownloaded, err = p.pullV2Tag(ctx, ref, os) |
|
92 |
+ layersDownloaded, err = p.pullV2Tag(ctx, ref, platform) |
|
93 | 93 |
if err != nil { |
94 | 94 |
return err |
95 | 95 |
} |
... | ... |
@@ -111,7 +112,7 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, os |
111 | 111 |
if err != nil { |
112 | 112 |
return err |
113 | 113 |
} |
114 |
- pulledNew, err := p.pullV2Tag(ctx, tagRef, os) |
|
114 |
+ pulledNew, err := p.pullV2Tag(ctx, tagRef, platform) |
|
115 | 115 |
if err != nil { |
116 | 116 |
// Since this is the pull-all-tags case, don't |
117 | 117 |
// allow an error pulling a particular tag to |
... | ... |
@@ -327,7 +328,7 @@ func (ld *v2LayerDescriptor) Registered(diffID layer.DiffID) { |
327 | 327 |
ld.V2MetadataService.Add(diffID, metadata.V2Metadata{Digest: ld.digest, SourceRepository: ld.repoInfo.Name.Name()}) |
328 | 328 |
} |
329 | 329 |
|
330 |
-func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string) (tagUpdated bool, err error) { |
|
330 |
+func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform *specs.Platform) (tagUpdated bool, err error) { |
|
331 | 331 |
manSvc, err := p.repo.Manifests(ctx) |
332 | 332 |
if err != nil { |
333 | 333 |
return false, err |
... | ... |
@@ -391,17 +392,17 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string |
391 | 391 |
if p.config.RequireSchema2 { |
392 | 392 |
return false, fmt.Errorf("invalid manifest: not schema2") |
393 | 393 |
} |
394 |
- id, manifestDigest, err = p.pullSchema1(ctx, ref, v, os) |
|
394 |
+ id, manifestDigest, err = p.pullSchema1(ctx, ref, v, platform) |
|
395 | 395 |
if err != nil { |
396 | 396 |
return false, err |
397 | 397 |
} |
398 | 398 |
case *schema2.DeserializedManifest: |
399 |
- id, manifestDigest, err = p.pullSchema2(ctx, ref, v, os) |
|
399 |
+ id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform) |
|
400 | 400 |
if err != nil { |
401 | 401 |
return false, err |
402 | 402 |
} |
403 | 403 |
case *manifestlist.DeserializedManifestList: |
404 |
- id, manifestDigest, err = p.pullManifestList(ctx, ref, v, os) |
|
404 |
+ id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform) |
|
405 | 405 |
if err != nil { |
406 | 406 |
return false, err |
407 | 407 |
} |
... | ... |
@@ -437,7 +438,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, os string |
437 | 437 |
return true, nil |
438 | 438 |
} |
439 | 439 |
|
440 |
-func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest, requestedOS string) (id digest.Digest, manifestDigest digest.Digest, err error) { |
|
440 |
+func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest, platform *specs.Platform) (id digest.Digest, manifestDigest digest.Digest, err error) { |
|
441 | 441 |
var verifiedManifest *schema1.Manifest |
442 | 442 |
verifiedManifest, err = verifySchema1Manifest(unverifiedManifest, ref) |
443 | 443 |
if err != nil { |
... | ... |
@@ -509,6 +510,17 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv |
509 | 509 |
} |
510 | 510 |
} |
511 | 511 |
|
512 |
+ // In the situation that the API call didn't specify an OS explicitly, but |
|
513 |
+ // we support the operating system, switch to that operating system. |
|
514 |
+ // eg FROM supertest2014/nyan with no platform specifier, and docker build |
|
515 |
+ // with no --platform= flag under LCOW. |
|
516 |
+ requestedOS := "" |
|
517 |
+ if platform != nil { |
|
518 |
+ requestedOS = platform.OS |
|
519 |
+ } else if system.IsOSSupported(configOS) { |
|
520 |
+ requestedOS = configOS |
|
521 |
+ } |
|
522 |
+ |
|
512 | 523 |
// Early bath if the requested OS doesn't match that of the configuration. |
513 | 524 |
// This avoids doing the download, only to potentially fail later. |
514 | 525 |
if !strings.EqualFold(configOS, requestedOS) { |
... | ... |
@@ -536,7 +548,7 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv |
536 | 536 |
return imageID, manifestDigest, nil |
537 | 537 |
} |
538 | 538 |
|
539 |
-func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest, requestedOS string) (id digest.Digest, manifestDigest digest.Digest, err error) { |
|
539 |
+func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *schema2.DeserializedManifest, platform *specs.Platform) (id digest.Digest, manifestDigest digest.Digest, err error) { |
|
540 | 540 |
manifestDigest, err = schema2ManifestDigest(ref, mfst) |
541 | 541 |
if err != nil { |
542 | 542 |
return "", "", err |
... | ... |
@@ -592,6 +604,11 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s |
592 | 592 |
configPlatform *specs.Platform // for LCOW when registering downloaded layers |
593 | 593 |
) |
594 | 594 |
|
595 |
+ layerStoreOS := runtime.GOOS |
|
596 |
+ if platform != nil { |
|
597 |
+ layerStoreOS = platform.OS |
|
598 |
+ } |
|
599 |
+ |
|
595 | 600 |
// https://github.com/docker/docker/issues/24766 - Err on the side of caution, |
596 | 601 |
// explicitly blocking images intended for linux from the Windows daemon. On |
597 | 602 |
// Windows, we do this before the attempt to download, effectively serialising |
... | ... |
@@ -615,11 +632,13 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s |
615 | 615 |
if len(descriptors) != len(configRootFS.DiffIDs) { |
616 | 616 |
return "", "", errRootFSMismatch |
617 | 617 |
} |
618 |
- |
|
619 |
- // Early bath if the requested OS doesn't match that of the configuration. |
|
620 |
- // This avoids doing the download, only to potentially fail later. |
|
621 |
- if !strings.EqualFold(configPlatform.OS, requestedOS) { |
|
622 |
- return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, requestedOS) |
|
618 |
+ if platform == nil { |
|
619 |
+ // Early bath if the requested OS doesn't match that of the configuration. |
|
620 |
+ // This avoids doing the download, only to potentially fail later. |
|
621 |
+ if !system.IsOSSupported(configPlatform.OS) { |
|
622 |
+ return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, layerStoreOS) |
|
623 |
+ } |
|
624 |
+ layerStoreOS = configPlatform.OS |
|
623 | 625 |
} |
624 | 626 |
|
625 | 627 |
// Populate diff ids in descriptors to avoid downloading foreign layers |
... | ... |
@@ -636,7 +655,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s |
636 | 636 |
rootFS image.RootFS |
637 | 637 |
) |
638 | 638 |
downloadRootFS := *image.NewRootFS() |
639 |
- rootFS, release, err = p.config.DownloadManager.Download(ctx, downloadRootFS, requestedOS, descriptors, p.config.ProgressOutput) |
|
639 |
+ rootFS, release, err = p.config.DownloadManager.Download(ctx, downloadRootFS, layerStoreOS, descriptors, p.config.ProgressOutput) |
|
640 | 640 |
if err != nil { |
641 | 641 |
// Intentionally do not cancel the config download here |
642 | 642 |
// as the error from config download (if there is one) |
... | ... |
@@ -722,18 +741,22 @@ func receiveConfig(s ImageConfigStore, configChan <-chan []byte, errChan <-chan |
722 | 722 |
|
723 | 723 |
// pullManifestList handles "manifest lists" which point to various |
724 | 724 |
// platform-specific manifests. |
725 |
-func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, os string) (id digest.Digest, manifestListDigest digest.Digest, err error) { |
|
725 |
+func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mfstList *manifestlist.DeserializedManifestList, pp *specs.Platform) (id digest.Digest, manifestListDigest digest.Digest, err error) { |
|
726 | 726 |
manifestListDigest, err = schema2ManifestDigest(ref, mfstList) |
727 | 727 |
if err != nil { |
728 | 728 |
return "", "", err |
729 | 729 |
} |
730 | 730 |
|
731 |
- logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a %s/%s match", ref, len(mfstList.Manifests), os, runtime.GOARCH) |
|
731 |
+ var platform specs.Platform |
|
732 |
+ if pp != nil { |
|
733 |
+ platform = *pp |
|
734 |
+ } |
|
735 |
+ 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) |
|
732 | 736 |
|
733 |
- manifestMatches := filterManifests(mfstList.Manifests, os) |
|
737 |
+ manifestMatches := filterManifests(mfstList.Manifests, platform) |
|
734 | 738 |
|
735 | 739 |
if len(manifestMatches) == 0 { |
736 |
- errMsg := fmt.Sprintf("no matching manifest for %s/%s in the manifest list entries", os, runtime.GOARCH) |
|
740 |
+ errMsg := fmt.Sprintf("no matching manifest for %s in the manifest list entries", platforms.Format(platform)) |
|
737 | 741 |
logrus.Debugf(errMsg) |
738 | 742 |
return "", "", errors.New(errMsg) |
739 | 743 |
} |
... | ... |
@@ -764,12 +787,14 @@ func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mf |
764 | 764 |
|
765 | 765 |
switch v := manifest.(type) { |
766 | 766 |
case *schema1.SignedManifest: |
767 |
- id, _, err = p.pullSchema1(ctx, manifestRef, v, os) |
|
767 |
+ platform := toOCIPlatform(manifestMatches[0].Platform) |
|
768 |
+ id, _, err = p.pullSchema1(ctx, manifestRef, v, &platform) |
|
768 | 769 |
if err != nil { |
769 | 770 |
return "", "", err |
770 | 771 |
} |
771 | 772 |
case *schema2.DeserializedManifest: |
772 |
- id, _, err = p.pullSchema2(ctx, manifestRef, v, os) |
|
773 |
+ platform := toOCIPlatform(manifestMatches[0].Platform) |
|
774 |
+ id, _, err = p.pullSchema2(ctx, manifestRef, v, &platform) |
|
773 | 775 |
if err != nil { |
774 | 776 |
return "", "", err |
775 | 777 |
} |
... | ... |
@@ -939,3 +964,13 @@ func fixManifestLayers(m *schema1.Manifest) error { |
939 | 939 |
func createDownloadFile() (*os.File, error) { |
940 | 940 |
return ioutil.TempFile("", "GetImageBlob") |
941 | 941 |
} |
942 |
+ |
|
943 |
+func toOCIPlatform(p manifestlist.PlatformSpec) specs.Platform { |
|
944 |
+ return specs.Platform{ |
|
945 |
+ OS: p.OS, |
|
946 |
+ Architecture: p.Architecture, |
|
947 |
+ Variant: p.Variant, |
|
948 |
+ OSFeatures: p.OSFeatures, |
|
949 |
+ OSVersion: p.OSVersion, |
|
950 |
+ } |
|
951 |
+} |
... | ... |
@@ -4,10 +4,11 @@ package distribution // import "github.com/docker/docker/distribution" |
4 | 4 |
|
5 | 5 |
import ( |
6 | 6 |
"context" |
7 |
- "runtime" |
|
8 | 7 |
|
8 |
+ "github.com/containerd/containerd/platforms" |
|
9 | 9 |
"github.com/docker/distribution" |
10 | 10 |
"github.com/docker/distribution/manifest/manifestlist" |
11 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
11 | 12 |
"github.com/sirupsen/logrus" |
12 | 13 |
) |
13 | 14 |
|
... | ... |
@@ -16,15 +17,28 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo |
16 | 16 |
return blobs.Open(ctx, ld.digest) |
17 | 17 |
} |
18 | 18 |
|
19 |
-func filterManifests(manifests []manifestlist.ManifestDescriptor, os string) []manifestlist.ManifestDescriptor { |
|
19 |
+func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platform) []manifestlist.ManifestDescriptor { |
|
20 |
+ p = platforms.Normalize(withDefault(p)) |
|
21 |
+ m := platforms.NewMatcher(p) |
|
20 | 22 |
var matches []manifestlist.ManifestDescriptor |
21 |
- for _, manifestDescriptor := range manifests { |
|
22 |
- if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == os { |
|
23 |
- matches = append(matches, manifestDescriptor) |
|
23 |
+ for _, desc := range manifests { |
|
24 |
+ if m.Match(toOCIPlatform(desc.Platform)) { |
|
25 |
+ matches = append(matches, desc) |
|
26 |
+ logrus.Debugf("found match for %s with media type %s, digest %s", platforms.Format(p), desc.MediaType, desc.Digest.String()) |
|
27 |
+ } |
|
28 |
+ } |
|
24 | 29 |
|
25 |
- logrus.Debugf("found match for %s/%s with media type %s, digest %s", os, runtime.GOARCH, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) |
|
30 |
+ // deprecated: backwards compatibility with older versions that didn't compare variant |
|
31 |
+ if len(matches) == 0 && p.Architecture == "arm" { |
|
32 |
+ p = platforms.Normalize(p) |
|
33 |
+ for _, desc := range manifests { |
|
34 |
+ if desc.Platform.OS == p.OS && desc.Platform.Architecture == p.Architecture { |
|
35 |
+ matches = append(matches, desc) |
|
36 |
+ logrus.Debugf("found deprecated partial match for %s with media type %s, digest %s", platforms.Format(p), desc.MediaType, desc.Digest.String()) |
|
37 |
+ } |
|
26 | 38 |
} |
27 | 39 |
} |
40 |
+ |
|
28 | 41 |
return matches |
29 | 42 |
} |
30 | 43 |
|
... | ... |
@@ -32,3 +46,15 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, os string) []m |
32 | 32 |
func checkImageCompatibility(imageOS, imageOSVersion string) error { |
33 | 33 |
return nil |
34 | 34 |
} |
35 |
+ |
|
36 |
+func withDefault(p specs.Platform) specs.Platform { |
|
37 |
+ def := platforms.DefaultSpec() |
|
38 |
+ if p.OS == "" { |
|
39 |
+ p.OS = def.OS |
|
40 |
+ } |
|
41 |
+ if p.Architecture == "" { |
|
42 |
+ p.Architecture = def.Architecture |
|
43 |
+ p.Variant = def.Variant |
|
44 |
+ } |
|
45 |
+ return p |
|
46 |
+} |
... | ... |
@@ -16,6 +16,7 @@ import ( |
16 | 16 |
"github.com/docker/distribution/manifest/schema2" |
17 | 17 |
"github.com/docker/distribution/registry/client/transport" |
18 | 18 |
"github.com/docker/docker/pkg/system" |
19 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
19 | 20 |
"github.com/sirupsen/logrus" |
20 | 21 |
) |
21 | 22 |
|
... | ... |
@@ -62,24 +63,27 @@ func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekClo |
62 | 62 |
return rsc, err |
63 | 63 |
} |
64 | 64 |
|
65 |
-func filterManifests(manifests []manifestlist.ManifestDescriptor, os string) []manifestlist.ManifestDescriptor { |
|
66 |
- osVersion := "" |
|
67 |
- if os == "windows" { |
|
68 |
- version := system.GetOSVersion() |
|
69 |
- osVersion = fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build) |
|
70 |
- logrus.Debugf("will prefer entries with version %s", osVersion) |
|
71 |
- } |
|
65 |
+func filterManifests(manifests []manifestlist.ManifestDescriptor, p specs.Platform) []manifestlist.ManifestDescriptor { |
|
66 |
+ version := system.GetOSVersion() |
|
67 |
+ osVersion := fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build) |
|
68 |
+ logrus.Debugf("will prefer Windows entries with version %s", osVersion) |
|
72 | 69 |
|
73 | 70 |
var matches []manifestlist.ManifestDescriptor |
71 |
+ foundWindowsMatch := false |
|
74 | 72 |
for _, manifestDescriptor := range manifests { |
75 |
- if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == os { |
|
73 |
+ if (manifestDescriptor.Platform.Architecture == runtime.GOARCH) && |
|
74 |
+ ((p.OS != "" && manifestDescriptor.Platform.OS == p.OS) || // Explicit user request for an OS we know we support |
|
75 |
+ (p.OS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support |
|
76 | 76 |
matches = append(matches, manifestDescriptor) |
77 |
- 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()) |
|
77 |
+ 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()) |
|
78 |
+ if strings.EqualFold("windows", manifestDescriptor.Platform.OS) { |
|
79 |
+ foundWindowsMatch = true |
|
80 |
+ } |
|
78 | 81 |
} else { |
79 |
- logrus.Debugf("ignoring %s/%s %s with media type %s, digest %s", os, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String()) |
|
82 |
+ 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()) |
|
80 | 83 |
} |
81 | 84 |
} |
82 |
- if os == "windows" { |
|
85 |
+ if foundWindowsMatch { |
|
83 | 86 |
sort.Stable(manifestsByVersion{osVersion, matches}) |
84 | 87 |
} |
85 | 88 |
return matches |
... | ... |
@@ -5,7 +5,6 @@ import ( |
5 | 5 |
"net/http" |
6 | 6 |
"net/http/httptest" |
7 | 7 |
"net/url" |
8 |
- "runtime" |
|
9 | 8 |
"strings" |
10 | 9 |
"testing" |
11 | 10 |
|
... | ... |
@@ -84,7 +83,7 @@ func testTokenPassThru(t *testing.T, ts *httptest.Server) { |
84 | 84 |
logrus.Debug("About to pull") |
85 | 85 |
// We expect it to fail, since we haven't mock'd the full registry exchange in our handler above |
86 | 86 |
tag, _ := reference.WithTag(n, "tag_goes_here") |
87 |
- _ = p.pullV2Repository(ctx, tag, runtime.GOOS) |
|
87 |
+ _ = p.pullV2Repository(ctx, tag, nil) |
|
88 | 88 |
} |
89 | 89 |
|
90 | 90 |
func TestTokenPassThru(t *testing.T) { |
... | ... |
@@ -76,7 +76,8 @@ func (is *store) restore() error { |
76 | 76 |
var l layer.Layer |
77 | 77 |
if chainID := img.RootFS.ChainID(); chainID != "" { |
78 | 78 |
if !system.IsOSSupported(img.OperatingSystem()) { |
79 |
- return system.ErrNotSupportedOperatingSystem |
|
79 |
+ logrus.Errorf("not restoring image with unsupported operating system %v, %v, %s", dgst, chainID, img.OperatingSystem()) |
|
80 |
+ return nil |
|
80 | 81 |
} |
81 | 82 |
l, err = is.lss[img.OperatingSystem()].Get(chainID) |
82 | 83 |
if err != nil { |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
"reflect" |
12 | 12 |
"runtime" |
13 | 13 |
|
14 |
+ "github.com/containerd/containerd/platforms" |
|
14 | 15 |
"github.com/docker/distribution" |
15 | 16 |
"github.com/docker/distribution/reference" |
16 | 17 |
"github.com/docker/docker/image" |
... | ... |
@@ -421,9 +422,11 @@ func checkCompatibleOS(imageOS string) error { |
421 | 421 |
if runtime.GOOS != "windows" && imageOS == "windows" { |
422 | 422 |
return fmt.Errorf("cannot load %s image on %s", imageOS, runtime.GOOS) |
423 | 423 |
} |
424 |
- // Finally, check the image OS is supported for the platform. |
|
425 |
- if err := system.ValidatePlatform(system.ParsePlatform(imageOS)); err != nil { |
|
426 |
- return fmt.Errorf("cannot load %s image on %s: %s", imageOS, runtime.GOOS, err) |
|
424 |
+ |
|
425 |
+ p, err := platforms.Parse(imageOS) |
|
426 |
+ if err != nil { |
|
427 |
+ return err |
|
427 | 428 |
} |
428 |
- return nil |
|
429 |
+ |
|
430 |
+ return system.ValidatePlatform(p) |
|
429 | 431 |
} |
... | ... |
@@ -1,69 +1,32 @@ |
1 | 1 |
package system // import "github.com/docker/docker/pkg/system" |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "fmt" |
|
5 | 4 |
"runtime" |
6 | 5 |
"strings" |
7 | 6 |
|
8 | 7 |
specs "github.com/opencontainers/image-spec/specs-go/v1" |
8 |
+ "github.com/pkg/errors" |
|
9 | 9 |
) |
10 | 10 |
|
11 |
-// ValidatePlatform determines if a platform structure is valid. |
|
12 |
-// TODO This is a temporary function - can be replaced by parsing from |
|
13 |
-// https://github.com/containerd/containerd/pull/1403/files at a later date. |
|
14 |
-// @jhowardmsft |
|
15 |
-func ValidatePlatform(platform *specs.Platform) error { |
|
16 |
- platform.Architecture = strings.ToLower(platform.Architecture) |
|
17 |
- platform.OS = strings.ToLower(platform.OS) |
|
18 |
- // Based on https://github.com/moby/moby/pull/34642#issuecomment-330375350, do |
|
19 |
- // not support anything except operating system. |
|
20 |
- if platform.Architecture != "" { |
|
21 |
- return fmt.Errorf("invalid platform architecture %q", platform.Architecture) |
|
22 |
- } |
|
23 |
- if platform.OS != "" { |
|
24 |
- if !(platform.OS == runtime.GOOS || (LCOWSupported() && platform.OS == "linux")) { |
|
25 |
- return fmt.Errorf("invalid platform os %q", platform.OS) |
|
26 |
- } |
|
27 |
- } |
|
28 |
- if len(platform.OSFeatures) != 0 { |
|
29 |
- return fmt.Errorf("invalid platform osfeatures %q", platform.OSFeatures) |
|
30 |
- } |
|
31 |
- if platform.OSVersion != "" { |
|
32 |
- return fmt.Errorf("invalid platform osversion %q", platform.OSVersion) |
|
33 |
- } |
|
34 |
- if platform.Variant != "" { |
|
35 |
- return fmt.Errorf("invalid platform variant %q", platform.Variant) |
|
36 |
- } |
|
37 |
- return nil |
|
38 |
-} |
|
39 |
- |
|
40 |
-// ParsePlatform parses a platform string in the format os[/arch[/variant] |
|
41 |
-// into an OCI image-spec platform structure. |
|
42 |
-// TODO This is a temporary function - can be replaced by parsing from |
|
43 |
-// https://github.com/containerd/containerd/pull/1403/files at a later date. |
|
44 |
-// @jhowardmsft |
|
45 |
-func ParsePlatform(in string) *specs.Platform { |
|
46 |
- p := &specs.Platform{} |
|
47 |
- elements := strings.SplitN(strings.ToLower(in), "/", 3) |
|
48 |
- if len(elements) == 3 { |
|
49 |
- p.Variant = elements[2] |
|
50 |
- } |
|
51 |
- if len(elements) >= 2 { |
|
52 |
- p.Architecture = elements[1] |
|
53 |
- } |
|
54 |
- if len(elements) >= 1 { |
|
55 |
- p.OS = elements[0] |
|
56 |
- } |
|
57 |
- return p |
|
58 |
-} |
|
59 |
- |
|
60 | 11 |
// IsOSSupported determines if an operating system is supported by the host |
61 | 12 |
func IsOSSupported(os string) bool { |
62 |
- if runtime.GOOS == os { |
|
13 |
+ if strings.EqualFold(runtime.GOOS, os) { |
|
63 | 14 |
return true |
64 | 15 |
} |
65 |
- if LCOWSupported() && os == "linux" { |
|
16 |
+ if LCOWSupported() && strings.EqualFold(os, "linux") { |
|
66 | 17 |
return true |
67 | 18 |
} |
68 | 19 |
return false |
69 | 20 |
} |
21 |
+ |
|
22 |
+// ValidatePlatform determines if a platform structure is valid. |
|
23 |
+// TODO This is a temporary windows-only function, should be replaced by |
|
24 |
+// comparison of worker capabilities |
|
25 |
+func ValidatePlatform(platform specs.Platform) error { |
|
26 |
+ if runtime.GOOS == "windows" { |
|
27 |
+ if !(platform.OS == runtime.GOOS || (LCOWSupported() && platform.OS == "linux")) { |
|
28 |
+ return errors.Errorf("unsupported os %s", platform.OS) |
|
29 |
+ } |
|
30 |
+ } |
|
31 |
+ return nil |
|
32 |
+} |
... | ... |
@@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.5 |
26 | 26 |
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 |
27 | 27 |
|
28 | 28 |
# buildkit |
29 |
-github.com/moby/buildkit dbf67a691ce77023a0a5ce9b005298631f8bbb4e |
|
29 |
+github.com/moby/buildkit cce2080ddbe4698912f2290892b247c83627efa8 |
|
30 | 30 |
github.com/tonistiigi/fsutil 8abad97ee3969cdf5e9c367f46adba2c212b3ddb |
31 | 31 |
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 |
32 | 32 |
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 |
... | ... |
@@ -542,8 +542,9 @@ func (m *ListWorkersResponse) GetRecord() []*WorkerRecord { |
542 | 542 |
} |
543 | 543 |
|
544 | 544 |
type WorkerRecord struct { |
545 |
- ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` |
|
546 |
- 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"` |
|
545 |
+ ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` |
|
546 |
+ 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"` |
|
547 |
+ Platforms []pb.Platform `protobuf:"bytes,3,rep,name=platforms" json:"platforms"` |
|
547 | 548 |
} |
548 | 549 |
|
549 | 550 |
func (m *WorkerRecord) Reset() { *m = WorkerRecord{} } |
... | ... |
@@ -565,6 +566,13 @@ func (m *WorkerRecord) GetLabels() map[string]string { |
565 | 565 |
return nil |
566 | 566 |
} |
567 | 567 |
|
568 |
+func (m *WorkerRecord) GetPlatforms() []pb.Platform { |
|
569 |
+ if m != nil { |
|
570 |
+ return m.Platforms |
|
571 |
+ } |
|
572 |
+ return nil |
|
573 |
+} |
|
574 |
+ |
|
568 | 575 |
func init() { |
569 | 576 |
proto.RegisterType((*PruneRequest)(nil), "moby.buildkit.v1.PruneRequest") |
570 | 577 |
proto.RegisterType((*DiskUsageRequest)(nil), "moby.buildkit.v1.DiskUsageRequest") |
... | ... |
@@ -1650,6 +1658,18 @@ func (m *WorkerRecord) MarshalTo(dAtA []byte) (int, error) { |
1650 | 1650 |
i += copy(dAtA[i:], v) |
1651 | 1651 |
} |
1652 | 1652 |
} |
1653 |
+ if len(m.Platforms) > 0 { |
|
1654 |
+ for _, msg := range m.Platforms { |
|
1655 |
+ dAtA[i] = 0x1a |
|
1656 |
+ i++ |
|
1657 |
+ i = encodeVarintControl(dAtA, i, uint64(msg.Size())) |
|
1658 |
+ n, err := msg.MarshalTo(dAtA[i:]) |
|
1659 |
+ if err != nil { |
|
1660 |
+ return 0, err |
|
1661 |
+ } |
|
1662 |
+ i += n |
|
1663 |
+ } |
|
1664 |
+ } |
|
1653 | 1665 |
return i, nil |
1654 | 1666 |
} |
1655 | 1667 |
|
... | ... |
@@ -1979,6 +1999,12 @@ func (m *WorkerRecord) Size() (n int) { |
1979 | 1979 |
n += mapEntrySize + 1 + sovControl(uint64(mapEntrySize)) |
1980 | 1980 |
} |
1981 | 1981 |
} |
1982 |
+ if len(m.Platforms) > 0 { |
|
1983 |
+ for _, e := range m.Platforms { |
|
1984 |
+ l = e.Size() |
|
1985 |
+ n += 1 + l + sovControl(uint64(l)) |
|
1986 |
+ } |
|
1987 |
+ } |
|
1982 | 1988 |
return n |
1983 | 1989 |
} |
1984 | 1990 |
|
... | ... |
@@ -4663,6 +4689,37 @@ func (m *WorkerRecord) Unmarshal(dAtA []byte) error { |
4663 | 4663 |
} |
4664 | 4664 |
m.Labels[mapkey] = mapvalue |
4665 | 4665 |
iNdEx = postIndex |
4666 |
+ case 3: |
|
4667 |
+ if wireType != 2 { |
|
4668 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Platforms", wireType) |
|
4669 |
+ } |
|
4670 |
+ var msglen int |
|
4671 |
+ for shift := uint(0); ; shift += 7 { |
|
4672 |
+ if shift >= 64 { |
|
4673 |
+ return ErrIntOverflowControl |
|
4674 |
+ } |
|
4675 |
+ if iNdEx >= l { |
|
4676 |
+ return io.ErrUnexpectedEOF |
|
4677 |
+ } |
|
4678 |
+ b := dAtA[iNdEx] |
|
4679 |
+ iNdEx++ |
|
4680 |
+ msglen |= (int(b) & 0x7F) << shift |
|
4681 |
+ if b < 0x80 { |
|
4682 |
+ break |
|
4683 |
+ } |
|
4684 |
+ } |
|
4685 |
+ if msglen < 0 { |
|
4686 |
+ return ErrInvalidLengthControl |
|
4687 |
+ } |
|
4688 |
+ postIndex := iNdEx + msglen |
|
4689 |
+ if postIndex > l { |
|
4690 |
+ return io.ErrUnexpectedEOF |
|
4691 |
+ } |
|
4692 |
+ m.Platforms = append(m.Platforms, pb.Platform{}) |
|
4693 |
+ if err := m.Platforms[len(m.Platforms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { |
|
4694 |
+ return err |
|
4695 |
+ } |
|
4696 |
+ iNdEx = postIndex |
|
4666 | 4697 |
default: |
4667 | 4698 |
iNdEx = preIndex |
4668 | 4699 |
skippy, err := skipControl(dAtA[iNdEx:]) |
... | ... |
@@ -4792,80 +4849,81 @@ var ( |
4792 | 4792 |
func init() { proto.RegisterFile("control.proto", fileDescriptorControl) } |
4793 | 4793 |
|
4794 | 4794 |
var fileDescriptorControl = []byte{ |
4795 |
- // 1192 bytes of a gzipped FileDescriptorProto |
|
4796 |
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6e, 0x23, 0x45, |
|
4797 |
- 0x10, 0x66, 0x6c, 0xc7, 0x3f, 0x65, 0x27, 0x0a, 0x0d, 0xac, 0x46, 0x03, 0x24, 0x66, 0x00, 0xc9, |
|
4798 |
- 0x8a, 0x76, 0xc7, 0xd9, 0xc0, 0x22, 0xc8, 0x61, 0xb5, 0xeb, 0x78, 0x11, 0x89, 0x12, 0xb1, 0x74, |
|
4799 |
- 0x36, 0xac, 0xc4, 0x6d, 0x6c, 0x77, 0xbc, 0xa3, 0xd8, 0xd3, 0xa6, 0xbb, 0x27, 0xda, 0xf0, 0x14, |
|
4800 |
- 0x1c, 0xb8, 0xf2, 0x14, 0x1c, 0x38, 0x73, 0x40, 0xda, 0x23, 0x67, 0x0e, 0x59, 0x94, 0x3b, 0x3c, |
|
4801 |
- 0x03, 0xea, 0x9f, 0xb1, 0xdb, 0x1e, 0xe7, 0xc7, 0xd9, 0x53, 0xba, 0x3a, 0x5f, 0x7d, 0x53, 0x5d, |
|
4802 |
- 0x5f, 0xb9, 0xaa, 0x60, 0xb9, 0x4b, 0x63, 0xc1, 0xe8, 0x20, 0x18, 0x31, 0x2a, 0x28, 0x5a, 0x1d, |
|
4803 |
- 0xd2, 0xce, 0x59, 0xd0, 0x49, 0xa2, 0x41, 0xef, 0x24, 0x12, 0xc1, 0xe9, 0x7d, 0xef, 0x5e, 0x3f, |
|
4804 |
- 0x12, 0x2f, 0x92, 0x4e, 0xd0, 0xa5, 0xc3, 0x66, 0x9f, 0xf6, 0x69, 0x53, 0x01, 0x3b, 0xc9, 0xb1, |
|
4805 |
- 0xb2, 0x94, 0xa1, 0x4e, 0x9a, 0xc0, 0x5b, 0xef, 0x53, 0xda, 0x1f, 0x90, 0x09, 0x4a, 0x44, 0x43, |
|
4806 |
- 0xc2, 0x45, 0x38, 0x1c, 0x19, 0xc0, 0x5d, 0x8b, 0x4f, 0x7e, 0xac, 0x99, 0x7e, 0xac, 0xc9, 0xe9, |
|
4807 |
- 0xe0, 0x94, 0xb0, 0xe6, 0xa8, 0xd3, 0xa4, 0x23, 0xae, 0xd1, 0xfe, 0x0a, 0xd4, 0x9e, 0xb2, 0x24, |
|
4808 |
- 0x26, 0x98, 0xfc, 0x98, 0x10, 0x2e, 0xfc, 0x0d, 0x58, 0x6d, 0x47, 0xfc, 0xe4, 0x88, 0x87, 0xfd, |
|
4809 |
- 0xf4, 0x0e, 0xdd, 0x81, 0xe2, 0x71, 0x34, 0x10, 0x84, 0xb9, 0x4e, 0xdd, 0x69, 0x54, 0xb0, 0xb1, |
|
4810 |
- 0xfc, 0x3d, 0x78, 0xdb, 0xc2, 0xf2, 0x11, 0x8d, 0x39, 0x41, 0x0f, 0xa0, 0xc8, 0x48, 0x97, 0xb2, |
|
4811 |
- 0x9e, 0xeb, 0xd4, 0xf3, 0x8d, 0xea, 0xd6, 0x87, 0xc1, 0xec, 0x8b, 0x03, 0xe3, 0x20, 0x41, 0xd8, |
|
4812 |
- 0x80, 0xfd, 0x3f, 0x72, 0x50, 0xb5, 0xee, 0xd1, 0x0a, 0xe4, 0x76, 0xdb, 0xe6, 0x7b, 0xb9, 0xdd, |
|
4813 |
- 0x36, 0x72, 0xa1, 0x74, 0x90, 0x88, 0xb0, 0x33, 0x20, 0x6e, 0xae, 0xee, 0x34, 0xca, 0x38, 0x35, |
|
4814 |
- 0xd1, 0xbb, 0xb0, 0xb4, 0x1b, 0x1f, 0x71, 0xe2, 0xe6, 0xd5, 0xbd, 0x36, 0x10, 0x82, 0xc2, 0x61, |
|
4815 |
- 0xf4, 0x13, 0x71, 0x0b, 0x75, 0xa7, 0x91, 0xc7, 0xea, 0x2c, 0xdf, 0xf1, 0x34, 0x64, 0x24, 0x16, |
|
4816 |
- 0xee, 0x92, 0x7e, 0x87, 0xb6, 0x50, 0x0b, 0x2a, 0x3b, 0x8c, 0x84, 0x82, 0xf4, 0x1e, 0x0b, 0xb7, |
|
4817 |
- 0x58, 0x77, 0x1a, 0xd5, 0x2d, 0x2f, 0xd0, 0x69, 0x0e, 0xd2, 0x34, 0x07, 0xcf, 0xd2, 0x34, 0xb7, |
|
4818 |
- 0xca, 0xaf, 0xce, 0xd7, 0xdf, 0xfa, 0xf9, 0xf5, 0xba, 0x83, 0x27, 0x6e, 0xe8, 0x11, 0xc0, 0x7e, |
|
4819 |
- 0xc8, 0xc5, 0x11, 0x57, 0x24, 0xa5, 0x6b, 0x49, 0x0a, 0x8a, 0xc0, 0xf2, 0x41, 0x6b, 0x00, 0x2a, |
|
4820 |
- 0x01, 0x3b, 0x34, 0x89, 0x85, 0x5b, 0x56, 0x71, 0x5b, 0x37, 0xa8, 0x0e, 0xd5, 0x36, 0xe1, 0x5d, |
|
4821 |
- 0x16, 0x8d, 0x44, 0x44, 0x63, 0xb7, 0xa2, 0x9e, 0x60, 0x5f, 0xf9, 0xbf, 0x14, 0xa0, 0x76, 0x28, |
|
4822 |
- 0x35, 0x4e, 0x85, 0x5b, 0x85, 0x3c, 0x26, 0xc7, 0x26, 0x8b, 0xf2, 0x88, 0x02, 0x80, 0x36, 0x39, |
|
4823 |
- 0x8e, 0xe2, 0x48, 0x71, 0xe4, 0x54, 0x98, 0x2b, 0xc1, 0xa8, 0x13, 0x4c, 0x6e, 0xb1, 0x85, 0x40, |
|
4824 |
- 0x1e, 0x94, 0x9f, 0xbc, 0x1c, 0x51, 0x26, 0xc5, 0xcf, 0x2b, 0x9a, 0xb1, 0x8d, 0x9e, 0xc3, 0x72, |
|
4825 |
- 0x7a, 0x7e, 0x2c, 0x04, 0xe3, 0x6e, 0x41, 0x09, 0x7e, 0x3f, 0x2b, 0xb8, 0x1d, 0x54, 0x30, 0xe5, |
|
4826 |
- 0xf3, 0x24, 0x16, 0xec, 0x0c, 0x4f, 0xf3, 0x48, 0xad, 0x0f, 0x09, 0xe7, 0x32, 0x42, 0x2d, 0x54, |
|
4827 |
- 0x6a, 0xca, 0x70, 0xbe, 0x66, 0x34, 0x16, 0x24, 0xee, 0x29, 0xa1, 0x2a, 0x78, 0x6c, 0xcb, 0x70, |
|
4828 |
- 0xd2, 0xb3, 0x0e, 0xa7, 0x74, 0xa3, 0x70, 0xa6, 0x7c, 0x4c, 0x38, 0x53, 0x77, 0x68, 0x1b, 0x96, |
|
4829 |
- 0x76, 0xc2, 0xee, 0x0b, 0xa2, 0x34, 0xa9, 0x6e, 0xad, 0x65, 0x09, 0xd5, 0xbf, 0xbf, 0x55, 0x22, |
|
4830 |
- 0xf0, 0x56, 0x41, 0x96, 0x07, 0xd6, 0x2e, 0xde, 0x23, 0x40, 0xd9, 0xf7, 0x4a, 0x5d, 0x4e, 0xc8, |
|
4831 |
- 0x59, 0xaa, 0xcb, 0x09, 0x39, 0x93, 0x45, 0x7c, 0x1a, 0x0e, 0x12, 0x5d, 0xdc, 0x15, 0xac, 0x8d, |
|
4832 |
- 0xed, 0xdc, 0x97, 0x8e, 0x64, 0xc8, 0x86, 0xb8, 0x08, 0x83, 0xff, 0xda, 0x81, 0x9a, 0x1d, 0x21, |
|
4833 |
- 0xfa, 0x00, 0x2a, 0x3a, 0xa8, 0x49, 0x71, 0x4c, 0x2e, 0x64, 0x1d, 0xee, 0x0e, 0x8d, 0xc1, 0xdd, |
|
4834 |
- 0x5c, 0x3d, 0xdf, 0xa8, 0x60, 0xeb, 0x06, 0x7d, 0x07, 0x55, 0x0d, 0xd6, 0x59, 0xce, 0xab, 0x2c, |
|
4835 |
- 0x37, 0xaf, 0x4e, 0x4a, 0x60, 0x79, 0xe8, 0x1c, 0xdb, 0x1c, 0xde, 0x43, 0x58, 0x9d, 0x05, 0x2c, |
|
4836 |
- 0xf4, 0xc2, 0xdf, 0x1d, 0x58, 0x36, 0xa2, 0x9a, 0x2e, 0x14, 0xa6, 0x8c, 0x84, 0xa5, 0x77, 0xa6, |
|
4837 |
- 0x1f, 0x3d, 0xb8, 0xb4, 0x1e, 0x34, 0x2c, 0x98, 0xf5, 0xd3, 0xf1, 0x66, 0xe8, 0xbc, 0x1d, 0x78, |
|
4838 |
- 0x6f, 0x2e, 0x74, 0xa1, 0xc8, 0x3f, 0x82, 0xe5, 0x43, 0x11, 0x8a, 0x84, 0x5f, 0xfa, 0x93, 0xf5, |
|
4839 |
- 0x7f, 0x73, 0x60, 0x25, 0xc5, 0x98, 0xd7, 0x7d, 0x0e, 0xe5, 0x53, 0xc2, 0x04, 0x79, 0x49, 0xb8, |
|
4840 |
- 0x79, 0x95, 0x9b, 0x7d, 0xd5, 0xf7, 0x0a, 0x81, 0xc7, 0x48, 0xb4, 0x0d, 0x65, 0xae, 0x78, 0x88, |
|
4841 |
- 0x96, 0x75, 0x6e, 0x29, 0x6b, 0x2f, 0xf3, 0xbd, 0x31, 0x1e, 0x35, 0xa1, 0x30, 0xa0, 0xfd, 0x54, |
|
4842 |
- 0xed, 0xf7, 0x2f, 0xf3, 0xdb, 0xa7, 0x7d, 0xac, 0x80, 0xfe, 0x79, 0x0e, 0x8a, 0xfa, 0x0e, 0xed, |
|
4843 |
- 0x41, 0xb1, 0x17, 0xf5, 0x09, 0x17, 0xfa, 0x55, 0xad, 0x2d, 0xf9, 0x03, 0xf9, 0xfb, 0x7c, 0x7d, |
|
4844 |
- 0xc3, 0x1a, 0x54, 0x74, 0x44, 0x62, 0x39, 0x28, 0xc3, 0x28, 0x26, 0x8c, 0x37, 0xfb, 0xf4, 0x9e, |
|
4845 |
- 0x76, 0x09, 0xda, 0xea, 0x0f, 0x36, 0x0c, 0x92, 0x2b, 0x8a, 0x47, 0x89, 0x30, 0x85, 0x79, 0x3b, |
|
4846 |
- 0x2e, 0xcd, 0x20, 0x47, 0x44, 0x1c, 0x0e, 0x89, 0xe9, 0x6b, 0xea, 0x2c, 0x47, 0x44, 0x57, 0xd6, |
|
4847 |
- 0x6d, 0x4f, 0x0d, 0x8e, 0x32, 0x36, 0x16, 0xda, 0x86, 0x12, 0x17, 0x21, 0x13, 0xa4, 0xa7, 0x5a, |
|
4848 |
- 0xd2, 0x4d, 0x7a, 0x7b, 0xea, 0x80, 0x1e, 0x42, 0xa5, 0x4b, 0x87, 0xa3, 0x01, 0x91, 0xde, 0xc5, |
|
4849 |
- 0x1b, 0x7a, 0x4f, 0x5c, 0x64, 0xf5, 0x10, 0xc6, 0x28, 0x53, 0x53, 0xa5, 0x82, 0xb5, 0xe1, 0xff, |
|
4850 |
- 0x97, 0x83, 0x9a, 0x2d, 0x56, 0x66, 0x62, 0xee, 0x41, 0x51, 0x4b, 0xaf, 0xab, 0xee, 0x76, 0xa9, |
|
4851 |
- 0xd2, 0x0c, 0x73, 0x53, 0xe5, 0x42, 0xa9, 0x9b, 0x30, 0x35, 0x4e, 0xf5, 0x90, 0x4d, 0x4d, 0x19, |
|
4852 |
- 0xb0, 0xa0, 0x22, 0x1c, 0xa8, 0x54, 0xe5, 0xb1, 0x36, 0xe4, 0x94, 0x1d, 0xaf, 0x2a, 0x8b, 0x4d, |
|
4853 |
- 0xd9, 0xb1, 0x9b, 0x2d, 0x43, 0xe9, 0x8d, 0x64, 0x28, 0x2f, 0x2c, 0x83, 0xff, 0xa7, 0x03, 0x95, |
|
4854 |
- 0x71, 0x95, 0x5b, 0xd9, 0x75, 0xde, 0x38, 0xbb, 0x53, 0x99, 0xc9, 0xdd, 0x2e, 0x33, 0x77, 0xa0, |
|
4855 |
- 0xc8, 0x05, 0x23, 0xe1, 0x50, 0x69, 0x94, 0xc7, 0xc6, 0x92, 0xfd, 0x64, 0xc8, 0xfb, 0x4a, 0xa1, |
|
4856 |
- 0x1a, 0x96, 0x47, 0xdf, 0x87, 0x5a, 0xeb, 0x4c, 0x10, 0x7e, 0x40, 0xb8, 0x5c, 0x2e, 0xa4, 0xb6, |
|
4857 |
- 0xbd, 0x50, 0x84, 0xea, 0x1d, 0x35, 0xac, 0xce, 0xfe, 0x5d, 0x40, 0xfb, 0x11, 0x17, 0xcf, 0x29, |
|
4858 |
- 0x3b, 0x21, 0x8c, 0xcf, 0xdb, 0x03, 0xf3, 0xd6, 0x1e, 0x78, 0x00, 0xef, 0x4c, 0xa1, 0x4d, 0x97, |
|
4859 |
- 0xfa, 0x62, 0x66, 0x13, 0x9c, 0xd3, 0x6d, 0xb4, 0xcb, 0xcc, 0x2a, 0xf8, 0xab, 0x03, 0x35, 0xfb, |
|
4860 |
- 0x1f, 0x99, 0xca, 0x6e, 0x41, 0x71, 0x3f, 0xec, 0x90, 0x41, 0xda, 0xc6, 0x36, 0xae, 0x26, 0x0e, |
|
4861 |
- 0x34, 0x58, 0xf7, 0x71, 0xe3, 0xe9, 0x7d, 0x05, 0x55, 0xeb, 0x7a, 0x91, 0x9e, 0xbd, 0xf5, 0x6f, |
|
4862 |
- 0x1e, 0x4a, 0x3b, 0x7a, 0xa9, 0x47, 0xcf, 0xa0, 0x32, 0x5e, 0x81, 0x91, 0x9f, 0x8d, 0x63, 0x76, |
|
4863 |
- 0x97, 0xf6, 0x3e, 0xbe, 0x12, 0x63, 0x32, 0xf7, 0x0d, 0x2c, 0xa9, 0xa5, 0x1c, 0xcd, 0x49, 0x99, |
|
4864 |
- 0xbd, 0xad, 0x7b, 0x57, 0x2f, 0xd7, 0x9b, 0x8e, 0x64, 0x52, 0xd3, 0x6d, 0x1e, 0x93, 0xbd, 0x06, |
|
4865 |
- 0x79, 0xeb, 0xd7, 0x8c, 0x45, 0x74, 0x00, 0x45, 0xd3, 0x68, 0xe6, 0x41, 0xed, 0x19, 0xe6, 0xd5, |
|
4866 |
- 0x2f, 0x07, 0x68, 0xb2, 0x4d, 0x07, 0x1d, 0x8c, 0x77, 0xbc, 0x79, 0xa1, 0xd9, 0x05, 0xea, 0x5d, |
|
4867 |
- 0xf3, 0xff, 0x86, 0xb3, 0xe9, 0xa0, 0x1f, 0xa0, 0x6a, 0x95, 0x20, 0xfa, 0x24, 0xeb, 0x92, 0xad, |
|
4868 |
- 0x67, 0xef, 0xd3, 0x6b, 0x50, 0x3a, 0xd8, 0x56, 0xed, 0xd5, 0xc5, 0x9a, 0xf3, 0xd7, 0xc5, 0x9a, |
|
4869 |
- 0xf3, 0xcf, 0xc5, 0x9a, 0xd3, 0x29, 0xaa, 0x5f, 0xe4, 0x67, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, |
|
4870 |
- 0x4d, 0x94, 0x5a, 0xb6, 0xd8, 0x0d, 0x00, 0x00, |
|
4795 |
+ // 1214 bytes of a gzipped FileDescriptorProto |
|
4796 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x4f, 0x6f, 0x1b, 0x55, |
|
4797 |
+ 0x10, 0x67, 0x6d, 0xc7, 0xf6, 0x8e, 0x9d, 0x28, 0x3c, 0xa0, 0x5a, 0x2d, 0x90, 0x98, 0x05, 0x24, |
|
4798 |
+ 0xab, 0x6a, 0xd7, 0x69, 0xa0, 0x08, 0x72, 0xa8, 0x5a, 0xc7, 0x45, 0x24, 0x4a, 0x44, 0xd8, 0x34, |
|
4799 |
+ 0x54, 0xe2, 0xb6, 0xb6, 0x5f, 0xdc, 0x55, 0xd6, 0xfb, 0x96, 0xf7, 0x9e, 0xa3, 0x86, 0x4f, 0xc1, |
|
4800 |
+ 0x81, 0x6f, 0xc2, 0x81, 0x33, 0x07, 0xa4, 0xde, 0xe0, 0xcc, 0x21, 0x45, 0xb9, 0xc3, 0x67, 0x40, |
|
4801 |
+ 0xef, 0xcf, 0xda, 0xcf, 0x5e, 0xe7, 0x8f, 0xd3, 0x93, 0xdf, 0xcc, 0xfe, 0xe6, 0xb7, 0xf3, 0x66, |
|
4802 |
+ 0x66, 0x67, 0xc6, 0xb0, 0xdc, 0x23, 0x09, 0xa7, 0x24, 0xf6, 0x53, 0x4a, 0x38, 0x41, 0xab, 0x43, |
|
4803 |
+ 0xd2, 0x3d, 0xf3, 0xbb, 0xa3, 0x28, 0xee, 0x9f, 0x44, 0xdc, 0x3f, 0x7d, 0xe0, 0xde, 0x1f, 0x44, |
|
4804 |
+ 0xfc, 0xc5, 0xa8, 0xeb, 0xf7, 0xc8, 0xb0, 0x35, 0x20, 0x03, 0xd2, 0x92, 0xc0, 0xee, 0xe8, 0x58, |
|
4805 |
+ 0x4a, 0x52, 0x90, 0x27, 0x45, 0xe0, 0xae, 0x0f, 0x08, 0x19, 0xc4, 0x78, 0x82, 0xe2, 0xd1, 0x10, |
|
4806 |
+ 0x33, 0x1e, 0x0e, 0x53, 0x0d, 0xb8, 0x67, 0xf0, 0x89, 0x97, 0xb5, 0xb2, 0x97, 0xb5, 0x18, 0x89, |
|
4807 |
+ 0x4f, 0x31, 0x6d, 0xa5, 0xdd, 0x16, 0x49, 0x99, 0x42, 0x7b, 0x2b, 0x50, 0x3f, 0xa0, 0xa3, 0x04, |
|
4808 |
+ 0x07, 0xf8, 0xc7, 0x11, 0x66, 0xdc, 0xbb, 0x0b, 0xab, 0x9d, 0x88, 0x9d, 0x1c, 0xb1, 0x70, 0x90, |
|
4809 |
+ 0xe9, 0xd0, 0x1d, 0x28, 0x1f, 0x47, 0x31, 0xc7, 0xd4, 0xb1, 0x1a, 0x56, 0xd3, 0x0e, 0xb4, 0xe4, |
|
4810 |
+ 0xed, 0xc2, 0xdb, 0x06, 0x96, 0xa5, 0x24, 0x61, 0x18, 0x3d, 0x84, 0x32, 0xc5, 0x3d, 0x42, 0xfb, |
|
4811 |
+ 0x8e, 0xd5, 0x28, 0x36, 0x6b, 0x9b, 0x1f, 0xfa, 0xb3, 0x37, 0xf6, 0xb5, 0x81, 0x00, 0x05, 0x1a, |
|
4812 |
+ 0xec, 0xfd, 0x5e, 0x80, 0x9a, 0xa1, 0x47, 0x2b, 0x50, 0xd8, 0xe9, 0xe8, 0xf7, 0x15, 0x76, 0x3a, |
|
4813 |
+ 0xc8, 0x81, 0xca, 0xfe, 0x88, 0x87, 0xdd, 0x18, 0x3b, 0x85, 0x86, 0xd5, 0xac, 0x06, 0x99, 0x88, |
|
4814 |
+ 0xde, 0x85, 0xa5, 0x9d, 0xe4, 0x88, 0x61, 0xa7, 0x28, 0xf5, 0x4a, 0x40, 0x08, 0x4a, 0x87, 0xd1, |
|
4815 |
+ 0x4f, 0xd8, 0x29, 0x35, 0xac, 0x66, 0x31, 0x90, 0x67, 0x71, 0x8f, 0x83, 0x90, 0xe2, 0x84, 0x3b, |
|
4816 |
+ 0x4b, 0xea, 0x1e, 0x4a, 0x42, 0x6d, 0xb0, 0xb7, 0x29, 0x0e, 0x39, 0xee, 0x3f, 0xe1, 0x4e, 0xb9, |
|
4817 |
+ 0x61, 0x35, 0x6b, 0x9b, 0xae, 0xaf, 0xc2, 0xec, 0x67, 0x61, 0xf6, 0x9f, 0x65, 0x61, 0x6e, 0x57, |
|
4818 |
+ 0x5f, 0x9d, 0xaf, 0xbf, 0xf5, 0xf3, 0xeb, 0x75, 0x2b, 0x98, 0x98, 0xa1, 0xc7, 0x00, 0x7b, 0x21, |
|
4819 |
+ 0xe3, 0x47, 0x4c, 0x92, 0x54, 0xae, 0x25, 0x29, 0x49, 0x02, 0xc3, 0x06, 0xad, 0x01, 0xc8, 0x00, |
|
4820 |
+ 0x6c, 0x93, 0x51, 0xc2, 0x9d, 0xaa, 0xf4, 0xdb, 0xd0, 0xa0, 0x06, 0xd4, 0x3a, 0x98, 0xf5, 0x68, |
|
4821 |
+ 0x94, 0xf2, 0x88, 0x24, 0x8e, 0x2d, 0xaf, 0x60, 0xaa, 0xbc, 0x5f, 0x4a, 0x50, 0x3f, 0x14, 0x39, |
|
4822 |
+ 0xce, 0x12, 0xb7, 0x0a, 0xc5, 0x00, 0x1f, 0xeb, 0x28, 0x8a, 0x23, 0xf2, 0x01, 0x3a, 0xf8, 0x38, |
|
4823 |
+ 0x4a, 0x22, 0xc9, 0x51, 0x90, 0x6e, 0xae, 0xf8, 0x69, 0xd7, 0x9f, 0x68, 0x03, 0x03, 0x81, 0x5c, |
|
4824 |
+ 0xa8, 0x3e, 0x7d, 0x99, 0x12, 0x2a, 0x92, 0x5f, 0x94, 0x34, 0x63, 0x19, 0x3d, 0x87, 0xe5, 0xec, |
|
4825 |
+ 0xfc, 0x84, 0x73, 0xca, 0x9c, 0x92, 0x4c, 0xf8, 0x83, 0x7c, 0xc2, 0x4d, 0xa7, 0xfc, 0x29, 0x9b, |
|
4826 |
+ 0xa7, 0x09, 0xa7, 0x67, 0xc1, 0x34, 0x8f, 0xc8, 0xf5, 0x21, 0x66, 0x4c, 0x78, 0xa8, 0x12, 0x95, |
|
4827 |
+ 0x89, 0xc2, 0x9d, 0xaf, 0x29, 0x49, 0x38, 0x4e, 0xfa, 0x32, 0x51, 0x76, 0x30, 0x96, 0x85, 0x3b, |
|
4828 |
+ 0xd9, 0x59, 0xb9, 0x53, 0xb9, 0x91, 0x3b, 0x53, 0x36, 0xda, 0x9d, 0x29, 0x1d, 0xda, 0x82, 0xa5, |
|
4829 |
+ 0xed, 0xb0, 0xf7, 0x02, 0xcb, 0x9c, 0xd4, 0x36, 0xd7, 0xf2, 0x84, 0xf2, 0xf1, 0xb7, 0x32, 0x09, |
|
4830 |
+ 0xac, 0x5d, 0x12, 0xe5, 0x11, 0x28, 0x13, 0xf7, 0x31, 0xa0, 0xfc, 0x7d, 0x45, 0x5e, 0x4e, 0xf0, |
|
4831 |
+ 0x59, 0x96, 0x97, 0x13, 0x7c, 0x26, 0x8a, 0xf8, 0x34, 0x8c, 0x47, 0xaa, 0xb8, 0xed, 0x40, 0x09, |
|
4832 |
+ 0x5b, 0x85, 0x2f, 0x2d, 0xc1, 0x90, 0x77, 0x71, 0x11, 0x06, 0xef, 0xb5, 0x05, 0x75, 0xd3, 0x43, |
|
4833 |
+ 0xf4, 0x01, 0xd8, 0xca, 0xa9, 0x49, 0x71, 0x4c, 0x14, 0xa2, 0x0e, 0x77, 0x86, 0x5a, 0x60, 0x4e, |
|
4834 |
+ 0xa1, 0x51, 0x6c, 0xda, 0x81, 0xa1, 0x41, 0xdf, 0x41, 0x4d, 0x81, 0x55, 0x94, 0x8b, 0x32, 0xca, |
|
4835 |
+ 0xad, 0xab, 0x83, 0xe2, 0x1b, 0x16, 0x2a, 0xc6, 0x26, 0x87, 0xfb, 0x08, 0x56, 0x67, 0x01, 0x0b, |
|
4836 |
+ 0xdd, 0xf0, 0x37, 0x0b, 0x96, 0x75, 0x52, 0x75, 0x17, 0x0a, 0x33, 0x46, 0x4c, 0x33, 0x9d, 0xee, |
|
4837 |
+ 0x47, 0x0f, 0x2f, 0xad, 0x07, 0x05, 0xf3, 0x67, 0xed, 0x94, 0xbf, 0x39, 0x3a, 0x77, 0x1b, 0xde, |
|
4838 |
+ 0x9b, 0x0b, 0x5d, 0xc8, 0xf3, 0x8f, 0x60, 0xf9, 0x90, 0x87, 0x7c, 0xc4, 0x2e, 0xfd, 0x64, 0xbd, |
|
4839 |
+ 0x5f, 0x2d, 0x58, 0xc9, 0x30, 0xfa, 0x76, 0x9f, 0x43, 0xf5, 0x14, 0x53, 0x8e, 0x5f, 0x62, 0xa6, |
|
4840 |
+ 0x6f, 0xe5, 0xe4, 0x6f, 0xf5, 0xbd, 0x44, 0x04, 0x63, 0x24, 0xda, 0x82, 0x2a, 0x93, 0x3c, 0x58, |
|
4841 |
+ 0xa5, 0x75, 0x6e, 0x29, 0x2b, 0x2b, 0xfd, 0xbe, 0x31, 0x1e, 0xb5, 0xa0, 0x14, 0x93, 0x41, 0x96, |
|
4842 |
+ 0xed, 0xf7, 0x2f, 0xb3, 0xdb, 0x23, 0x83, 0x40, 0x02, 0xbd, 0xf3, 0x02, 0x94, 0x95, 0x0e, 0xed, |
|
4843 |
+ 0x42, 0xb9, 0x1f, 0x0d, 0x30, 0xe3, 0xea, 0x56, 0xed, 0x4d, 0xf1, 0x81, 0xfc, 0x7d, 0xbe, 0x7e, |
|
4844 |
+ 0xd7, 0x18, 0x54, 0x24, 0xc5, 0x89, 0x18, 0x94, 0x61, 0x94, 0x60, 0xca, 0x5a, 0x03, 0x72, 0x5f, |
|
4845 |
+ 0x99, 0xf8, 0x1d, 0xf9, 0x13, 0x68, 0x06, 0xc1, 0x15, 0x25, 0xe9, 0x88, 0xeb, 0xc2, 0xbc, 0x1d, |
|
4846 |
+ 0x97, 0x62, 0x10, 0x23, 0x22, 0x09, 0x87, 0x58, 0xf7, 0x35, 0x79, 0x16, 0x23, 0xa2, 0x27, 0xea, |
|
4847 |
+ 0xb6, 0x2f, 0x07, 0x47, 0x35, 0xd0, 0x12, 0xda, 0x82, 0x0a, 0xe3, 0x21, 0xe5, 0xb8, 0x2f, 0x5b, |
|
4848 |
+ 0xd2, 0x4d, 0x7a, 0x7b, 0x66, 0x80, 0x1e, 0x81, 0xdd, 0x23, 0xc3, 0x34, 0xc6, 0xc2, 0xba, 0x7c, |
|
4849 |
+ 0x43, 0xeb, 0x89, 0x89, 0xa8, 0x1e, 0x4c, 0x29, 0xa1, 0x72, 0xaa, 0xd8, 0x81, 0x12, 0xbc, 0xff, |
|
4850 |
+ 0x0a, 0x50, 0x37, 0x93, 0x95, 0x9b, 0x98, 0xbb, 0x50, 0x56, 0xa9, 0x57, 0x55, 0x77, 0xbb, 0x50, |
|
4851 |
+ 0x29, 0x86, 0xb9, 0xa1, 0x72, 0xa0, 0xd2, 0x1b, 0x51, 0x39, 0x4e, 0xd5, 0x90, 0xcd, 0x44, 0xe1, |
|
4852 |
+ 0x30, 0x27, 0x3c, 0x8c, 0x65, 0xa8, 0x8a, 0x81, 0x12, 0xc4, 0x94, 0x1d, 0xaf, 0x2a, 0x8b, 0x4d, |
|
4853 |
+ 0xd9, 0xb1, 0x99, 0x99, 0x86, 0xca, 0x1b, 0xa5, 0xa1, 0xba, 0x70, 0x1a, 0xbc, 0x3f, 0x2c, 0xb0, |
|
4854 |
+ 0xc7, 0x55, 0x6e, 0x44, 0xd7, 0x7a, 0xe3, 0xe8, 0x4e, 0x45, 0xa6, 0x70, 0xbb, 0xc8, 0xdc, 0x81, |
|
4855 |
+ 0x32, 0xe3, 0x14, 0x87, 0x43, 0x99, 0xa3, 0x62, 0xa0, 0x25, 0xd1, 0x4f, 0x86, 0x6c, 0x20, 0x33, |
|
4856 |
+ 0x54, 0x0f, 0xc4, 0xd1, 0xf3, 0xa0, 0xde, 0x3e, 0xe3, 0x98, 0xed, 0x63, 0x26, 0x96, 0x0b, 0x91, |
|
4857 |
+ 0xdb, 0x7e, 0xc8, 0x43, 0x79, 0x8f, 0x7a, 0x20, 0xcf, 0xde, 0x3d, 0x40, 0x7b, 0x11, 0xe3, 0xcf, |
|
4858 |
+ 0x09, 0x3d, 0xc1, 0x94, 0xcd, 0xdb, 0x03, 0x8b, 0xc6, 0x1e, 0xb8, 0x0f, 0xef, 0x4c, 0xa1, 0x75, |
|
4859 |
+ 0x97, 0xfa, 0x62, 0x66, 0x13, 0x9c, 0xd3, 0x6d, 0x94, 0xc9, 0xcc, 0x2a, 0xf8, 0xa7, 0x05, 0x75, |
|
4860 |
+ 0xf3, 0x41, 0xae, 0xb2, 0xdb, 0x50, 0xde, 0x0b, 0xbb, 0x38, 0xce, 0xda, 0xd8, 0xdd, 0xab, 0x89, |
|
4861 |
+ 0x7d, 0x05, 0x56, 0x7d, 0x5c, 0x5b, 0xa2, 0x0d, 0xb0, 0xd3, 0x38, 0xe4, 0xc7, 0x84, 0x0e, 0xb3, |
|
4862 |
+ 0xae, 0x56, 0x17, 0x7b, 0xd0, 0x81, 0x56, 0xea, 0x31, 0x3e, 0x01, 0xb9, 0x5f, 0x41, 0xcd, 0x20, |
|
4863 |
+ 0x5a, 0xa4, 0xcb, 0x6f, 0xfe, 0x5b, 0x84, 0xca, 0xb6, 0xfa, 0x1b, 0x80, 0x9e, 0x81, 0x3d, 0x5e, |
|
4864 |
+ 0x9a, 0x91, 0x97, 0xf7, 0x7c, 0x76, 0xfb, 0x76, 0x3f, 0xbe, 0x12, 0xa3, 0x63, 0xfd, 0x0d, 0x2c, |
|
4865 |
+ 0xc9, 0x35, 0x1e, 0xcd, 0x09, 0xb2, 0xb9, 0xdf, 0xbb, 0x57, 0xaf, 0xe3, 0x1b, 0x96, 0x60, 0x92, |
|
4866 |
+ 0xf3, 0x70, 0x1e, 0x93, 0xb9, 0x38, 0xb9, 0xeb, 0xd7, 0x0c, 0x52, 0xb4, 0x0f, 0x65, 0xdd, 0x9a, |
|
4867 |
+ 0xe6, 0x41, 0xcd, 0xa9, 0xe7, 0x36, 0x2e, 0x07, 0x28, 0xb2, 0x0d, 0x0b, 0xed, 0x8f, 0xb7, 0xc2, |
|
4868 |
+ 0x79, 0xae, 0x99, 0x25, 0xed, 0x5e, 0xf3, 0xbc, 0x69, 0x6d, 0x58, 0xe8, 0x07, 0xa8, 0x19, 0x45, |
|
4869 |
+ 0x8b, 0x3e, 0xc9, 0x9b, 0xe4, 0xbf, 0x00, 0xf7, 0xd3, 0x6b, 0x50, 0xca, 0xd9, 0x76, 0xfd, 0xd5, |
|
4870 |
+ 0xc5, 0x9a, 0xf5, 0xd7, 0xc5, 0x9a, 0xf5, 0xcf, 0xc5, 0x9a, 0xd5, 0x2d, 0xcb, 0x6f, 0xf8, 0xb3, |
|
4871 |
+ 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x86, 0xd4, 0x0f, 0xa1, 0x0a, 0x0e, 0x00, 0x00, |
|
4871 | 4872 |
} |
... | ... |
@@ -17,7 +17,7 @@ import ( |
17 | 17 |
) |
18 | 18 |
|
19 | 19 |
var ( |
20 |
- errLocked = errors.New("locked") |
|
20 |
+ ErrLocked = errors.New("locked") |
|
21 | 21 |
errNotFound = errors.New("not found") |
22 | 22 |
errInvalid = errors.New("invalid") |
23 | 23 |
) |
... | ... |
@@ -122,7 +122,7 @@ func (cm *cacheManager) get(ctx context.Context, id string, fromSnapshotter bool |
122 | 122 |
|
123 | 123 |
if rec.mutable { |
124 | 124 |
if len(rec.refs) != 0 { |
125 |
- return nil, errors.Wrapf(errLocked, "%s is locked", id) |
|
125 |
+ return nil, errors.Wrapf(ErrLocked, "%s is locked", id) |
|
126 | 126 |
} |
127 | 127 |
if rec.equalImmutable != nil { |
128 | 128 |
return rec.equalImmutable.ref(), nil |
... | ... |
@@ -279,12 +279,12 @@ func (cm *cacheManager) GetMutable(ctx context.Context, id string) (MutableRef, |
279 | 279 |
} |
280 | 280 |
|
281 | 281 |
if len(rec.refs) != 0 { |
282 |
- return nil, errors.Wrapf(errLocked, "%s is locked", id) |
|
282 |
+ return nil, errors.Wrapf(ErrLocked, "%s is locked", id) |
|
283 | 283 |
} |
284 | 284 |
|
285 | 285 |
if rec.equalImmutable != nil { |
286 | 286 |
if len(rec.equalImmutable.refs) != 0 { |
287 |
- return nil, errors.Wrapf(errLocked, "%s is locked", id) |
|
287 |
+ return nil, errors.Wrapf(ErrLocked, "%s is locked", id) |
|
288 | 288 |
} |
289 | 289 |
delete(cm.records, rec.equalImmutable.ID()) |
290 | 290 |
if err := rec.equalImmutable.remove(ctx, false); err != nil { |
... | ... |
@@ -513,7 +513,7 @@ func (cm *cacheManager) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) |
513 | 513 |
} |
514 | 514 |
|
515 | 515 |
func IsLocked(err error) bool { |
516 |
- return errors.Cause(err) == errLocked |
|
516 |
+ return errors.Cause(err) == ErrLocked |
|
517 | 517 |
} |
518 | 518 |
|
519 | 519 |
func IsNotFound(err error) bool { |
... | ... |
@@ -5,7 +5,6 @@ import ( |
5 | 5 |
"crypto/tls" |
6 | 6 |
"crypto/x509" |
7 | 7 |
"io/ioutil" |
8 |
- "time" |
|
9 | 8 |
|
10 | 9 |
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" |
11 | 10 |
controlapi "github.com/moby/buildkit/api/services/control" |
... | ... |
@@ -23,7 +22,7 @@ type Client struct { |
23 | 23 |
type ClientOpt interface{} |
24 | 24 |
|
25 | 25 |
// New returns a new buildkit client. Address can be empty for the system-default address. |
26 |
-func New(address string, opts ...ClientOpt) (*Client, error) { |
|
26 |
+func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error) { |
|
27 | 27 |
gopts := []grpc.DialOption{ |
28 | 28 |
grpc.WithDialer(dialer), |
29 | 29 |
grpc.FailOnNonTempDialError(true), |
... | ... |
@@ -54,9 +53,6 @@ func New(address string, opts ...ClientOpt) (*Client, error) { |
54 | 54 |
address = appdefaults.Address |
55 | 55 |
} |
56 | 56 |
|
57 |
- ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
|
58 |
- defer cancel() |
|
59 |
- |
|
60 | 57 |
conn, err := grpc.DialContext(ctx, address, gopts...) |
61 | 58 |
if err != nil { |
62 | 59 |
return nil, errors.Wrapf(err, "failed to dial %q . make sure buildkitd is running", address) |
... | ... |
@@ -17,8 +17,8 @@ type Meta struct { |
17 | 17 |
ProxyEnv *ProxyEnv |
18 | 18 |
} |
19 | 19 |
|
20 |
-func NewExecOp(root Output, meta Meta, readOnly bool, md OpMetadata) *ExecOp { |
|
21 |
- e := &ExecOp{meta: meta, cachedOpMetadata: md} |
|
20 |
+func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp { |
|
21 |
+ e := &ExecOp{meta: meta, constraints: c} |
|
22 | 22 |
rootMount := &mount{ |
23 | 23 |
target: pb.RootMount, |
24 | 24 |
source: root, |
... | ... |
@@ -28,32 +28,35 @@ func NewExecOp(root Output, meta Meta, readOnly bool, md OpMetadata) *ExecOp { |
28 | 28 |
if readOnly { |
29 | 29 |
e.root = root |
30 | 30 |
} else { |
31 |
- e.root = &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} |
|
31 |
+ o := &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} |
|
32 |
+ if p := c.Platform; p != nil { |
|
33 |
+ o.platform = p |
|
34 |
+ } |
|
35 |
+ e.root = o |
|
32 | 36 |
} |
33 | 37 |
rootMount.output = e.root |
34 |
- |
|
35 | 38 |
return e |
36 | 39 |
} |
37 | 40 |
|
38 | 41 |
type mount struct { |
39 |
- target string |
|
40 |
- readonly bool |
|
41 |
- source Output |
|
42 |
- output Output |
|
43 |
- selector string |
|
44 |
- cacheID string |
|
45 |
- tmpfs bool |
|
42 |
+ target string |
|
43 |
+ readonly bool |
|
44 |
+ source Output |
|
45 |
+ output Output |
|
46 |
+ selector string |
|
47 |
+ cacheID string |
|
48 |
+ tmpfs bool |
|
49 |
+ cacheSharing CacheMountSharingMode |
|
46 | 50 |
// hasOutput bool |
47 | 51 |
} |
48 | 52 |
|
49 | 53 |
type ExecOp struct { |
50 |
- root Output |
|
51 |
- mounts []*mount |
|
52 |
- meta Meta |
|
53 |
- cachedPBDigest digest.Digest |
|
54 |
- cachedPB []byte |
|
55 |
- cachedOpMetadata OpMetadata |
|
56 |
- isValidated bool |
|
54 |
+ MarshalCache |
|
55 |
+ root Output |
|
56 |
+ mounts []*mount |
|
57 |
+ meta Meta |
|
58 |
+ constraints Constraints |
|
59 |
+ isValidated bool |
|
57 | 60 |
} |
58 | 61 |
|
59 | 62 |
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 |
70 | 70 |
} else if m.tmpfs { |
71 | 71 |
m.output = &output{vertex: e, err: errors.Errorf("tmpfs mount for %s can't be used as a parent", target)} |
72 | 72 |
} else { |
73 |
- m.output = &output{vertex: e, getIndex: e.getMountIndexFn(m)} |
|
73 |
+ o := &output{vertex: e, getIndex: e.getMountIndexFn(m)} |
|
74 |
+ if p := e.constraints.Platform; p != nil { |
|
75 |
+ o.platform = p |
|
76 |
+ } |
|
77 |
+ m.output = o |
|
74 | 78 |
} |
75 |
- e.cachedPB = nil |
|
79 |
+ e.Store(nil, nil, nil) |
|
76 | 80 |
e.isValidated = false |
77 | 81 |
return m.output |
78 | 82 |
} |
... | ... |
@@ -107,9 +114,9 @@ func (e *ExecOp) Validate() error { |
107 | 107 |
return nil |
108 | 108 |
} |
109 | 109 |
|
110 |
-func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
|
111 |
- if e.cachedPB != nil { |
|
112 |
- return e.cachedPBDigest, e.cachedPB, &e.cachedOpMetadata, nil |
|
110 |
+func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { |
|
111 |
+ if e.Cached(c) { |
|
112 |
+ return e.Load() |
|
113 | 113 |
} |
114 | 114 |
if err := e.Validate(); err != nil { |
115 | 115 |
return "", nil, nil, err |
... | ... |
@@ -137,10 +144,9 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
137 | 137 |
} |
138 | 138 |
} |
139 | 139 |
|
140 |
- pop := &pb.Op{ |
|
141 |
- Op: &pb.Op_Exec{ |
|
142 |
- Exec: peo, |
|
143 |
- }, |
|
140 |
+ pop, md := MarshalConstraints(c, &e.constraints) |
|
141 |
+ pop.Op = &pb.Op_Exec{ |
|
142 |
+ Exec: peo, |
|
144 | 143 |
} |
145 | 144 |
|
146 | 145 |
outIndex := 0 |
... | ... |
@@ -150,7 +156,7 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
150 | 150 |
if m.tmpfs { |
151 | 151 |
return "", nil, nil, errors.Errorf("tmpfs mounts must use scratch") |
152 | 152 |
} |
153 |
- inp, err := m.source.ToInput() |
|
153 |
+ inp, err := m.source.ToInput(c) |
|
154 | 154 |
if err != nil { |
155 | 155 |
return "", nil, nil, err |
156 | 156 |
} |
... | ... |
@@ -190,6 +196,14 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
190 | 190 |
pm.CacheOpt = &pb.CacheOpt{ |
191 | 191 |
ID: m.cacheID, |
192 | 192 |
} |
193 |
+ switch m.cacheSharing { |
|
194 |
+ case CacheMountShared: |
|
195 |
+ pm.CacheOpt.Sharing = pb.CacheSharingOpt_SHARED |
|
196 |
+ case CacheMountPrivate: |
|
197 |
+ pm.CacheOpt.Sharing = pb.CacheSharingOpt_PRIVATE |
|
198 |
+ case CacheMountLocked: |
|
199 |
+ pm.CacheOpt.Sharing = pb.CacheSharingOpt_LOCKED |
|
200 |
+ } |
|
193 | 201 |
} |
194 | 202 |
if m.tmpfs { |
195 | 203 |
pm.MountType = pb.MountType_TMPFS |
... | ... |
@@ -201,9 +215,8 @@ func (e *ExecOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
201 | 201 |
if err != nil { |
202 | 202 |
return "", nil, nil, err |
203 | 203 |
} |
204 |
- e.cachedPBDigest = digest.FromBytes(dt) |
|
205 |
- e.cachedPB = dt |
|
206 |
- return e.cachedPBDigest, dt, &e.cachedOpMetadata, nil |
|
204 |
+ e.Store(dt, md, c) |
|
205 |
+ return e.Load() |
|
207 | 206 |
} |
208 | 207 |
|
209 | 208 |
func (e *ExecOp) Output() Output { |
... | ... |
@@ -273,9 +286,10 @@ func SourcePath(src string) MountOption { |
273 | 273 |
} |
274 | 274 |
} |
275 | 275 |
|
276 |
-func AsPersistentCacheDir(id string) MountOption { |
|
276 |
+func AsPersistentCacheDir(id string, sharing CacheMountSharingMode) MountOption { |
|
277 | 277 |
return func(m *mount) { |
278 | 278 |
m.cacheID = id |
279 |
+ m.cacheSharing = sharing |
|
279 | 280 |
} |
280 | 281 |
} |
281 | 282 |
|
... | ... |
@@ -366,7 +380,7 @@ func WithProxy(ps ProxyEnv) RunOption { |
366 | 366 |
} |
367 | 367 |
|
368 | 368 |
type ExecInfo struct { |
369 |
- opMetaWrapper |
|
369 |
+ constraintsWrapper |
|
370 | 370 |
State State |
371 | 371 |
Mounts []MountInfo |
372 | 372 |
ReadonlyRootFS bool |
... | ... |
@@ -385,3 +399,11 @@ type ProxyEnv struct { |
385 | 385 |
FtpProxy string |
386 | 386 |
NoProxy string |
387 | 387 |
} |
388 |
+ |
|
389 |
+type CacheMountSharingMode int |
|
390 |
+ |
|
391 |
+const ( |
|
392 |
+ CacheMountShared CacheMountSharingMode = iota |
|
393 |
+ CacheMountPrivate |
|
394 |
+ CacheMountLocked |
|
395 |
+) |
... | ... |
@@ -12,6 +12,7 @@ import ( |
12 | 12 |
"github.com/moby/buildkit/util/contentutil" |
13 | 13 |
"github.com/moby/buildkit/util/imageutil" |
14 | 14 |
digest "github.com/opencontainers/go-digest" |
15 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
15 | 16 |
) |
16 | 17 |
|
17 | 18 |
var defaultImageMetaResolver llb.ImageMetaResolver |
... | ... |
@@ -22,12 +23,12 @@ var WithDefault = llb.ImageOptionFunc(func(ii *llb.ImageInfo) { |
22 | 22 |
}) |
23 | 23 |
|
24 | 24 |
type imageMetaResolverOpts struct { |
25 |
- platform string |
|
25 |
+ platform *specs.Platform |
|
26 | 26 |
} |
27 | 27 |
|
28 | 28 |
type ImageMetaResolverOpt func(o *imageMetaResolverOpts) |
29 | 29 |
|
30 |
-func WithPlatform(p string) ImageMetaResolverOpt { |
|
30 |
+func WithDefaultPlatform(p *specs.Platform) ImageMetaResolverOpt { |
|
31 | 31 |
return func(o *imageMetaResolverOpts) { |
32 | 32 |
o.platform = p |
33 | 33 |
} |
... | ... |
@@ -59,7 +60,7 @@ func Default() llb.ImageMetaResolver { |
59 | 59 |
type imageMetaResolver struct { |
60 | 60 |
resolver remotes.Resolver |
61 | 61 |
buffer contentutil.Buffer |
62 |
- platform string |
|
62 |
+ platform *specs.Platform |
|
63 | 63 |
locker *locker.Locker |
64 | 64 |
cache map[string]resolveResult |
65 | 65 |
} |
... | ... |
@@ -69,7 +70,7 @@ type resolveResult struct { |
69 | 69 |
dgst digest.Digest |
70 | 70 |
} |
71 | 71 |
|
72 |
-func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { |
|
72 |
+func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) { |
|
73 | 73 |
imr.locker.Lock(ref) |
74 | 74 |
defer imr.locker.Unlock(ref) |
75 | 75 |
|
... | ... |
@@ -77,7 +78,11 @@ func (imr *imageMetaResolver) ResolveImageConfig(ctx context.Context, ref string |
77 | 77 |
return res.dgst, res.config, nil |
78 | 78 |
} |
79 | 79 |
|
80 |
- dgst, config, err := imageutil.Config(ctx, ref, imr.resolver, imr.buffer, imr.platform) |
|
80 |
+ if platform == nil { |
|
81 |
+ platform = imr.platform |
|
82 |
+ } |
|
83 |
+ |
|
84 |
+ dgst, config, err := imageutil.Config(ctx, ref, imr.resolver, imr.buffer, platform) |
|
81 | 85 |
if err != nil { |
82 | 86 |
return "", nil, err |
83 | 87 |
} |
... | ... |
@@ -4,6 +4,7 @@ import ( |
4 | 4 |
"io" |
5 | 5 |
"io/ioutil" |
6 | 6 |
|
7 |
+ "github.com/containerd/containerd/platforms" |
|
7 | 8 |
"github.com/moby/buildkit/solver/pb" |
8 | 9 |
digest "github.com/opencontainers/go-digest" |
9 | 10 |
) |
... | ... |
@@ -12,11 +13,11 @@ import ( |
12 | 12 |
// Corresponds to the Definition structure defined in solver/pb.Definition. |
13 | 13 |
type Definition struct { |
14 | 14 |
Def [][]byte |
15 |
- Metadata map[digest.Digest]OpMetadata |
|
15 |
+ Metadata map[digest.Digest]pb.OpMetadata |
|
16 | 16 |
} |
17 | 17 |
|
18 | 18 |
func (def *Definition) ToPB() *pb.Definition { |
19 |
- md := make(map[digest.Digest]OpMetadata) |
|
19 |
+ md := make(map[digest.Digest]pb.OpMetadata) |
|
20 | 20 |
for k, v := range def.Metadata { |
21 | 21 |
md[k] = v |
22 | 22 |
} |
... | ... |
@@ -28,14 +29,12 @@ func (def *Definition) ToPB() *pb.Definition { |
28 | 28 |
|
29 | 29 |
func (def *Definition) FromPB(x *pb.Definition) { |
30 | 30 |
def.Def = x.Def |
31 |
- def.Metadata = make(map[digest.Digest]OpMetadata) |
|
31 |
+ def.Metadata = make(map[digest.Digest]pb.OpMetadata) |
|
32 | 32 |
for k, v := range x.Metadata { |
33 | 33 |
def.Metadata[k] = v |
34 | 34 |
} |
35 | 35 |
} |
36 | 36 |
|
37 |
-type OpMetadata = pb.OpMetadata |
|
38 |
- |
|
39 | 37 |
func WriteTo(def *Definition, w io.Writer) error { |
40 | 38 |
b, err := def.ToPB().Marshal() |
41 | 39 |
if err != nil { |
... | ... |
@@ -58,3 +57,56 @@ func ReadFrom(r io.Reader) (*Definition, error) { |
58 | 58 |
def.FromPB(&pbDef) |
59 | 59 |
return &def, nil |
60 | 60 |
} |
61 |
+ |
|
62 |
+func MarshalConstraints(base, override *Constraints) (*pb.Op, *pb.OpMetadata) { |
|
63 |
+ c := *base |
|
64 |
+ c.WorkerConstraints = append([]string{}, c.WorkerConstraints...) |
|
65 |
+ |
|
66 |
+ if p := override.Platform; p != nil { |
|
67 |
+ c.Platform = p |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ for _, wc := range override.WorkerConstraints { |
|
71 |
+ c.WorkerConstraints = append(c.WorkerConstraints, wc) |
|
72 |
+ } |
|
73 |
+ |
|
74 |
+ c.Metadata = mergeMetadata(c.Metadata, override.Metadata) |
|
75 |
+ |
|
76 |
+ if c.Platform == nil { |
|
77 |
+ defaultPlatform := platforms.Normalize(platforms.DefaultSpec()) |
|
78 |
+ c.Platform = &defaultPlatform |
|
79 |
+ } |
|
80 |
+ |
|
81 |
+ return &pb.Op{ |
|
82 |
+ Platform: &pb.Platform{ |
|
83 |
+ OS: c.Platform.OS, |
|
84 |
+ Architecture: c.Platform.Architecture, |
|
85 |
+ Variant: c.Platform.Variant, |
|
86 |
+ OSVersion: c.Platform.OSVersion, |
|
87 |
+ OSFeatures: c.Platform.OSFeatures, |
|
88 |
+ }, |
|
89 |
+ Constraints: &pb.WorkerConstraints{ |
|
90 |
+ Filter: c.WorkerConstraints, |
|
91 |
+ }, |
|
92 |
+ }, &c.Metadata |
|
93 |
+} |
|
94 |
+ |
|
95 |
+type MarshalCache struct { |
|
96 |
+ digest digest.Digest |
|
97 |
+ dt []byte |
|
98 |
+ md *pb.OpMetadata |
|
99 |
+ constraints *Constraints |
|
100 |
+} |
|
101 |
+ |
|
102 |
+func (mc *MarshalCache) Cached(c *Constraints) bool { |
|
103 |
+ return mc.dt != nil && mc.constraints == c |
|
104 |
+} |
|
105 |
+func (mc *MarshalCache) Load() (digest.Digest, []byte, *pb.OpMetadata, error) { |
|
106 |
+ return mc.digest, mc.dt, mc.md, nil |
|
107 |
+} |
|
108 |
+func (mc *MarshalCache) Store(dt []byte, md *pb.OpMetadata, c *Constraints) { |
|
109 |
+ mc.digest = digest.FromBytes(dt) |
|
110 |
+ mc.dt = dt |
|
111 |
+ mc.md = md |
|
112 |
+ mc.constraints = c |
|
113 |
+} |
... | ... |
@@ -4,16 +4,19 @@ import ( |
4 | 4 |
"fmt" |
5 | 5 |
"path" |
6 | 6 |
|
7 |
+ "github.com/containerd/containerd/platforms" |
|
7 | 8 |
"github.com/google/shlex" |
9 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
8 | 10 |
) |
9 | 11 |
|
10 | 12 |
type contextKeyT string |
11 | 13 |
|
12 | 14 |
var ( |
13 |
- keyArgs = contextKeyT("llb.exec.args") |
|
14 |
- keyDir = contextKeyT("llb.exec.dir") |
|
15 |
- keyEnv = contextKeyT("llb.exec.env") |
|
16 |
- keyUser = contextKeyT("llb.exec.user") |
|
15 |
+ keyArgs = contextKeyT("llb.exec.args") |
|
16 |
+ keyDir = contextKeyT("llb.exec.dir") |
|
17 |
+ keyEnv = contextKeyT("llb.exec.env") |
|
18 |
+ keyUser = contextKeyT("llb.exec.user") |
|
19 |
+ keyPlatform = contextKeyT("llb.platform") |
|
17 | 20 |
) |
18 | 21 |
|
19 | 22 |
func addEnv(key, value string) StateOption { |
... | ... |
@@ -106,6 +109,21 @@ func shlexf(str string, v ...interface{}) StateOption { |
106 | 106 |
} |
107 | 107 |
} |
108 | 108 |
|
109 |
+func platform(p specs.Platform) StateOption { |
|
110 |
+ return func(s State) State { |
|
111 |
+ return s.WithValue(keyPlatform, platforms.Normalize(p)) |
|
112 |
+ } |
|
113 |
+} |
|
114 |
+ |
|
115 |
+func getPlatform(s State) *specs.Platform { |
|
116 |
+ v := s.Value(keyPlatform) |
|
117 |
+ if v != nil { |
|
118 |
+ p := v.(specs.Platform) |
|
119 |
+ return &p |
|
120 |
+ } |
|
121 |
+ return nil |
|
122 |
+} |
|
123 |
+ |
|
109 | 124 |
type EnvList []KeyValue |
110 | 125 |
|
111 | 126 |
type KeyValue struct { |
... | ... |
@@ -4,6 +4,7 @@ import ( |
4 | 4 |
"context" |
5 | 5 |
|
6 | 6 |
digest "github.com/opencontainers/go-digest" |
7 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
7 | 8 |
) |
8 | 9 |
|
9 | 10 |
func WithMetaResolver(mr ImageMetaResolver) ImageOption { |
... | ... |
@@ -13,5 +14,5 @@ func WithMetaResolver(mr ImageMetaResolver) ImageOption { |
13 | 13 |
} |
14 | 14 |
|
15 | 15 |
type ImageMetaResolver interface { |
16 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
16 |
+ ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) |
|
17 | 17 |
} |
... | ... |
@@ -15,22 +15,21 @@ import ( |
15 | 15 |
) |
16 | 16 |
|
17 | 17 |
type SourceOp struct { |
18 |
- id string |
|
19 |
- attrs map[string]string |
|
20 |
- output Output |
|
21 |
- cachedPBDigest digest.Digest |
|
22 |
- cachedPB []byte |
|
23 |
- cachedOpMetadata OpMetadata |
|
24 |
- err error |
|
18 |
+ MarshalCache |
|
19 |
+ id string |
|
20 |
+ attrs map[string]string |
|
21 |
+ output Output |
|
22 |
+ constraints Constraints |
|
23 |
+ err error |
|
25 | 24 |
} |
26 | 25 |
|
27 |
-func NewSource(id string, attrs map[string]string, md OpMetadata) *SourceOp { |
|
26 |
+func NewSource(id string, attrs map[string]string, c Constraints) *SourceOp { |
|
28 | 27 |
s := &SourceOp{ |
29 |
- id: id, |
|
30 |
- attrs: attrs, |
|
31 |
- cachedOpMetadata: md, |
|
28 |
+ id: id, |
|
29 |
+ attrs: attrs, |
|
30 |
+ constraints: c, |
|
32 | 31 |
} |
33 |
- s.output = &output{vertex: s} |
|
32 |
+ s.output = &output{vertex: s, platform: c.Platform} |
|
34 | 33 |
return s |
35 | 34 |
} |
36 | 35 |
|
... | ... |
@@ -44,26 +43,26 @@ func (s *SourceOp) Validate() error { |
44 | 44 |
return nil |
45 | 45 |
} |
46 | 46 |
|
47 |
-func (s *SourceOp) Marshal() (digest.Digest, []byte, *OpMetadata, error) { |
|
48 |
- if s.cachedPB != nil { |
|
49 |
- return s.cachedPBDigest, s.cachedPB, &s.cachedOpMetadata, nil |
|
47 |
+func (s *SourceOp) Marshal(constraints *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { |
|
48 |
+ if s.Cached(constraints) { |
|
49 |
+ return s.Load() |
|
50 | 50 |
} |
51 | 51 |
if err := s.Validate(); err != nil { |
52 | 52 |
return "", nil, nil, err |
53 | 53 |
} |
54 | 54 |
|
55 |
- proto := &pb.Op{ |
|
56 |
- Op: &pb.Op_Source{ |
|
57 |
- Source: &pb.SourceOp{Identifier: s.id, Attrs: s.attrs}, |
|
58 |
- }, |
|
55 |
+ proto, md := MarshalConstraints(constraints, &s.constraints) |
|
56 |
+ |
|
57 |
+ proto.Op = &pb.Op_Source{ |
|
58 |
+ Source: &pb.SourceOp{Identifier: s.id, Attrs: s.attrs}, |
|
59 | 59 |
} |
60 | 60 |
dt, err := proto.Marshal() |
61 | 61 |
if err != nil { |
62 | 62 |
return "", nil, nil, err |
63 | 63 |
} |
64 |
- s.cachedPB = dt |
|
65 |
- s.cachedPBDigest = digest.FromBytes(dt) |
|
66 |
- return s.cachedPBDigest, dt, &s.cachedOpMetadata, nil |
|
64 |
+ |
|
65 |
+ s.Store(dt, md, constraints) |
|
66 |
+ return s.Load() |
|
67 | 67 |
} |
68 | 68 |
|
69 | 69 |
func (s *SourceOp) Output() Output { |
... | ... |
@@ -74,10 +73,6 @@ func (s *SourceOp) Inputs() []Output { |
74 | 74 |
return nil |
75 | 75 |
} |
76 | 76 |
|
77 |
-func Source(id string) State { |
|
78 |
- return NewState(NewSource(id, nil, OpMetadata{}).Output()) |
|
79 |
-} |
|
80 |
- |
|
81 | 77 |
func Image(ref string, opts ...ImageOption) State { |
82 | 78 |
r, err := reference.ParseNormalizedNamed(ref) |
83 | 79 |
if err == nil { |
... | ... |
@@ -87,12 +82,12 @@ func Image(ref string, opts ...ImageOption) State { |
87 | 87 |
for _, opt := range opts { |
88 | 88 |
opt.SetImageOption(&info) |
89 | 89 |
} |
90 |
- src := NewSource("docker-image://"+ref, nil, info.Metadata()) // controversial |
|
90 |
+ src := NewSource("docker-image://"+ref, nil, info.Constraints) // controversial |
|
91 | 91 |
if err != nil { |
92 | 92 |
src.err = err |
93 | 93 |
} |
94 | 94 |
if info.metaResolver != nil { |
95 |
- _, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref) |
|
95 |
+ _, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref, info.Constraints.Platform) |
|
96 | 96 |
if err != nil { |
97 | 97 |
src.err = err |
98 | 98 |
} else { |
... | ... |
@@ -136,7 +131,7 @@ func (fn ImageOptionFunc) SetImageOption(ii *ImageInfo) { |
136 | 136 |
} |
137 | 137 |
|
138 | 138 |
type ImageInfo struct { |
139 |
- opMetaWrapper |
|
139 |
+ constraintsWrapper |
|
140 | 140 |
metaResolver ImageMetaResolver |
141 | 141 |
} |
142 | 142 |
|
... | ... |
@@ -169,7 +164,7 @@ func Git(remote, ref string, opts ...GitOption) State { |
169 | 169 |
if url != "" { |
170 | 170 |
attrs[pb.AttrFullRemoteURL] = url |
171 | 171 |
} |
172 |
- source := NewSource("git://"+id, attrs, gi.Metadata()) |
|
172 |
+ source := NewSource("git://"+id, attrs, gi.Constraints) |
|
173 | 173 |
return NewState(source.Output()) |
174 | 174 |
} |
175 | 175 |
|
... | ... |
@@ -183,7 +178,7 @@ func (fn gitOptionFunc) SetGitOption(gi *GitInfo) { |
183 | 183 |
} |
184 | 184 |
|
185 | 185 |
type GitInfo struct { |
186 |
- opMetaWrapper |
|
186 |
+ constraintsWrapper |
|
187 | 187 |
KeepGitDir bool |
188 | 188 |
} |
189 | 189 |
|
... | ... |
@@ -220,7 +215,7 @@ func Local(name string, opts ...LocalOption) State { |
220 | 220 |
attrs[pb.AttrSharedKeyHint] = gi.SharedKeyHint |
221 | 221 |
} |
222 | 222 |
|
223 |
- source := NewSource("local://"+name, attrs, gi.Metadata()) |
|
223 |
+ source := NewSource("local://"+name, attrs, gi.Constraints) |
|
224 | 224 |
return NewState(source.Output()) |
225 | 225 |
} |
226 | 226 |
|
... | ... |
@@ -280,7 +275,7 @@ func SharedKeyHint(h string) LocalOption { |
280 | 280 |
} |
281 | 281 |
|
282 | 282 |
type LocalInfo struct { |
283 |
- opMetaWrapper |
|
283 |
+ constraintsWrapper |
|
284 | 284 |
SessionID string |
285 | 285 |
IncludePatterns string |
286 | 286 |
ExcludePatterns string |
... | ... |
@@ -310,12 +305,12 @@ func HTTP(url string, opts ...HTTPOption) State { |
310 | 310 |
attrs[pb.AttrHTTPGID] = strconv.Itoa(hi.GID) |
311 | 311 |
} |
312 | 312 |
|
313 |
- source := NewSource(url, attrs, hi.Metadata()) |
|
313 |
+ source := NewSource(url, attrs, hi.Constraints) |
|
314 | 314 |
return NewState(source.Output()) |
315 | 315 |
} |
316 | 316 |
|
317 | 317 |
type HTTPInfo struct { |
318 |
- opMetaWrapper |
|
318 |
+ constraintsWrapper |
|
319 | 319 |
Checksum digest.Digest |
320 | 320 |
Filename string |
321 | 321 |
Perm int |
... | ... |
@@ -3,21 +3,23 @@ package llb |
3 | 3 |
import ( |
4 | 4 |
"context" |
5 | 5 |
|
6 |
+ "github.com/containerd/containerd/platforms" |
|
6 | 7 |
"github.com/moby/buildkit/solver/pb" |
7 | 8 |
"github.com/moby/buildkit/util/system" |
8 | 9 |
digest "github.com/opencontainers/go-digest" |
10 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
9 | 11 |
) |
10 | 12 |
|
11 | 13 |
type StateOption func(State) State |
12 | 14 |
|
13 | 15 |
type Output interface { |
14 |
- ToInput() (*pb.Input, error) |
|
16 |
+ ToInput(*Constraints) (*pb.Input, error) |
|
15 | 17 |
Vertex() Vertex |
16 | 18 |
} |
17 | 19 |
|
18 | 20 |
type Vertex interface { |
19 | 21 |
Validate() error |
20 |
- Marshal() (digest.Digest, []byte, *OpMetadata, error) |
|
22 |
+ Marshal(*Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) |
|
21 | 23 |
Output() Output |
22 | 24 |
Inputs() []Output |
23 | 25 |
} |
... | ... |
@@ -29,12 +31,25 @@ func NewState(o Output) State { |
29 | 29 |
} |
30 | 30 |
s = dir("/")(s) |
31 | 31 |
s = addEnv("PATH", system.DefaultPathEnv)(s) |
32 |
+ s = s.ensurePlatform() |
|
32 | 33 |
return s |
33 | 34 |
} |
34 | 35 |
|
35 | 36 |
type State struct { |
36 |
- out Output |
|
37 |
- ctx context.Context |
|
37 |
+ out Output |
|
38 |
+ ctx context.Context |
|
39 |
+ opts []ConstraintsOpt |
|
40 |
+} |
|
41 |
+ |
|
42 |
+func (s State) ensurePlatform() State { |
|
43 |
+ if o, ok := s.out.(interface { |
|
44 |
+ Platform() *specs.Platform |
|
45 |
+ }); ok { |
|
46 |
+ if p := o.Platform(); p != nil { |
|
47 |
+ s = platform(*p)(s) |
|
48 |
+ } |
|
49 |
+ } |
|
50 |
+ return s |
|
38 | 51 |
} |
39 | 52 |
|
40 | 53 |
func (s State) WithValue(k, v interface{}) State { |
... | ... |
@@ -48,18 +63,32 @@ func (s State) Value(k interface{}) interface{} { |
48 | 48 |
return s.ctx.Value(k) |
49 | 49 |
} |
50 | 50 |
|
51 |
-func (s State) Marshal(md ...MetadataOpt) (*Definition, error) { |
|
51 |
+func (s State) SetMarhalDefaults(co ...ConstraintsOpt) State { |
|
52 |
+ s.opts = co |
|
53 |
+ return s |
|
54 |
+} |
|
55 |
+ |
|
56 |
+func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) { |
|
52 | 57 |
def := &Definition{ |
53 |
- Metadata: make(map[digest.Digest]OpMetadata, 0), |
|
58 |
+ Metadata: make(map[digest.Digest]pb.OpMetadata, 0), |
|
54 | 59 |
} |
55 | 60 |
if s.Output() == nil { |
56 | 61 |
return def, nil |
57 | 62 |
} |
58 |
- def, err := marshal(s.Output().Vertex(), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, md) |
|
63 |
+ |
|
64 |
+ defaultPlatform := platforms.Normalize(platforms.DefaultSpec()) |
|
65 |
+ c := &Constraints{ |
|
66 |
+ Platform: &defaultPlatform, |
|
67 |
+ } |
|
68 |
+ for _, o := range append(s.opts, co...) { |
|
69 |
+ o.SetConstraintsOption(c) |
|
70 |
+ } |
|
71 |
+ |
|
72 |
+ def, err := marshal(s.Output().Vertex(), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, c) |
|
59 | 73 |
if err != nil { |
60 | 74 |
return def, err |
61 | 75 |
} |
62 |
- inp, err := s.Output().ToInput() |
|
76 |
+ inp, err := s.Output().ToInput(c) |
|
63 | 77 |
if err != nil { |
64 | 78 |
return def, err |
65 | 79 |
} |
... | ... |
@@ -72,29 +101,25 @@ func (s State) Marshal(md ...MetadataOpt) (*Definition, error) { |
72 | 72 |
return def, nil |
73 | 73 |
} |
74 | 74 |
|
75 |
-func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, md []MetadataOpt) (*Definition, error) { |
|
75 |
+func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, c *Constraints) (*Definition, error) { |
|
76 | 76 |
if _, ok := vertexCache[v]; ok { |
77 | 77 |
return def, nil |
78 | 78 |
} |
79 | 79 |
for _, inp := range v.Inputs() { |
80 | 80 |
var err error |
81 |
- def, err = marshal(inp.Vertex(), def, cache, vertexCache, md) |
|
81 |
+ def, err = marshal(inp.Vertex(), def, cache, vertexCache, c) |
|
82 | 82 |
if err != nil { |
83 | 83 |
return def, err |
84 | 84 |
} |
85 | 85 |
} |
86 | 86 |
|
87 |
- dgst, dt, opMeta, err := v.Marshal() |
|
87 |
+ dgst, dt, opMeta, err := v.Marshal(c) |
|
88 | 88 |
if err != nil { |
89 | 89 |
return def, err |
90 | 90 |
} |
91 | 91 |
vertexCache[v] = struct{}{} |
92 | 92 |
if opMeta != nil { |
93 |
- m := mergeMetadata(def.Metadata[dgst], *opMeta) |
|
94 |
- for _, f := range md { |
|
95 |
- f.SetMetadataOption(&m) |
|
96 |
- } |
|
97 |
- def.Metadata[dgst] = m |
|
93 |
+ def.Metadata[dgst] = mergeMetadata(def.Metadata[dgst], *opMeta) |
|
98 | 94 |
} |
99 | 95 |
if _, ok := cache[dgst]; ok { |
100 | 96 |
return def, nil |
... | ... |
@@ -113,14 +138,19 @@ func (s State) Output() Output { |
113 | 113 |
} |
114 | 114 |
|
115 | 115 |
func (s State) WithOutput(o Output) State { |
116 |
- return State{ |
|
116 |
+ s = State{ |
|
117 | 117 |
out: o, |
118 | 118 |
ctx: s.ctx, |
119 | 119 |
} |
120 |
+ s = s.ensurePlatform() |
|
121 |
+ return s |
|
120 | 122 |
} |
121 | 123 |
|
122 | 124 |
func (s State) Run(ro ...RunOption) ExecState { |
123 | 125 |
ei := &ExecInfo{State: s} |
126 |
+ if p := s.GetPlatform(); p != nil { |
|
127 |
+ ei.Constraints.Platform = p |
|
128 |
+ } |
|
124 | 129 |
for _, o := range ro { |
125 | 130 |
o.SetRunOption(ei) |
126 | 131 |
} |
... | ... |
@@ -132,7 +162,7 @@ func (s State) Run(ro ...RunOption) ExecState { |
132 | 132 |
ProxyEnv: ei.ProxyEnv, |
133 | 133 |
} |
134 | 134 |
|
135 |
- exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Metadata()) |
|
135 |
+ exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Constraints) |
|
136 | 136 |
for _, m := range ei.Mounts { |
137 | 137 |
exec.AddMount(m.Target, m.Source, m.Opts...) |
138 | 138 |
} |
... | ... |
@@ -178,6 +208,14 @@ func (s State) User(v string) State { |
178 | 178 |
return user(v)(s) |
179 | 179 |
} |
180 | 180 |
|
181 |
+func (s State) Platform(p specs.Platform) State { |
|
182 |
+ return platform(p)(s) |
|
183 |
+} |
|
184 |
+ |
|
185 |
+func (s State) GetPlatform() *specs.Platform { |
|
186 |
+ return getPlatform(s) |
|
187 |
+} |
|
188 |
+ |
|
181 | 189 |
func (s State) With(so ...StateOption) State { |
182 | 190 |
for _, o := range so { |
183 | 191 |
s = o(s) |
... | ... |
@@ -189,9 +227,10 @@ type output struct { |
189 | 189 |
vertex Vertex |
190 | 190 |
getIndex func() (pb.OutputIndex, error) |
191 | 191 |
err error |
192 |
+ platform *specs.Platform |
|
192 | 193 |
} |
193 | 194 |
|
194 |
-func (o *output) ToInput() (*pb.Input, error) { |
|
195 |
+func (o *output) ToInput(c *Constraints) (*pb.Input, error) { |
|
195 | 196 |
if o.err != nil { |
196 | 197 |
return nil, o.err |
197 | 198 |
} |
... | ... |
@@ -203,7 +242,7 @@ func (o *output) ToInput() (*pb.Input, error) { |
203 | 203 |
return nil, err |
204 | 204 |
} |
205 | 205 |
} |
206 |
- dgst, _, _, err := o.vertex.Marshal() |
|
206 |
+ dgst, _, _, err := o.vertex.Marshal(c) |
|
207 | 207 |
if err != nil { |
208 | 208 |
return nil, err |
209 | 209 |
} |
... | ... |
@@ -214,8 +253,12 @@ func (o *output) Vertex() Vertex { |
214 | 214 |
return o.vertex |
215 | 215 |
} |
216 | 216 |
|
217 |
-type MetadataOpt interface { |
|
218 |
- SetMetadataOption(*OpMetadata) |
|
217 |
+func (o *output) Platform() *specs.Platform { |
|
218 |
+ return o.platform |
|
219 |
+} |
|
220 |
+ |
|
221 |
+type ConstraintsOpt interface { |
|
222 |
+ SetConstraintsOption(*Constraints) |
|
219 | 223 |
RunOption |
220 | 224 |
LocalOption |
221 | 225 |
HTTPOption |
... | ... |
@@ -223,33 +266,33 @@ type MetadataOpt interface { |
223 | 223 |
GitOption |
224 | 224 |
} |
225 | 225 |
|
226 |
-type metadataOptFunc func(m *OpMetadata) |
|
226 |
+type constraintsOptFunc func(m *Constraints) |
|
227 | 227 |
|
228 |
-func (fn metadataOptFunc) SetMetadataOption(m *OpMetadata) { |
|
228 |
+func (fn constraintsOptFunc) SetConstraintsOption(m *Constraints) { |
|
229 | 229 |
fn(m) |
230 | 230 |
} |
231 | 231 |
|
232 |
-func (fn metadataOptFunc) SetRunOption(ei *ExecInfo) { |
|
233 |
- ei.ApplyMetadata(fn) |
|
232 |
+func (fn constraintsOptFunc) SetRunOption(ei *ExecInfo) { |
|
233 |
+ ei.applyConstraints(fn) |
|
234 | 234 |
} |
235 | 235 |
|
236 |
-func (fn metadataOptFunc) SetLocalOption(li *LocalInfo) { |
|
237 |
- li.ApplyMetadata(fn) |
|
236 |
+func (fn constraintsOptFunc) SetLocalOption(li *LocalInfo) { |
|
237 |
+ li.applyConstraints(fn) |
|
238 | 238 |
} |
239 | 239 |
|
240 |
-func (fn metadataOptFunc) SetHTTPOption(hi *HTTPInfo) { |
|
241 |
- hi.ApplyMetadata(fn) |
|
240 |
+func (fn constraintsOptFunc) SetHTTPOption(hi *HTTPInfo) { |
|
241 |
+ hi.applyConstraints(fn) |
|
242 | 242 |
} |
243 | 243 |
|
244 |
-func (fn metadataOptFunc) SetImageOption(ii *ImageInfo) { |
|
245 |
- ii.ApplyMetadata(fn) |
|
244 |
+func (fn constraintsOptFunc) SetImageOption(ii *ImageInfo) { |
|
245 |
+ ii.applyConstraints(fn) |
|
246 | 246 |
} |
247 | 247 |
|
248 |
-func (fn metadataOptFunc) SetGitOption(gi *GitInfo) { |
|
249 |
- gi.ApplyMetadata(fn) |
|
248 |
+func (fn constraintsOptFunc) SetGitOption(gi *GitInfo) { |
|
249 |
+ gi.applyConstraints(fn) |
|
250 | 250 |
} |
251 | 251 |
|
252 |
-func mergeMetadata(m1, m2 OpMetadata) OpMetadata { |
|
252 |
+func mergeMetadata(m1, m2 pb.OpMetadata) pb.OpMetadata { |
|
253 | 253 |
if m2.IgnoreCache { |
254 | 254 |
m1.IgnoreCache = true |
255 | 255 |
} |
... | ... |
@@ -268,49 +311,77 @@ func mergeMetadata(m1, m2 OpMetadata) OpMetadata { |
268 | 268 |
return m1 |
269 | 269 |
} |
270 | 270 |
|
271 |
-var IgnoreCache = metadataOptFunc(func(md *OpMetadata) { |
|
272 |
- md.IgnoreCache = true |
|
271 |
+var IgnoreCache = constraintsOptFunc(func(c *Constraints) { |
|
272 |
+ c.Metadata.IgnoreCache = true |
|
273 | 273 |
}) |
274 | 274 |
|
275 |
-func WithDescription(m map[string]string) MetadataOpt { |
|
276 |
- return metadataOptFunc(func(md *OpMetadata) { |
|
277 |
- md.Description = m |
|
275 |
+func WithDescription(m map[string]string) ConstraintsOpt { |
|
276 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
277 |
+ c.Metadata.Description = m |
|
278 | 278 |
}) |
279 | 279 |
} |
280 | 280 |
|
281 | 281 |
// WithExportCache forces results for this vertex to be exported with the cache |
282 |
-func WithExportCache() MetadataOpt { |
|
283 |
- return metadataOptFunc(func(md *OpMetadata) { |
|
284 |
- md.ExportCache = &pb.ExportCache{Value: true} |
|
282 |
+func WithExportCache() ConstraintsOpt { |
|
283 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
284 |
+ c.Metadata.ExportCache = &pb.ExportCache{Value: true} |
|
285 | 285 |
}) |
286 | 286 |
} |
287 | 287 |
|
288 | 288 |
// WithoutExportCache sets results for this vertex to be not exported with |
289 | 289 |
// the cache |
290 |
-func WithoutExportCache() MetadataOpt { |
|
291 |
- return metadataOptFunc(func(md *OpMetadata) { |
|
290 |
+func WithoutExportCache() ConstraintsOpt { |
|
291 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
292 | 292 |
// ExportCache with value false means to disable exporting |
293 |
- md.ExportCache = &pb.ExportCache{Value: false} |
|
293 |
+ c.Metadata.ExportCache = &pb.ExportCache{Value: false} |
|
294 | 294 |
}) |
295 | 295 |
} |
296 | 296 |
|
297 | 297 |
// WithoutDefaultExportCache resets the cache export for the vertex to use |
298 | 298 |
// the default defined by the build configuration. |
299 |
-func WithoutDefaultExportCache() MetadataOpt { |
|
300 |
- return metadataOptFunc(func(md *OpMetadata) { |
|
299 |
+func WithoutDefaultExportCache() ConstraintsOpt { |
|
300 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
301 | 301 |
// nil means no vertex based config has been set |
302 |
- md.ExportCache = nil |
|
302 |
+ c.Metadata.ExportCache = nil |
|
303 | 303 |
}) |
304 | 304 |
} |
305 | 305 |
|
306 |
-type opMetaWrapper struct { |
|
307 |
- OpMetadata |
|
306 |
+type constraintsWrapper struct { |
|
307 |
+ Constraints |
|
308 |
+} |
|
309 |
+ |
|
310 |
+func (cw *constraintsWrapper) applyConstraints(f func(c *Constraints)) { |
|
311 |
+ f(&cw.Constraints) |
|
308 | 312 |
} |
309 | 313 |
|
310 |
-func (mw *opMetaWrapper) ApplyMetadata(f func(m *OpMetadata)) { |
|
311 |
- f(&mw.OpMetadata) |
|
314 |
+type Constraints struct { |
|
315 |
+ Platform *specs.Platform |
|
316 |
+ WorkerConstraints []string |
|
317 |
+ Metadata pb.OpMetadata |
|
312 | 318 |
} |
313 | 319 |
|
314 |
-func (mw *opMetaWrapper) Metadata() OpMetadata { |
|
315 |
- return mw.OpMetadata |
|
320 |
+func Platform(p specs.Platform) ConstraintsOpt { |
|
321 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
322 |
+ c.Platform = &p |
|
323 |
+ }) |
|
324 |
+} |
|
325 |
+ |
|
326 |
+var ( |
|
327 |
+ LinuxAmd64 = Platform(specs.Platform{OS: "linux", Architecture: "amd64"}) |
|
328 |
+ LinuxArmhf = Platform(specs.Platform{OS: "linux", Architecture: "arm", Variant: "v7"}) |
|
329 |
+ LinuxArm = LinuxArmhf |
|
330 |
+ LinuxArmel = Platform(specs.Platform{OS: "linux", Architecture: "arm", Variant: "v6"}) |
|
331 |
+ LinuxArm64 = Platform(specs.Platform{OS: "linux", Architecture: "arm64"}) |
|
332 |
+ LinuxS390x = Platform(specs.Platform{OS: "linux", Architecture: "s390x"}) |
|
333 |
+ LinuxPpc64le = Platform(specs.Platform{OS: "linux", Architecture: "ppc64le"}) |
|
334 |
+ Darwin = Platform(specs.Platform{OS: "darwin", Architecture: "amd64"}) |
|
335 |
+ Windows = Platform(specs.Platform{OS: "windows", Architecture: "amd64"}) |
|
336 |
+) |
|
337 |
+ |
|
338 |
+func Require(filters ...string) ConstraintsOpt { |
|
339 |
+ return constraintsOptFunc(func(c *Constraints) { |
|
340 |
+ for _, f := range filters { |
|
341 |
+ c.WorkerConstraints = append(c.WorkerConstraints, f) |
|
342 |
+ } |
|
343 |
+ }) |
|
316 | 344 |
} |
... | ... |
@@ -4,12 +4,15 @@ import ( |
4 | 4 |
"context" |
5 | 5 |
|
6 | 6 |
controlapi "github.com/moby/buildkit/api/services/control" |
7 |
+ "github.com/moby/buildkit/solver/pb" |
|
8 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
7 | 9 |
"github.com/pkg/errors" |
8 | 10 |
) |
9 | 11 |
|
10 | 12 |
type WorkerInfo struct { |
11 |
- ID string |
|
12 |
- Labels map[string]string |
|
13 |
+ ID string |
|
14 |
+ Labels map[string]string |
|
15 |
+ Platforms []specs.Platform |
|
13 | 16 |
} |
14 | 17 |
|
15 | 18 |
func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([]*WorkerInfo, error) { |
... | ... |
@@ -28,8 +31,9 @@ func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([] |
28 | 28 |
|
29 | 29 |
for _, w := range resp.Record { |
30 | 30 |
wi = append(wi, &WorkerInfo{ |
31 |
- ID: w.ID, |
|
32 |
- Labels: w.Labels, |
|
31 |
+ ID: w.ID, |
|
32 |
+ Labels: w.Labels, |
|
33 |
+ Platforms: toClientPlatforms(w.Platforms), |
|
33 | 34 |
}) |
34 | 35 |
} |
35 | 36 |
|
... | ... |
@@ -47,3 +51,17 @@ func WithWorkerFilter(f []string) ListWorkersOption { |
47 | 47 |
wi.Filter = f |
48 | 48 |
} |
49 | 49 |
} |
50 |
+ |
|
51 |
+func toClientPlatforms(p []pb.Platform) []specs.Platform { |
|
52 |
+ out := make([]specs.Platform, 0, len(p)) |
|
53 |
+ for _, pp := range p { |
|
54 |
+ out = append(out, specs.Platform{ |
|
55 |
+ OS: pp.OS, |
|
56 |
+ Architecture: pp.Architecture, |
|
57 |
+ Variant: pp.Variant, |
|
58 |
+ OSVersion: pp.OSVersion, |
|
59 |
+ OSFeatures: pp.OSFeatures, |
|
60 |
+ }) |
|
61 |
+ } |
|
62 |
+ return out |
|
63 |
+} |
... | ... |
@@ -13,7 +13,9 @@ import ( |
13 | 13 |
"github.com/moby/buildkit/session/grpchijack" |
14 | 14 |
"github.com/moby/buildkit/solver" |
15 | 15 |
"github.com/moby/buildkit/solver/llbsolver" |
16 |
+ "github.com/moby/buildkit/solver/pb" |
|
16 | 17 |
"github.com/moby/buildkit/worker" |
18 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
17 | 19 |
"github.com/pkg/errors" |
18 | 20 |
"github.com/sirupsen/logrus" |
19 | 21 |
"golang.org/x/sync/errgroup" |
... | ... |
@@ -35,7 +37,10 @@ type Controller struct { // TODO: ControlService |
35 | 35 |
} |
36 | 36 |
|
37 | 37 |
func NewController(opt Opt) (*Controller, error) { |
38 |
- solver := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter) |
|
38 |
+ solver, err := llbsolver.New(opt.WorkerController, opt.Frontends, opt.CacheKeyStorage, opt.CacheImporter) |
|
39 |
+ if err != nil { |
|
40 |
+ return nil, errors.Wrap(err, "failed to create solver") |
|
41 |
+ } |
|
39 | 42 |
|
40 | 43 |
c := &Controller{ |
41 | 44 |
opt: opt, |
... | ... |
@@ -265,8 +270,9 @@ func (c *Controller) ListWorkers(ctx context.Context, r *controlapi.ListWorkersR |
265 | 265 |
} |
266 | 266 |
for _, w := range workers { |
267 | 267 |
resp.Record = append(resp.Record, &controlapi.WorkerRecord{ |
268 |
- ID: w.ID(), |
|
269 |
- Labels: w.Labels(), |
|
268 |
+ ID: w.ID(), |
|
269 |
+ Labels: w.Labels(), |
|
270 |
+ Platforms: toPBPlatforms(w.Platforms()), |
|
270 | 271 |
}) |
271 | 272 |
} |
272 | 273 |
return resp, nil |
... | ... |
@@ -290,3 +296,17 @@ func parseCacheExporterOpt(opt map[string]string) solver.CacheExportMode { |
290 | 290 |
} |
291 | 291 |
return solver.CacheExportModeMin |
292 | 292 |
} |
293 |
+ |
|
294 |
+func toPBPlatforms(p []specs.Platform) []pb.Platform { |
|
295 |
+ out := make([]pb.Platform, 0, len(p)) |
|
296 |
+ for _, pp := range p { |
|
297 |
+ out = append(out, pb.Platform{ |
|
298 |
+ OS: pp.OS, |
|
299 |
+ Architecture: pp.Architecture, |
|
300 |
+ Variant: pp.Variant, |
|
301 |
+ OSVersion: pp.OSVersion, |
|
302 |
+ OSFeatures: pp.OSFeatures, |
|
303 |
+ }) |
|
304 |
+ } |
|
305 |
+ return out |
|
306 |
+} |
... | ... |
@@ -8,10 +8,12 @@ import ( |
8 | 8 |
"regexp" |
9 | 9 |
"strings" |
10 | 10 |
|
11 |
+ "github.com/containerd/containerd/platforms" |
|
11 | 12 |
"github.com/docker/docker/builder/dockerignore" |
12 | 13 |
"github.com/moby/buildkit/client/llb" |
13 | 14 |
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb" |
14 | 15 |
"github.com/moby/buildkit/frontend/gateway/client" |
16 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
15 | 17 |
"github.com/pkg/errors" |
16 | 18 |
"golang.org/x/sync/errgroup" |
17 | 19 |
) |
... | ... |
@@ -28,14 +30,26 @@ const ( |
28 | 28 |
buildArgPrefix = "build-arg:" |
29 | 29 |
labelPrefix = "label:" |
30 | 30 |
keyNoCache = "no-cache" |
31 |
+ keyTargetPlatform = "platform" |
|
31 | 32 |
) |
32 | 33 |
|
33 | 34 |
var httpPrefix = regexp.MustCompile("^https?://") |
34 |
-var gitUrlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$") |
|
35 |
+var gitUrlPathWithFragmentSuffix = regexp.MustCompile("\\.git(?:#.+)?$") |
|
35 | 36 |
|
36 | 37 |
func Build(ctx context.Context, c client.Client) error { |
37 | 38 |
opts := c.Opts() |
38 | 39 |
|
40 |
+ // TODO: read buildPlatforms from workers |
|
41 |
+ buildPlatforms := []specs.Platform{platforms.DefaultSpec()} |
|
42 |
+ targetPlatform := platforms.DefaultSpec() |
|
43 |
+ if v := opts[keyTargetPlatform]; v != "" { |
|
44 |
+ var err error |
|
45 |
+ targetPlatform, err = platforms.Parse(v) |
|
46 |
+ if err != nil { |
|
47 |
+ return errors.Wrapf(err, "failed to parse target platform %s", v) |
|
48 |
+ } |
|
49 |
+ } |
|
50 |
+ |
|
39 | 51 |
filename := opts[keyFilename] |
40 | 52 |
if filename == "" { |
41 | 53 |
filename = defaultDockerfileName |
... | ... |
@@ -166,14 +180,16 @@ func Build(ctx context.Context, c client.Client) error { |
166 | 166 |
} |
167 | 167 |
|
168 | 168 |
st, img, err := dockerfile2llb.Dockerfile2LLB(ctx, dtDockerfile, dockerfile2llb.ConvertOpt{ |
169 |
- Target: opts[keyTarget], |
|
170 |
- MetaResolver: c, |
|
171 |
- BuildArgs: filter(opts, buildArgPrefix), |
|
172 |
- Labels: filter(opts, labelPrefix), |
|
173 |
- SessionID: c.SessionID(), |
|
174 |
- BuildContext: buildContext, |
|
175 |
- Excludes: excludes, |
|
176 |
- IgnoreCache: ignoreCache, |
|
169 |
+ Target: opts[keyTarget], |
|
170 |
+ MetaResolver: c, |
|
171 |
+ BuildArgs: filter(opts, buildArgPrefix), |
|
172 |
+ Labels: filter(opts, labelPrefix), |
|
173 |
+ SessionID: c.SessionID(), |
|
174 |
+ BuildContext: buildContext, |
|
175 |
+ Excludes: excludes, |
|
176 |
+ IgnoreCache: ignoreCache, |
|
177 |
+ TargetPlatform: &targetPlatform, |
|
178 |
+ BuildPlatforms: buildPlatforms, |
|
177 | 179 |
}) |
178 | 180 |
|
179 | 181 |
if err != nil { |
... | ... |
@@ -12,6 +12,7 @@ import ( |
12 | 12 |
"strconv" |
13 | 13 |
"strings" |
14 | 14 |
|
15 |
+ "github.com/containerd/containerd/platforms" |
|
15 | 16 |
"github.com/docker/distribution/reference" |
16 | 17 |
"github.com/docker/docker/pkg/signal" |
17 | 18 |
"github.com/docker/go-connections/nat" |
... | ... |
@@ -20,7 +21,7 @@ import ( |
20 | 20 |
"github.com/moby/buildkit/frontend/dockerfile/instructions" |
21 | 21 |
"github.com/moby/buildkit/frontend/dockerfile/parser" |
22 | 22 |
"github.com/moby/buildkit/frontend/dockerfile/shell" |
23 |
- ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
23 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
24 | 24 |
"github.com/pkg/errors" |
25 | 25 |
"golang.org/x/sync/errgroup" |
26 | 26 |
) |
... | ... |
@@ -30,7 +31,7 @@ const ( |
30 | 30 |
localNameContext = "context" |
31 | 31 |
historyComment = "buildkit.dockerfile.v0" |
32 | 32 |
|
33 |
- CopyImage = "tonistiigi/copy:v0.1.3@sha256:87c46e7b413cdd2c2702902b481b390ce263ac9d942253d366f3b1a3c16f96d6" |
|
33 |
+ CopyImage = "tonistiigi/copy:v0.1.3@sha256:e57a3b4d6240f55bac26b655d2cfb751f8b9412d6f7bb1f787e946391fb4b21b" |
|
34 | 34 |
) |
35 | 35 |
|
36 | 36 |
type ConvertOpt struct { |
... | ... |
@@ -46,6 +47,8 @@ type ConvertOpt struct { |
46 | 46 |
IgnoreCache []string |
47 | 47 |
// CacheIDNamespace scopes the IDs for different cache mounts |
48 | 48 |
CacheIDNamespace string |
49 |
+ TargetPlatform *specs.Platform |
|
50 |
+ BuildPlatforms []specs.Platform |
|
49 | 51 |
} |
50 | 52 |
|
51 | 53 |
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, |
53 | 53 |
return nil, nil, errors.Errorf("the Dockerfile cannot be empty") |
54 | 54 |
} |
55 | 55 |
|
56 |
+ if opt.TargetPlatform != nil && opt.BuildPlatforms == nil { |
|
57 |
+ opt.BuildPlatforms = []specs.Platform{*opt.TargetPlatform} |
|
58 |
+ } |
|
59 |
+ if len(opt.BuildPlatforms) == 0 { |
|
60 |
+ opt.BuildPlatforms = []specs.Platform{platforms.DefaultSpec()} |
|
61 |
+ } |
|
62 |
+ implicitTargetPlatform := false |
|
63 |
+ if opt.TargetPlatform == nil { |
|
64 |
+ implicitTargetPlatform = true |
|
65 |
+ opt.TargetPlatform = &opt.BuildPlatforms[0] |
|
66 |
+ } |
|
67 |
+ |
|
56 | 68 |
dockerfile, err := parser.Parse(bytes.NewReader(dt)) |
57 | 69 |
if err != nil { |
58 | 70 |
return nil, nil, err |
... | ... |
@@ -92,6 +107,20 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, |
92 | 92 |
deps: make(map[*dispatchState]struct{}), |
93 | 93 |
ctxPaths: make(map[string]struct{}), |
94 | 94 |
} |
95 |
+ |
|
96 |
+ if v := st.Platform; v != "" { |
|
97 |
+ v, err := shlex.ProcessWord(v, toEnvList(metaArgs, nil)) |
|
98 |
+ if err != nil { |
|
99 |
+ return nil, nil, errors.Wrapf(err, "failed to process arguments for platform %s", v) |
|
100 |
+ } |
|
101 |
+ |
|
102 |
+ p, err := platforms.Parse(v) |
|
103 |
+ if err != nil { |
|
104 |
+ return nil, nil, errors.Wrapf(err, "failed to parse platform %s", v) |
|
105 |
+ } |
|
106 |
+ ds.platform = &p |
|
107 |
+ } |
|
108 |
+ |
|
95 | 109 |
if d, ok := dispatchStatesByName[st.BaseName]; ok { |
96 | 110 |
ds.base = d |
97 | 111 |
} |
... | ... |
@@ -150,7 +179,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, |
150 | 150 |
if d.base == nil { |
151 | 151 |
if d.stage.BaseName == emptyImageName { |
152 | 152 |
d.state = llb.Scratch() |
153 |
- d.image = emptyImage() |
|
153 |
+ d.image = emptyImage(*opt.TargetPlatform) |
|
154 | 154 |
continue |
155 | 155 |
} |
156 | 156 |
func(i int, d *dispatchState) { |
... | ... |
@@ -159,16 +188,25 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, |
159 | 159 |
if err != nil { |
160 | 160 |
return err |
161 | 161 |
} |
162 |
+ platform := d.platform |
|
163 |
+ if platform == nil { |
|
164 |
+ platform = opt.TargetPlatform |
|
165 |
+ } |
|
162 | 166 |
d.stage.BaseName = reference.TagNameOnly(ref).String() |
163 | 167 |
var isScratch bool |
164 | 168 |
if metaResolver != nil && reachable { |
165 |
- dgst, dt, err := metaResolver.ResolveImageConfig(ctx, d.stage.BaseName) |
|
169 |
+ dgst, dt, err := metaResolver.ResolveImageConfig(ctx, d.stage.BaseName, platform) |
|
166 | 170 |
if err == nil { // handle the error while builder is actually running |
167 | 171 |
var img Image |
168 | 172 |
if err := json.Unmarshal(dt, &img); err != nil { |
169 | 173 |
return err |
170 | 174 |
} |
171 | 175 |
img.Created = nil |
176 |
+ // if there is no explicit target platform, try to match based on image config |
|
177 |
+ if d.platform == nil && implicitTargetPlatform { |
|
178 |
+ p := autoDetectPlatform(img, *platform, opt.BuildPlatforms) |
|
179 |
+ platform = &p |
|
180 |
+ } |
|
172 | 181 |
d.image = img |
173 | 182 |
if dgst != "" { |
174 | 183 |
ref, err = reference.WithDigest(ref, dgst) |
... | ... |
@@ -186,7 +224,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, |
186 | 186 |
if isScratch { |
187 | 187 |
d.state = llb.Scratch() |
188 | 188 |
} else { |
189 |
- d.state = llb.Image(d.stage.BaseName, dfCmd(d.stage.SourceCode)) |
|
189 |
+ d.state = llb.Image(d.stage.BaseName, dfCmd(d.stage.SourceCode), llb.Platform(*platform)) |
|
190 | 190 |
} |
191 | 191 |
return nil |
192 | 192 |
}) |
... | ... |
@@ -242,6 +280,8 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, |
242 | 242 |
buildContext: llb.NewState(buildContext), |
243 | 243 |
proxyEnv: proxyEnv, |
244 | 244 |
cacheIDNamespace: opt.CacheIDNamespace, |
245 |
+ buildPlatforms: opt.BuildPlatforms, |
|
246 |
+ targetPlatform: *opt.TargetPlatform, |
|
245 | 247 |
} |
246 | 248 |
|
247 | 249 |
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, |
280 | 280 |
} |
281 | 281 |
buildContext.Output = bc.Output() |
282 | 282 |
|
283 |
- return &target.state, &target.image, nil |
|
283 |
+ st := target.state.SetMarhalDefaults(llb.Platform(*opt.TargetPlatform)) |
|
284 |
+ |
|
285 |
+ if !implicitTargetPlatform { |
|
286 |
+ target.image.OS = opt.TargetPlatform.OS |
|
287 |
+ target.image.Architecture = opt.TargetPlatform.Architecture |
|
288 |
+ } |
|
289 |
+ |
|
290 |
+ return &st, &target.image, nil |
|
284 | 291 |
} |
285 | 292 |
|
286 | 293 |
func toCommand(ic instructions.Command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) (command, error) { |
... | ... |
@@ -325,6 +372,8 @@ type dispatchOpt struct { |
325 | 325 |
buildContext llb.State |
326 | 326 |
proxyEnv *llb.ProxyEnv |
327 | 327 |
cacheIDNamespace string |
328 |
+ targetPlatform specs.Platform |
|
329 |
+ buildPlatforms []specs.Platform |
|
328 | 330 |
} |
329 | 331 |
|
330 | 332 |
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { |
... | ... |
@@ -348,7 +397,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { |
348 | 348 |
case *instructions.WorkdirCommand: |
349 | 349 |
err = dispatchWorkdir(d, c, true) |
350 | 350 |
case *instructions.AddCommand: |
351 |
- err = dispatchCopy(d, c.SourcesAndDest, opt.buildContext, true, c, "") |
|
351 |
+ err = dispatchCopy(d, c.SourcesAndDest, opt.buildContext, true, c, "", opt) |
|
352 | 352 |
if err == nil { |
353 | 353 |
for _, src := range c.Sources() { |
354 | 354 |
d.ctxPaths[path.Join("/", filepath.ToSlash(src))] = struct{}{} |
... | ... |
@@ -381,7 +430,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { |
381 | 381 |
if len(cmd.sources) != 0 { |
382 | 382 |
l = cmd.sources[0].state |
383 | 383 |
} |
384 |
- err = dispatchCopy(d, c.SourcesAndDest, l, false, c, c.Chown) |
|
384 |
+ err = dispatchCopy(d, c.SourcesAndDest, l, false, c, c.Chown, opt) |
|
385 | 385 |
if err == nil && len(cmd.sources) == 0 { |
386 | 386 |
for _, src := range c.Sources() { |
387 | 387 |
d.ctxPaths[path.Join("/", filepath.ToSlash(src))] = struct{}{} |
... | ... |
@@ -395,6 +444,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { |
395 | 395 |
type dispatchState struct { |
396 | 396 |
state llb.State |
397 | 397 |
image Image |
398 |
+ platform *specs.Platform |
|
398 | 399 |
stage instructions.Stage |
399 | 400 |
base *dispatchState |
400 | 401 |
deps map[*dispatchState]struct{} |
... | ... |
@@ -467,7 +517,11 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE |
467 | 467 |
opt = append(opt, llb.WithProxy(*proxy)) |
468 | 468 |
} |
469 | 469 |
|
470 |
- opt = append(opt, dispatchRunMounts(d, c, sources, dopt)...) |
|
470 |
+ runMounts, err := dispatchRunMounts(d, c, sources, dopt) |
|
471 |
+ if err != nil { |
|
472 |
+ return err |
|
473 |
+ } |
|
474 |
+ opt = append(opt, runMounts...) |
|
471 | 475 |
|
472 | 476 |
d.state = d.state.Run(opt...).Root() |
473 | 477 |
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 |
486 | 486 |
return nil |
487 | 487 |
} |
488 | 488 |
|
489 |
-func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool, cmdToPrint interface{}, chown string) error { |
|
489 |
+func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool, cmdToPrint interface{}, chown string, opt dispatchOpt) error { |
|
490 | 490 |
// TODO: this should use CopyOp instead. Current implementation is inefficient |
491 |
- img := llb.Image(CopyImage) |
|
491 |
+ img := llb.Image(CopyImage, llb.Platform(opt.buildPlatforms[0])) |
|
492 | 492 |
|
493 | 493 |
dest := path.Join(".", pathRelativeToWorkingDir(d.state, c.Dest())) |
494 | 494 |
if c.Dest() == "." || c.Dest()[len(c.Dest())-1] == filepath.Separator { |
... | ... |
@@ -554,12 +608,12 @@ func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState l |
554 | 554 |
args = append(args[:1], append([]string{"--unpack"}, args[1:]...)...) |
555 | 555 |
} |
556 | 556 |
|
557 |
- opt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint)} |
|
557 |
+ runOpt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint)} |
|
558 | 558 |
if d.ignoreCache { |
559 |
- opt = append(opt, llb.IgnoreCache) |
|
559 |
+ runOpt = append(runOpt, llb.IgnoreCache) |
|
560 | 560 |
} |
561 |
- run := img.Run(append(opt, mounts...)...) |
|
562 |
- d.state = run.AddMount("/dest", d.state) |
|
561 |
+ run := img.Run(append(runOpt, mounts...)...) |
|
562 |
+ d.state = run.AddMount("/dest", d.state).Platform(opt.targetPlatform) |
|
563 | 563 |
|
564 | 564 |
return commitToHistory(&d.image, commitMessage.String(), true, &d.state) |
565 | 565 |
} |
... | ... |
@@ -767,7 +821,7 @@ func getArgValue(arg instructions.ArgCommand) string { |
767 | 767 |
return v |
768 | 768 |
} |
769 | 769 |
|
770 |
-func dfCmd(cmd interface{}) llb.MetadataOpt { |
|
770 |
+func dfCmd(cmd interface{}) llb.ConstraintsOpt { |
|
771 | 771 |
// TODO: add fmt.Stringer to instructions.Command to remove interface{} |
772 | 772 |
var cmdStr string |
773 | 773 |
if cmd, ok := cmd.(fmt.Stringer); ok { |
... | ... |
@@ -798,7 +852,7 @@ func commitToHistory(img *Image, msg string, withLayer bool, st *llb.State) erro |
798 | 798 |
msg += " # buildkit" |
799 | 799 |
} |
800 | 800 |
|
801 |
- img.History = append(img.History, ocispec.History{ |
|
801 |
+ img.History = append(img.History, specs.History{ |
|
802 | 802 |
CreatedBy: msg, |
803 | 803 |
Comment: historyComment, |
804 | 804 |
EmptyLayer: !withLayer, |
... | ... |
@@ -930,3 +984,17 @@ func withShell(img Image, args []string) []string { |
930 | 930 |
} |
931 | 931 |
return append(shell, strings.Join(args, " ")) |
932 | 932 |
} |
933 |
+ |
|
934 |
+func autoDetectPlatform(img Image, target specs.Platform, supported []specs.Platform) specs.Platform { |
|
935 |
+ os := img.OS |
|
936 |
+ arch := img.Architecture |
|
937 |
+ if target.OS == os && target.Architecture == arch { |
|
938 |
+ return target |
|
939 |
+ } |
|
940 |
+ for _, p := range supported { |
|
941 |
+ if p.OS == os && p.Architecture == arch { |
|
942 |
+ return p |
|
943 |
+ } |
|
944 |
+ } |
|
945 |
+ return target |
|
946 |
+} |
... | ... |
@@ -11,6 +11,6 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState |
11 | 11 |
return false |
12 | 12 |
} |
13 | 13 |
|
14 |
-func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption { |
|
15 |
- return nil |
|
14 |
+func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) { |
|
15 |
+ return nil, nil |
|
16 | 16 |
} |
... | ... |
@@ -9,6 +9,7 @@ import ( |
9 | 9 |
|
10 | 10 |
"github.com/moby/buildkit/client/llb" |
11 | 11 |
"github.com/moby/buildkit/frontend/dockerfile/instructions" |
12 |
+ "github.com/pkg/errors" |
|
12 | 13 |
) |
13 | 14 |
|
14 | 15 |
func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool { |
... | ... |
@@ -40,7 +41,7 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState |
40 | 40 |
return false |
41 | 41 |
} |
42 | 42 |
|
43 |
-func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption { |
|
43 |
+func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) { |
|
44 | 44 |
var out []llb.RunOption |
45 | 45 |
mounts := instructions.GetMounts(c) |
46 | 46 |
|
... | ... |
@@ -61,14 +62,25 @@ func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []* |
61 | 61 |
mountOpts = append(mountOpts, llb.Readonly) |
62 | 62 |
} |
63 | 63 |
if mount.Type == instructions.MountTypeCache { |
64 |
- mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID)) |
|
64 |
+ sharing := llb.CacheMountShared |
|
65 |
+ if mount.CacheSharing == instructions.MountSharingPrivate { |
|
66 |
+ sharing = llb.CacheMountPrivate |
|
67 |
+ } |
|
68 |
+ if mount.CacheSharing == instructions.MountSharingLocked { |
|
69 |
+ sharing = llb.CacheMountLocked |
|
70 |
+ } |
|
71 |
+ mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID, sharing)) |
|
72 |
+ } |
|
73 |
+ target := path.Join("/", mount.Target) |
|
74 |
+ if target == "/" { |
|
75 |
+ return nil, errors.Errorf("invalid mount target %q", mount.Target) |
|
65 | 76 |
} |
66 | 77 |
if src := path.Join("/", mount.Source); src != "/" { |
67 | 78 |
mountOpts = append(mountOpts, llb.SourcePath(src)) |
68 | 79 |
} |
69 |
- out = append(out, llb.AddMount(path.Join("/", mount.Target), st, mountOpts...)) |
|
80 |
+ out = append(out, llb.AddMount(target, st, mountOpts...)) |
|
70 | 81 |
|
71 | 82 |
d.ctxPaths[path.Join("/", filepath.ToSlash(mount.Source))] = struct{}{} |
72 | 83 |
} |
73 |
- return out |
|
84 |
+ return out, nil |
|
74 | 85 |
} |
... | ... |
@@ -1,12 +1,11 @@ |
1 | 1 |
package dockerfile2llb |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "runtime" |
|
5 | 4 |
"time" |
6 | 5 |
|
7 | 6 |
"github.com/docker/docker/api/types/strslice" |
8 | 7 |
"github.com/moby/buildkit/util/system" |
9 |
- ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
8 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
10 | 9 |
) |
11 | 10 |
|
12 | 11 |
// HealthConfig holds configuration settings for the HEALTHCHECK feature. |
... | ... |
@@ -31,7 +30,7 @@ type HealthConfig struct { |
31 | 31 |
} |
32 | 32 |
|
33 | 33 |
type ImageConfig struct { |
34 |
- ocispec.ImageConfig |
|
34 |
+ specs.ImageConfig |
|
35 | 35 |
|
36 | 36 |
Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy |
37 | 37 |
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific) |
... | ... |
@@ -46,7 +45,7 @@ type ImageConfig struct { |
46 | 46 |
// Image is the JSON structure which describes some basic information about the image. |
47 | 47 |
// This provides the `application/vnd.oci.image.config.v1+json` mediatype when marshalled to JSON. |
48 | 48 |
type Image struct { |
49 |
- ocispec.Image |
|
49 |
+ specs.Image |
|
50 | 50 |
|
51 | 51 |
// Config defines the execution parameters which should be used as a base when running a container using the image. |
52 | 52 |
Config ImageConfig `json:"config,omitempty"` |
... | ... |
@@ -61,11 +60,11 @@ func clone(src Image) Image { |
61 | 61 |
return img |
62 | 62 |
} |
63 | 63 |
|
64 |
-func emptyImage() Image { |
|
64 |
+func emptyImage(platform specs.Platform) Image { |
|
65 | 65 |
img := Image{ |
66 |
- Image: ocispec.Image{ |
|
67 |
- Architecture: runtime.GOARCH, |
|
68 |
- OS: runtime.GOOS, |
|
66 |
+ Image: specs.Image{ |
|
67 |
+ Architecture: platform.Architecture, |
|
68 |
+ OS: platform.OS, |
|
69 | 69 |
}, |
70 | 70 |
} |
71 | 71 |
img.RootFS.Type = "layers" |
... | ... |
@@ -6,7 +6,6 @@ import ( |
6 | 6 |
|
7 | 7 |
"github.com/docker/docker/api/types/container" |
8 | 8 |
"github.com/docker/docker/api/types/strslice" |
9 |
- specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
10 | 9 |
) |
11 | 10 |
|
12 | 11 |
// KeyValuePair represent an arbitrary named value (useful in slice instead of map[string] string to preserve ordering) |
... | ... |
@@ -382,7 +381,7 @@ type Stage struct { |
382 | 382 |
Commands []Command |
383 | 383 |
BaseName string |
384 | 384 |
SourceCode string |
385 |
- Platform specs.Platform |
|
385 |
+ Platform string |
|
386 | 386 |
} |
387 | 387 |
|
388 | 388 |
// AddCommand to the stage |
... | ... |
@@ -20,6 +20,16 @@ var allowedMountTypes = map[string]struct{}{ |
20 | 20 |
MountTypeTmpfs: {}, |
21 | 21 |
} |
22 | 22 |
|
23 |
+const MountSharingShared = "shared" |
|
24 |
+const MountSharingPrivate = "private" |
|
25 |
+const MountSharingLocked = "locked" |
|
26 |
+ |
|
27 |
+var allowedSharingTypes = map[string]struct{}{ |
|
28 |
+ MountSharingShared: {}, |
|
29 |
+ MountSharingPrivate: {}, |
|
30 |
+ MountSharingLocked: {}, |
|
31 |
+} |
|
32 |
+ |
|
23 | 33 |
type mountsKeyT string |
24 | 34 |
|
25 | 35 |
var mountsKey = mountsKeyT("dockerfile/run/mounts") |
... | ... |
@@ -76,12 +86,13 @@ type mountState struct { |
76 | 76 |
} |
77 | 77 |
|
78 | 78 |
type Mount struct { |
79 |
- Type string |
|
80 |
- From string |
|
81 |
- Source string |
|
82 |
- Target string |
|
83 |
- ReadOnly bool |
|
84 |
- CacheID string |
|
79 |
+ Type string |
|
80 |
+ From string |
|
81 |
+ Source string |
|
82 |
+ Target string |
|
83 |
+ ReadOnly bool |
|
84 |
+ CacheID string |
|
85 |
+ CacheSharing string |
|
85 | 86 |
} |
86 | 87 |
|
87 | 88 |
func parseMount(value string) (*Mount, error) { |
... | ... |
@@ -120,7 +131,7 @@ func parseMount(value string) (*Mount, error) { |
120 | 120 |
switch key { |
121 | 121 |
case "type": |
122 | 122 |
if !isValidMountType(strings.ToLower(value)) { |
123 |
- return nil, errors.Errorf("invalid mount type %q", value) |
|
123 |
+ return nil, errors.Errorf("unsupported mount type %q", value) |
|
124 | 124 |
} |
125 | 125 |
m.Type = strings.ToLower(value) |
126 | 126 |
case "from": |
... | ... |
@@ -144,6 +155,11 @@ func parseMount(value string) (*Mount, error) { |
144 | 144 |
roAuto = false |
145 | 145 |
case "id": |
146 | 146 |
m.CacheID = value |
147 |
+ case "sharing": |
|
148 |
+ if _, ok := allowedSharingTypes[strings.ToLower(value)]; !ok { |
|
149 |
+ return nil, errors.Errorf("unsupported sharing value %q", value) |
|
150 |
+ } |
|
151 |
+ m.CacheSharing = strings.ToLower(value) |
|
147 | 152 |
default: |
148 | 153 |
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field) |
149 | 154 |
} |
... | ... |
@@ -157,5 +173,9 @@ func parseMount(value string) (*Mount, error) { |
157 | 157 |
} |
158 | 158 |
} |
159 | 159 |
|
160 |
+ if m.CacheSharing != "" && m.Type != MountTypeCache { |
|
161 |
+ return nil, errors.Errorf("invalid cache sharing set for %v mount", m.Type) |
|
162 |
+ } |
|
163 |
+ |
|
160 | 164 |
return m, nil |
161 | 165 |
} |
... | ... |
@@ -10,7 +10,6 @@ import ( |
10 | 10 |
|
11 | 11 |
"github.com/docker/docker/api/types/container" |
12 | 12 |
"github.com/docker/docker/api/types/strslice" |
13 |
- "github.com/docker/docker/pkg/system" |
|
14 | 13 |
"github.com/moby/buildkit/frontend/dockerfile/command" |
15 | 14 |
"github.com/moby/buildkit/frontend/dockerfile/parser" |
16 | 15 |
"github.com/pkg/errors" |
... | ... |
@@ -279,13 +278,14 @@ func parseFrom(req parseRequest) (*Stage, error) { |
279 | 279 |
if err := req.flags.Parse(); err != nil { |
280 | 280 |
return nil, err |
281 | 281 |
} |
282 |
+ |
|
282 | 283 |
code := strings.TrimSpace(req.original) |
283 | 284 |
return &Stage{ |
284 | 285 |
BaseName: req.args[0], |
285 | 286 |
Name: stageName, |
286 | 287 |
SourceCode: code, |
287 | 288 |
Commands: []Command{}, |
288 |
- Platform: *system.ParsePlatform(flPlatform.Value), |
|
289 |
+ Platform: flPlatform.Value, |
|
289 | 290 |
}, nil |
290 | 291 |
|
291 | 292 |
} |
... | ... |
@@ -9,6 +9,7 @@ import ( |
9 | 9 |
"github.com/moby/buildkit/solver" |
10 | 10 |
"github.com/moby/buildkit/solver/pb" |
11 | 11 |
digest "github.com/opencontainers/go-digest" |
12 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
12 | 13 |
) |
13 | 14 |
|
14 | 15 |
type Frontend interface { |
... | ... |
@@ -17,7 +18,7 @@ type Frontend interface { |
17 | 17 |
|
18 | 18 |
type FrontendLLBBridge interface { |
19 | 19 |
Solve(ctx context.Context, req SolveRequest) (solver.CachedResult, map[string][]byte, error) |
20 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
20 |
+ ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) |
|
21 | 21 |
Exec(ctx context.Context, meta executor.Meta, rootfs cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error |
22 | 22 |
} |
23 | 23 |
|
... | ... |
@@ -5,12 +5,13 @@ import ( |
5 | 5 |
|
6 | 6 |
"github.com/moby/buildkit/solver/pb" |
7 | 7 |
digest "github.com/opencontainers/go-digest" |
8 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
8 | 9 |
) |
9 | 10 |
|
10 | 11 |
// TODO: make this take same options as LLBBridge. Add Return() |
11 | 12 |
type Client interface { |
12 | 13 |
Solve(ctx context.Context, req SolveRequest, exporterAttr map[string][]byte, final bool) (Reference, error) |
13 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
14 |
+ ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) |
|
14 | 15 |
Opts() map[string]string |
15 | 16 |
SessionID() string |
16 | 17 |
} |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"net" |
9 | 9 |
"os" |
10 | 10 |
"strings" |
11 |
+ "sync" |
|
11 | 12 |
"time" |
12 | 13 |
|
13 | 14 |
"github.com/docker/distribution/reference" |
... | ... |
@@ -21,7 +22,7 @@ import ( |
21 | 21 |
"github.com/moby/buildkit/solver" |
22 | 22 |
"github.com/moby/buildkit/util/tracing" |
23 | 23 |
"github.com/moby/buildkit/worker" |
24 |
- ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
24 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
25 | 25 |
"github.com/pkg/errors" |
26 | 26 |
"github.com/sirupsen/logrus" |
27 | 27 |
"golang.org/x/net/http2" |
... | ... |
@@ -62,7 +63,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
62 | 62 |
sid := session.FromContext(ctx) |
63 | 63 |
|
64 | 64 |
_, isDevel := opts[keyDevel] |
65 |
- var img ocispec.Image |
|
65 |
+ var img specs.Image |
|
66 | 66 |
var rootFS cache.ImmutableRef |
67 | 67 |
var readonly bool // TODO: try to switch to read-only by default. |
68 | 68 |
|
... | ... |
@@ -94,7 +95,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
94 | 94 |
return nil, nil, err |
95 | 95 |
} |
96 | 96 |
|
97 |
- dgst, config, err := llbBridge.ResolveImageConfig(ctx, reference.TagNameOnly(sourceRef).String()) |
|
97 |
+ dgst, config, err := llbBridge.ResolveImageConfig(ctx, reference.TagNameOnly(sourceRef).String(), nil) // TODO: |
|
98 | 98 |
if err != nil { |
99 | 99 |
return nil, nil, err |
100 | 100 |
} |
... | ... |
@@ -103,9 +104,11 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
103 | 103 |
return nil, nil, err |
104 | 104 |
} |
105 | 105 |
|
106 |
- sourceRef, err = reference.WithDigest(sourceRef, dgst) |
|
107 |
- if err != nil { |
|
108 |
- return nil, nil, err |
|
106 |
+ if dgst != "" { |
|
107 |
+ sourceRef, err = reference.WithDigest(sourceRef, dgst) |
|
108 |
+ if err != nil { |
|
109 |
+ return nil, nil, err |
|
110 |
+ } |
|
109 | 111 |
} |
110 | 112 |
|
111 | 113 |
src := llb.Image(sourceRef.String()) |
... | ... |
@@ -248,6 +251,7 @@ func (d dummyAddr) String() string { |
248 | 248 |
} |
249 | 249 |
|
250 | 250 |
type llbBridgeForwarder struct { |
251 |
+ mu sync.Mutex |
|
251 | 252 |
callCtx context.Context |
252 | 253 |
llbBridge frontend.FrontendLLBBridge |
253 | 254 |
refs map[string]solver.Result |
... | ... |
@@ -258,7 +262,17 @@ type llbBridgeForwarder struct { |
258 | 258 |
|
259 | 259 |
func (lbf *llbBridgeForwarder) ResolveImageConfig(ctx context.Context, req *pb.ResolveImageConfigRequest) (*pb.ResolveImageConfigResponse, error) { |
260 | 260 |
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx) |
261 |
- dgst, dt, err := lbf.llbBridge.ResolveImageConfig(ctx, req.Ref) |
|
261 |
+ var platform *specs.Platform |
|
262 |
+ if p := req.Platform; p != nil { |
|
263 |
+ platform = &specs.Platform{ |
|
264 |
+ OS: p.OS, |
|
265 |
+ Architecture: p.Architecture, |
|
266 |
+ Variant: p.Variant, |
|
267 |
+ OSVersion: p.OSVersion, |
|
268 |
+ OSFeatures: p.OSFeatures, |
|
269 |
+ } |
|
270 |
+ } |
|
271 |
+ dgst, dt, err := lbf.llbBridge.ResolveImageConfig(ctx, req.Ref, platform) |
|
262 | 272 |
if err != nil { |
263 | 273 |
return nil, err |
264 | 274 |
} |
... | ... |
@@ -292,7 +306,9 @@ func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) |
292 | 292 |
} |
293 | 293 |
|
294 | 294 |
id := identity.NewID() |
295 |
+ lbf.mu.Lock() |
|
295 | 296 |
lbf.refs[id] = ref |
297 |
+ lbf.mu.Unlock() |
|
296 | 298 |
if req.Final { |
297 | 299 |
lbf.lastRef = ref |
298 | 300 |
lbf.exporterAttr = exp |
... | ... |
@@ -304,7 +320,9 @@ func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) |
304 | 304 |
} |
305 | 305 |
func (lbf *llbBridgeForwarder) ReadFile(ctx context.Context, req *pb.ReadFileRequest) (*pb.ReadFileResponse, error) { |
306 | 306 |
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx) |
307 |
+ lbf.mu.Lock() |
|
307 | 308 |
ref, ok := lbf.refs[req.Ref] |
309 |
+ lbf.mu.Unlock() |
|
308 | 310 |
if !ok { |
309 | 311 |
return nil, errors.Errorf("no such ref: %v", req.Ref) |
310 | 312 |
} |
... | ... |
@@ -45,7 +45,8 @@ var _ = math.Inf |
45 | 45 |
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package |
46 | 46 |
|
47 | 47 |
type ResolveImageConfigRequest struct { |
48 |
- Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` |
|
48 |
+ Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` |
|
49 |
+ Platform *pb.Platform `protobuf:"bytes,2,opt,name=Platform" json:"Platform,omitempty"` |
|
49 | 50 |
} |
50 | 51 |
|
51 | 52 |
func (m *ResolveImageConfigRequest) Reset() { *m = ResolveImageConfigRequest{} } |
... | ... |
@@ -60,6 +61,13 @@ func (m *ResolveImageConfigRequest) GetRef() string { |
60 | 60 |
return "" |
61 | 61 |
} |
62 | 62 |
|
63 |
+func (m *ResolveImageConfigRequest) GetPlatform() *pb.Platform { |
|
64 |
+ if m != nil { |
|
65 |
+ return m.Platform |
|
66 |
+ } |
|
67 |
+ return nil |
|
68 |
+} |
|
69 |
+ |
|
63 | 70 |
type ResolveImageConfigResponse struct { |
64 | 71 |
Digest github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=Digest,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"Digest"` |
65 | 72 |
Config []byte `protobuf:"bytes,2,opt,name=Config,proto3" json:"Config,omitempty"` |
... | ... |
@@ -451,6 +459,16 @@ func (m *ResolveImageConfigRequest) MarshalTo(dAtA []byte) (int, error) { |
451 | 451 |
i = encodeVarintGateway(dAtA, i, uint64(len(m.Ref))) |
452 | 452 |
i += copy(dAtA[i:], m.Ref) |
453 | 453 |
} |
454 |
+ if m.Platform != nil { |
|
455 |
+ dAtA[i] = 0x12 |
|
456 |
+ i++ |
|
457 |
+ i = encodeVarintGateway(dAtA, i, uint64(m.Platform.Size())) |
|
458 |
+ n1, err := m.Platform.MarshalTo(dAtA[i:]) |
|
459 |
+ if err != nil { |
|
460 |
+ return 0, err |
|
461 |
+ } |
|
462 |
+ i += n1 |
|
463 |
+ } |
|
454 | 464 |
return i, nil |
455 | 465 |
} |
456 | 466 |
|
... | ... |
@@ -503,11 +521,11 @@ func (m *SolveRequest) MarshalTo(dAtA []byte) (int, error) { |
503 | 503 |
dAtA[i] = 0xa |
504 | 504 |
i++ |
505 | 505 |
i = encodeVarintGateway(dAtA, i, uint64(m.Definition.Size())) |
506 |
- n1, err := m.Definition.MarshalTo(dAtA[i:]) |
|
506 |
+ n2, err := m.Definition.MarshalTo(dAtA[i:]) |
|
507 | 507 |
if err != nil { |
508 | 508 |
return 0, err |
509 | 509 |
} |
510 |
- i += n1 |
|
510 |
+ i += n2 |
|
511 | 511 |
} |
512 | 512 |
if len(m.Frontend) > 0 { |
513 | 513 |
dAtA[i] = 0x12 |
... | ... |
@@ -627,11 +645,11 @@ func (m *ReadFileRequest) MarshalTo(dAtA []byte) (int, error) { |
627 | 627 |
dAtA[i] = 0x1a |
628 | 628 |
i++ |
629 | 629 |
i = encodeVarintGateway(dAtA, i, uint64(m.Range.Size())) |
630 |
- n2, err := m.Range.MarshalTo(dAtA[i:]) |
|
630 |
+ n3, err := m.Range.MarshalTo(dAtA[i:]) |
|
631 | 631 |
if err != nil { |
632 | 632 |
return 0, err |
633 | 633 |
} |
634 |
- i += n2 |
|
634 |
+ i += n3 |
|
635 | 635 |
} |
636 | 636 |
return i, nil |
637 | 637 |
} |
... | ... |
@@ -740,6 +758,10 @@ func (m *ResolveImageConfigRequest) Size() (n int) { |
740 | 740 |
if l > 0 { |
741 | 741 |
n += 1 + l + sovGateway(uint64(l)) |
742 | 742 |
} |
743 |
+ if m.Platform != nil { |
|
744 |
+ l = m.Platform.Size() |
|
745 |
+ n += 1 + l + sovGateway(uint64(l)) |
|
746 |
+ } |
|
743 | 747 |
return n |
744 | 748 |
} |
745 | 749 |
|
... | ... |
@@ -929,6 +951,39 @@ func (m *ResolveImageConfigRequest) Unmarshal(dAtA []byte) error { |
929 | 929 |
} |
930 | 930 |
m.Ref = string(dAtA[iNdEx:postIndex]) |
931 | 931 |
iNdEx = postIndex |
932 |
+ case 2: |
|
933 |
+ if wireType != 2 { |
|
934 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType) |
|
935 |
+ } |
|
936 |
+ var msglen int |
|
937 |
+ for shift := uint(0); ; shift += 7 { |
|
938 |
+ if shift >= 64 { |
|
939 |
+ return ErrIntOverflowGateway |
|
940 |
+ } |
|
941 |
+ if iNdEx >= l { |
|
942 |
+ return io.ErrUnexpectedEOF |
|
943 |
+ } |
|
944 |
+ b := dAtA[iNdEx] |
|
945 |
+ iNdEx++ |
|
946 |
+ msglen |= (int(b) & 0x7F) << shift |
|
947 |
+ if b < 0x80 { |
|
948 |
+ break |
|
949 |
+ } |
|
950 |
+ } |
|
951 |
+ if msglen < 0 { |
|
952 |
+ return ErrInvalidLengthGateway |
|
953 |
+ } |
|
954 |
+ postIndex := iNdEx + msglen |
|
955 |
+ if postIndex > l { |
|
956 |
+ return io.ErrUnexpectedEOF |
|
957 |
+ } |
|
958 |
+ if m.Platform == nil { |
|
959 |
+ m.Platform = &pb.Platform{} |
|
960 |
+ } |
|
961 |
+ if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { |
|
962 |
+ return err |
|
963 |
+ } |
|
964 |
+ iNdEx = postIndex |
|
932 | 965 |
default: |
933 | 966 |
iNdEx = preIndex |
934 | 967 |
skippy, err := skipGateway(dAtA[iNdEx:]) |
... | ... |
@@ -1998,45 +2053,46 @@ var ( |
1998 | 1998 |
func init() { proto.RegisterFile("gateway.proto", fileDescriptorGateway) } |
1999 | 1999 |
|
2000 | 2000 |
var fileDescriptorGateway = []byte{ |
2001 |
- // 629 bytes of a gzipped FileDescriptorProto |
|
2002 |
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x40, |
|
2003 |
- 0x10, 0xad, 0x63, 0x40, 0x64, 0x12, 0x3e, 0xb4, 0xaa, 0x2a, 0xe3, 0x03, 0x44, 0x56, 0x45, 0x2d, |
|
2004 |
- 0x5a, 0x6c, 0x35, 0x6d, 0x25, 0x44, 0xa5, 0x4a, 0x0d, 0x1f, 0x12, 0x15, 0x12, 0x68, 0x7b, 0xa8, |
|
2005 |
- 0xc4, 0xcd, 0x4e, 0xc6, 0x66, 0x45, 0xb2, 0xeb, 0xda, 0x1b, 0xda, 0xa8, 0x97, 0xf6, 0xe7, 0xf4, |
|
2006 |
- 0x9f, 0x70, 0xec, 0x99, 0x03, 0xaa, 0xf8, 0x25, 0x95, 0xd7, 0xeb, 0x60, 0x48, 0x49, 0xe9, 0x6d, |
|
2007 |
- 0xdf, 0x78, 0xe6, 0xed, 0x9b, 0x79, 0xb3, 0x86, 0x85, 0x38, 0x90, 0xf8, 0x25, 0x18, 0x79, 0x49, |
|
2008 |
- 0x2a, 0xa4, 0x20, 0x2b, 0x03, 0x11, 0x8e, 0xbc, 0x70, 0xc8, 0xfa, 0xbd, 0x33, 0x26, 0xbd, 0xf3, |
|
2009 |
- 0x97, 0x5e, 0x94, 0x0a, 0x2e, 0x91, 0xf7, 0xec, 0xcd, 0x98, 0xc9, 0xd3, 0x61, 0xe8, 0x75, 0xc5, |
|
2010 |
- 0xc0, 0x8f, 0x45, 0x2c, 0x7c, 0x55, 0x11, 0x0e, 0x23, 0x85, 0x14, 0x50, 0xa7, 0x82, 0xc9, 0x7e, |
|
2011 |
- 0x51, 0x49, 0xcf, 0x49, 0xfd, 0x92, 0xd4, 0xcf, 0x44, 0xff, 0x1c, 0x53, 0x3f, 0x09, 0x7d, 0x91, |
|
2012 |
- 0x64, 0x45, 0xb6, 0xb3, 0x09, 0x2b, 0x14, 0xd5, 0x87, 0x83, 0x41, 0x10, 0xe3, 0x8e, 0xe0, 0x11, |
|
2013 |
- 0x8b, 0x29, 0x7e, 0x1e, 0x62, 0x26, 0xc9, 0x32, 0x98, 0x14, 0x23, 0xcb, 0x68, 0x19, 0x6e, 0x9d, |
|
2014 |
- 0xe6, 0x47, 0xe7, 0xbb, 0x01, 0xf6, 0xdf, 0xf2, 0xb3, 0x44, 0xf0, 0x0c, 0xc9, 0x07, 0x98, 0xdb, |
|
2015 |
- 0x65, 0x31, 0x66, 0xb2, 0xa8, 0xe9, 0xb4, 0x2f, 0xae, 0xd6, 0x1e, 0x5d, 0x5e, 0xad, 0x6d, 0x54, |
|
2016 |
- 0x34, 0x89, 0x04, 0x79, 0x57, 0x70, 0x19, 0x30, 0x8e, 0x69, 0xe6, 0xc7, 0x62, 0xb3, 0xa7, 0x4a, |
|
2017 |
- 0xbc, 0xa2, 0x92, 0x6a, 0x06, 0xf2, 0x04, 0xe6, 0x0a, 0x76, 0xab, 0xd6, 0x32, 0xdc, 0x26, 0xd5, |
|
2018 |
- 0xc8, 0xb9, 0xac, 0x41, 0xf3, 0x63, 0x2e, 0xa0, 0x54, 0xe9, 0x01, 0xec, 0x62, 0xc4, 0x38, 0x93, |
|
2019 |
- 0x4c, 0x70, 0x75, 0x71, 0xa3, 0xbd, 0xe8, 0x25, 0xa1, 0x77, 0x13, 0xa5, 0x95, 0x0c, 0x62, 0xc3, |
|
2020 |
- 0xfc, 0xbe, 0x9e, 0xad, 0xa2, 0xae, 0xd3, 0x31, 0x26, 0x27, 0xd0, 0x28, 0xcf, 0x47, 0x89, 0xb4, |
|
2021 |
- 0xcc, 0x96, 0xe9, 0x36, 0xda, 0x5b, 0xde, 0xbd, 0xe6, 0x78, 0x55, 0x25, 0x5e, 0xa5, 0x74, 0x8f, |
|
2022 |
- 0xcb, 0x74, 0x44, 0xab, 0x64, 0xc4, 0x85, 0xa5, 0x83, 0x41, 0x22, 0x52, 0xb9, 0x13, 0x74, 0x4f, |
|
2023 |
- 0x91, 0x62, 0x94, 0x59, 0x33, 0x2d, 0xd3, 0xad, 0xd3, 0xbb, 0x61, 0xf2, 0x18, 0x66, 0xf7, 0x19, |
|
2024 |
- 0x0f, 0xfa, 0x16, 0xb4, 0x0c, 0x77, 0x9e, 0x16, 0x80, 0x38, 0xd0, 0xdc, 0xfb, 0x9a, 0x27, 0x62, |
|
2025 |
- 0xfa, 0x5e, 0xca, 0xd4, 0x6a, 0xa8, 0xb1, 0xdc, 0x8a, 0xd9, 0xef, 0x60, 0xf9, 0xae, 0x88, 0xdc, |
|
2026 |
- 0xc5, 0x33, 0x1c, 0x95, 0x2e, 0x9e, 0xe1, 0x28, 0xe7, 0x3f, 0x0f, 0xfa, 0x43, 0xd4, 0xed, 0x17, |
|
2027 |
- 0x60, 0xbb, 0xb6, 0x65, 0x38, 0x7b, 0xb0, 0xa0, 0x3b, 0xd2, 0x8e, 0x4e, 0xac, 0xc0, 0x84, 0x8c, |
|
2028 |
- 0xda, 0xa4, 0x0c, 0xe7, 0x1b, 0x2c, 0x51, 0x0c, 0x7a, 0xfb, 0xac, 0x8f, 0xf7, 0xee, 0x92, 0xf2, |
|
2029 |
- 0x81, 0xf5, 0xf1, 0x38, 0x90, 0xa7, 0x63, 0x1f, 0x34, 0x26, 0xdb, 0x30, 0x4b, 0x03, 0x1e, 0xa3, |
|
2030 |
- 0x65, 0x2a, 0x3b, 0x9f, 0x4e, 0x71, 0x40, 0x5d, 0x92, 0xe7, 0xd2, 0xa2, 0xc4, 0x79, 0x0b, 0xf5, |
|
2031 |
- 0x71, 0x2c, 0xdf, 0xa2, 0xa3, 0x28, 0xca, 0xb0, 0xd8, 0x48, 0x93, 0x6a, 0x94, 0xc7, 0x0f, 0x91, |
|
2032 |
- 0xc7, 0xfa, 0x6a, 0x93, 0x6a, 0xe4, 0xac, 0xc3, 0xf2, 0x8d, 0x72, 0x3d, 0x03, 0x02, 0x33, 0xbb, |
|
2033 |
- 0x81, 0x0c, 0x14, 0x43, 0x93, 0xaa, 0xb3, 0xb3, 0x00, 0x8d, 0x63, 0xc6, 0xcb, 0x97, 0xe2, 0x2c, |
|
2034 |
- 0x42, 0xf3, 0x58, 0xf0, 0xf1, 0x43, 0x68, 0xff, 0x34, 0xa1, 0x7e, 0x78, 0xd8, 0xe9, 0xa4, 0xac, |
|
2035 |
- 0x17, 0x23, 0xf9, 0x61, 0x00, 0x99, 0x7c, 0x35, 0xe4, 0xf5, 0x94, 0xae, 0xee, 0x7d, 0x94, 0xf6, |
|
2036 |
- 0x9b, 0xff, 0xac, 0xd2, 0x4d, 0x9c, 0xc0, 0xac, 0x72, 0x96, 0x3c, 0x7b, 0xe0, 0x36, 0xdb, 0xee, |
|
2037 |
- 0xbf, 0x13, 0x35, 0x77, 0x17, 0xe6, 0xcb, 0xa1, 0x91, 0x8d, 0xa9, 0xf2, 0x6e, 0xed, 0x84, 0xfd, |
|
2038 |
- 0xfc, 0x41, 0xb9, 0xfa, 0x92, 0x4f, 0x30, 0x93, 0x4f, 0x9c, 0xac, 0x4f, 0x29, 0xaa, 0x58, 0x62, |
|
2039 |
- 0x4f, 0xeb, 0xb3, 0xea, 0x55, 0xa7, 0x79, 0x71, 0xbd, 0x6a, 0xfc, 0xba, 0x5e, 0x35, 0x7e, 0x5f, |
|
2040 |
- 0xaf, 0x1a, 0xe1, 0x9c, 0xfa, 0x2f, 0xbe, 0xfa, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x21, 0xd1, |
|
2041 |
- 0x98, 0xa0, 0x05, 0x00, 0x00, |
|
2001 |
+ // 652 bytes of a gzipped FileDescriptorProto |
|
2002 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x4a, |
|
2003 |
+ 0x14, 0x7d, 0x8e, 0x01, 0x25, 0x37, 0xe6, 0x43, 0xa3, 0xa7, 0x27, 0xe3, 0x05, 0x44, 0xd6, 0x13, |
|
2004 |
+ 0xcf, 0xe2, 0x15, 0x5b, 0x4d, 0x5b, 0x09, 0x51, 0xa9, 0x52, 0xc3, 0x87, 0x44, 0x85, 0x44, 0x34, |
|
2005 |
+ 0x5d, 0x20, 0xb1, 0x1b, 0x27, 0x63, 0x33, 0xc2, 0x99, 0x71, 0xed, 0x09, 0x6d, 0xd4, 0x4d, 0xfb, |
|
2006 |
+ 0x73, 0xfa, 0x4f, 0x58, 0x76, 0xcd, 0x02, 0x55, 0xfc, 0x92, 0xca, 0xe3, 0x71, 0x30, 0x50, 0x52, |
|
2007 |
+ 0xba, 0x9b, 0x73, 0x7d, 0xef, 0x99, 0x73, 0xe7, 0xdc, 0x6b, 0x58, 0x8c, 0x89, 0xa4, 0x1f, 0xc9, |
|
2008 |
+ 0xc4, 0x4f, 0x33, 0x21, 0x05, 0x5a, 0x1d, 0x89, 0x70, 0xe2, 0x87, 0x63, 0x96, 0x0c, 0xcf, 0x99, |
|
2009 |
+ 0xf4, 0x2f, 0x9e, 0xfb, 0x51, 0x26, 0xb8, 0xa4, 0x7c, 0xe8, 0x6c, 0xc5, 0x4c, 0x9e, 0x8d, 0x43, |
|
2010 |
+ 0x7f, 0x20, 0x46, 0x41, 0x2c, 0x62, 0x11, 0xa8, 0x8a, 0x70, 0x1c, 0x29, 0xa4, 0x80, 0x3a, 0x95, |
|
2011 |
+ 0x4c, 0xce, 0xb3, 0x5a, 0x7a, 0x41, 0x1a, 0x54, 0xa4, 0x41, 0x2e, 0x92, 0x0b, 0x9a, 0x05, 0x69, |
|
2012 |
+ 0x18, 0x88, 0x34, 0x2f, 0xb3, 0xdd, 0x13, 0x58, 0xc5, 0x54, 0x7d, 0x38, 0x1c, 0x91, 0x98, 0xee, |
|
2013 |
+ 0x0a, 0x1e, 0xb1, 0x18, 0xd3, 0x0f, 0x63, 0x9a, 0x4b, 0xb4, 0x02, 0x26, 0xa6, 0x91, 0x6d, 0x74, |
|
2014 |
+ 0x0c, 0xaf, 0x85, 0x8b, 0x23, 0xf2, 0xa0, 0xd9, 0x4f, 0x88, 0x8c, 0x44, 0x36, 0xb2, 0x1b, 0x1d, |
|
2015 |
+ 0xc3, 0x6b, 0x77, 0x2d, 0x3f, 0x0d, 0xfd, 0x2a, 0x86, 0xa7, 0x5f, 0xdd, 0x2f, 0x06, 0x38, 0xbf, |
|
2016 |
+ 0x62, 0xce, 0x53, 0xc1, 0x73, 0x8a, 0xde, 0xc1, 0xc2, 0x1e, 0x8b, 0x69, 0x2e, 0x4b, 0xf6, 0x5e, |
|
2017 |
+ 0xf7, 0xf2, 0x7a, 0xfd, 0xaf, 0xab, 0xeb, 0xf5, 0xcd, 0x9a, 0x7a, 0x91, 0x52, 0x3e, 0x10, 0x5c, |
|
2018 |
+ 0x12, 0xc6, 0x69, 0x96, 0x07, 0xb1, 0xd8, 0x1a, 0xaa, 0x12, 0xbf, 0xac, 0xc4, 0x9a, 0x01, 0xfd, |
|
2019 |
+ 0x03, 0x0b, 0x25, 0xbb, 0x92, 0x64, 0x61, 0x8d, 0xdc, 0xab, 0x06, 0x58, 0xef, 0x0b, 0x01, 0x55, |
|
2020 |
+ 0x3f, 0x3e, 0xc0, 0x1e, 0x8d, 0x18, 0x67, 0x92, 0x09, 0xae, 0x2e, 0x6e, 0x77, 0x97, 0x0a, 0xfd, |
|
2021 |
+ 0xb7, 0x51, 0x5c, 0xcb, 0x40, 0x0e, 0x34, 0x0f, 0xb4, 0x0b, 0x8a, 0xba, 0x85, 0xa7, 0x18, 0x9d, |
|
2022 |
+ 0x42, 0xbb, 0x3a, 0x1f, 0xa7, 0xd2, 0x36, 0x3b, 0xa6, 0xd7, 0xee, 0x6e, 0xfb, 0x8f, 0xda, 0xe8, |
|
2023 |
+ 0xd7, 0x95, 0xf8, 0xb5, 0xd2, 0x7d, 0x2e, 0xb3, 0x09, 0xae, 0x93, 0x21, 0x0f, 0x96, 0x0f, 0x47, |
|
2024 |
+ 0xa9, 0xc8, 0xe4, 0x2e, 0x19, 0x9c, 0x51, 0x4c, 0xa3, 0xdc, 0x9e, 0xeb, 0x98, 0x5e, 0x0b, 0xdf, |
|
2025 |
+ 0x0f, 0xa3, 0xbf, 0x61, 0xfe, 0x80, 0x71, 0x92, 0xd8, 0xd0, 0x31, 0xbc, 0x26, 0x2e, 0x01, 0x72, |
|
2026 |
+ 0xc1, 0xda, 0xff, 0x54, 0x24, 0xd2, 0xec, 0xad, 0x94, 0x99, 0xdd, 0x56, 0xcf, 0x72, 0x27, 0xe6, |
|
2027 |
+ 0xbc, 0x81, 0x95, 0xfb, 0x22, 0x0a, 0xbf, 0xcf, 0xe9, 0xa4, 0xf2, 0xfb, 0x9c, 0x4e, 0x0a, 0xfe, |
|
2028 |
+ 0x0b, 0x92, 0x8c, 0xa9, 0x6e, 0xbf, 0x04, 0x3b, 0x8d, 0x6d, 0xc3, 0xdd, 0x87, 0x45, 0xdd, 0x91, |
|
2029 |
+ 0x76, 0xf4, 0xe1, 0xb0, 0xdc, 0x97, 0xd1, 0x78, 0x28, 0xc3, 0xfd, 0x0c, 0xcb, 0x98, 0x92, 0xe1, |
|
2030 |
+ 0x01, 0x4b, 0xe8, 0xe3, 0x53, 0x57, 0xf8, 0xc0, 0x12, 0xda, 0x27, 0xf2, 0x6c, 0xea, 0x83, 0xc6, |
|
2031 |
+ 0x68, 0x07, 0xe6, 0x31, 0xe1, 0x31, 0xb5, 0x4d, 0x65, 0xe7, 0xbf, 0x33, 0x1c, 0x50, 0x97, 0x14, |
|
2032 |
+ 0xb9, 0xb8, 0x2c, 0x71, 0x5f, 0x43, 0x6b, 0x1a, 0x2b, 0xa6, 0xe8, 0x38, 0x8a, 0x72, 0x5a, 0x4e, |
|
2033 |
+ 0xa4, 0x89, 0x35, 0x2a, 0xe2, 0x47, 0x94, 0xc7, 0xfa, 0x6a, 0x13, 0x6b, 0xe4, 0x6e, 0xc0, 0xca, |
|
2034 |
+ 0xad, 0x72, 0xfd, 0x06, 0x08, 0xe6, 0xf6, 0x88, 0x24, 0x8a, 0xc1, 0xc2, 0xea, 0xec, 0x2e, 0x42, |
|
2035 |
+ 0xbb, 0xcf, 0x78, 0xb5, 0x53, 0xee, 0x12, 0x58, 0x7d, 0xc1, 0xa7, 0x8b, 0xd0, 0xfd, 0x66, 0x42, |
|
2036 |
+ 0xeb, 0xe8, 0xa8, 0xd7, 0xcb, 0xd8, 0x30, 0xa6, 0xe8, 0xab, 0x01, 0xe8, 0xe1, 0xd6, 0xa0, 0x97, |
|
2037 |
+ 0x33, 0xba, 0x7a, 0x74, 0x7d, 0x9d, 0x57, 0x7f, 0x58, 0xa5, 0x9b, 0x38, 0x85, 0x79, 0xe5, 0x2c, |
|
2038 |
+ 0xfa, 0xef, 0x89, 0xd3, 0xec, 0x78, 0xbf, 0x4f, 0xd4, 0xdc, 0x03, 0x68, 0x56, 0x8f, 0x86, 0x36, |
|
2039 |
+ 0x67, 0xca, 0xbb, 0x33, 0x13, 0xce, 0xff, 0x4f, 0xca, 0xd5, 0x97, 0x9c, 0xc0, 0x5c, 0xf1, 0xe2, |
|
2040 |
+ 0x68, 0x63, 0x46, 0x51, 0xcd, 0x12, 0x67, 0x56, 0x9f, 0x75, 0xaf, 0x7a, 0xd6, 0xe5, 0xcd, 0x9a, |
|
2041 |
+ 0xf1, 0xfd, 0x66, 0xcd, 0xf8, 0x71, 0xb3, 0x66, 0x84, 0x0b, 0xea, 0x0f, 0xfa, 0xe2, 0x67, 0x00, |
|
2042 |
+ 0x00, 0x00, 0xff, 0xff, 0xbc, 0x68, 0x1b, 0xf0, 0xca, 0x05, 0x00, 0x00, |
|
2042 | 2043 |
} |
... | ... |
@@ -15,6 +15,7 @@ import ( |
15 | 15 |
"github.com/moby/buildkit/util/tracing" |
16 | 16 |
"github.com/moby/buildkit/worker" |
17 | 17 |
digest "github.com/opencontainers/go-digest" |
18 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
18 | 19 |
"github.com/pkg/errors" |
19 | 20 |
) |
20 | 21 |
|
... | ... |
@@ -25,6 +26,7 @@ type llbBridge struct { |
25 | 25 |
ci *remotecache.CacheImporter |
26 | 26 |
cms map[string]solver.CacheManager |
27 | 27 |
cmsMu sync.Mutex |
28 |
+ platforms []specs.Platform |
|
28 | 29 |
} |
29 | 30 |
|
30 | 31 |
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 |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
if req.Definition != nil && req.Definition.Def != nil { |
62 |
- edge, err := Load(req.Definition, WithCacheSources(cms)) |
|
62 |
+ edge, err := Load(req.Definition, WithCacheSources(cms), RuntimePlatforms(b.platforms)) |
|
63 | 63 |
if err != nil { |
64 | 64 |
return nil, nil, err |
65 | 65 |
} |
... | ... |
@@ -108,12 +110,12 @@ func (s *llbBridge) Exec(ctx context.Context, meta executor.Meta, root cache.Imm |
108 | 108 |
return err |
109 | 109 |
} |
110 | 110 |
|
111 |
-func (s *llbBridge) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) { |
|
111 |
+func (s *llbBridge) ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) { |
|
112 | 112 |
w, err := s.resolveWorker() |
113 | 113 |
if err != nil { |
114 | 114 |
return "", nil, err |
115 | 115 |
} |
116 |
- return w.ResolveImageConfig(ctx, ref) |
|
116 |
+ return w.ResolveImageConfig(ctx, ref, platform) |
|
117 | 117 |
} |
118 | 118 |
|
119 | 119 |
type lazyCacheManager struct { |
... | ... |
@@ -11,9 +11,11 @@ import ( |
11 | 11 |
"sort" |
12 | 12 |
"strings" |
13 | 13 |
"sync" |
14 |
+ "time" |
|
14 | 15 |
|
15 | 16 |
"github.com/boltdb/bolt" |
16 | 17 |
"github.com/containerd/containerd/mount" |
18 |
+ "github.com/docker/docker/pkg/locker" |
|
17 | 19 |
"github.com/moby/buildkit/cache" |
18 | 20 |
"github.com/moby/buildkit/cache/metadata" |
19 | 21 |
"github.com/moby/buildkit/executor" |
... | ... |
@@ -37,16 +39,19 @@ type execOp struct { |
37 | 37 |
exec executor.Executor |
38 | 38 |
w worker.Worker |
39 | 39 |
numInputs int |
40 |
+ |
|
41 |
+ cacheMounts map[string]*cacheRefShare |
|
40 | 42 |
} |
41 | 43 |
|
42 | 44 |
func NewExecOp(v solver.Vertex, op *pb.Op_Exec, cm cache.Manager, md *metadata.Store, exec executor.Executor, w worker.Worker) (solver.Op, error) { |
43 | 45 |
return &execOp{ |
44 |
- op: op.Exec, |
|
45 |
- cm: cm, |
|
46 |
- md: md, |
|
47 |
- exec: exec, |
|
48 |
- numInputs: len(v.Inputs()), |
|
49 |
- w: w, |
|
46 |
+ op: op.Exec, |
|
47 |
+ cm: cm, |
|
48 |
+ md: md, |
|
49 |
+ exec: exec, |
|
50 |
+ numInputs: len(v.Inputs()), |
|
51 |
+ w: w, |
|
52 |
+ cacheMounts: map[string]*cacheRefShare{}, |
|
50 | 53 |
}, nil |
51 | 54 |
} |
52 | 55 |
|
... | ... |
@@ -165,32 +170,72 @@ func (e *execOp) getMountDeps() ([]dep, error) { |
165 | 165 |
return deps, nil |
166 | 166 |
} |
167 | 167 |
|
168 |
-func (e *execOp) getRefCacheDir(ctx context.Context, ref cache.ImmutableRef, id string, m *pb.Mount) (cache.MutableRef, error) { |
|
168 |
+func (e *execOp) getRefCacheDir(ctx context.Context, ref cache.ImmutableRef, id string, m *pb.Mount, sharing pb.CacheSharingOpt) (mref cache.MutableRef, err error) { |
|
169 | 169 |
|
170 | 170 |
key := "cache-dir:" + id |
171 | 171 |
if ref != nil { |
172 | 172 |
key += ":" + ref.ID() |
173 | 173 |
} |
174 | 174 |
|
175 |
- return sharedCacheRefs.get(key, func() (cache.MutableRef, error) { |
|
176 |
- return e.getRefCacheDirNoCache(ctx, key, ref, id, m) |
|
177 |
- }) |
|
175 |
+ if ref, ok := e.cacheMounts[key]; ok { |
|
176 |
+ return ref.clone(), nil |
|
177 |
+ } |
|
178 |
+ defer func() { |
|
179 |
+ if err == nil { |
|
180 |
+ share := &cacheRefShare{MutableRef: mref, refs: map[*cacheRef]struct{}{}} |
|
181 |
+ e.cacheMounts[key] = share |
|
182 |
+ mref = share.clone() |
|
183 |
+ } |
|
184 |
+ }() |
|
185 |
+ |
|
186 |
+ switch sharing { |
|
187 |
+ case pb.CacheSharingOpt_SHARED: |
|
188 |
+ return sharedCacheRefs.get(key, func() (cache.MutableRef, error) { |
|
189 |
+ return e.getRefCacheDirNoCache(ctx, key, ref, id, m, false) |
|
190 |
+ }) |
|
191 |
+ case pb.CacheSharingOpt_PRIVATE: |
|
192 |
+ return e.getRefCacheDirNoCache(ctx, key, ref, id, m, false) |
|
193 |
+ case pb.CacheSharingOpt_LOCKED: |
|
194 |
+ return e.getRefCacheDirNoCache(ctx, key, ref, id, m, true) |
|
195 |
+ default: |
|
196 |
+ return nil, errors.Errorf("invalid cache sharing option: %s", sharing.String()) |
|
197 |
+ } |
|
198 |
+ |
|
178 | 199 |
} |
179 | 200 |
|
180 |
-func (e *execOp) getRefCacheDirNoCache(ctx context.Context, key string, ref cache.ImmutableRef, id string, m *pb.Mount) (cache.MutableRef, error) { |
|
201 |
+func (e *execOp) getRefCacheDirNoCache(ctx context.Context, key string, ref cache.ImmutableRef, id string, m *pb.Mount, block bool) (cache.MutableRef, error) { |
|
181 | 202 |
makeMutable := func(cache.ImmutableRef) (cache.MutableRef, error) { |
182 | 203 |
desc := fmt.Sprintf("cached mount %s from exec %s", m.Dest, strings.Join(e.op.Meta.Args, " ")) |
183 | 204 |
return e.cm.New(ctx, ref, cache.WithDescription(desc), cache.CachePolicyRetain) |
184 | 205 |
} |
185 | 206 |
|
186 |
- sis, err := e.md.Search(key) |
|
187 |
- if err != nil { |
|
188 |
- return nil, err |
|
189 |
- } |
|
190 |
- for _, si := range sis { |
|
191 |
- if mRef, err := e.cm.GetMutable(ctx, si.ID()); err == nil { |
|
192 |
- logrus.Debugf("reusing ref for cache dir: %s", mRef.ID()) |
|
193 |
- return mRef, nil |
|
207 |
+ cacheRefsLocker.Lock(key) |
|
208 |
+ defer cacheRefsLocker.Unlock(key) |
|
209 |
+ for { |
|
210 |
+ sis, err := e.md.Search(key) |
|
211 |
+ if err != nil { |
|
212 |
+ return nil, err |
|
213 |
+ } |
|
214 |
+ locked := false |
|
215 |
+ for _, si := range sis { |
|
216 |
+ if mRef, err := e.cm.GetMutable(ctx, si.ID()); err == nil { |
|
217 |
+ logrus.Debugf("reusing ref for cache dir: %s", mRef.ID()) |
|
218 |
+ return mRef, nil |
|
219 |
+ } else if errors.Cause(err) == cache.ErrLocked { |
|
220 |
+ locked = true |
|
221 |
+ } |
|
222 |
+ } |
|
223 |
+ if block && locked { |
|
224 |
+ cacheRefsLocker.Unlock(key) |
|
225 |
+ select { |
|
226 |
+ case <-ctx.Done(): |
|
227 |
+ cacheRefsLocker.Lock(key) |
|
228 |
+ return nil, ctx.Err() |
|
229 |
+ case <-time.After(100 * time.Millisecond): |
|
230 |
+ cacheRefsLocker.Lock(key) |
|
231 |
+ } |
|
232 |
+ } else { |
|
233 |
+ break |
|
194 | 234 |
} |
195 | 235 |
} |
196 | 236 |
mRef, err := makeMutable(ref) |
... | ... |
@@ -287,7 +332,7 @@ func (e *execOp) Exec(ctx context.Context, inputs []solver.Result) ([]solver.Res |
287 | 287 |
if m.CacheOpt == nil { |
288 | 288 |
return nil, errors.Errorf("missing cache mount options") |
289 | 289 |
} |
290 |
- mRef, err := e.getRefCacheDir(ctx, ref, m.CacheOpt.ID, m) |
|
290 |
+ mRef, err := e.getRefCacheDir(ctx, ref, m.CacheOpt.ID, m, m.CacheOpt.Sharing) |
|
291 | 291 |
if err != nil { |
292 | 292 |
return nil, err |
293 | 293 |
} |
... | ... |
@@ -418,6 +463,7 @@ func (m *tmpfsMount) Release() error { |
418 | 418 |
return nil |
419 | 419 |
} |
420 | 420 |
|
421 |
+var cacheRefsLocker = locker.New() |
|
421 | 422 |
var sharedCacheRefs = &cacheRefs{} |
422 | 423 |
|
423 | 424 |
type cacheRefs struct { |
... | ... |
@@ -466,9 +512,11 @@ func (r *cacheRefShare) clone() cache.MutableRef { |
466 | 466 |
} |
467 | 467 |
|
468 | 468 |
func (r *cacheRefShare) release(ctx context.Context) error { |
469 |
- r.main.mu.Lock() |
|
470 |
- defer r.main.mu.Unlock() |
|
471 |
- delete(r.main.shares, r.key) |
|
469 |
+ if r.main != nil { |
|
470 |
+ r.main.mu.Lock() |
|
471 |
+ defer r.main.mu.Unlock() |
|
472 |
+ delete(r.main.shares, r.key) |
|
473 |
+ } |
|
472 | 474 |
return r.MutableRef.Release(ctx) |
473 | 475 |
} |
474 | 476 |
|
... | ... |
@@ -14,18 +14,20 @@ import ( |
14 | 14 |
const sourceCacheType = "buildkit.source.v0" |
15 | 15 |
|
16 | 16 |
type sourceOp struct { |
17 |
- mu sync.Mutex |
|
18 |
- op *pb.Op_Source |
|
19 |
- sm *source.Manager |
|
20 |
- src source.SourceInstance |
|
21 |
- w worker.Worker |
|
17 |
+ mu sync.Mutex |
|
18 |
+ op *pb.Op_Source |
|
19 |
+ platform *pb.Platform |
|
20 |
+ sm *source.Manager |
|
21 |
+ src source.SourceInstance |
|
22 |
+ w worker.Worker |
|
22 | 23 |
} |
23 | 24 |
|
24 |
-func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, sm *source.Manager, w worker.Worker) (solver.Op, error) { |
|
25 |
+func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, w worker.Worker) (solver.Op, error) { |
|
25 | 26 |
return &sourceOp{ |
26 |
- op: op, |
|
27 |
- sm: sm, |
|
28 |
- w: w, |
|
27 |
+ op: op, |
|
28 |
+ sm: sm, |
|
29 |
+ w: w, |
|
30 |
+ platform: platform, |
|
29 | 31 |
}, nil |
30 | 32 |
} |
31 | 33 |
|
... | ... |
@@ -35,7 +37,7 @@ func (s *sourceOp) instance(ctx context.Context) (source.SourceInstance, error) |
35 | 35 |
if s.src != nil { |
36 | 36 |
return s.src, nil |
37 | 37 |
} |
38 |
- id, err := source.FromLLB(s.op) |
|
38 |
+ id, err := source.FromLLB(s.op, s.platform) |
|
39 | 39 |
if err != nil { |
40 | 40 |
return nil, err |
41 | 41 |
} |
... | ... |
@@ -13,6 +13,7 @@ import ( |
13 | 13 |
"github.com/moby/buildkit/solver" |
14 | 14 |
"github.com/moby/buildkit/util/progress" |
15 | 15 |
"github.com/moby/buildkit/worker" |
16 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
16 | 17 |
"github.com/pkg/errors" |
17 | 18 |
) |
18 | 19 |
|
... | ... |
@@ -30,9 +31,10 @@ type Solver struct { |
30 | 30 |
resolveWorker ResolveWorkerFunc |
31 | 31 |
frontends map[string]frontend.Frontend |
32 | 32 |
ci *remotecache.CacheImporter |
33 |
+ platforms []specs.Platform |
|
33 | 34 |
} |
34 | 35 |
|
35 |
-func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) *Solver { |
|
36 |
+func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solver.CacheKeyStorage, ci *remotecache.CacheImporter) (*Solver, error) { |
|
36 | 37 |
s := &Solver{ |
37 | 38 |
resolveWorker: defaultResolver(wc), |
38 | 39 |
frontends: f, |
... | ... |
@@ -43,11 +45,18 @@ func New(wc *worker.Controller, f map[string]frontend.Frontend, cacheStore solve |
43 | 43 |
|
44 | 44 |
cache := solver.NewCacheManager("local", cacheStore, results) |
45 | 45 |
|
46 |
+ // executing is currently only allowed on default worker |
|
47 |
+ w, err := wc.GetDefault() |
|
48 |
+ if err != nil { |
|
49 |
+ return nil, err |
|
50 |
+ } |
|
51 |
+ s.platforms = w.Platforms() |
|
52 |
+ |
|
46 | 53 |
s.solver = solver.NewSolver(solver.SolverOpt{ |
47 | 54 |
ResolveOpFunc: s.resolver(), |
48 | 55 |
DefaultCache: cache, |
49 | 56 |
}) |
50 |
- return s |
|
57 |
+ return s, nil |
|
51 | 58 |
} |
52 | 59 |
|
53 | 60 |
func (s *Solver) resolver() solver.ResolveOpFunc { |
... | ... |
@@ -67,6 +76,7 @@ func (s *Solver) Bridge(b solver.Builder) frontend.FrontendLLBBridge { |
67 | 67 |
resolveWorker: s.resolveWorker, |
68 | 68 |
ci: s.ci, |
69 | 69 |
cms: map[string]solver.CacheManager{}, |
70 |
+ platforms: s.platforms, |
|
70 | 71 |
} |
71 | 72 |
} |
72 | 73 |
|
... | ... |
@@ -3,10 +3,12 @@ package llbsolver |
3 | 3 |
import ( |
4 | 4 |
"strings" |
5 | 5 |
|
6 |
+ "github.com/containerd/containerd/platforms" |
|
6 | 7 |
"github.com/moby/buildkit/solver" |
7 | 8 |
"github.com/moby/buildkit/solver/pb" |
8 | 9 |
"github.com/moby/buildkit/source" |
9 | 10 |
digest "github.com/opencontainers/go-digest" |
11 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
10 | 12 |
"github.com/pkg/errors" |
11 | 13 |
) |
12 | 14 |
|
... | ... |
@@ -38,11 +40,44 @@ func (v *vertex) Name() string { |
38 | 38 |
return v.name |
39 | 39 |
} |
40 | 40 |
|
41 |
-type LoadOpt func(*solver.VertexOptions) |
|
41 |
+type LoadOpt func(*pb.Op, *pb.OpMetadata, *solver.VertexOptions) error |
|
42 | 42 |
|
43 | 43 |
func WithCacheSources(cms []solver.CacheManager) LoadOpt { |
44 |
- return func(opt *solver.VertexOptions) { |
|
44 |
+ return func(_ *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error { |
|
45 | 45 |
opt.CacheSources = cms |
46 |
+ return nil |
|
47 |
+ } |
|
48 |
+} |
|
49 |
+ |
|
50 |
+func RuntimePlatforms(p []specs.Platform) LoadOpt { |
|
51 |
+ var defaultPlatform *pb.Platform |
|
52 |
+ for i := range p { |
|
53 |
+ p[i] = platforms.Normalize(p[i]) |
|
54 |
+ } |
|
55 |
+ return func(op *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error { |
|
56 |
+ if op.Platform == nil { |
|
57 |
+ if defaultPlatform == nil { |
|
58 |
+ p := platforms.DefaultSpec() |
|
59 |
+ defaultPlatform = &pb.Platform{ |
|
60 |
+ OS: p.OS, |
|
61 |
+ Architecture: p.Architecture, |
|
62 |
+ } |
|
63 |
+ } |
|
64 |
+ op.Platform = defaultPlatform |
|
65 |
+ } |
|
66 |
+ if _, ok := op.Op.(*pb.Op_Exec); ok { |
|
67 |
+ var found bool |
|
68 |
+ for _, pp := range p { |
|
69 |
+ if pp.OS == op.Platform.OS && pp.Architecture == op.Platform.Architecture && pp.Variant == op.Platform.Variant { |
|
70 |
+ found = true |
|
71 |
+ break |
|
72 |
+ } |
|
73 |
+ } |
|
74 |
+ if !found { |
|
75 |
+ 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})) |
|
76 |
+ } |
|
77 |
+ } |
|
78 |
+ return nil |
|
46 | 79 |
} |
47 | 80 |
} |
48 | 81 |
|
... | ... |
@@ -67,9 +102,11 @@ func newVertex(dgst digest.Digest, op *pb.Op, opMeta *pb.OpMetadata, load func(d |
67 | 67 |
} |
68 | 68 |
} |
69 | 69 |
for _, fn := range opts { |
70 |
- fn(&opt) |
|
70 |
+ if err := fn(op, opMeta, &opt); err != nil { |
|
71 |
+ return nil, err |
|
72 |
+ } |
|
71 | 73 |
} |
72 |
- vtx := &vertex{sys: op.Op, options: opt, digest: dgst, name: llbOpName(op)} |
|
74 |
+ vtx := &vertex{sys: op, options: opt, digest: dgst, name: llbOpName(op)} |
|
73 | 75 |
for _, in := range op.Inputs { |
74 | 76 |
sub, err := load(in.Digest) |
75 | 77 |
if err != nil { |
... | ... |
@@ -129,7 +166,7 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige |
129 | 129 |
func llbOpName(op *pb.Op) string { |
130 | 130 |
switch op := op.Op.(type) { |
131 | 131 |
case *pb.Op_Source: |
132 |
- if id, err := source.FromLLB(op); err == nil { |
|
132 |
+ if id, err := source.FromLLB(op, nil); err == nil { |
|
133 | 133 |
if id, ok := id.(*source.LocalIdentifier); ok { |
134 | 134 |
if len(id.IncludePatterns) == 1 { |
135 | 135 |
return op.Source.Identifier + " (" + id.IncludePatterns[0] + ")" |
... | ... |
@@ -12,6 +12,7 @@ |
12 | 12 |
|
13 | 13 |
It has these top-level messages: |
14 | 14 |
Op |
15 |
+ Platform |
|
15 | 16 |
Input |
16 | 17 |
ExecOp |
17 | 18 |
Meta |
... | ... |
@@ -25,7 +26,7 @@ |
25 | 25 |
OpMetadata |
26 | 26 |
ExportCache |
27 | 27 |
ProxyEnv |
28 |
- WorkerConstraint |
|
28 |
+ WorkerConstraints |
|
29 | 29 |
Definition |
30 | 30 |
*/ |
31 | 31 |
package pb |
... | ... |
@@ -50,6 +51,7 @@ var _ = math.Inf |
50 | 50 |
// proto package needs to be updated. |
51 | 51 |
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package |
52 | 52 |
|
53 |
+// MountType defines a type of a mount from a supported set |
|
53 | 54 |
type MountType int32 |
54 | 55 |
|
55 | 56 |
const ( |
... | ... |
@@ -80,6 +82,34 @@ func (x MountType) String() string { |
80 | 80 |
} |
81 | 81 |
func (MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorOps, []int{0} } |
82 | 82 |
|
83 |
+// CacheSharingOpt defines different sharing modes for cache mount |
|
84 |
+type CacheSharingOpt int32 |
|
85 |
+ |
|
86 |
+const ( |
|
87 |
+ // SHARED cache mount can be used concurrently by multiple writers |
|
88 |
+ CacheSharingOpt_SHARED CacheSharingOpt = 0 |
|
89 |
+ // PRIVATE creates a new mount if there are multiple writers |
|
90 |
+ CacheSharingOpt_PRIVATE CacheSharingOpt = 1 |
|
91 |
+ // LOCKED pauses second writer until first one releases the mount |
|
92 |
+ CacheSharingOpt_LOCKED CacheSharingOpt = 2 |
|
93 |
+) |
|
94 |
+ |
|
95 |
+var CacheSharingOpt_name = map[int32]string{ |
|
96 |
+ 0: "SHARED", |
|
97 |
+ 1: "PRIVATE", |
|
98 |
+ 2: "LOCKED", |
|
99 |
+} |
|
100 |
+var CacheSharingOpt_value = map[string]int32{ |
|
101 |
+ "SHARED": 0, |
|
102 |
+ "PRIVATE": 1, |
|
103 |
+ "LOCKED": 2, |
|
104 |
+} |
|
105 |
+ |
|
106 |
+func (x CacheSharingOpt) String() string { |
|
107 |
+ return proto.EnumName(CacheSharingOpt_name, int32(x)) |
|
108 |
+} |
|
109 |
+func (CacheSharingOpt) EnumDescriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } |
|
110 |
+ |
|
83 | 111 |
// Op represents a vertex of the LLB DAG. |
84 | 112 |
type Op struct { |
85 | 113 |
// inputs is a set of input edges. |
... | ... |
@@ -89,7 +119,9 @@ type Op struct { |
89 | 89 |
// *Op_Source |
90 | 90 |
// *Op_Copy |
91 | 91 |
// *Op_Build |
92 |
- Op isOp_Op `protobuf_oneof:"op"` |
|
92 |
+ Op isOp_Op `protobuf_oneof:"op"` |
|
93 |
+ Platform *Platform `protobuf:"bytes,10,opt,name=platform" json:"platform,omitempty"` |
|
94 |
+ Constraints *WorkerConstraints `protobuf:"bytes,11,opt,name=constraints" json:"constraints,omitempty"` |
|
93 | 95 |
} |
94 | 96 |
|
95 | 97 |
func (m *Op) Reset() { *m = Op{} } |
... | ... |
@@ -163,6 +195,20 @@ func (m *Op) GetBuild() *BuildOp { |
163 | 163 |
return nil |
164 | 164 |
} |
165 | 165 |
|
166 |
+func (m *Op) GetPlatform() *Platform { |
|
167 |
+ if m != nil { |
|
168 |
+ return m.Platform |
|
169 |
+ } |
|
170 |
+ return nil |
|
171 |
+} |
|
172 |
+ |
|
173 |
+func (m *Op) GetConstraints() *WorkerConstraints { |
|
174 |
+ if m != nil { |
|
175 |
+ return m.Constraints |
|
176 |
+ } |
|
177 |
+ return nil |
|
178 |
+} |
|
179 |
+ |
|
166 | 180 |
// XXX_OneofFuncs is for the internal use of the proto package. |
167 | 181 |
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{}) { |
168 | 182 |
return _Op_OneofMarshaler, _Op_OneofUnmarshaler, _Op_OneofSizer, []interface{}{ |
... | ... |
@@ -275,6 +321,55 @@ func _Op_OneofSizer(msg proto.Message) (n int) { |
275 | 275 |
return n |
276 | 276 |
} |
277 | 277 |
|
278 |
+// Platform is github.com/opencontainers/image-spec/specs-go/v1.Platform |
|
279 |
+type Platform struct { |
|
280 |
+ Architecture string `protobuf:"bytes,1,opt,name=Architecture,proto3" json:"Architecture,omitempty"` |
|
281 |
+ OS string `protobuf:"bytes,2,opt,name=OS,proto3" json:"OS,omitempty"` |
|
282 |
+ Variant string `protobuf:"bytes,3,opt,name=Variant,proto3" json:"Variant,omitempty"` |
|
283 |
+ OSVersion string `protobuf:"bytes,4,opt,name=OSVersion,proto3" json:"OSVersion,omitempty"` |
|
284 |
+ OSFeatures []string `protobuf:"bytes,5,rep,name=OSFeatures" json:"OSFeatures,omitempty"` |
|
285 |
+} |
|
286 |
+ |
|
287 |
+func (m *Platform) Reset() { *m = Platform{} } |
|
288 |
+func (m *Platform) String() string { return proto.CompactTextString(m) } |
|
289 |
+func (*Platform) ProtoMessage() {} |
|
290 |
+func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } |
|
291 |
+ |
|
292 |
+func (m *Platform) GetArchitecture() string { |
|
293 |
+ if m != nil { |
|
294 |
+ return m.Architecture |
|
295 |
+ } |
|
296 |
+ return "" |
|
297 |
+} |
|
298 |
+ |
|
299 |
+func (m *Platform) GetOS() string { |
|
300 |
+ if m != nil { |
|
301 |
+ return m.OS |
|
302 |
+ } |
|
303 |
+ return "" |
|
304 |
+} |
|
305 |
+ |
|
306 |
+func (m *Platform) GetVariant() string { |
|
307 |
+ if m != nil { |
|
308 |
+ return m.Variant |
|
309 |
+ } |
|
310 |
+ return "" |
|
311 |
+} |
|
312 |
+ |
|
313 |
+func (m *Platform) GetOSVersion() string { |
|
314 |
+ if m != nil { |
|
315 |
+ return m.OSVersion |
|
316 |
+ } |
|
317 |
+ return "" |
|
318 |
+} |
|
319 |
+ |
|
320 |
+func (m *Platform) GetOSFeatures() []string { |
|
321 |
+ if m != nil { |
|
322 |
+ return m.OSFeatures |
|
323 |
+ } |
|
324 |
+ return nil |
|
325 |
+} |
|
326 |
+ |
|
278 | 327 |
// Input represents an input edge for an Op. |
279 | 328 |
type Input struct { |
280 | 329 |
// digest of the marshaled input Op |
... | ... |
@@ -286,7 +381,7 @@ type Input struct { |
286 | 286 |
func (m *Input) Reset() { *m = Input{} } |
287 | 287 |
func (m *Input) String() string { return proto.CompactTextString(m) } |
288 | 288 |
func (*Input) ProtoMessage() {} |
289 |
-func (*Input) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{1} } |
|
289 |
+func (*Input) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{2} } |
|
290 | 290 |
|
291 | 291 |
// ExecOp executes a command in a container. |
292 | 292 |
type ExecOp struct { |
... | ... |
@@ -297,7 +392,7 @@ type ExecOp struct { |
297 | 297 |
func (m *ExecOp) Reset() { *m = ExecOp{} } |
298 | 298 |
func (m *ExecOp) String() string { return proto.CompactTextString(m) } |
299 | 299 |
func (*ExecOp) ProtoMessage() {} |
300 |
-func (*ExecOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{2} } |
|
300 |
+func (*ExecOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{3} } |
|
301 | 301 |
|
302 | 302 |
func (m *ExecOp) GetMeta() *Meta { |
303 | 303 |
if m != nil { |
... | ... |
@@ -327,7 +422,7 @@ type Meta struct { |
327 | 327 |
func (m *Meta) Reset() { *m = Meta{} } |
328 | 328 |
func (m *Meta) String() string { return proto.CompactTextString(m) } |
329 | 329 |
func (*Meta) ProtoMessage() {} |
330 |
-func (*Meta) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{3} } |
|
330 |
+func (*Meta) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{4} } |
|
331 | 331 |
|
332 | 332 |
func (m *Meta) GetArgs() []string { |
333 | 333 |
if m != nil { |
... | ... |
@@ -378,7 +473,7 @@ type Mount struct { |
378 | 378 |
func (m *Mount) Reset() { *m = Mount{} } |
379 | 379 |
func (m *Mount) String() string { return proto.CompactTextString(m) } |
380 | 380 |
func (*Mount) ProtoMessage() {} |
381 |
-func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{4} } |
|
381 |
+func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{5} } |
|
382 | 382 |
|
383 | 383 |
func (m *Mount) GetSelector() string { |
384 | 384 |
if m != nil { |
... | ... |
@@ -415,14 +510,18 @@ func (m *Mount) GetCacheOpt() *CacheOpt { |
415 | 415 |
return nil |
416 | 416 |
} |
417 | 417 |
|
418 |
+// CacheOpt defines options specific to cache mounts |
|
418 | 419 |
type CacheOpt struct { |
420 |
+ // ID is an optional namespace for the mount |
|
419 | 421 |
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` |
422 |
+ // Sharing is the sharing mode for the mount |
|
423 |
+ Sharing CacheSharingOpt `protobuf:"varint,2,opt,name=sharing,proto3,enum=pb.CacheSharingOpt" json:"sharing,omitempty"` |
|
420 | 424 |
} |
421 | 425 |
|
422 | 426 |
func (m *CacheOpt) Reset() { *m = CacheOpt{} } |
423 | 427 |
func (m *CacheOpt) String() string { return proto.CompactTextString(m) } |
424 | 428 |
func (*CacheOpt) ProtoMessage() {} |
425 |
-func (*CacheOpt) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{5} } |
|
429 |
+func (*CacheOpt) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{6} } |
|
426 | 430 |
|
427 | 431 |
func (m *CacheOpt) GetID() string { |
428 | 432 |
if m != nil { |
... | ... |
@@ -431,6 +530,13 @@ func (m *CacheOpt) GetID() string { |
431 | 431 |
return "" |
432 | 432 |
} |
433 | 433 |
|
434 |
+func (m *CacheOpt) GetSharing() CacheSharingOpt { |
|
435 |
+ if m != nil { |
|
436 |
+ return m.Sharing |
|
437 |
+ } |
|
438 |
+ return CacheSharingOpt_SHARED |
|
439 |
+} |
|
440 |
+ |
|
434 | 441 |
// CopyOp copies files across Ops. |
435 | 442 |
type CopyOp struct { |
436 | 443 |
Src []*CopySource `protobuf:"bytes,1,rep,name=src" json:"src,omitempty"` |
... | ... |
@@ -440,7 +546,7 @@ type CopyOp struct { |
440 | 440 |
func (m *CopyOp) Reset() { *m = CopyOp{} } |
441 | 441 |
func (m *CopyOp) String() string { return proto.CompactTextString(m) } |
442 | 442 |
func (*CopyOp) ProtoMessage() {} |
443 |
-func (*CopyOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{6} } |
|
443 |
+func (*CopyOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{7} } |
|
444 | 444 |
|
445 | 445 |
func (m *CopyOp) GetSrc() []*CopySource { |
446 | 446 |
if m != nil { |
... | ... |
@@ -465,7 +571,7 @@ type CopySource struct { |
465 | 465 |
func (m *CopySource) Reset() { *m = CopySource{} } |
466 | 466 |
func (m *CopySource) String() string { return proto.CompactTextString(m) } |
467 | 467 |
func (*CopySource) ProtoMessage() {} |
468 |
-func (*CopySource) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{7} } |
|
468 |
+func (*CopySource) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{8} } |
|
469 | 469 |
|
470 | 470 |
func (m *CopySource) GetSelector() string { |
471 | 471 |
if m != nil { |
... | ... |
@@ -486,7 +592,7 @@ type SourceOp struct { |
486 | 486 |
func (m *SourceOp) Reset() { *m = SourceOp{} } |
487 | 487 |
func (m *SourceOp) String() string { return proto.CompactTextString(m) } |
488 | 488 |
func (*SourceOp) ProtoMessage() {} |
489 |
-func (*SourceOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{8} } |
|
489 |
+func (*SourceOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{9} } |
|
490 | 490 |
|
491 | 491 |
func (m *SourceOp) GetIdentifier() string { |
492 | 492 |
if m != nil { |
... | ... |
@@ -513,7 +619,7 @@ type BuildOp struct { |
513 | 513 |
func (m *BuildOp) Reset() { *m = BuildOp{} } |
514 | 514 |
func (m *BuildOp) String() string { return proto.CompactTextString(m) } |
515 | 515 |
func (*BuildOp) ProtoMessage() {} |
516 |
-func (*BuildOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{9} } |
|
516 |
+func (*BuildOp) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{10} } |
|
517 | 517 |
|
518 | 518 |
func (m *BuildOp) GetInputs() map[string]*BuildInput { |
519 | 519 |
if m != nil { |
... | ... |
@@ -544,22 +650,23 @@ type BuildInput struct { |
544 | 544 |
func (m *BuildInput) Reset() { *m = BuildInput{} } |
545 | 545 |
func (m *BuildInput) String() string { return proto.CompactTextString(m) } |
546 | 546 |
func (*BuildInput) ProtoMessage() {} |
547 |
-func (*BuildInput) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{10} } |
|
547 |
+func (*BuildInput) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{11} } |
|
548 | 548 |
|
549 | 549 |
// OpMetadata is a per-vertex metadata entry, which can be defined for arbitrary Op vertex and overridable on the run time. |
550 | 550 |
type OpMetadata struct { |
551 | 551 |
// ignore_cache specifies to ignore the cache for this Op. |
552 | 552 |
IgnoreCache bool `protobuf:"varint,1,opt,name=ignore_cache,json=ignoreCache,proto3" json:"ignore_cache,omitempty"` |
553 | 553 |
// Description can be used for keeping any text fields that builder doesn't parse |
554 |
- 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"` |
|
555 |
- WorkerConstraint *WorkerConstraint `protobuf:"bytes,3,opt,name=worker_constraint,json=workerConstraint" json:"worker_constraint,omitempty"` |
|
556 |
- ExportCache *ExportCache `protobuf:"bytes,4,opt,name=export_cache,json=exportCache" json:"export_cache,omitempty"` |
|
554 |
+ 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"` |
|
555 |
+ // index 3 reserved for WorkerConstraint in previous versions |
|
556 |
+ // WorkerConstraint worker_constraint = 3; |
|
557 |
+ ExportCache *ExportCache `protobuf:"bytes,4,opt,name=export_cache,json=exportCache" json:"export_cache,omitempty"` |
|
557 | 558 |
} |
558 | 559 |
|
559 | 560 |
func (m *OpMetadata) Reset() { *m = OpMetadata{} } |
560 | 561 |
func (m *OpMetadata) String() string { return proto.CompactTextString(m) } |
561 | 562 |
func (*OpMetadata) ProtoMessage() {} |
562 |
-func (*OpMetadata) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{11} } |
|
563 |
+func (*OpMetadata) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{12} } |
|
563 | 564 |
|
564 | 565 |
func (m *OpMetadata) GetIgnoreCache() bool { |
565 | 566 |
if m != nil { |
... | ... |
@@ -575,13 +682,6 @@ func (m *OpMetadata) GetDescription() map[string]string { |
575 | 575 |
return nil |
576 | 576 |
} |
577 | 577 |
|
578 |
-func (m *OpMetadata) GetWorkerConstraint() *WorkerConstraint { |
|
579 |
- if m != nil { |
|
580 |
- return m.WorkerConstraint |
|
581 |
- } |
|
582 |
- return nil |
|
583 |
-} |
|
584 |
- |
|
585 | 578 |
func (m *OpMetadata) GetExportCache() *ExportCache { |
586 | 579 |
if m != nil { |
587 | 580 |
return m.ExportCache |
... | ... |
@@ -596,7 +696,7 @@ type ExportCache struct { |
596 | 596 |
func (m *ExportCache) Reset() { *m = ExportCache{} } |
597 | 597 |
func (m *ExportCache) String() string { return proto.CompactTextString(m) } |
598 | 598 |
func (*ExportCache) ProtoMessage() {} |
599 |
-func (*ExportCache) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{12} } |
|
599 |
+func (*ExportCache) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{13} } |
|
600 | 600 |
|
601 | 601 |
func (m *ExportCache) GetValue() bool { |
602 | 602 |
if m != nil { |
... | ... |
@@ -615,7 +715,7 @@ type ProxyEnv struct { |
615 | 615 |
func (m *ProxyEnv) Reset() { *m = ProxyEnv{} } |
616 | 616 |
func (m *ProxyEnv) String() string { return proto.CompactTextString(m) } |
617 | 617 |
func (*ProxyEnv) ProtoMessage() {} |
618 |
-func (*ProxyEnv) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{13} } |
|
618 |
+func (*ProxyEnv) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{14} } |
|
619 | 619 |
|
620 | 620 |
func (m *ProxyEnv) GetHttpProxy() string { |
621 | 621 |
if m != nil { |
... | ... |
@@ -645,17 +745,17 @@ func (m *ProxyEnv) GetNoProxy() string { |
645 | 645 |
return "" |
646 | 646 |
} |
647 | 647 |
|
648 |
-// WorkerConstraint is experimental and likely to be changed. |
|
649 |
-type WorkerConstraint struct { |
|
648 |
+// WorkerConstraints defines conditions for the worker |
|
649 |
+type WorkerConstraints struct { |
|
650 | 650 |
Filter []string `protobuf:"bytes,1,rep,name=filter" json:"filter,omitempty"` |
651 | 651 |
} |
652 | 652 |
|
653 |
-func (m *WorkerConstraint) Reset() { *m = WorkerConstraint{} } |
|
654 |
-func (m *WorkerConstraint) String() string { return proto.CompactTextString(m) } |
|
655 |
-func (*WorkerConstraint) ProtoMessage() {} |
|
656 |
-func (*WorkerConstraint) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{14} } |
|
653 |
+func (m *WorkerConstraints) Reset() { *m = WorkerConstraints{} } |
|
654 |
+func (m *WorkerConstraints) String() string { return proto.CompactTextString(m) } |
|
655 |
+func (*WorkerConstraints) ProtoMessage() {} |
|
656 |
+func (*WorkerConstraints) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{15} } |
|
657 | 657 |
|
658 |
-func (m *WorkerConstraint) GetFilter() []string { |
|
658 |
+func (m *WorkerConstraints) GetFilter() []string { |
|
659 | 659 |
if m != nil { |
660 | 660 |
return m.Filter |
661 | 661 |
} |
... | ... |
@@ -674,7 +774,7 @@ type Definition struct { |
674 | 674 |
func (m *Definition) Reset() { *m = Definition{} } |
675 | 675 |
func (m *Definition) String() string { return proto.CompactTextString(m) } |
676 | 676 |
func (*Definition) ProtoMessage() {} |
677 |
-func (*Definition) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{15} } |
|
677 |
+func (*Definition) Descriptor() ([]byte, []int) { return fileDescriptorOps, []int{16} } |
|
678 | 678 |
|
679 | 679 |
func (m *Definition) GetDef() [][]byte { |
680 | 680 |
if m != nil { |
... | ... |
@@ -692,6 +792,7 @@ func (m *Definition) GetMetadata() map[github_com_opencontainers_go_digest.Diges |
692 | 692 |
|
693 | 693 |
func init() { |
694 | 694 |
proto.RegisterType((*Op)(nil), "pb.Op") |
695 |
+ proto.RegisterType((*Platform)(nil), "pb.Platform") |
|
695 | 696 |
proto.RegisterType((*Input)(nil), "pb.Input") |
696 | 697 |
proto.RegisterType((*ExecOp)(nil), "pb.ExecOp") |
697 | 698 |
proto.RegisterType((*Meta)(nil), "pb.Meta") |
... | ... |
@@ -705,9 +806,10 @@ func init() { |
705 | 705 |
proto.RegisterType((*OpMetadata)(nil), "pb.OpMetadata") |
706 | 706 |
proto.RegisterType((*ExportCache)(nil), "pb.ExportCache") |
707 | 707 |
proto.RegisterType((*ProxyEnv)(nil), "pb.ProxyEnv") |
708 |
- proto.RegisterType((*WorkerConstraint)(nil), "pb.WorkerConstraint") |
|
708 |
+ proto.RegisterType((*WorkerConstraints)(nil), "pb.WorkerConstraints") |
|
709 | 709 |
proto.RegisterType((*Definition)(nil), "pb.Definition") |
710 | 710 |
proto.RegisterEnum("pb.MountType", MountType_name, MountType_value) |
711 |
+ proto.RegisterEnum("pb.CacheSharingOpt", CacheSharingOpt_name, CacheSharingOpt_value) |
|
711 | 712 |
} |
712 | 713 |
func (m *Op) Marshal() (dAtA []byte, err error) { |
713 | 714 |
size := m.Size() |
... | ... |
@@ -743,6 +845,26 @@ func (m *Op) MarshalTo(dAtA []byte) (int, error) { |
743 | 743 |
} |
744 | 744 |
i += nn1 |
745 | 745 |
} |
746 |
+ if m.Platform != nil { |
|
747 |
+ dAtA[i] = 0x52 |
|
748 |
+ i++ |
|
749 |
+ i = encodeVarintOps(dAtA, i, uint64(m.Platform.Size())) |
|
750 |
+ n2, err := m.Platform.MarshalTo(dAtA[i:]) |
|
751 |
+ if err != nil { |
|
752 |
+ return 0, err |
|
753 |
+ } |
|
754 |
+ i += n2 |
|
755 |
+ } |
|
756 |
+ if m.Constraints != nil { |
|
757 |
+ dAtA[i] = 0x5a |
|
758 |
+ i++ |
|
759 |
+ i = encodeVarintOps(dAtA, i, uint64(m.Constraints.Size())) |
|
760 |
+ n3, err := m.Constraints.MarshalTo(dAtA[i:]) |
|
761 |
+ if err != nil { |
|
762 |
+ return 0, err |
|
763 |
+ } |
|
764 |
+ i += n3 |
|
765 |
+ } |
|
746 | 766 |
return i, nil |
747 | 767 |
} |
748 | 768 |
|
... | ... |
@@ -752,11 +874,11 @@ func (m *Op_Exec) MarshalTo(dAtA []byte) (int, error) { |
752 | 752 |
dAtA[i] = 0x12 |
753 | 753 |
i++ |
754 | 754 |
i = encodeVarintOps(dAtA, i, uint64(m.Exec.Size())) |
755 |
- n2, err := m.Exec.MarshalTo(dAtA[i:]) |
|
755 |
+ n4, err := m.Exec.MarshalTo(dAtA[i:]) |
|
756 | 756 |
if err != nil { |
757 | 757 |
return 0, err |
758 | 758 |
} |
759 |
- i += n2 |
|
759 |
+ i += n4 |
|
760 | 760 |
} |
761 | 761 |
return i, nil |
762 | 762 |
} |
... | ... |
@@ -766,11 +888,11 @@ func (m *Op_Source) MarshalTo(dAtA []byte) (int, error) { |
766 | 766 |
dAtA[i] = 0x1a |
767 | 767 |
i++ |
768 | 768 |
i = encodeVarintOps(dAtA, i, uint64(m.Source.Size())) |
769 |
- n3, err := m.Source.MarshalTo(dAtA[i:]) |
|
769 |
+ n5, err := m.Source.MarshalTo(dAtA[i:]) |
|
770 | 770 |
if err != nil { |
771 | 771 |
return 0, err |
772 | 772 |
} |
773 |
- i += n3 |
|
773 |
+ i += n5 |
|
774 | 774 |
} |
775 | 775 |
return i, nil |
776 | 776 |
} |
... | ... |
@@ -780,11 +902,11 @@ func (m *Op_Copy) MarshalTo(dAtA []byte) (int, error) { |
780 | 780 |
dAtA[i] = 0x22 |
781 | 781 |
i++ |
782 | 782 |
i = encodeVarintOps(dAtA, i, uint64(m.Copy.Size())) |
783 |
- n4, err := m.Copy.MarshalTo(dAtA[i:]) |
|
783 |
+ n6, err := m.Copy.MarshalTo(dAtA[i:]) |
|
784 | 784 |
if err != nil { |
785 | 785 |
return 0, err |
786 | 786 |
} |
787 |
- i += n4 |
|
787 |
+ i += n6 |
|
788 | 788 |
} |
789 | 789 |
return i, nil |
790 | 790 |
} |
... | ... |
@@ -794,14 +916,71 @@ func (m *Op_Build) MarshalTo(dAtA []byte) (int, error) { |
794 | 794 |
dAtA[i] = 0x2a |
795 | 795 |
i++ |
796 | 796 |
i = encodeVarintOps(dAtA, i, uint64(m.Build.Size())) |
797 |
- n5, err := m.Build.MarshalTo(dAtA[i:]) |
|
797 |
+ n7, err := m.Build.MarshalTo(dAtA[i:]) |
|
798 | 798 |
if err != nil { |
799 | 799 |
return 0, err |
800 | 800 |
} |
801 |
- i += n5 |
|
801 |
+ i += n7 |
|
802 |
+ } |
|
803 |
+ return i, nil |
|
804 |
+} |
|
805 |
+func (m *Platform) Marshal() (dAtA []byte, err error) { |
|
806 |
+ size := m.Size() |
|
807 |
+ dAtA = make([]byte, size) |
|
808 |
+ n, err := m.MarshalTo(dAtA) |
|
809 |
+ if err != nil { |
|
810 |
+ return nil, err |
|
811 |
+ } |
|
812 |
+ return dAtA[:n], nil |
|
813 |
+} |
|
814 |
+ |
|
815 |
+func (m *Platform) MarshalTo(dAtA []byte) (int, error) { |
|
816 |
+ var i int |
|
817 |
+ _ = i |
|
818 |
+ var l int |
|
819 |
+ _ = l |
|
820 |
+ if len(m.Architecture) > 0 { |
|
821 |
+ dAtA[i] = 0xa |
|
822 |
+ i++ |
|
823 |
+ i = encodeVarintOps(dAtA, i, uint64(len(m.Architecture))) |
|
824 |
+ i += copy(dAtA[i:], m.Architecture) |
|
825 |
+ } |
|
826 |
+ if len(m.OS) > 0 { |
|
827 |
+ dAtA[i] = 0x12 |
|
828 |
+ i++ |
|
829 |
+ i = encodeVarintOps(dAtA, i, uint64(len(m.OS))) |
|
830 |
+ i += copy(dAtA[i:], m.OS) |
|
831 |
+ } |
|
832 |
+ if len(m.Variant) > 0 { |
|
833 |
+ dAtA[i] = 0x1a |
|
834 |
+ i++ |
|
835 |
+ i = encodeVarintOps(dAtA, i, uint64(len(m.Variant))) |
|
836 |
+ i += copy(dAtA[i:], m.Variant) |
|
837 |
+ } |
|
838 |
+ if len(m.OSVersion) > 0 { |
|
839 |
+ dAtA[i] = 0x22 |
|
840 |
+ i++ |
|
841 |
+ i = encodeVarintOps(dAtA, i, uint64(len(m.OSVersion))) |
|
842 |
+ i += copy(dAtA[i:], m.OSVersion) |
|
843 |
+ } |
|
844 |
+ if len(m.OSFeatures) > 0 { |
|
845 |
+ for _, s := range m.OSFeatures { |
|
846 |
+ dAtA[i] = 0x2a |
|
847 |
+ i++ |
|
848 |
+ l = len(s) |
|
849 |
+ for l >= 1<<7 { |
|
850 |
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80) |
|
851 |
+ l >>= 7 |
|
852 |
+ i++ |
|
853 |
+ } |
|
854 |
+ dAtA[i] = uint8(l) |
|
855 |
+ i++ |
|
856 |
+ i += copy(dAtA[i:], s) |
|
857 |
+ } |
|
802 | 858 |
} |
803 | 859 |
return i, nil |
804 | 860 |
} |
861 |
+ |
|
805 | 862 |
func (m *Input) Marshal() (dAtA []byte, err error) { |
806 | 863 |
size := m.Size() |
807 | 864 |
dAtA = make([]byte, size) |
... | ... |
@@ -850,11 +1029,11 @@ func (m *ExecOp) MarshalTo(dAtA []byte) (int, error) { |
850 | 850 |
dAtA[i] = 0xa |
851 | 851 |
i++ |
852 | 852 |
i = encodeVarintOps(dAtA, i, uint64(m.Meta.Size())) |
853 |
- n6, err := m.Meta.MarshalTo(dAtA[i:]) |
|
853 |
+ n8, err := m.Meta.MarshalTo(dAtA[i:]) |
|
854 | 854 |
if err != nil { |
855 | 855 |
return 0, err |
856 | 856 |
} |
857 |
- i += n6 |
|
857 |
+ i += n8 |
|
858 | 858 |
} |
859 | 859 |
if len(m.Mounts) > 0 { |
860 | 860 |
for _, msg := range m.Mounts { |
... | ... |
@@ -932,11 +1111,11 @@ func (m *Meta) MarshalTo(dAtA []byte) (int, error) { |
932 | 932 |
dAtA[i] = 0x2a |
933 | 933 |
i++ |
934 | 934 |
i = encodeVarintOps(dAtA, i, uint64(m.ProxyEnv.Size())) |
935 |
- n7, err := m.ProxyEnv.MarshalTo(dAtA[i:]) |
|
935 |
+ n9, err := m.ProxyEnv.MarshalTo(dAtA[i:]) |
|
936 | 936 |
if err != nil { |
937 | 937 |
return 0, err |
938 | 938 |
} |
939 |
- i += n7 |
|
939 |
+ i += n9 |
|
940 | 940 |
} |
941 | 941 |
return i, nil |
942 | 942 |
} |
... | ... |
@@ -999,11 +1178,11 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) { |
999 | 999 |
dAtA[i] = 0x1 |
1000 | 1000 |
i++ |
1001 | 1001 |
i = encodeVarintOps(dAtA, i, uint64(m.CacheOpt.Size())) |
1002 |
- n8, err := m.CacheOpt.MarshalTo(dAtA[i:]) |
|
1002 |
+ n10, err := m.CacheOpt.MarshalTo(dAtA[i:]) |
|
1003 | 1003 |
if err != nil { |
1004 | 1004 |
return 0, err |
1005 | 1005 |
} |
1006 |
- i += n8 |
|
1006 |
+ i += n10 |
|
1007 | 1007 |
} |
1008 | 1008 |
return i, nil |
1009 | 1009 |
} |
... | ... |
@@ -1029,6 +1208,11 @@ func (m *CacheOpt) MarshalTo(dAtA []byte) (int, error) { |
1029 | 1029 |
i = encodeVarintOps(dAtA, i, uint64(len(m.ID))) |
1030 | 1030 |
i += copy(dAtA[i:], m.ID) |
1031 | 1031 |
} |
1032 |
+ if m.Sharing != 0 { |
|
1033 |
+ dAtA[i] = 0x10 |
|
1034 |
+ i++ |
|
1035 |
+ i = encodeVarintOps(dAtA, i, uint64(m.Sharing)) |
|
1036 |
+ } |
|
1032 | 1037 |
return i, nil |
1033 | 1038 |
} |
1034 | 1039 |
|
... | ... |
@@ -1178,11 +1362,11 @@ func (m *BuildOp) MarshalTo(dAtA []byte) (int, error) { |
1178 | 1178 |
dAtA[i] = 0x12 |
1179 | 1179 |
i++ |
1180 | 1180 |
i = encodeVarintOps(dAtA, i, uint64(v.Size())) |
1181 |
- n9, err := v.MarshalTo(dAtA[i:]) |
|
1181 |
+ n11, err := v.MarshalTo(dAtA[i:]) |
|
1182 | 1182 |
if err != nil { |
1183 | 1183 |
return 0, err |
1184 | 1184 |
} |
1185 |
- i += n9 |
|
1185 |
+ i += n11 |
|
1186 | 1186 |
} |
1187 | 1187 |
} |
1188 | 1188 |
} |
... | ... |
@@ -1190,11 +1374,11 @@ func (m *BuildOp) MarshalTo(dAtA []byte) (int, error) { |
1190 | 1190 |
dAtA[i] = 0x1a |
1191 | 1191 |
i++ |
1192 | 1192 |
i = encodeVarintOps(dAtA, i, uint64(m.Def.Size())) |
1193 |
- n10, err := m.Def.MarshalTo(dAtA[i:]) |
|
1193 |
+ n12, err := m.Def.MarshalTo(dAtA[i:]) |
|
1194 | 1194 |
if err != nil { |
1195 | 1195 |
return 0, err |
1196 | 1196 |
} |
1197 |
- i += n10 |
|
1197 |
+ i += n12 |
|
1198 | 1198 |
} |
1199 | 1199 |
if len(m.Attrs) > 0 { |
1200 | 1200 |
for k, _ := range m.Attrs { |
... | ... |
@@ -1281,25 +1465,15 @@ func (m *OpMetadata) MarshalTo(dAtA []byte) (int, error) { |
1281 | 1281 |
i += copy(dAtA[i:], v) |
1282 | 1282 |
} |
1283 | 1283 |
} |
1284 |
- if m.WorkerConstraint != nil { |
|
1285 |
- dAtA[i] = 0x1a |
|
1286 |
- i++ |
|
1287 |
- i = encodeVarintOps(dAtA, i, uint64(m.WorkerConstraint.Size())) |
|
1288 |
- n11, err := m.WorkerConstraint.MarshalTo(dAtA[i:]) |
|
1289 |
- if err != nil { |
|
1290 |
- return 0, err |
|
1291 |
- } |
|
1292 |
- i += n11 |
|
1293 |
- } |
|
1294 | 1284 |
if m.ExportCache != nil { |
1295 | 1285 |
dAtA[i] = 0x22 |
1296 | 1286 |
i++ |
1297 | 1287 |
i = encodeVarintOps(dAtA, i, uint64(m.ExportCache.Size())) |
1298 |
- n12, err := m.ExportCache.MarshalTo(dAtA[i:]) |
|
1288 |
+ n13, err := m.ExportCache.MarshalTo(dAtA[i:]) |
|
1299 | 1289 |
if err != nil { |
1300 | 1290 |
return 0, err |
1301 | 1291 |
} |
1302 |
- i += n12 |
|
1292 |
+ i += n13 |
|
1303 | 1293 |
} |
1304 | 1294 |
return i, nil |
1305 | 1295 |
} |
... | ... |
@@ -1374,7 +1548,7 @@ func (m *ProxyEnv) MarshalTo(dAtA []byte) (int, error) { |
1374 | 1374 |
return i, nil |
1375 | 1375 |
} |
1376 | 1376 |
|
1377 |
-func (m *WorkerConstraint) Marshal() (dAtA []byte, err error) { |
|
1377 |
+func (m *WorkerConstraints) Marshal() (dAtA []byte, err error) { |
|
1378 | 1378 |
size := m.Size() |
1379 | 1379 |
dAtA = make([]byte, size) |
1380 | 1380 |
n, err := m.MarshalTo(dAtA) |
... | ... |
@@ -1384,7 +1558,7 @@ func (m *WorkerConstraint) Marshal() (dAtA []byte, err error) { |
1384 | 1384 |
return dAtA[:n], nil |
1385 | 1385 |
} |
1386 | 1386 |
|
1387 |
-func (m *WorkerConstraint) MarshalTo(dAtA []byte) (int, error) { |
|
1387 |
+func (m *WorkerConstraints) MarshalTo(dAtA []byte) (int, error) { |
|
1388 | 1388 |
var i int |
1389 | 1389 |
_ = i |
1390 | 1390 |
var l int |
... | ... |
@@ -1449,11 +1623,11 @@ func (m *Definition) MarshalTo(dAtA []byte) (int, error) { |
1449 | 1449 |
dAtA[i] = 0x12 |
1450 | 1450 |
i++ |
1451 | 1451 |
i = encodeVarintOps(dAtA, i, uint64((&v).Size())) |
1452 |
- n13, err := (&v).MarshalTo(dAtA[i:]) |
|
1452 |
+ n14, err := (&v).MarshalTo(dAtA[i:]) |
|
1453 | 1453 |
if err != nil { |
1454 | 1454 |
return 0, err |
1455 | 1455 |
} |
1456 |
- i += n13 |
|
1456 |
+ i += n14 |
|
1457 | 1457 |
} |
1458 | 1458 |
} |
1459 | 1459 |
return i, nil |
... | ... |
@@ -1480,6 +1654,14 @@ func (m *Op) Size() (n int) { |
1480 | 1480 |
if m.Op != nil { |
1481 | 1481 |
n += m.Op.Size() |
1482 | 1482 |
} |
1483 |
+ if m.Platform != nil { |
|
1484 |
+ l = m.Platform.Size() |
|
1485 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1486 |
+ } |
|
1487 |
+ if m.Constraints != nil { |
|
1488 |
+ l = m.Constraints.Size() |
|
1489 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1490 |
+ } |
|
1483 | 1491 |
return n |
1484 | 1492 |
} |
1485 | 1493 |
|
... | ... |
@@ -1519,6 +1701,34 @@ func (m *Op_Build) Size() (n int) { |
1519 | 1519 |
} |
1520 | 1520 |
return n |
1521 | 1521 |
} |
1522 |
+func (m *Platform) Size() (n int) { |
|
1523 |
+ var l int |
|
1524 |
+ _ = l |
|
1525 |
+ l = len(m.Architecture) |
|
1526 |
+ if l > 0 { |
|
1527 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1528 |
+ } |
|
1529 |
+ l = len(m.OS) |
|
1530 |
+ if l > 0 { |
|
1531 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1532 |
+ } |
|
1533 |
+ l = len(m.Variant) |
|
1534 |
+ if l > 0 { |
|
1535 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1536 |
+ } |
|
1537 |
+ l = len(m.OSVersion) |
|
1538 |
+ if l > 0 { |
|
1539 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1540 |
+ } |
|
1541 |
+ if len(m.OSFeatures) > 0 { |
|
1542 |
+ for _, s := range m.OSFeatures { |
|
1543 |
+ l = len(s) |
|
1544 |
+ n += 1 + l + sovOps(uint64(l)) |
|
1545 |
+ } |
|
1546 |
+ } |
|
1547 |
+ return n |
|
1548 |
+} |
|
1549 |
+ |
|
1522 | 1550 |
func (m *Input) Size() (n int) { |
1523 | 1551 |
var l int |
1524 | 1552 |
_ = l |
... | ... |
@@ -1615,6 +1825,9 @@ func (m *CacheOpt) Size() (n int) { |
1615 | 1615 |
if l > 0 { |
1616 | 1616 |
n += 1 + l + sovOps(uint64(l)) |
1617 | 1617 |
} |
1618 |
+ if m.Sharing != 0 { |
|
1619 |
+ n += 1 + sovOps(uint64(m.Sharing)) |
|
1620 |
+ } |
|
1618 | 1621 |
return n |
1619 | 1622 |
} |
1620 | 1623 |
|
... | ... |
@@ -1722,10 +1935,6 @@ func (m *OpMetadata) Size() (n int) { |
1722 | 1722 |
n += mapEntrySize + 1 + sovOps(uint64(mapEntrySize)) |
1723 | 1723 |
} |
1724 | 1724 |
} |
1725 |
- if m.WorkerConstraint != nil { |
|
1726 |
- l = m.WorkerConstraint.Size() |
|
1727 |
- n += 1 + l + sovOps(uint64(l)) |
|
1728 |
- } |
|
1729 | 1725 |
if m.ExportCache != nil { |
1730 | 1726 |
l = m.ExportCache.Size() |
1731 | 1727 |
n += 1 + l + sovOps(uint64(l)) |
... | ... |
@@ -1764,7 +1973,7 @@ func (m *ProxyEnv) Size() (n int) { |
1764 | 1764 |
return n |
1765 | 1765 |
} |
1766 | 1766 |
|
1767 |
-func (m *WorkerConstraint) Size() (n int) { |
|
1767 |
+func (m *WorkerConstraints) Size() (n int) { |
|
1768 | 1768 |
var l int |
1769 | 1769 |
_ = l |
1770 | 1770 |
if len(m.Filter) > 0 { |
... | ... |
@@ -1998,6 +2207,267 @@ func (m *Op) Unmarshal(dAtA []byte) error { |
1998 | 1998 |
} |
1999 | 1999 |
m.Op = &Op_Build{v} |
2000 | 2000 |
iNdEx = postIndex |
2001 |
+ case 10: |
|
2002 |
+ if wireType != 2 { |
|
2003 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType) |
|
2004 |
+ } |
|
2005 |
+ var msglen int |
|
2006 |
+ for shift := uint(0); ; shift += 7 { |
|
2007 |
+ if shift >= 64 { |
|
2008 |
+ return ErrIntOverflowOps |
|
2009 |
+ } |
|
2010 |
+ if iNdEx >= l { |
|
2011 |
+ return io.ErrUnexpectedEOF |
|
2012 |
+ } |
|
2013 |
+ b := dAtA[iNdEx] |
|
2014 |
+ iNdEx++ |
|
2015 |
+ msglen |= (int(b) & 0x7F) << shift |
|
2016 |
+ if b < 0x80 { |
|
2017 |
+ break |
|
2018 |
+ } |
|
2019 |
+ } |
|
2020 |
+ if msglen < 0 { |
|
2021 |
+ return ErrInvalidLengthOps |
|
2022 |
+ } |
|
2023 |
+ postIndex := iNdEx + msglen |
|
2024 |
+ if postIndex > l { |
|
2025 |
+ return io.ErrUnexpectedEOF |
|
2026 |
+ } |
|
2027 |
+ if m.Platform == nil { |
|
2028 |
+ m.Platform = &Platform{} |
|
2029 |
+ } |
|
2030 |
+ if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { |
|
2031 |
+ return err |
|
2032 |
+ } |
|
2033 |
+ iNdEx = postIndex |
|
2034 |
+ case 11: |
|
2035 |
+ if wireType != 2 { |
|
2036 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Constraints", wireType) |
|
2037 |
+ } |
|
2038 |
+ var msglen int |
|
2039 |
+ for shift := uint(0); ; shift += 7 { |
|
2040 |
+ if shift >= 64 { |
|
2041 |
+ return ErrIntOverflowOps |
|
2042 |
+ } |
|
2043 |
+ if iNdEx >= l { |
|
2044 |
+ return io.ErrUnexpectedEOF |
|
2045 |
+ } |
|
2046 |
+ b := dAtA[iNdEx] |
|
2047 |
+ iNdEx++ |
|
2048 |
+ msglen |= (int(b) & 0x7F) << shift |
|
2049 |
+ if b < 0x80 { |
|
2050 |
+ break |
|
2051 |
+ } |
|
2052 |
+ } |
|
2053 |
+ if msglen < 0 { |
|
2054 |
+ return ErrInvalidLengthOps |
|
2055 |
+ } |
|
2056 |
+ postIndex := iNdEx + msglen |
|
2057 |
+ if postIndex > l { |
|
2058 |
+ return io.ErrUnexpectedEOF |
|
2059 |
+ } |
|
2060 |
+ if m.Constraints == nil { |
|
2061 |
+ m.Constraints = &WorkerConstraints{} |
|
2062 |
+ } |
|
2063 |
+ if err := m.Constraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { |
|
2064 |
+ return err |
|
2065 |
+ } |
|
2066 |
+ iNdEx = postIndex |
|
2067 |
+ default: |
|
2068 |
+ iNdEx = preIndex |
|
2069 |
+ skippy, err := skipOps(dAtA[iNdEx:]) |
|
2070 |
+ if err != nil { |
|
2071 |
+ return err |
|
2072 |
+ } |
|
2073 |
+ if skippy < 0 { |
|
2074 |
+ return ErrInvalidLengthOps |
|
2075 |
+ } |
|
2076 |
+ if (iNdEx + skippy) > l { |
|
2077 |
+ return io.ErrUnexpectedEOF |
|
2078 |
+ } |
|
2079 |
+ iNdEx += skippy |
|
2080 |
+ } |
|
2081 |
+ } |
|
2082 |
+ |
|
2083 |
+ if iNdEx > l { |
|
2084 |
+ return io.ErrUnexpectedEOF |
|
2085 |
+ } |
|
2086 |
+ return nil |
|
2087 |
+} |
|
2088 |
+func (m *Platform) Unmarshal(dAtA []byte) error { |
|
2089 |
+ l := len(dAtA) |
|
2090 |
+ iNdEx := 0 |
|
2091 |
+ for iNdEx < l { |
|
2092 |
+ preIndex := iNdEx |
|
2093 |
+ var wire uint64 |
|
2094 |
+ for shift := uint(0); ; shift += 7 { |
|
2095 |
+ if shift >= 64 { |
|
2096 |
+ return ErrIntOverflowOps |
|
2097 |
+ } |
|
2098 |
+ if iNdEx >= l { |
|
2099 |
+ return io.ErrUnexpectedEOF |
|
2100 |
+ } |
|
2101 |
+ b := dAtA[iNdEx] |
|
2102 |
+ iNdEx++ |
|
2103 |
+ wire |= (uint64(b) & 0x7F) << shift |
|
2104 |
+ if b < 0x80 { |
|
2105 |
+ break |
|
2106 |
+ } |
|
2107 |
+ } |
|
2108 |
+ fieldNum := int32(wire >> 3) |
|
2109 |
+ wireType := int(wire & 0x7) |
|
2110 |
+ if wireType == 4 { |
|
2111 |
+ return fmt.Errorf("proto: Platform: wiretype end group for non-group") |
|
2112 |
+ } |
|
2113 |
+ if fieldNum <= 0 { |
|
2114 |
+ return fmt.Errorf("proto: Platform: illegal tag %d (wire type %d)", fieldNum, wire) |
|
2115 |
+ } |
|
2116 |
+ switch fieldNum { |
|
2117 |
+ case 1: |
|
2118 |
+ if wireType != 2 { |
|
2119 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Architecture", wireType) |
|
2120 |
+ } |
|
2121 |
+ var stringLen uint64 |
|
2122 |
+ for shift := uint(0); ; shift += 7 { |
|
2123 |
+ if shift >= 64 { |
|
2124 |
+ return ErrIntOverflowOps |
|
2125 |
+ } |
|
2126 |
+ if iNdEx >= l { |
|
2127 |
+ return io.ErrUnexpectedEOF |
|
2128 |
+ } |
|
2129 |
+ b := dAtA[iNdEx] |
|
2130 |
+ iNdEx++ |
|
2131 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
2132 |
+ if b < 0x80 { |
|
2133 |
+ break |
|
2134 |
+ } |
|
2135 |
+ } |
|
2136 |
+ intStringLen := int(stringLen) |
|
2137 |
+ if intStringLen < 0 { |
|
2138 |
+ return ErrInvalidLengthOps |
|
2139 |
+ } |
|
2140 |
+ postIndex := iNdEx + intStringLen |
|
2141 |
+ if postIndex > l { |
|
2142 |
+ return io.ErrUnexpectedEOF |
|
2143 |
+ } |
|
2144 |
+ m.Architecture = string(dAtA[iNdEx:postIndex]) |
|
2145 |
+ iNdEx = postIndex |
|
2146 |
+ case 2: |
|
2147 |
+ if wireType != 2 { |
|
2148 |
+ return fmt.Errorf("proto: wrong wireType = %d for field OS", wireType) |
|
2149 |
+ } |
|
2150 |
+ var stringLen uint64 |
|
2151 |
+ for shift := uint(0); ; shift += 7 { |
|
2152 |
+ if shift >= 64 { |
|
2153 |
+ return ErrIntOverflowOps |
|
2154 |
+ } |
|
2155 |
+ if iNdEx >= l { |
|
2156 |
+ return io.ErrUnexpectedEOF |
|
2157 |
+ } |
|
2158 |
+ b := dAtA[iNdEx] |
|
2159 |
+ iNdEx++ |
|
2160 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
2161 |
+ if b < 0x80 { |
|
2162 |
+ break |
|
2163 |
+ } |
|
2164 |
+ } |
|
2165 |
+ intStringLen := int(stringLen) |
|
2166 |
+ if intStringLen < 0 { |
|
2167 |
+ return ErrInvalidLengthOps |
|
2168 |
+ } |
|
2169 |
+ postIndex := iNdEx + intStringLen |
|
2170 |
+ if postIndex > l { |
|
2171 |
+ return io.ErrUnexpectedEOF |
|
2172 |
+ } |
|
2173 |
+ m.OS = string(dAtA[iNdEx:postIndex]) |
|
2174 |
+ iNdEx = postIndex |
|
2175 |
+ case 3: |
|
2176 |
+ if wireType != 2 { |
|
2177 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Variant", wireType) |
|
2178 |
+ } |
|
2179 |
+ var stringLen uint64 |
|
2180 |
+ for shift := uint(0); ; shift += 7 { |
|
2181 |
+ if shift >= 64 { |
|
2182 |
+ return ErrIntOverflowOps |
|
2183 |
+ } |
|
2184 |
+ if iNdEx >= l { |
|
2185 |
+ return io.ErrUnexpectedEOF |
|
2186 |
+ } |
|
2187 |
+ b := dAtA[iNdEx] |
|
2188 |
+ iNdEx++ |
|
2189 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
2190 |
+ if b < 0x80 { |
|
2191 |
+ break |
|
2192 |
+ } |
|
2193 |
+ } |
|
2194 |
+ intStringLen := int(stringLen) |
|
2195 |
+ if intStringLen < 0 { |
|
2196 |
+ return ErrInvalidLengthOps |
|
2197 |
+ } |
|
2198 |
+ postIndex := iNdEx + intStringLen |
|
2199 |
+ if postIndex > l { |
|
2200 |
+ return io.ErrUnexpectedEOF |
|
2201 |
+ } |
|
2202 |
+ m.Variant = string(dAtA[iNdEx:postIndex]) |
|
2203 |
+ iNdEx = postIndex |
|
2204 |
+ case 4: |
|
2205 |
+ if wireType != 2 { |
|
2206 |
+ return fmt.Errorf("proto: wrong wireType = %d for field OSVersion", wireType) |
|
2207 |
+ } |
|
2208 |
+ var stringLen uint64 |
|
2209 |
+ for shift := uint(0); ; shift += 7 { |
|
2210 |
+ if shift >= 64 { |
|
2211 |
+ return ErrIntOverflowOps |
|
2212 |
+ } |
|
2213 |
+ if iNdEx >= l { |
|
2214 |
+ return io.ErrUnexpectedEOF |
|
2215 |
+ } |
|
2216 |
+ b := dAtA[iNdEx] |
|
2217 |
+ iNdEx++ |
|
2218 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
2219 |
+ if b < 0x80 { |
|
2220 |
+ break |
|
2221 |
+ } |
|
2222 |
+ } |
|
2223 |
+ intStringLen := int(stringLen) |
|
2224 |
+ if intStringLen < 0 { |
|
2225 |
+ return ErrInvalidLengthOps |
|
2226 |
+ } |
|
2227 |
+ postIndex := iNdEx + intStringLen |
|
2228 |
+ if postIndex > l { |
|
2229 |
+ return io.ErrUnexpectedEOF |
|
2230 |
+ } |
|
2231 |
+ m.OSVersion = string(dAtA[iNdEx:postIndex]) |
|
2232 |
+ iNdEx = postIndex |
|
2233 |
+ case 5: |
|
2234 |
+ if wireType != 2 { |
|
2235 |
+ return fmt.Errorf("proto: wrong wireType = %d for field OSFeatures", wireType) |
|
2236 |
+ } |
|
2237 |
+ var stringLen uint64 |
|
2238 |
+ for shift := uint(0); ; shift += 7 { |
|
2239 |
+ if shift >= 64 { |
|
2240 |
+ return ErrIntOverflowOps |
|
2241 |
+ } |
|
2242 |
+ if iNdEx >= l { |
|
2243 |
+ return io.ErrUnexpectedEOF |
|
2244 |
+ } |
|
2245 |
+ b := dAtA[iNdEx] |
|
2246 |
+ iNdEx++ |
|
2247 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
2248 |
+ if b < 0x80 { |
|
2249 |
+ break |
|
2250 |
+ } |
|
2251 |
+ } |
|
2252 |
+ intStringLen := int(stringLen) |
|
2253 |
+ if intStringLen < 0 { |
|
2254 |
+ return ErrInvalidLengthOps |
|
2255 |
+ } |
|
2256 |
+ postIndex := iNdEx + intStringLen |
|
2257 |
+ if postIndex > l { |
|
2258 |
+ return io.ErrUnexpectedEOF |
|
2259 |
+ } |
|
2260 |
+ m.OSFeatures = append(m.OSFeatures, string(dAtA[iNdEx:postIndex])) |
|
2261 |
+ iNdEx = postIndex |
|
2001 | 2262 |
default: |
2002 | 2263 |
iNdEx = preIndex |
2003 | 2264 |
skippy, err := skipOps(dAtA[iNdEx:]) |
... | ... |
@@ -2706,6 +3176,25 @@ func (m *CacheOpt) Unmarshal(dAtA []byte) error { |
2706 | 2706 |
} |
2707 | 2707 |
m.ID = string(dAtA[iNdEx:postIndex]) |
2708 | 2708 |
iNdEx = postIndex |
2709 |
+ case 2: |
|
2710 |
+ if wireType != 0 { |
|
2711 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Sharing", wireType) |
|
2712 |
+ } |
|
2713 |
+ m.Sharing = 0 |
|
2714 |
+ for shift := uint(0); ; shift += 7 { |
|
2715 |
+ if shift >= 64 { |
|
2716 |
+ return ErrIntOverflowOps |
|
2717 |
+ } |
|
2718 |
+ if iNdEx >= l { |
|
2719 |
+ return io.ErrUnexpectedEOF |
|
2720 |
+ } |
|
2721 |
+ b := dAtA[iNdEx] |
|
2722 |
+ iNdEx++ |
|
2723 |
+ m.Sharing |= (CacheSharingOpt(b) & 0x7F) << shift |
|
2724 |
+ if b < 0x80 { |
|
2725 |
+ break |
|
2726 |
+ } |
|
2727 |
+ } |
|
2709 | 2728 |
default: |
2710 | 2729 |
iNdEx = preIndex |
2711 | 2730 |
skippy, err := skipOps(dAtA[iNdEx:]) |
... | ... |
@@ -3711,39 +4200,6 @@ func (m *OpMetadata) Unmarshal(dAtA []byte) error { |
3711 | 3711 |
} |
3712 | 3712 |
m.Description[mapkey] = mapvalue |
3713 | 3713 |
iNdEx = postIndex |
3714 |
- case 3: |
|
3715 |
- if wireType != 2 { |
|
3716 |
- return fmt.Errorf("proto: wrong wireType = %d for field WorkerConstraint", wireType) |
|
3717 |
- } |
|
3718 |
- var msglen int |
|
3719 |
- for shift := uint(0); ; shift += 7 { |
|
3720 |
- if shift >= 64 { |
|
3721 |
- return ErrIntOverflowOps |
|
3722 |
- } |
|
3723 |
- if iNdEx >= l { |
|
3724 |
- return io.ErrUnexpectedEOF |
|
3725 |
- } |
|
3726 |
- b := dAtA[iNdEx] |
|
3727 |
- iNdEx++ |
|
3728 |
- msglen |= (int(b) & 0x7F) << shift |
|
3729 |
- if b < 0x80 { |
|
3730 |
- break |
|
3731 |
- } |
|
3732 |
- } |
|
3733 |
- if msglen < 0 { |
|
3734 |
- return ErrInvalidLengthOps |
|
3735 |
- } |
|
3736 |
- postIndex := iNdEx + msglen |
|
3737 |
- if postIndex > l { |
|
3738 |
- return io.ErrUnexpectedEOF |
|
3739 |
- } |
|
3740 |
- if m.WorkerConstraint == nil { |
|
3741 |
- m.WorkerConstraint = &WorkerConstraint{} |
|
3742 |
- } |
|
3743 |
- if err := m.WorkerConstraint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { |
|
3744 |
- return err |
|
3745 |
- } |
|
3746 |
- iNdEx = postIndex |
|
3747 | 3714 |
case 4: |
3748 | 3715 |
if wireType != 2 { |
3749 | 3716 |
return fmt.Errorf("proto: wrong wireType = %d for field ExportCache", wireType) |
... | ... |
@@ -4034,7 +4490,7 @@ func (m *ProxyEnv) Unmarshal(dAtA []byte) error { |
4034 | 4034 |
} |
4035 | 4035 |
return nil |
4036 | 4036 |
} |
4037 |
-func (m *WorkerConstraint) Unmarshal(dAtA []byte) error { |
|
4037 |
+func (m *WorkerConstraints) Unmarshal(dAtA []byte) error { |
|
4038 | 4038 |
l := len(dAtA) |
4039 | 4039 |
iNdEx := 0 |
4040 | 4040 |
for iNdEx < l { |
... | ... |
@@ -4057,10 +4513,10 @@ func (m *WorkerConstraint) Unmarshal(dAtA []byte) error { |
4057 | 4057 |
fieldNum := int32(wire >> 3) |
4058 | 4058 |
wireType := int(wire & 0x7) |
4059 | 4059 |
if wireType == 4 { |
4060 |
- return fmt.Errorf("proto: WorkerConstraint: wiretype end group for non-group") |
|
4060 |
+ return fmt.Errorf("proto: WorkerConstraints: wiretype end group for non-group") |
|
4061 | 4061 |
} |
4062 | 4062 |
if fieldNum <= 0 { |
4063 |
- return fmt.Errorf("proto: WorkerConstraint: illegal tag %d (wire type %d)", fieldNum, wire) |
|
4063 |
+ return fmt.Errorf("proto: WorkerConstraints: illegal tag %d (wire type %d)", fieldNum, wire) |
|
4064 | 4064 |
} |
4065 | 4065 |
switch fieldNum { |
4066 | 4066 |
case 1: |
... | ... |
@@ -4423,72 +4879,81 @@ var ( |
4423 | 4423 |
func init() { proto.RegisterFile("ops.proto", fileDescriptorOps) } |
4424 | 4424 |
|
4425 | 4425 |
var fileDescriptorOps = []byte{ |
4426 |
- // 1062 bytes of a gzipped FileDescriptorProto |
|
4427 |
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, |
|
4428 |
- 0x17, 0xcf, 0xae, 0x3f, 0xb2, 0x7b, 0x36, 0xed, 0xdf, 0xff, 0x21, 0x2a, 0xc6, 0x94, 0xc4, 0x6c, |
|
4429 |
- 0x11, 0x72, 0xd3, 0xc6, 0x91, 0x8c, 0x84, 0x2a, 0x2e, 0x2a, 0xe2, 0x0f, 0x14, 0x83, 0x42, 0xaa, |
|
4430 |
- 0x49, 0x04, 0x97, 0x91, 0xbd, 0x1e, 0x3b, 0xab, 0x3a, 0x3b, 0xab, 0xdd, 0xd9, 0x24, 0xbe, 0x00, |
|
4431 |
- 0x89, 0x3e, 0x01, 0x12, 0x4f, 0xc1, 0x43, 0xc0, 0x75, 0x2f, 0xb9, 0x85, 0x8b, 0x82, 0xc2, 0x8b, |
|
4432 |
- 0xa0, 0x73, 0x66, 0xbc, 0xeb, 0x86, 0x22, 0xb5, 0x82, 0x2b, 0xcf, 0x9c, 0xf3, 0x3b, 0x67, 0xce, |
|
4433 |
- 0xf9, 0x9d, 0x8f, 0x35, 0xb8, 0x32, 0x4e, 0xdb, 0x71, 0x22, 0x95, 0x64, 0x76, 0x3c, 0x6e, 0xec, |
|
4434 |
- 0xce, 0x42, 0x75, 0x96, 0x8d, 0xdb, 0x81, 0x3c, 0xdf, 0x9b, 0xc9, 0x99, 0xdc, 0x23, 0xd5, 0x38, |
|
4435 |
- 0x9b, 0xd2, 0x8d, 0x2e, 0x74, 0xd2, 0x26, 0xfe, 0xcf, 0x16, 0xd8, 0x47, 0x31, 0x7b, 0x1f, 0xaa, |
|
4436 |
- 0x61, 0x14, 0x67, 0x2a, 0xad, 0x5b, 0xcd, 0x52, 0xcb, 0xeb, 0xb8, 0xed, 0x78, 0xdc, 0x1e, 0xa2, |
|
4437 |
- 0x84, 0x1b, 0x05, 0x6b, 0x42, 0x59, 0x5c, 0x89, 0xa0, 0x6e, 0x37, 0xad, 0x96, 0xd7, 0x01, 0x04, |
|
4438 |
- 0x0c, 0xae, 0x44, 0x70, 0x14, 0x1f, 0xac, 0x71, 0xd2, 0xb0, 0x0f, 0xa1, 0x9a, 0xca, 0x2c, 0x09, |
|
4439 |
- 0x44, 0xbd, 0x44, 0x98, 0x0d, 0xc4, 0x1c, 0x93, 0x84, 0x50, 0x46, 0x8b, 0x9e, 0x02, 0x19, 0x2f, |
|
4440 |
- 0xea, 0xe5, 0xc2, 0x53, 0x4f, 0xc6, 0x0b, 0xed, 0x09, 0x35, 0xec, 0x1e, 0x54, 0xc6, 0x59, 0x38, |
|
4441 |
- 0x9f, 0xd4, 0x2b, 0x04, 0xf1, 0x10, 0xd2, 0x45, 0x01, 0x61, 0xb4, 0xae, 0x5b, 0x06, 0x5b, 0xc6, |
|
4442 |
- 0xfe, 0xb7, 0x50, 0xa1, 0x38, 0xd9, 0xe7, 0x50, 0x9d, 0x84, 0x33, 0x91, 0xaa, 0xba, 0xd5, 0xb4, |
|
4443 |
- 0x5a, 0x6e, 0xb7, 0xf3, 0xfc, 0xc5, 0xf6, 0xda, 0x6f, 0x2f, 0xb6, 0x77, 0x56, 0x08, 0x91, 0xb1, |
|
4444 |
- 0x88, 0x02, 0x19, 0xa9, 0x51, 0x18, 0x89, 0x24, 0xdd, 0x9b, 0xc9, 0x5d, 0x6d, 0xd2, 0xee, 0xd3, |
|
4445 |
- 0x0f, 0x37, 0x1e, 0xd8, 0x7d, 0xa8, 0x84, 0xd1, 0x44, 0x5c, 0x51, 0xb2, 0xa5, 0xee, 0x5b, 0xc6, |
|
4446 |
- 0x95, 0x77, 0x94, 0xa9, 0x38, 0x53, 0x43, 0x54, 0x71, 0x8d, 0xf0, 0x87, 0x50, 0xd5, 0x34, 0xb0, |
|
4447 |
- 0xbb, 0x50, 0x3e, 0x17, 0x6a, 0x44, 0xcf, 0x7b, 0x1d, 0x07, 0x63, 0x3e, 0x14, 0x6a, 0xc4, 0x49, |
|
4448 |
- 0x8a, 0x0c, 0x9f, 0xcb, 0x2c, 0x52, 0x69, 0xdd, 0x2e, 0x18, 0x3e, 0x44, 0x09, 0x37, 0x0a, 0xff, |
|
4449 |
- 0x1b, 0x28, 0xa3, 0x01, 0x63, 0x50, 0x1e, 0x25, 0x33, 0x5d, 0x0a, 0x97, 0xd3, 0x99, 0xd5, 0xa0, |
|
4450 |
- 0x24, 0xa2, 0x0b, 0xb2, 0x75, 0x39, 0x1e, 0x51, 0x12, 0x5c, 0x4e, 0x88, 0x6a, 0x97, 0xe3, 0x11, |
|
4451 |
- 0xed, 0xb2, 0x54, 0x24, 0xc4, 0xab, 0xcb, 0xe9, 0xcc, 0xee, 0x83, 0x1b, 0x27, 0xf2, 0x6a, 0x71, |
|
4452 |
- 0x8a, 0xd6, 0x95, 0xa2, 0x2c, 0x4f, 0x50, 0x38, 0x88, 0x2e, 0xb8, 0x13, 0x9b, 0x93, 0xff, 0x9d, |
|
4453 |
- 0x0d, 0x15, 0x0a, 0x88, 0xb5, 0x30, 0xfd, 0x38, 0xd3, 0x4c, 0x96, 0xba, 0xcc, 0xa4, 0x0f, 0x44, |
|
4454 |
- 0x74, 0x9e, 0x3d, 0x92, 0xde, 0x00, 0x27, 0x15, 0x73, 0x11, 0x28, 0x99, 0x10, 0x57, 0x2e, 0xcf, |
|
4455 |
- 0xef, 0x18, 0xce, 0x04, 0xcb, 0xa1, 0x23, 0xa4, 0x33, 0x7b, 0x00, 0x55, 0x49, 0x1c, 0x52, 0x90, |
|
4456 |
- 0xff, 0xc0, 0xac, 0x81, 0xa0, 0xf3, 0x44, 0x8c, 0x26, 0x32, 0x9a, 0x2f, 0x28, 0x74, 0x87, 0xe7, |
|
4457 |
- 0x77, 0xf6, 0x00, 0x5c, 0x62, 0xed, 0x64, 0x11, 0x8b, 0x7a, 0xb5, 0x69, 0xb5, 0x6e, 0x77, 0x6e, |
|
4458 |
- 0xe5, 0x8c, 0xa2, 0x90, 0x17, 0x7a, 0xd6, 0x02, 0x27, 0x18, 0x05, 0x67, 0xe2, 0x28, 0x56, 0xf5, |
|
4459 |
- 0xcd, 0x82, 0x83, 0x9e, 0x91, 0xf1, 0x5c, 0xeb, 0x37, 0xc0, 0x59, 0x4a, 0xd9, 0x6d, 0xb0, 0x87, |
|
4460 |
- 0x7d, 0xdd, 0x4c, 0xdc, 0x1e, 0xf6, 0xfd, 0xc7, 0x50, 0xd5, 0x6d, 0xca, 0x9a, 0x50, 0x4a, 0x93, |
|
4461 |
- 0xc0, 0x8c, 0xca, 0xed, 0x65, 0xff, 0xea, 0x4e, 0xe7, 0xa8, 0xca, 0x73, 0xb7, 0x8b, 0xdc, 0x7d, |
|
4462 |
- 0x0e, 0x50, 0xc0, 0xfe, 0x1b, 0x8e, 0xfd, 0x1f, 0x2c, 0x70, 0x96, 0x13, 0xc6, 0xb6, 0x00, 0xc2, |
|
4463 |
- 0x89, 0x88, 0x54, 0x38, 0x0d, 0x45, 0x62, 0x02, 0x5f, 0x91, 0xb0, 0x5d, 0xa8, 0x8c, 0x94, 0x4a, |
|
4464 |
- 0x96, 0x1d, 0xf8, 0xf6, 0xea, 0x78, 0xb6, 0xf7, 0x51, 0x33, 0x88, 0x54, 0xb2, 0xe0, 0x1a, 0xd5, |
|
4465 |
- 0x78, 0x04, 0x50, 0x08, 0xb1, 0xdd, 0x9e, 0x8a, 0x85, 0xf1, 0x8a, 0x47, 0xb6, 0x09, 0x95, 0x8b, |
|
4466 |
- 0xd1, 0x3c, 0x13, 0x26, 0x28, 0x7d, 0xf9, 0xc4, 0x7e, 0x64, 0xf9, 0x3f, 0xd9, 0xb0, 0x6e, 0xc6, |
|
4467 |
- 0x95, 0x3d, 0x84, 0x75, 0x1a, 0x57, 0x13, 0xd1, 0xab, 0x33, 0x5d, 0x42, 0xd8, 0x5e, 0xbe, 0x87, |
|
4468 |
- 0x56, 0x62, 0x34, 0xae, 0xf4, 0x3e, 0x32, 0x31, 0x16, 0x5b, 0xa9, 0x34, 0x11, 0x53, 0xb3, 0x70, |
|
4469 |
- 0xa8, 0x14, 0x7d, 0x31, 0x0d, 0xa3, 0x50, 0x85, 0x32, 0xe2, 0xa8, 0x62, 0x0f, 0x97, 0x59, 0x97, |
|
4470 |
- 0xc9, 0xe3, 0x9d, 0x55, 0x8f, 0x7f, 0x4f, 0x7a, 0x08, 0xde, 0xca, 0x33, 0xaf, 0xc8, 0xfa, 0x83, |
|
4471 |
- 0xd5, 0xac, 0xcd, 0x93, 0xe4, 0x4e, 0x6f, 0xcb, 0x82, 0x85, 0x7f, 0xc1, 0xdf, 0xc7, 0x00, 0x85, |
|
4472 |
- 0xcb, 0xd7, 0xef, 0x14, 0xff, 0x47, 0x1b, 0xe0, 0x28, 0xc6, 0x1d, 0x32, 0x19, 0xd1, 0xca, 0xd9, |
|
4473 |
- 0x08, 0x67, 0x91, 0x4c, 0xc4, 0x29, 0xf5, 0x37, 0xd9, 0x3b, 0xdc, 0xd3, 0x32, 0x6a, 0x73, 0xb6, |
|
4474 |
- 0x0f, 0xde, 0x44, 0xa4, 0x41, 0x12, 0xc6, 0x48, 0x98, 0x21, 0x7d, 0x1b, 0x73, 0x2a, 0xfc, 0xb4, |
|
4475 |
- 0xfb, 0x05, 0x42, 0x73, 0xb5, 0x6a, 0xc3, 0xf6, 0xe1, 0xff, 0x97, 0x32, 0x79, 0x2a, 0x92, 0xd3, |
|
4476 |
- 0x40, 0x46, 0xa9, 0x4a, 0x46, 0x61, 0xa4, 0x4c, 0x3d, 0x36, 0xd1, 0xd1, 0xd7, 0xa4, 0xec, 0xe5, |
|
4477 |
- 0x3a, 0x5e, 0xbb, 0xbc, 0x21, 0x61, 0x1d, 0xd8, 0x10, 0x57, 0xb1, 0x4c, 0x94, 0x09, 0x54, 0x7f, |
|
4478 |
- 0x18, 0xfe, 0xa7, 0x3f, 0x31, 0x28, 0xa7, 0x60, 0xb9, 0x27, 0x8a, 0x4b, 0xe3, 0x31, 0xd4, 0x6e, |
|
4479 |
- 0xc6, 0xf5, 0x46, 0x1c, 0xdf, 0x03, 0x6f, 0xc5, 0x37, 0x02, 0xbf, 0x22, 0xa0, 0x26, 0x49, 0x5f, |
|
4480 |
- 0xfc, 0x67, 0x16, 0x38, 0xcb, 0x4d, 0xc9, 0xde, 0x03, 0x38, 0x53, 0x2a, 0x3e, 0xa5, 0x85, 0x69, |
|
4481 |
- 0x1e, 0x71, 0x51, 0x42, 0x08, 0xb6, 0x0d, 0x1e, 0x5e, 0x52, 0xa3, 0xd7, 0x0f, 0x92, 0x45, 0xaa, |
|
4482 |
- 0x01, 0xef, 0x82, 0x3b, 0xcd, 0xcd, 0xf5, 0x52, 0x74, 0xa6, 0x4b, 0xeb, 0x77, 0xc0, 0x89, 0xa4, |
|
4483 |
- 0xd1, 0xe9, 0xfd, 0xbd, 0x1e, 0x49, 0x52, 0xf9, 0x3b, 0x50, 0xbb, 0xc9, 0x21, 0xbb, 0x03, 0xd5, |
|
4484 |
- 0x69, 0x38, 0x57, 0x34, 0x54, 0xf8, 0x45, 0x30, 0x37, 0xff, 0x57, 0x0b, 0xa0, 0x18, 0x00, 0x24, |
|
4485 |
- 0x04, 0xa7, 0x03, 0x31, 0x1b, 0x7a, 0x1a, 0xe6, 0xe0, 0x9c, 0x9b, 0xba, 0x9a, 0x6a, 0xdf, 0x7d, |
|
4486 |
- 0x79, 0x68, 0xda, 0xcb, 0xb2, 0x13, 0xa5, 0xfa, 0x2b, 0xfa, 0xec, 0xf7, 0x37, 0xfa, 0x8a, 0xe6, |
|
4487 |
- 0x2f, 0x34, 0xbe, 0x80, 0x5b, 0x2f, 0xb9, 0x7b, 0xcd, 0x79, 0x2a, 0x7a, 0x6f, 0xa5, 0x62, 0x3b, |
|
4488 |
- 0x9f, 0x82, 0x9b, 0x6f, 0x77, 0xe6, 0x40, 0xb9, 0x3b, 0xfc, 0xb2, 0x5f, 0x5b, 0x63, 0x00, 0xd5, |
|
4489 |
- 0xe3, 0x41, 0x8f, 0x0f, 0x4e, 0x6a, 0x16, 0x5b, 0x87, 0xd2, 0xf1, 0xf1, 0x41, 0xcd, 0x66, 0x2e, |
|
4490 |
- 0x54, 0x7a, 0xfb, 0xbd, 0x83, 0x41, 0xad, 0x84, 0xc7, 0x93, 0xc3, 0x27, 0x9f, 0x1d, 0xd7, 0xca, |
|
4491 |
- 0xdd, 0xda, 0xf3, 0xeb, 0x2d, 0xeb, 0x97, 0xeb, 0x2d, 0xeb, 0x8f, 0xeb, 0x2d, 0xeb, 0xfb, 0x3f, |
|
4492 |
- 0xb7, 0xd6, 0xc6, 0x55, 0xfa, 0x17, 0xf4, 0xd1, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x76, |
|
4493 |
- 0x25, 0x54, 0x45, 0x09, 0x00, 0x00, |
|
4426 |
+ // 1203 bytes of a gzipped FileDescriptorProto |
|
4427 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4d, 0x8f, 0x1b, 0x45, |
|
4428 |
+ 0x13, 0xde, 0x19, 0x7f, 0xcd, 0xd4, 0x6c, 0x36, 0x7e, 0x3b, 0x79, 0x83, 0x59, 0xc2, 0xae, 0x99, |
|
4429 |
+ 0x20, 0xe4, 0x7c, 0xac, 0x57, 0x32, 0x52, 0x88, 0x38, 0x44, 0xac, 0x3f, 0xa2, 0x35, 0x21, 0x38, |
|
4430 |
+ 0x6a, 0xaf, 0x96, 0x63, 0x34, 0x1e, 0xb7, 0xbd, 0xa3, 0x78, 0xa7, 0x47, 0x3d, 0xed, 0xb0, 0x3e, |
|
4431 |
+ 0x80, 0x44, 0x7e, 0x01, 0x12, 0x12, 0x77, 0x7e, 0x08, 0xf7, 0x1c, 0xb9, 0xc2, 0x21, 0xa0, 0x20, |
|
4432 |
+ 0xf1, 0x3b, 0x50, 0x75, 0xb7, 0x67, 0x66, 0x93, 0x20, 0x25, 0x82, 0x93, 0xbb, 0xab, 0x9e, 0x7a, |
|
4433 |
+ 0xba, 0xea, 0xe9, 0x9a, 0x6a, 0x83, 0xcb, 0x93, 0xb4, 0x9d, 0x08, 0x2e, 0x39, 0xb1, 0x93, 0xc9, |
|
4434 |
+ 0xf6, 0xde, 0x3c, 0x92, 0x27, 0xcb, 0x49, 0x3b, 0xe4, 0xa7, 0xfb, 0x73, 0x3e, 0xe7, 0xfb, 0xca, |
|
4435 |
+ 0x35, 0x59, 0xce, 0xd4, 0x4e, 0x6d, 0xd4, 0x4a, 0x87, 0xf8, 0x3f, 0xd9, 0x60, 0x8f, 0x12, 0xf2, |
|
4436 |
+ 0x01, 0x54, 0xa3, 0x38, 0x59, 0xca, 0xb4, 0x61, 0x35, 0x4b, 0x2d, 0xaf, 0xe3, 0xb6, 0x93, 0x49, |
|
4437 |
+ 0x7b, 0x88, 0x16, 0x6a, 0x1c, 0xa4, 0x09, 0x65, 0x76, 0xc6, 0xc2, 0x86, 0xdd, 0xb4, 0x5a, 0x5e, |
|
4438 |
+ 0x07, 0x10, 0x30, 0x38, 0x63, 0xe1, 0x28, 0x39, 0xdc, 0xa0, 0xca, 0x43, 0x3e, 0x82, 0x6a, 0xca, |
|
4439 |
+ 0x97, 0x22, 0x64, 0x8d, 0x92, 0xc2, 0x6c, 0x22, 0x66, 0xac, 0x2c, 0x0a, 0x65, 0xbc, 0xc8, 0x14, |
|
4440 |
+ 0xf2, 0x64, 0xd5, 0x28, 0xe7, 0x4c, 0x3d, 0x9e, 0xac, 0x34, 0x13, 0x7a, 0xc8, 0x35, 0xa8, 0x4c, |
|
4441 |
+ 0x96, 0xd1, 0x62, 0xda, 0xa8, 0x28, 0x88, 0x87, 0x90, 0x2e, 0x1a, 0x14, 0x46, 0xfb, 0x48, 0x0b, |
|
4442 |
+ 0x9c, 0x64, 0x11, 0xc8, 0x19, 0x17, 0xa7, 0x0d, 0xc8, 0x0f, 0x7c, 0x68, 0x6c, 0x34, 0xf3, 0x92, |
|
4443 |
+ 0x4f, 0xc0, 0x0b, 0x79, 0x9c, 0x4a, 0x11, 0x44, 0xb1, 0x4c, 0x1b, 0x9e, 0x02, 0xff, 0x1f, 0xc1, |
|
4444 |
+ 0x5f, 0x71, 0xf1, 0x98, 0x89, 0x5e, 0xee, 0xa4, 0x45, 0x64, 0xb7, 0x0c, 0x36, 0x4f, 0xfc, 0x1f, |
|
4445 |
+ 0x2d, 0x70, 0xd6, 0xac, 0xc4, 0x87, 0xcd, 0x03, 0x11, 0x9e, 0x44, 0x92, 0x85, 0x72, 0x29, 0x58, |
|
4446 |
+ 0xc3, 0x6a, 0x5a, 0x2d, 0x97, 0x9e, 0xb3, 0x91, 0x2d, 0xb0, 0x47, 0x63, 0x25, 0x94, 0x4b, 0xed, |
|
4447 |
+ 0xd1, 0x98, 0x34, 0xa0, 0x76, 0x1c, 0x88, 0x28, 0x88, 0xa5, 0x52, 0xc6, 0xa5, 0xeb, 0x2d, 0xb9, |
|
4448 |
+ 0x0a, 0xee, 0x68, 0x7c, 0xcc, 0x44, 0x1a, 0xf1, 0x58, 0xe9, 0xe1, 0xd2, 0xdc, 0x40, 0x76, 0x00, |
|
4449 |
+ 0x46, 0xe3, 0x7b, 0x2c, 0x40, 0xd2, 0xb4, 0x51, 0x69, 0x96, 0x5a, 0x2e, 0x2d, 0x58, 0xfc, 0x6f, |
|
4450 |
+ 0xa1, 0xa2, 0xee, 0x88, 0x7c, 0x0e, 0xd5, 0x69, 0x34, 0x67, 0xa9, 0xd4, 0xe9, 0x74, 0x3b, 0xcf, |
|
4451 |
+ 0x9e, 0xef, 0x6e, 0xfc, 0xf6, 0x7c, 0xf7, 0x46, 0xa1, 0x19, 0x78, 0xc2, 0xe2, 0x90, 0xc7, 0x32, |
|
4452 |
+ 0x88, 0x62, 0x26, 0xd2, 0xfd, 0x39, 0xdf, 0xd3, 0x21, 0xed, 0xbe, 0xfa, 0xa1, 0x86, 0x81, 0x5c, |
|
4453 |
+ 0x87, 0x4a, 0x14, 0x4f, 0xd9, 0x99, 0xca, 0xbf, 0xd4, 0xbd, 0x64, 0xa8, 0xbc, 0xd1, 0x52, 0x26, |
|
4454 |
+ 0x4b, 0x39, 0x44, 0x17, 0xd5, 0x08, 0x7f, 0x08, 0x55, 0xdd, 0x02, 0xe4, 0x2a, 0x94, 0x4f, 0x99, |
|
4455 |
+ 0x0c, 0xd4, 0xf1, 0x5e, 0xc7, 0x41, 0x69, 0x1f, 0x30, 0x19, 0x50, 0x65, 0xc5, 0xee, 0x3a, 0xe5, |
|
4456 |
+ 0x4b, 0x94, 0xde, 0xce, 0xbb, 0xeb, 0x01, 0x5a, 0xa8, 0x71, 0xf8, 0xdf, 0x40, 0x19, 0x03, 0x08, |
|
4457 |
+ 0x81, 0x72, 0x20, 0xe6, 0xba, 0x0d, 0x5d, 0xaa, 0xd6, 0xa4, 0x0e, 0x25, 0x16, 0x3f, 0x51, 0xb1, |
|
4458 |
+ 0x2e, 0xc5, 0x25, 0x5a, 0xc2, 0xaf, 0xa7, 0x46, 0x4c, 0x5c, 0x62, 0xdc, 0x32, 0x65, 0xc2, 0x68, |
|
4459 |
+ 0xa8, 0xd6, 0xe4, 0x3a, 0xb8, 0x89, 0xe0, 0x67, 0xab, 0x47, 0x18, 0x5d, 0x29, 0x74, 0x08, 0x1a, |
|
4460 |
+ 0x07, 0xf1, 0x13, 0xea, 0x24, 0x66, 0xe5, 0x7f, 0x67, 0x43, 0x45, 0x25, 0x44, 0x5a, 0x58, 0x7e, |
|
4461 |
+ 0xb2, 0xd4, 0x4a, 0x96, 0xba, 0xc4, 0x94, 0x0f, 0x4a, 0xe8, 0xac, 0x7a, 0x14, 0x7d, 0x1b, 0x9c, |
|
4462 |
+ 0x94, 0x2d, 0x58, 0x28, 0xb9, 0x30, 0x77, 0x9d, 0xed, 0x31, 0x9d, 0x29, 0x5e, 0x87, 0xce, 0x50, |
|
4463 |
+ 0xad, 0xc9, 0x4d, 0xa8, 0x72, 0xa5, 0xa1, 0x4a, 0xf2, 0x1f, 0x94, 0x35, 0x10, 0x24, 0x17, 0x2c, |
|
4464 |
+ 0x98, 0xf2, 0x78, 0xb1, 0x52, 0xa9, 0x3b, 0x34, 0xdb, 0x93, 0x9b, 0xe0, 0x2a, 0xd5, 0x8e, 0x56, |
|
4465 |
+ 0x09, 0x6b, 0x54, 0x9b, 0x56, 0x6b, 0xab, 0x73, 0x21, 0x53, 0x14, 0x8d, 0x34, 0xf7, 0xe3, 0x57, |
|
4466 |
+ 0x12, 0x06, 0xe1, 0x09, 0x1b, 0x25, 0xb2, 0x71, 0x39, 0xd7, 0xa0, 0x67, 0x6c, 0x34, 0xf3, 0xfa, |
|
4467 |
+ 0x43, 0x70, 0xd6, 0x56, 0xec, 0xe0, 0x61, 0xdf, 0xf4, 0xb6, 0x3d, 0xec, 0x93, 0x3d, 0xa8, 0xa5, |
|
4468 |
+ 0x27, 0x81, 0x88, 0xe2, 0xb9, 0x2a, 0x75, 0xab, 0x73, 0x29, 0x23, 0x19, 0x6b, 0x3b, 0x72, 0xad, |
|
4469 |
+ 0x31, 0xfe, 0x5d, 0xa8, 0xea, 0x2f, 0x9a, 0x34, 0xa1, 0x94, 0x8a, 0xd0, 0x4c, 0x95, 0xad, 0xf5, |
|
4470 |
+ 0xa7, 0xae, 0x87, 0x02, 0x45, 0x57, 0x26, 0x95, 0x9d, 0x4b, 0xe5, 0x53, 0x80, 0x1c, 0xf6, 0xdf, |
|
4471 |
+ 0x5c, 0x89, 0xff, 0x83, 0x05, 0xce, 0x7a, 0x18, 0xe1, 0x97, 0x15, 0x4d, 0x59, 0x2c, 0xa3, 0x59, |
|
4472 |
+ 0xc4, 0x84, 0xa9, 0xb3, 0x60, 0x21, 0x7b, 0x50, 0x09, 0xa4, 0x14, 0xeb, 0x86, 0x7d, 0xa7, 0x38, |
|
4473 |
+ 0xc9, 0xda, 0x07, 0xe8, 0x19, 0xc4, 0x52, 0xac, 0xa8, 0x46, 0x6d, 0xdf, 0x01, 0xc8, 0x8d, 0xd8, |
|
4474 |
+ 0x9d, 0x8f, 0xd9, 0xca, 0xb0, 0xe2, 0x92, 0x5c, 0x86, 0xca, 0x93, 0x60, 0xb1, 0x64, 0x26, 0x29, |
|
4475 |
+ 0xbd, 0xf9, 0xd4, 0xbe, 0x63, 0xf9, 0x3f, 0xdb, 0x50, 0x33, 0x93, 0x8d, 0xdc, 0x82, 0x9a, 0x9a, |
|
4476 |
+ 0x6c, 0x26, 0xa3, 0xd7, 0x57, 0xba, 0x86, 0x90, 0xfd, 0x6c, 0x64, 0x17, 0x72, 0x34, 0x54, 0x7a, |
|
4477 |
+ 0x74, 0x9b, 0x1c, 0xf3, 0x01, 0x5e, 0x9a, 0xb2, 0x99, 0x99, 0xcd, 0xea, 0x2a, 0xfa, 0x6c, 0x16, |
|
4478 |
+ 0xc5, 0x91, 0x8c, 0x78, 0x4c, 0xd1, 0x45, 0x6e, 0xad, 0xab, 0x2e, 0x2b, 0xc6, 0x2b, 0x45, 0xc6, |
|
4479 |
+ 0x57, 0x8b, 0x1e, 0x82, 0x57, 0x38, 0xe6, 0x35, 0x55, 0x7f, 0x58, 0xac, 0xda, 0x1c, 0xa9, 0xe8, |
|
4480 |
+ 0xf4, 0xc3, 0x92, 0xab, 0xf0, 0x2f, 0xf4, 0xbb, 0x0d, 0x90, 0x53, 0xbe, 0x79, 0xa7, 0xf8, 0x7f, |
|
4481 |
+ 0x59, 0x00, 0xa3, 0x04, 0x47, 0xce, 0x34, 0x50, 0x13, 0x6a, 0x33, 0x9a, 0xc7, 0x5c, 0xb0, 0x47, |
|
4482 |
+ 0xea, 0x73, 0x50, 0xf1, 0x0e, 0xf5, 0xb4, 0x4d, 0xb5, 0x39, 0x39, 0x00, 0x6f, 0xca, 0xd2, 0x50, |
|
4483 |
+ 0x44, 0x09, 0x0a, 0x66, 0x44, 0xdf, 0xc5, 0x9a, 0x72, 0x9e, 0x76, 0x3f, 0x47, 0x68, 0xad, 0x8a, |
|
4484 |
+ 0x31, 0xa4, 0x03, 0x9b, 0xec, 0x2c, 0xe1, 0x42, 0x9a, 0x53, 0xf4, 0x03, 0x78, 0x51, 0x3f, 0xa5, |
|
4485 |
+ 0x68, 0x57, 0x27, 0x51, 0x8f, 0xe5, 0x9b, 0xed, 0xbb, 0x50, 0x7f, 0x99, 0xf4, 0xad, 0x04, 0xba, |
|
4486 |
+ 0x06, 0x5e, 0x81, 0x1b, 0x81, 0xc7, 0x0a, 0xa8, 0x2b, 0xd4, 0x1b, 0xff, 0x29, 0xbe, 0x70, 0x66, |
|
4487 |
+ 0x16, 0x92, 0xf7, 0x01, 0x4e, 0xa4, 0x4c, 0x1e, 0xa9, 0xe1, 0x68, 0x0e, 0x71, 0xd1, 0xa2, 0x10, |
|
4488 |
+ 0x64, 0x17, 0x3c, 0xdc, 0xa4, 0xc6, 0xaf, 0x0f, 0x54, 0x11, 0xa9, 0x06, 0xbc, 0x07, 0xee, 0x2c, |
|
4489 |
+ 0x0b, 0xd7, 0x03, 0xd0, 0x99, 0xad, 0xa3, 0xdf, 0x05, 0x27, 0xe6, 0xc6, 0xa7, 0x67, 0x75, 0x2d, |
|
4490 |
+ 0xe6, 0xca, 0xe5, 0xdf, 0x84, 0xff, 0xbd, 0xf2, 0x1c, 0x93, 0x2b, 0x50, 0x9d, 0x45, 0x0b, 0xa9, |
|
4491 |
+ 0x3e, 0x09, 0x1c, 0xff, 0x66, 0xe7, 0xff, 0x6a, 0x01, 0xe4, 0xed, 0x8b, 0x8a, 0x60, 0x6f, 0x23, |
|
4492 |
+ 0x66, 0x53, 0xf7, 0xf2, 0x02, 0x9c, 0x53, 0x73, 0x2b, 0xe6, 0xae, 0xae, 0x9e, 0x6f, 0xf9, 0xf6, |
|
4493 |
+ 0xfa, 0xd2, 0x94, 0xa6, 0xfa, 0xc9, 0x7c, 0xfa, 0xfb, 0x5b, 0x3d, 0x99, 0xd9, 0x09, 0xdb, 0xf7, |
|
4494 |
+ 0xe1, 0xc2, 0x39, 0xba, 0x37, 0xfc, 0x1a, 0xf2, 0xce, 0x29, 0x5c, 0xd9, 0x8d, 0xcf, 0xc0, 0xcd, |
|
4495 |
+ 0x46, 0x39, 0x71, 0xa0, 0xdc, 0x1d, 0x7e, 0xd9, 0xaf, 0x6f, 0x10, 0x80, 0xea, 0x78, 0xd0, 0xa3, |
|
4496 |
+ 0x83, 0xa3, 0xba, 0x45, 0x6a, 0x50, 0x1a, 0x8f, 0x0f, 0xeb, 0x36, 0x71, 0xa1, 0xd2, 0x3b, 0xe8, |
|
4497 |
+ 0x1d, 0x0e, 0xea, 0x25, 0x5c, 0x1e, 0x3d, 0x78, 0x78, 0x6f, 0x5c, 0x2f, 0xdf, 0xb8, 0x0d, 0x17, |
|
4498 |
+ 0x5f, 0x9a, 0xcd, 0x2a, 0xfa, 0xf0, 0x80, 0x0e, 0x90, 0xc9, 0x83, 0xda, 0x43, 0x3a, 0x3c, 0x3e, |
|
4499 |
+ 0x38, 0x1a, 0xd4, 0x2d, 0x74, 0x7c, 0x31, 0xea, 0xdd, 0x1f, 0xf4, 0xeb, 0x76, 0xb7, 0xfe, 0xec, |
|
4500 |
+ 0xc5, 0x8e, 0xf5, 0xcb, 0x8b, 0x1d, 0xeb, 0x8f, 0x17, 0x3b, 0xd6, 0xf7, 0x7f, 0xee, 0x6c, 0x4c, |
|
4501 |
+ 0xaa, 0xea, 0x6f, 0xe2, 0xc7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x42, 0x80, 0x11, 0x1b, 0x66, |
|
4502 |
+ 0x0a, 0x00, 0x00, |
|
4494 | 4503 |
} |
... | ... |
@@ -15,7 +15,18 @@ message Op { |
15 | 15 |
SourceOp source = 3; |
16 | 16 |
CopyOp copy = 4; |
17 | 17 |
BuildOp build = 5; |
18 |
- } |
|
18 |
+ } |
|
19 |
+ Platform platform = 10; |
|
20 |
+ WorkerConstraints constraints = 11; |
|
21 |
+} |
|
22 |
+ |
|
23 |
+// Platform is github.com/opencontainers/image-spec/specs-go/v1.Platform |
|
24 |
+message Platform { |
|
25 |
+ string Architecture = 1; |
|
26 |
+ string OS = 2; |
|
27 |
+ string Variant = 3; |
|
28 |
+ string OSVersion = 4; // unused |
|
29 |
+ repeated string OSFeatures = 5; // unused |
|
19 | 30 |
} |
20 | 31 |
|
21 | 32 |
// Input represents an input edge for an Op. |
... | ... |
@@ -54,6 +65,7 @@ message Mount { |
54 | 54 |
CacheOpt cacheOpt = 20; |
55 | 55 |
} |
56 | 56 |
|
57 |
+// MountType defines a type of a mount from a supported set |
|
57 | 58 |
enum MountType { |
58 | 59 |
BIND = 0; |
59 | 60 |
SECRET = 1; |
... | ... |
@@ -62,8 +74,22 @@ enum MountType { |
62 | 62 |
TMPFS = 4; |
63 | 63 |
} |
64 | 64 |
|
65 |
+// CacheOpt defines options specific to cache mounts |
|
65 | 66 |
message CacheOpt { |
67 |
+ // ID is an optional namespace for the mount |
|
66 | 68 |
string ID = 1; |
69 |
+ // Sharing is the sharing mode for the mount |
|
70 |
+ CacheSharingOpt sharing = 2; |
|
71 |
+} |
|
72 |
+ |
|
73 |
+// CacheSharingOpt defines different sharing modes for cache mount |
|
74 |
+enum CacheSharingOpt { |
|
75 |
+ // SHARED cache mount can be used concurrently by multiple writers |
|
76 |
+ SHARED = 0; |
|
77 |
+ // PRIVATE creates a new mount if there are multiple writers |
|
78 |
+ PRIVATE = 1; |
|
79 |
+ // LOCKED pauses second writer until first one releases the mount |
|
80 |
+ LOCKED = 2; |
|
67 | 81 |
} |
68 | 82 |
|
69 | 83 |
// CopyOp copies files across Ops. |
... | ... |
@@ -106,8 +132,9 @@ message OpMetadata { |
106 | 106 |
// ignore_cache specifies to ignore the cache for this Op. |
107 | 107 |
bool ignore_cache = 1; |
108 | 108 |
// Description can be used for keeping any text fields that builder doesn't parse |
109 |
- map<string, string> description = 2; |
|
110 |
- WorkerConstraint worker_constraint = 3; |
|
109 |
+ map<string, string> description = 2; |
|
110 |
+ // index 3 reserved for WorkerConstraint in previous versions |
|
111 |
+ // WorkerConstraint worker_constraint = 3; |
|
111 | 112 |
ExportCache export_cache = 4; |
112 | 113 |
} |
113 | 114 |
|
... | ... |
@@ -122,8 +149,8 @@ message ProxyEnv { |
122 | 122 |
string no_proxy = 4; |
123 | 123 |
} |
124 | 124 |
|
125 |
-// WorkerConstraint is experimental and likely to be changed. |
|
126 |
-message WorkerConstraint { |
|
125 |
+// WorkerConstraints defines conditions for the worker |
|
126 |
+message WorkerConstraints { |
|
127 | 127 |
repeated string filter = 1; // containerd-style filter |
128 | 128 |
} |
129 | 129 |
|
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"github.com/containerd/containerd/reference" |
9 | 9 |
"github.com/moby/buildkit/solver/pb" |
10 | 10 |
digest "github.com/opencontainers/go-digest" |
11 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
11 | 12 |
"github.com/pkg/errors" |
12 | 13 |
) |
13 | 14 |
|
... | ... |
@@ -50,11 +51,20 @@ func FromString(s string) (Identifier, error) { |
50 | 50 |
return nil, errors.Wrapf(errNotFound, "unknown schema %s", parts[0]) |
51 | 51 |
} |
52 | 52 |
} |
53 |
-func FromLLB(op *pb.Op_Source) (Identifier, error) { |
|
53 |
+func FromLLB(op *pb.Op_Source, platform *pb.Platform) (Identifier, error) { |
|
54 | 54 |
id, err := FromString(op.Source.Identifier) |
55 | 55 |
if err != nil { |
56 | 56 |
return nil, err |
57 | 57 |
} |
58 |
+ if id, ok := id.(*ImageIdentifier); ok && platform != nil { |
|
59 |
+ id.Platform = &specs.Platform{ |
|
60 |
+ OS: platform.OS, |
|
61 |
+ Architecture: platform.Architecture, |
|
62 |
+ Variant: platform.Variant, |
|
63 |
+ OSVersion: platform.OSVersion, |
|
64 |
+ OSFeatures: platform.OSFeatures, |
|
65 |
+ } |
|
66 |
+ } |
|
58 | 67 |
if id, ok := id.(*GitIdentifier); ok { |
59 | 68 |
for k, v := range op.Source.Attrs { |
60 | 69 |
switch k { |
... | ... |
@@ -136,6 +146,7 @@ func FromLLB(op *pb.Op_Source) (Identifier, error) { |
136 | 136 |
|
137 | 137 |
type ImageIdentifier struct { |
138 | 138 |
Reference reference.Spec |
139 |
+ Platform *specs.Platform |
|
139 | 140 |
} |
140 | 141 |
|
141 | 142 |
func NewImageIdentifier(str string) (*ImageIdentifier, error) { |
... | ... |
@@ -10,7 +10,7 @@ import ( |
10 | 10 |
"github.com/containerd/containerd/reference" |
11 | 11 |
"github.com/containerd/containerd/remotes" |
12 | 12 |
digest "github.com/opencontainers/go-digest" |
13 |
- ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
13 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
14 | 14 |
"github.com/pkg/errors" |
15 | 15 |
) |
16 | 16 |
|
... | ... |
@@ -19,16 +19,18 @@ type IngesterProvider interface { |
19 | 19 |
content.Provider |
20 | 20 |
} |
21 | 21 |
|
22 |
-func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester IngesterProvider, platform string) (digest.Digest, []byte, error) { |
|
23 |
- if platform == "" { |
|
24 |
- platform = platforms.Default() |
|
22 |
+func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester IngesterProvider, platform *specs.Platform) (digest.Digest, []byte, error) { |
|
23 |
+ // TODO: fix containerd to take struct instead of string |
|
24 |
+ platformStr := platforms.Default() |
|
25 |
+ if platform != nil { |
|
26 |
+ platformStr = platforms.Format(*platform) |
|
25 | 27 |
} |
26 | 28 |
ref, err := reference.Parse(str) |
27 | 29 |
if err != nil { |
28 | 30 |
return "", nil, errors.WithStack(err) |
29 | 31 |
} |
30 | 32 |
|
31 |
- desc := ocispec.Descriptor{ |
|
33 |
+ desc := specs.Descriptor{ |
|
32 | 34 |
Digest: ref.Digest(), |
33 | 35 |
} |
34 | 36 |
if desc.Digest != "" { |
... | ... |
@@ -56,12 +58,12 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester |
56 | 56 |
|
57 | 57 |
handlers := []images.Handler{ |
58 | 58 |
remotes.FetchHandler(ingester, fetcher), |
59 |
- childrenConfigHandler(ingester, platform), |
|
59 |
+ childrenConfigHandler(ingester, platformStr), |
|
60 | 60 |
} |
61 | 61 |
if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil { |
62 | 62 |
return "", nil, err |
63 | 63 |
} |
64 |
- config, err := images.Config(ctx, ingester, desc, platform) |
|
64 |
+ config, err := images.Config(ctx, ingester, desc, platformStr) |
|
65 | 65 |
if err != nil { |
66 | 66 |
return "", nil, err |
67 | 67 |
} |
... | ... |
@@ -75,10 +77,10 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester |
75 | 75 |
} |
76 | 76 |
|
77 | 77 |
func childrenConfigHandler(provider content.Provider, platform string) images.HandlerFunc { |
78 |
- return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { |
|
79 |
- var descs []ocispec.Descriptor |
|
78 |
+ return func(ctx context.Context, desc specs.Descriptor) ([]specs.Descriptor, error) { |
|
79 |
+ var descs []specs.Descriptor |
|
80 | 80 |
switch desc.MediaType { |
81 |
- case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: |
|
81 |
+ case images.MediaTypeDockerSchema2Manifest, specs.MediaTypeImageManifest: |
|
82 | 82 |
p, err := content.ReadBlob(ctx, provider, desc) |
83 | 83 |
if err != nil { |
84 | 84 |
return nil, err |
... | ... |
@@ -86,19 +88,19 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha |
86 | 86 |
|
87 | 87 |
// TODO(stevvooe): We just assume oci manifest, for now. There may be |
88 | 88 |
// subtle differences from the docker version. |
89 |
- var manifest ocispec.Manifest |
|
89 |
+ var manifest specs.Manifest |
|
90 | 90 |
if err := json.Unmarshal(p, &manifest); err != nil { |
91 | 91 |
return nil, err |
92 | 92 |
} |
93 | 93 |
|
94 | 94 |
descs = append(descs, manifest.Config) |
95 |
- case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: |
|
95 |
+ case images.MediaTypeDockerSchema2ManifestList, specs.MediaTypeImageIndex: |
|
96 | 96 |
p, err := content.ReadBlob(ctx, provider, desc) |
97 | 97 |
if err != nil { |
98 | 98 |
return nil, err |
99 | 99 |
} |
100 | 100 |
|
101 |
- var index ocispec.Index |
|
101 |
+ var index specs.Index |
|
102 | 102 |
if err := json.Unmarshal(p, &index); err != nil { |
103 | 103 |
return nil, err |
104 | 104 |
} |
... | ... |
@@ -118,7 +120,7 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha |
118 | 118 |
} else { |
119 | 119 |
descs = append(descs, index.Manifests...) |
120 | 120 |
} |
121 |
- case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig: |
|
121 |
+ case images.MediaTypeDockerSchema2Config, specs.MediaTypeImageConfig: |
|
122 | 122 |
// childless data types. |
123 | 123 |
return nil, nil |
124 | 124 |
default: |
... | ... |
@@ -129,7 +131,7 @@ func childrenConfigHandler(provider content.Provider, platform string) images.Ha |
129 | 129 |
} |
130 | 130 |
} |
131 | 131 |
|
132 |
-// ocispec.MediaTypeImageManifest, // TODO: detect schema1/manifest-list |
|
132 |
+// specs.MediaTypeImageManifest, // TODO: detect schema1/manifest-list |
|
133 | 133 |
func DetectManifestMediaType(ra content.ReaderAt) (string, error) { |
134 | 134 |
// TODO: schema1 |
135 | 135 |
|
... | ... |
@@ -6,7 +6,7 @@ github.com/davecgh/go-spew v1.1.0 |
6 | 6 |
github.com/pmezard/go-difflib v1.0.0 |
7 | 7 |
golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 |
8 | 8 |
|
9 |
-github.com/containerd/containerd 63522d9eaa5a0443d225642c4b6f4f5fdedf932b |
|
9 |
+github.com/containerd/containerd 08f7ee9828af1783dc98cc5cc1739e915697c667 |
|
10 | 10 |
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 |
11 | 11 |
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c |
12 | 12 |
github.com/sirupsen/logrus v1.0.0 |
... | ... |
@@ -11,16 +11,18 @@ import ( |
11 | 11 |
"github.com/moby/buildkit/frontend" |
12 | 12 |
"github.com/moby/buildkit/solver" |
13 | 13 |
digest "github.com/opencontainers/go-digest" |
14 |
+ specs "github.com/opencontainers/image-spec/specs-go/v1" |
|
14 | 15 |
) |
15 | 16 |
|
16 | 17 |
type Worker interface { |
17 | 18 |
// ID needs to be unique in the cluster |
18 | 19 |
ID() string |
19 | 20 |
Labels() map[string]string |
21 |
+ Platforms() []specs.Platform |
|
20 | 22 |
LoadRef(id string) (cache.ImmutableRef, error) |
21 | 23 |
// ResolveOp resolves Vertex.Sys() to Op implementation. |
22 | 24 |
ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) |
23 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
25 |
+ ResolveImageConfig(ctx context.Context, ref string, platform *specs.Platform) (digest.Digest, []byte, error) |
|
24 | 26 |
// Exec is similar to executor.Exec but without []mount.Mount |
25 | 27 |
Exec(ctx context.Context, meta executor.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error |
26 | 28 |
DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error) |
... | ... |
@@ -33,8 +35,6 @@ type Worker interface { |
33 | 33 |
// Pre-defined label keys |
34 | 34 |
const ( |
35 | 35 |
labelPrefix = "org.mobyproject.buildkit.worker." |
36 |
- LabelOS = labelPrefix + "os" // GOOS |
|
37 |
- LabelArch = labelPrefix + "arch" // GOARCH |
|
38 | 36 |
LabelExecutor = labelPrefix + "executor" // "oci" or "containerd" |
39 | 37 |
LabelSnapshotter = labelPrefix + "snapshotter" // containerd snapshotter name ("overlay", "native", ...) |
40 | 38 |
LabelHostname = labelPrefix + "hostname" |