Skip to content

Commit 276fc0f

Browse files
committed
feat(cross-platform-builds): basic support of --platform=OS/ARCH[/VARIANT] parameter for buildah builder
Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
1 parent 95fa0e3 commit 276fc0f

File tree

5 files changed

+59
-9
lines changed

5 files changed

+59
-9
lines changed

cmd/werf/common/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ func SetupPlatform(cmdData *CmdData, cmd *cobra.Command) {
14341434
}
14351435
}
14361436

1437-
cmd.Flags().StringVarP(cmdData.Platform, "platform", "", defaultValue, "Enable platform emulation when building images with werf. The only supported option for now is linux/amd64.")
1437+
cmd.Flags().StringVarP(cmdData.Platform, "platform", "", defaultValue, "Enable platform emulation when building images with werf, format: OS/ARCH[/VARIANT].")
14381438
}
14391439

14401440
func GetContext() context.Context {

cmd/werf/common/container_backend.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,15 @@ func InitProcessContainerBackend(ctx context.Context, cmdData *CmdData) (contain
117117
Isolation: buildahIsolation,
118118
StorageDriver: storageDriver,
119119
},
120+
NativeModeOpts: buildah.NativeModeOpts{
121+
Platform: *cmdData.Platform,
122+
},
120123
})
121124
if err != nil {
122125
return nil, ctx, fmt.Errorf("unable to get buildah client: %w", err)
123126
}
124127

125-
return wrapContainerBackend(container_backend.NewBuildahBackend(b, filepath.Join(werf.GetServiceDir(), "tmp", "buildah"))), ctx, nil
128+
return wrapContainerBackend(container_backend.NewBuildahBackend(b, container_backend.BuildahBackendOptions{TmpDir: filepath.Join(werf.GetServiceDir(), "tmp", "buildah")})), ctx, nil
126129
}
127130

128131
newCtx, err := InitProcessDocker(ctx, cmdData)

pkg/buildah/common.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ type CommonBuildahOpts struct {
123123
Insecure bool
124124
}
125125

126-
type NativeModeOpts struct{}
126+
type NativeModeOpts struct {
127+
Platform string
128+
}
127129

128130
type DockerWithFuseModeOpts struct{}
129131

pkg/buildah/native_linux.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/containers/buildah/define"
1818
"github.com/containers/buildah/docker"
1919
"github.com/containers/buildah/imagebuildah"
20+
"github.com/containers/buildah/pkg/parse"
2021
"github.com/containers/common/libimage"
2122
"github.com/containers/image/v5/manifest"
2223
imgstor "github.com/containers/image/v5/storage"
@@ -62,6 +63,8 @@ type NativeBuildah struct {
6263
Runtime libimage.Runtime
6364
DefaultSystemContext imgtypes.SystemContext
6465
DefaultCommonBuildOptions define.CommonBuildOptions
66+
67+
platforms []struct{ OS, Arch, Variant string }
6568
}
6669

6770
func NewNativeBuildah(commonOpts CommonBuildahOpts, opts NativeModeOpts) (*NativeBuildah, error) {
@@ -95,6 +98,21 @@ func NewNativeBuildah(commonOpts CommonBuildahOpts, opts NativeModeOpts) (*Nativ
9598
DockerDaemonInsecureSkipTLSVerify: b.Insecure,
9699
}
97100

101+
if opts.Platform != "" {
102+
os, arch, variant, err := parse.Platform(opts.Platform)
103+
if err != nil {
104+
return nil, fmt.Errorf("unable to parse platform %q: %w", opts.Platform, err)
105+
}
106+
107+
b.DefaultSystemContext.OSChoice = os
108+
b.DefaultSystemContext.ArchitectureChoice = arch
109+
b.DefaultSystemContext.VariantChoice = variant
110+
111+
b.platforms = []struct{ OS, Arch, Variant string }{
112+
{os, arch, variant},
113+
}
114+
}
115+
98116
b.DefaultCommonBuildOptions = define.CommonBuildOptions{
99117
ShmSize: DefaultShmSize,
100118
}
@@ -177,6 +195,7 @@ func (b *NativeBuildah) BuildFromDockerfile(ctx context.Context, dockerfile []by
177195
Target: opts.Target,
178196
MaxPullPushRetries: MaxPullPushRetries,
179197
PullPushRetryDelay: PullPushRetryDelay,
198+
Platforms: b.platforms,
180199
}
181200

182201
errLog := &bytes.Buffer{}
@@ -287,10 +306,36 @@ func (b *NativeBuildah) Pull(ctx context.Context, ref string, opts PullOpts) err
287306
PullPolicy: define.PullIfNewer,
288307
}
289308

290-
if _, err := buildah.Pull(ctx, ref, pullOpts); err != nil {
309+
imageID, err := buildah.Pull(ctx, ref, pullOpts)
310+
if err != nil {
291311
return fmt.Errorf("error pulling image %q: %w", ref, err)
292312
}
293313

314+
imageInspect, err := b.Inspect(ctx, imageID)
315+
if err != nil {
316+
return fmt.Errorf("unable to inspect pulled image %q: %w", imageID, err)
317+
}
318+
319+
platformMismatch := false
320+
if b.DefaultSystemContext.OSChoice != "" && b.DefaultSystemContext.OSChoice != imageInspect.OCIv1.OS {
321+
platformMismatch = true
322+
}
323+
if b.DefaultSystemContext.ArchitectureChoice != "" && b.DefaultSystemContext.ArchitectureChoice != imageInspect.OCIv1.Architecture {
324+
platformMismatch = true
325+
}
326+
if b.DefaultSystemContext.VariantChoice != "" && b.DefaultSystemContext.VariantChoice != imageInspect.OCIv1.Variant {
327+
platformMismatch = true
328+
}
329+
330+
if platformMismatch {
331+
imagePlatform := fmt.Sprintf("%s/%s/%s", imageInspect.OCIv1.OS, imageInspect.OCIv1.Architecture, imageInspect.OCIv1.Variant)
332+
expectedPlatform := fmt.Sprintf("%s/%s", b.DefaultSystemContext.OSChoice, b.DefaultSystemContext.ArchitectureChoice)
333+
if b.DefaultSystemContext.VariantChoice != "" {
334+
expectedPlatform = fmt.Sprintf("%s/%s", expectedPlatform, b.DefaultSystemContext.VariantChoice)
335+
}
336+
return fmt.Errorf("image platform mismatch: image uses %s, expecting %s platform", imagePlatform, expectedPlatform)
337+
}
338+
294339
return nil
295340
}
296341

pkg/container_backend/buildah_backend.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ import (
2525
)
2626

2727
type BuildahBackend struct {
28-
TmpDir string
2928
buildah buildah.Buildah
29+
BuildahBackendOptions
3030
}
3131

32-
type BuildahImage struct {
33-
Image LegacyImageInterface
32+
type BuildahBackendOptions struct {
33+
TmpDir string
3434
}
3535

36-
func NewBuildahBackend(buildah buildah.Buildah, tmpDir string) *BuildahBackend {
37-
return &BuildahBackend{buildah: buildah, TmpDir: tmpDir}
36+
func NewBuildahBackend(buildah buildah.Buildah, opts BuildahBackendOptions) *BuildahBackend {
37+
return &BuildahBackend{buildah: buildah, BuildahBackendOptions: opts}
3838
}
3939

4040
func (runtime *BuildahBackend) HasStapelBuildSupport() bool {

0 commit comments

Comments
 (0)