Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -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, nil) |
|
| 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 {
|