Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of the multi-platform support for builders and buildpack packages RFC 0128 #2086

Merged
416 changes: 393 additions & 23 deletions acceptance/acceptance_test.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions acceptance/assertions/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ func (o OutputAssertionManager) IncludesUsagePrompt() {
o.assert.Contains(o.output, "Run 'pack --help' for usage.")
}

func (o OutputAssertionManager) ReportsBuilderCreated(name string) {
o.testObject.Helper()

o.assert.ContainsF(o.output, "Successfully created builder image '%s'", name)
}

func (o OutputAssertionManager) ReportsSettingDefaultBuilder(name string) {
o.testObject.Helper()

Expand Down
1 change: 1 addition & 0 deletions acceptance/buildpacks/folder_buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ var (
ExtFolderSimpleLayers = folderBuildModule{name: "simple-layers-extension"}
MetaBpFolder = folderBuildModule{name: "meta-buildpack"}
MetaBpDependency = folderBuildModule{name: "meta-buildpack-dependency"}
MultiPlatformFolderBP = folderBuildModule{name: "multi-platform-buildpack"}
)
4 changes: 4 additions & 0 deletions acceptance/invoke/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ const (
FlattenBuilderCreationV2
FixesRunImageMetadata
ManifestCommands
MultiPlatformBuildersAndBuildPackages
)

var featureTests = map[Feature]func(i *PackInvoker) bool{
Expand Down Expand Up @@ -278,6 +279,9 @@ var featureTests = map[Feature]func(i *PackInvoker) bool{
ManifestCommands: func(i *PackInvoker) bool {
return i.atLeast("v0.34.0")
},
MultiPlatformBuildersAndBuildPackages: func(i *PackInvoker) bool {
return i.atLeast("v0.34.0")
},
}

func (i *PackInvoker) SupportsFeature(f Feature) bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
api = "0.10"

[buildpack]
id = "simple/layers"
version = "simple-layers-version"
name = "Simple Layers Buildpack"

[[targets]]
os = "linux"
arch = "amd64"

[[targets]]
os = "windows"
arch = "amd64"

[[stacks]]
id = "*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

echo "---> Build: NOOP Buildpack"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

## always detect
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@echo off

echo ---- Build: NOOP Buildpack
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@echo off
:: always detect
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[[buildpacks]]
id = "simple/layers"
version = "simple-layers-version"
uri = "{{ .BuildpackURI }}"

[[order]]
[[order.group]]
id = "simple/layers"
version = "simple-layers-version"

[build]
image = "{{ .BuildImage }}"

[run]
[[run.images]]
image = "{{ .RunImage }}"



28 changes: 28 additions & 0 deletions acceptance/testdata/pack_fixtures/builder_multi_platform.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[[buildpacks]]
id = "simple/layers"
version = "simple-layers-version"
uri = "{{ .BuildpackURI }}"

[[order]]
[[order.group]]
id = "simple/layers"
version = "simple-layers-version"

# Targets the buildpack will work with
[[targets]]
os = "linux"
arch = "amd64"

[[targets]]
os = "windows"
arch = "amd64"

[build]
image = "{{ .BuildImage }}"

[run]
[[run.images]]
image = "{{ .RunImage }}"



2 changes: 1 addition & 1 deletion acceptance/testdata/pack_fixtures/package_aggregate.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ uri = "{{ .BuildpackURI }}"
image = "{{ .PackageName }}"

[platform]
os = "{{ .OS }}"
os = "{{ .OS }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[buildpack]
uri = "{{ .BuildpackURI }}"

[[dependencies]]
uri = "{{ .PackageName }}"
1 change: 1 addition & 0 deletions builder/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Config struct {
Lifecycle LifecycleConfig `toml:"lifecycle"`
Run RunConfig `toml:"run"`
Build BuildConfig `toml:"build"`
Targets []dist.Target `toml:"targets"`
}

// ModuleCollection is a list of ModuleConfigs
Expand Down
17 changes: 16 additions & 1 deletion buildpackage/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ type Config struct {
Buildpack dist.BuildpackURI `toml:"buildpack"`
Extension dist.BuildpackURI `toml:"extension"`
Dependencies []dist.ImageOrURI `toml:"dependencies"`
Platform dist.Platform `toml:"platform"`
// deprecated
Platform dist.Platform `toml:"platform"`

// Define targets for composite buildpacks
Targets []dist.Target `toml:"targets"`
}

func DefaultConfig() Config {
Expand Down Expand Up @@ -117,6 +121,17 @@ func (r *ConfigReader) Read(path string) (Config, error) {
return packageConfig, nil
}

func (r *ConfigReader) ReadBuildpackDescriptor(path string) (dist.BuildpackDescriptor, error) {
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
buildpackCfg := dist.BuildpackDescriptor{}

_, err := toml.DecodeFile(path, &buildpackCfg)
if err != nil {
return dist.BuildpackDescriptor{}, err
}

return buildpackCfg, nil
}

func validateURI(uri, relativeBaseDir string) error {
locatorType, err := buildpack.GetLocatorType(uri, relativeBaseDir, nil)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require (
github.com/Masterminds/semver v1.5.0
github.com/Microsoft/go-winio v0.6.2
github.com/apex/log v1.9.0
github.com/buildpacks/imgutil v0.0.0-20240507132533-9f7b96c3d09d
github.com/buildpacks/imgutil v0.0.0-20240514200737-4af87862ff7e
github.com/buildpacks/lifecycle v0.19.6
github.com/docker/cli v26.1.1+incompatible
github.com/docker/docker v26.1.1+incompatible
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/buildpacks/imgutil v0.0.0-20240507132533-9f7b96c3d09d h1:GVRuY/C8j4pjOddeeZelbKKLMMX+dYR3TlxE4L1hECU=
github.com/buildpacks/imgutil v0.0.0-20240507132533-9f7b96c3d09d/go.mod h1:n2R6VRuWsAX3cyHCp/u0Z4WJcixny0gYg075J39owrk=
github.com/buildpacks/imgutil v0.0.0-20240514200737-4af87862ff7e h1:IBH3oJu2okeB8W+bMTCYsRqbDT1+cjt6GuFtE52tAxM=
github.com/buildpacks/imgutil v0.0.0-20240514200737-4af87862ff7e/go.mod h1:n2R6VRuWsAX3cyHCp/u0Z4WJcixny0gYg075J39owrk=
github.com/buildpacks/lifecycle v0.19.6 h1:/bmfMs35aSkxyzYDF+iHl9VnYmUBBbHBmnvo8XNEINk=
github.com/buildpacks/lifecycle v0.19.6/go.mod h1:sWrBJzf/7dWrcHrWiV/P2+3jS8G8Ki5tczq8jO3XVRQ=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
Expand Down
5 changes: 5 additions & 0 deletions internal/builder/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,8 @@ func (l *lifecycle) binaries() []string {
}
return binaries
}

// SupportedLinuxArchitecture returns true for each binary architecture available at https://github.com/buildpacks/lifecycle/releases/
func SupportedLinuxArchitecture(arch string) bool {
return arch == "arm64" || arch == "ppc64le" || arch == "s390x"
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
}
17 changes: 17 additions & 0 deletions internal/commands/builder_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type BuilderCreateFlags struct {
Registry string
Policy string
Flatten []string
Targets []string
jjbustamante marked this conversation as resolved.
Show resolved Hide resolved
Label map[string]string
}

Expand Down Expand Up @@ -87,6 +88,15 @@ Creating a custom builder allows you to control what buildpacks are used and wha
return err
}

multiArchCfg, err := processMultiArchitectureConfig(logger, flags.Targets, builderConfig.Targets, !flags.Publish)
if err != nil {
return err
}

if len(multiArchCfg.Targets()) == 0 {
logger.Infof("Pro tip: use --targets flag OR [[targets]] in builder.toml to specify the desired platform")
}

imageName := args[0]
if err := pack.CreateBuilder(cmd.Context(), client.CreateBuilderOptions{
RelativeBaseDir: relativeBaseDir,
Expand All @@ -98,6 +108,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
PullPolicy: pullPolicy,
Flatten: toFlatten,
Labels: flags.Label,
Targets: multiArchCfg.Targets(),
}); err != nil {
return err
}
Expand All @@ -116,6 +127,12 @@ Creating a custom builder allows you to control what buildpacks are used and wha
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
cmd.Flags().StringArrayVar(&flags.Flatten, "flatten", nil, "List of buildpacks to flatten together into a single layer (format: '<buildpack-id>@<buildpack-version>,<buildpack-id>@<buildpack-version>'")
cmd.Flags().StringToStringVarP(&flags.Label, "label", "l", nil, "Labels to add to the builder image, in the form of '<name>=<value>'")
cmd.Flags().StringSliceVarP(&flags.Targets, "target", "t", nil,
`Target platforms to build for.\nTargets should be in the format '[os][/arch][/variant]:[distroname@osversion@anotherversion];[distroname@osversion]'.
- To specify two different architectures: '--target "linux/amd64" --target "linux/arm64"'
- To specify the distribution version: '--target "linux/arm/v6:ubuntu@14.04"'
- To specify multiple distribution versions: '--target "linux/arm/v6:ubuntu@14.04" --target "linux/arm/v6:ubuntu@16.04"'
`)

AddHelpFlag(cmd, "create")
return cmd
Expand Down
Loading
Loading