Skip to content

Commit 33b8b33

Browse files
authored
Merge pull request #302 from bojidar-bg/l1599-local-platform
Docker: pass Options.platform to inspect and default local platform to linux/$GOARCH
2 parents 3e23350 + ee231a0 commit 33b8b33

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

local/new.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ package local
33
import (
44
"context"
55
"fmt"
6+
"runtime"
7+
"strings"
68

79
cerrdefs "github.com/containerd/errdefs"
810
v1 "github.com/google/go-containerregistry/pkg/v1"
911
"github.com/moby/moby/api/types/image"
1012
"github.com/moby/moby/client"
13+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1114

1215
"github.com/buildpacks/imgutil"
1316
)
@@ -26,7 +29,7 @@ func NewImage(repoName string, dockerClient DockerClient, ops ...imgutil.ImageOp
2629
return nil, err
2730
}
2831

29-
previousImage, err := processImageOption(options.PreviousImageRepoName, dockerClient, true)
32+
previousImage, err := processImageOption(options.PreviousImageRepoName, options.Platform, dockerClient, true)
3033
if err != nil {
3134
return nil, err
3235
}
@@ -38,7 +41,7 @@ func NewImage(repoName string, dockerClient DockerClient, ops ...imgutil.ImageOp
3841
baseIdentifier string
3942
store *Store
4043
)
41-
baseImage, err := processImageOption(options.BaseImageRepoName, dockerClient, false)
44+
baseImage, err := processImageOption(options.BaseImageRepoName, options.Platform, dockerClient, false)
4245
if err != nil {
4346
return nil, err
4447
}
@@ -69,6 +72,14 @@ func defaultPlatform(dockerClient DockerClient) (imgutil.Platform, error) {
6972
if err != nil {
7073
return imgutil.Platform{}, err
7174
}
75+
if daemonInfo.Os == "linux" {
76+
// When running on a different architecture than the daemon, we still want to use images matching our own architecture
77+
// https://github.com/buildpacks/lifecycle/issues/1599
78+
return imgutil.Platform{
79+
OS: "linux",
80+
Architecture: runtime.GOARCH,
81+
}, nil
82+
}
7283
return imgutil.Platform{
7384
OS: daemonInfo.Os,
7485
Architecture: daemonInfo.Arch,
@@ -96,11 +107,11 @@ type imageResult struct {
96107
layerStore *Store
97108
}
98109

99-
func processImageOption(repoName string, dockerClient DockerClient, downloadLayersOnAccess bool) (imageResult, error) {
110+
func processImageOption(repoName string, platform imgutil.Platform, dockerClient DockerClient, downloadLayersOnAccess bool) (imageResult, error) {
100111
if repoName == "" {
101112
return imageResult{}, nil
102113
}
103-
inspect, history, err := getInspectAndHistory(repoName, dockerClient)
114+
inspect, history, err := getInspectAndHistory(repoName, platform, dockerClient)
104115
if err != nil {
105116
return imageResult{}, err
106117
}
@@ -119,8 +130,25 @@ func processImageOption(repoName string, dockerClient DockerClient, downloadLaye
119130
}, nil
120131
}
121132

122-
func getInspectAndHistory(repoName string, dockerClient DockerClient) (*image.InspectResponse, []image.HistoryResponseItem, error) {
123-
inspect, err := dockerClient.ImageInspect(context.Background(), repoName)
133+
func getInspectAndHistory(repoName string, platform imgutil.Platform, dockerClient DockerClient) (*image.InspectResponse, []image.HistoryResponseItem, error) {
134+
platformOpt := client.ImageInspectWithPlatform(&ocispec.Platform{
135+
Architecture: platform.Architecture,
136+
OS: platform.OS,
137+
OSVersion: platform.OSVersion,
138+
Variant: platform.Variant,
139+
})
140+
// Try to inspect the image with the default platform/arch
141+
inspect, err := dockerClient.ImageInspect(context.Background(), repoName, platformOpt)
142+
if err != nil {
143+
// ...and if that fails, inspect without the platform
144+
if cerrdefs.IsNotImplemented(err) || strings.Contains(err.Error(), "requires API version") {
145+
fmt.Printf("Docker API Version < 1.49. Platform defaulting to daemon platform\n")
146+
inspect, err = dockerClient.ImageInspect(context.Background(), repoName)
147+
} else if cerrdefs.IsNotFound(err) {
148+
fmt.Printf("Docker did not find image %s with platform %s/%s; retrying without specifying a platform\n", repoName, platform.OS, platform.Architecture)
149+
inspect, err = dockerClient.ImageInspect(context.Background(), repoName)
150+
}
151+
}
124152
if err != nil {
125153
if cerrdefs.IsNotFound(err) {
126154
return nil, nil, nil

local/v1_facade.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ func newV1ImageFacadeFromInspect(dockerInspect image.InspectResponse, history []
2727
return nil, err
2828
}
2929
configFile := &v1.ConfigFile{
30-
Architecture: dockerInspect.Architecture, // FIXME: this should come from options.Platform
30+
Architecture: dockerInspect.Architecture,
3131
Author: dockerInspect.Author,
3232
Created: toV1Time(dockerInspect.Created),
3333
History: imgutil.NormalizedHistory(toV1History(history), len(dockerInspect.RootFS.Layers)),
3434
OS: dockerInspect.Os,
3535
RootFS: rootFS,
3636
Config: toV1Config(dockerInspect.Config),
37-
OSVersion: dockerInspect.OsVersion, // FIXME: this should come from options.Platform
38-
Variant: dockerInspect.Variant, // FIXME: this should come from options.Platform
37+
OSVersion: dockerInspect.OsVersion,
38+
Variant: dockerInspect.Variant,
3939
}
4040
layersToSet := newEmptyLayerListFrom(configFile, downloadLayersOnAccess, withStore, dockerInspect.ID)
4141
return imageFrom(layersToSet, configFile, imgutil.DockerTypes) // FIXME: this should be configurable with options.MediaTypes

0 commit comments

Comments
 (0)