Skip to content

Commit

Permalink
feat(cross-platform-builds): basic support of --platform=OS/ARCH[/VAR…
Browse files Browse the repository at this point in the history
…IANT] parameter for buildah builder

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed May 19, 2022
1 parent 95fa0e3 commit 276fc0f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/werf/common/common.go
Expand Up @@ -1434,7 +1434,7 @@ func SetupPlatform(cmdData *CmdData, cmd *cobra.Command) {
}
}

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

func GetContext() context.Context {
Expand Down
5 changes: 4 additions & 1 deletion cmd/werf/common/container_backend.go
Expand Up @@ -117,12 +117,15 @@ func InitProcessContainerBackend(ctx context.Context, cmdData *CmdData) (contain
Isolation: buildahIsolation,
StorageDriver: storageDriver,
},
NativeModeOpts: buildah.NativeModeOpts{
Platform: *cmdData.Platform,
},
})
if err != nil {
return nil, ctx, fmt.Errorf("unable to get buildah client: %w", err)
}

return wrapContainerBackend(container_backend.NewBuildahBackend(b, filepath.Join(werf.GetServiceDir(), "tmp", "buildah"))), ctx, nil
return wrapContainerBackend(container_backend.NewBuildahBackend(b, container_backend.BuildahBackendOptions{TmpDir: filepath.Join(werf.GetServiceDir(), "tmp", "buildah")})), ctx, nil
}

newCtx, err := InitProcessDocker(ctx, cmdData)
Expand Down
4 changes: 3 additions & 1 deletion pkg/buildah/common.go
Expand Up @@ -123,7 +123,9 @@ type CommonBuildahOpts struct {
Insecure bool
}

type NativeModeOpts struct{}
type NativeModeOpts struct {
Platform string
}

type DockerWithFuseModeOpts struct{}

Expand Down
47 changes: 46 additions & 1 deletion pkg/buildah/native_linux.go
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/containers/buildah/define"
"github.com/containers/buildah/docker"
"github.com/containers/buildah/imagebuildah"
"github.com/containers/buildah/pkg/parse"
"github.com/containers/common/libimage"
"github.com/containers/image/v5/manifest"
imgstor "github.com/containers/image/v5/storage"
Expand Down Expand Up @@ -62,6 +63,8 @@ type NativeBuildah struct {
Runtime libimage.Runtime
DefaultSystemContext imgtypes.SystemContext
DefaultCommonBuildOptions define.CommonBuildOptions

platforms []struct{ OS, Arch, Variant string }
}

func NewNativeBuildah(commonOpts CommonBuildahOpts, opts NativeModeOpts) (*NativeBuildah, error) {
Expand Down Expand Up @@ -95,6 +98,21 @@ func NewNativeBuildah(commonOpts CommonBuildahOpts, opts NativeModeOpts) (*Nativ
DockerDaemonInsecureSkipTLSVerify: b.Insecure,
}

if opts.Platform != "" {
os, arch, variant, err := parse.Platform(opts.Platform)
if err != nil {
return nil, fmt.Errorf("unable to parse platform %q: %w", opts.Platform, err)
}

b.DefaultSystemContext.OSChoice = os
b.DefaultSystemContext.ArchitectureChoice = arch
b.DefaultSystemContext.VariantChoice = variant

b.platforms = []struct{ OS, Arch, Variant string }{
{os, arch, variant},
}
}

b.DefaultCommonBuildOptions = define.CommonBuildOptions{
ShmSize: DefaultShmSize,
}
Expand Down Expand Up @@ -177,6 +195,7 @@ func (b *NativeBuildah) BuildFromDockerfile(ctx context.Context, dockerfile []by
Target: opts.Target,
MaxPullPushRetries: MaxPullPushRetries,
PullPushRetryDelay: PullPushRetryDelay,
Platforms: b.platforms,
}

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

if _, err := buildah.Pull(ctx, ref, pullOpts); err != nil {
imageID, err := buildah.Pull(ctx, ref, pullOpts)
if err != nil {
return fmt.Errorf("error pulling image %q: %w", ref, err)
}

imageInspect, err := b.Inspect(ctx, imageID)
if err != nil {
return fmt.Errorf("unable to inspect pulled image %q: %w", imageID, err)
}

platformMismatch := false
if b.DefaultSystemContext.OSChoice != "" && b.DefaultSystemContext.OSChoice != imageInspect.OCIv1.OS {
platformMismatch = true
}
if b.DefaultSystemContext.ArchitectureChoice != "" && b.DefaultSystemContext.ArchitectureChoice != imageInspect.OCIv1.Architecture {
platformMismatch = true
}
if b.DefaultSystemContext.VariantChoice != "" && b.DefaultSystemContext.VariantChoice != imageInspect.OCIv1.Variant {
platformMismatch = true
}

if platformMismatch {
imagePlatform := fmt.Sprintf("%s/%s/%s", imageInspect.OCIv1.OS, imageInspect.OCIv1.Architecture, imageInspect.OCIv1.Variant)
expectedPlatform := fmt.Sprintf("%s/%s", b.DefaultSystemContext.OSChoice, b.DefaultSystemContext.ArchitectureChoice)
if b.DefaultSystemContext.VariantChoice != "" {
expectedPlatform = fmt.Sprintf("%s/%s", expectedPlatform, b.DefaultSystemContext.VariantChoice)
}
return fmt.Errorf("image platform mismatch: image uses %s, expecting %s platform", imagePlatform, expectedPlatform)
}

return nil
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/container_backend/buildah_backend.go
Expand Up @@ -25,16 +25,16 @@ import (
)

type BuildahBackend struct {
TmpDir string
buildah buildah.Buildah
BuildahBackendOptions
}

type BuildahImage struct {
Image LegacyImageInterface
type BuildahBackendOptions struct {
TmpDir string
}

func NewBuildahBackend(buildah buildah.Buildah, tmpDir string) *BuildahBackend {
return &BuildahBackend{buildah: buildah, TmpDir: tmpDir}
func NewBuildahBackend(buildah buildah.Buildah, opts BuildahBackendOptions) *BuildahBackend {
return &BuildahBackend{buildah: buildah, BuildahBackendOptions: opts}
}

func (runtime *BuildahBackend) HasStapelBuildSupport() bool {
Expand Down

0 comments on commit 276fc0f

Please sign in to comment.