@@ -3,11 +3,14 @@ package local
33import (
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
0 commit comments