diff --git a/internal/builder/lifecycle.go b/internal/builder/lifecycle.go index 5651ad4b6..009983a37 100644 --- a/internal/builder/lifecycle.go +++ b/internal/builder/lifecycle.go @@ -124,3 +124,8 @@ func (l *lifecycle) binaries() []string { func SupportedLinuxArchitecture(arch string) bool { return arch == "arm64" || arch == "ppc64le" || arch == "s390x" || arch == "x86-64" } + +// SupportedFreeBSDArchitecture returns true for each binary architecture available at https://github.com/buildpacks/lifecycle/releases/ +func SupportedFreeBSDArchitecture(arch string) bool { + return arch == "amd64" || arch == "arm64" +} diff --git a/pkg/client/create_builder.go b/pkg/client/create_builder.go index fb42b83ef..a83e6af81 100644 --- a/pkg/client/create_builder.go +++ b/pkg/client/create_builder.go @@ -456,24 +456,70 @@ func validateModule(kind string, module buildpack.BuildModule, source, expectedI } func (c *Client) uriFromLifecycleVersion(version semver.Version, os string, architecture string) string { - arch := "x86-64" - - if os == "windows" { + switch os { + case "windows": + // Windows container support was deprecated at lifecycle v0.20.5. + // See: https://medium.com/buildpacks/deprecation-announcement-windows-container-feature-in-cloud-native-buildpacks-bbb70351343d + lastWindowsVersion := semver.MustParse("0.20.5") + if version.GreaterThan(lastWindowsVersion) { + c.logger.Warnf("Windows lifecycle binaries are not available after v0.20.5; capping version to v0.20.5") + version = *lastWindowsVersion + } + arch := windowsArch(architecture) return fmt.Sprintf("https://github.com/buildpacks/lifecycle/releases/download/v%s/lifecycle-v%s+windows.%s.tgz", version.String(), version.String(), arch) + + case "freebsd": + arch := freebsdArch(architecture) + if arch == "" { + arch = "amd64" + c.logger.Warnf("failed to find a lifecycle binary for requested architecture %s on FreeBSD, defaulting to %s", style.Symbol(architecture), style.Symbol(arch)) + } + return fmt.Sprintf("https://github.com/buildpacks/lifecycle/releases/download/v%s/lifecycle-v%s+freebsd.%s.tgz", version.String(), version.String(), arch) + + default: // linux + arch := linuxArch(architecture) + if arch == "" { + arch = "x86-64" + c.logger.Warnf("failed to find a lifecycle binary for requested architecture %s, defaulting to %s", style.Symbol(architecture), style.Symbol(arch)) + } + return fmt.Sprintf("https://github.com/buildpacks/lifecycle/releases/download/v%s/lifecycle-v%s+linux.%s.tgz", version.String(), version.String(), arch) } +} - if architecture == "amd64" { - architecture = "x86-64" +// linuxArch maps the input architecture to the lifecycle binary suffix for Linux. +// Returns empty string for unsupported architectures. +func linuxArch(architecture string) string { + switch architecture { + case "amd64", "x86-64": + return "x86-64" + case "arm64": + return "arm64" + case "ppc64le": + return "ppc64le" + case "s390x": + return "s390x" + default: + return "" } +} - if builder.SupportedLinuxArchitecture(architecture) { - arch = architecture - } else { - // FIXME: this should probably be an error case in the future, see https://github.com/buildpacks/pack/issues/2163 - c.logger.Warnf("failed to find a lifecycle binary for requested architecture %s, defaulting to %s", style.Symbol(architecture), style.Symbol(arch)) +// freebsdArch maps the input architecture to the lifecycle binary suffix for FreeBSD. +// Returns empty string for unsupported architectures. +func freebsdArch(architecture string) string { + switch architecture { + case "amd64", "x86-64": + return "amd64" + case "arm64": + return "arm64" + default: + return "" } +} - return fmt.Sprintf("https://github.com/buildpacks/lifecycle/releases/download/v%s/lifecycle-v%s+linux.%s.tgz", version.String(), version.String(), arch) +// windowsArch maps the input architecture to the lifecycle binary suffix for Windows. +func windowsArch(architecture string) string { + // Only x86-64 was ever published for Windows. + return "x86-64" } func stripTopDirAndWrite(layerReader io.ReadCloser, outputPath string) (*OS.File, error) {