Skip to content

Commit

Permalink
Merge branch 'main' into extension-downloader
Browse files Browse the repository at this point in the history
  • Loading branch information
jkutner authored May 19, 2023
2 parents 1575e82 + 1aa6461 commit de9c113
Show file tree
Hide file tree
Showing 23 changed files with 464 additions and 176 deletions.
61 changes: 42 additions & 19 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import (
"testing"
"time"

"github.com/buildpacks/pack/pkg/cache"

"github.com/buildpacks/lifecycle/api"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/ghodss/yaml"
Expand All @@ -35,6 +34,7 @@ import (
"github.com/buildpacks/pack/acceptance/managers"
"github.com/buildpacks/pack/internal/style"
"github.com/buildpacks/pack/pkg/archive"
"github.com/buildpacks/pack/pkg/cache"
h "github.com/buildpacks/pack/testhelpers"
)

Expand Down Expand Up @@ -761,8 +761,8 @@ func testAcceptance(

when("builder has extensions", func() {
it.Before(func() {
h.SkipIf(t, !createBuilderPack.SupportsFeature(invoke.Extensions), "")
h.SkipIf(t, !pack.SupportsFeature(invoke.Extensions), "")
h.SkipIf(t, !createBuilderPack.SupportsFeature(invoke.BuildImageExtensions), "")
h.SkipIf(t, !pack.SupportsFeature(invoke.BuildImageExtensions), "")
h.SkipIf(t, !lifecycle.SupportsFeature(config.BuildImageExtensions), "")
// create a task, handled by a 'task manager' which executes our pack commands during tests.
// looks like this is used to de-dup tasks
Expand Down Expand Up @@ -866,6 +866,7 @@ func testAcceptance(

when("there are run image extensions", func() {
it.Before(func() {
h.SkipIf(t, !pack.SupportsFeature(invoke.RunImageExtensions), "")
h.SkipIf(t, !lifecycle.SupportsFeature(config.RunImageExtensions), "")
})

Expand Down Expand Up @@ -1046,7 +1047,7 @@ func testAcceptance(
assertImage.HasBaseImage(repoName, runImage)

t.Log("sets the run image metadata")
assertImage.HasLabelWithData(repoName, "io.buildpacks.lifecycle.metadata", fmt.Sprintf(`"stack":{"runImage":{"image":"%s","mirrors":["%s"]}}}`, runImage, runImageMirror))
assertImage.HasLabelWithData(repoName, "io.buildpacks.lifecycle.metadata", fmt.Sprintf(`"image":"pack-test/run","mirrors":["%s"]`, runImageMirror))

t.Log("sets the source metadata")
assertImage.HasLabelWithData(repoName, "io.buildpacks.project.metadata", (`{"source":{"type":"project","version":{"declared":"1.0.2"},"metadata":{"url":"https://github.com/buildpacks/pack"}}}`))
Expand Down Expand Up @@ -1554,24 +1555,51 @@ func testAcceptance(
var otherStackBuilderTgz string

it.Before(func() {
// The Platform API is new if pack is new AND the lifecycle is new
// Therefore skip if pack is old OR the lifecycle is old
h.SkipIf(t,
pack.SupportsFeature(invoke.StackValidation) ||
api.MustParse(lifecycle.LatestPlatformAPIVersion()).LessThan("0.12"), "")
otherStackBuilderTgz = h.CreateTGZ(t, filepath.Join(bpDir, "other-stack-buildpack"), "./", 0755)
})

it.After(func() {
h.SkipIf(t,
pack.SupportsFeature(invoke.StackValidation) ||
api.MustParse(lifecycle.LatestPlatformAPIVersion()).LessThan("0.12"), "")
assert.Succeeds(os.Remove(otherStackBuilderTgz))
})

it("errors", func() {
output, err := pack.Run(
it("succeeds", func() {
_, err := pack.Run(
"build", repoName,
"-p", filepath.Join("testdata", "mock_app"),
"--buildpack", otherStackBuilderTgz,
)
assert.Nil(err)
})

assert.NotNil(err)
assert.Contains(output, "other/stack/bp")
assert.Contains(output, "other-stack-version")
assert.Contains(output, "does not support stack 'pack.test.stack'")
when("platform API < 0.12", func() {
it.Before(func() {
// The Platform API is old if pack is old OR the lifecycle is old
// Therefore skip if pack is new AND the lifecycle is new
h.SkipIf(t,
!pack.SupportsFeature(invoke.StackValidation) &&
api.MustParse(lifecycle.LatestPlatformAPIVersion()).AtLeast("0.12"), "")
})

it("errors", func() {
output, err := pack.Run(
"build", repoName,
"-p", filepath.Join("testdata", "mock_app"),
"--buildpack", otherStackBuilderTgz,
)

assert.NotNil(err)
assert.Contains(output, "other/stack/bp")
assert.Contains(output, "other-stack-version")
assert.Contains(output, "does not support stack 'pack.test.stack'")
})
})
})
})
Expand Down Expand Up @@ -1905,7 +1933,6 @@ func testAcceptance(
when("--cache with options for build cache as image", func() {
var cacheImageName, cacheFlags string
it.Before(func() {
h.SkipIf(t, !pack.SupportsFeature(invoke.Cache), "")
cacheImageName = fmt.Sprintf("%s-cache", repoName)
cacheFlags = fmt.Sprintf("type=build;format=image;name=%s", cacheImageName)
})
Expand Down Expand Up @@ -1947,8 +1974,9 @@ func testAcceptance(
var bindCacheDir, cacheFlags string
it.Before(func() {
h.SkipIf(t, !pack.SupportsFeature(invoke.Cache), "")
cacheBindName := fmt.Sprintf("%s-bind", repoName)
bindCacheDir, err := os.MkdirTemp("", cacheBindName)
cacheBindName := strings.ReplaceAll(strings.ReplaceAll(fmt.Sprintf("%s-bind", repoName), string(filepath.Separator), "-"), ":", "-")
var err error
bindCacheDir, err = os.MkdirTemp("", cacheBindName)
assert.Nil(err)
cacheFlags = fmt.Sprintf("type=build;format=bind;source=%s", bindCacheDir)
})
Expand Down Expand Up @@ -2187,11 +2215,6 @@ include = [ "*.jar", "media/mountain.jpg", "/media/person.png", ]
})

when("--creation-time", func() {
it.Before(func() {
h.SkipIf(t, !pack.SupportsFeature(invoke.CreationTime), "")
h.SkipIf(t, !lifecycle.SupportsFeature(config.CreationTime), "")
})

when("provided as 'now'", func() {
it("image has create time of the current time", func() {
expectedTime := time.Now()
Expand Down
2 changes: 1 addition & 1 deletion acceptance/config/asset_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (
var (
currentPackFixturesDir = filepath.Join("testdata", "pack_fixtures")
previousPackFixturesOverridesDir = filepath.Join("testdata", "pack_previous_fixtures_overrides")
lifecycleTgzExp = regexp.MustCompile(`lifecycle-v\d+.\d+.\d+\+linux.x86-64.tgz`)
lifecycleTgzExp = regexp.MustCompile(`lifecycle-v\d+.\d+.\d+(-pre.\d+)?(-rc.\d+)?\+linux.x86-64.tgz`)
)

type AssetManager struct {
Expand Down
18 changes: 18 additions & 0 deletions acceptance/config/lifecycle_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ func earliestVersion(versions []*api.Version) *api.Version {
return earliest
}

func latestVersion(versions []*api.Version) *api.Version {
var latest *api.Version
for _, version := range versions {
switch {
case version == nil:
continue
case latest == nil:
latest = version
case latest.Compare(version) < 0:
latest = version
}
}
return latest
}
func (l *LifecycleAsset) EarliestBuildpackAPIVersion() string {
return earliestVersion(l.descriptor.APIs.Buildpack.Supported).String()
}
Expand All @@ -78,6 +92,10 @@ func (l *LifecycleAsset) EarliestPlatformAPIVersion() string {
return earliestVersion(l.descriptor.APIs.Platform.Supported).String()
}

func (l *LifecycleAsset) LatestPlatformAPIVersion() string {
return latestVersion(l.descriptor.APIs.Platform.Supported).String()
}

func (l *LifecycleAsset) OutputForAPIs() (deprecatedBuildpackAPIs, supportedBuildpackAPIs, deprecatedPlatformAPIs, supportedPlatformAPIs string) {
stringify := func(apiSet builder.APISet) string {
versions := apiSet.AsStrings()
Expand Down
17 changes: 14 additions & 3 deletions acceptance/invoke/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (i *PackInvoker) EnableExperimental() {
// - "<command>" (e.g. "create-builder")
// - "<flag>" (e.g. "--verbose")
// - "<command> <flag>" (e.g. "build --network")
// - "<command>... <flag>" (e.g. "config trusted-builder--network")
// - "<command>... <flag>" (e.g. "config trusted-builder --network")
//
// Any other form may return false.
func (i *PackInvoker) Supports(command string) bool {
Expand All @@ -218,6 +218,9 @@ func (i *PackInvoker) Supports(command string) bool {
output, err := i.baseCmd(cmdParts...).CombinedOutput()
i.assert.Nil(err)

// FIXME: this doesn't appear to be working as expected,
// as tests against "build --creation-time" and "build --cache" are returning unsupported
// even on the latest version of pack.
return re.MatchString(string(output)) && !strings.Contains(string(output), "Unknown help topic")
}

Expand All @@ -226,7 +229,9 @@ type Feature int
const (
CreationTime = iota
Cache
Extensions
BuildImageExtensions
RunImageExtensions
StackValidation
)

var featureTests = map[Feature]func(i *PackInvoker) bool{
Expand All @@ -236,9 +241,15 @@ var featureTests = map[Feature]func(i *PackInvoker) bool{
Cache: func(i *PackInvoker) bool {
return i.Supports("build --cache")
},
Extensions: func(i *PackInvoker) bool {
BuildImageExtensions: func(i *PackInvoker) bool {
return i.laterThan("v0.27.0")
},
RunImageExtensions: func(i *PackInvoker) bool {
return i.laterThan("v0.29.0")
},
StackValidation: func(i *PackInvoker) bool {
return !i.atLeast("v0.30.0")
},
}

func (i *PackInvoker) SupportsFeature(f Feature) bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

echo "---> Build: Other Stack Buildpack"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@echo off

echo ---- Build: Other Stack 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,2 @@
@echo off
:: always detect
2 changes: 1 addition & 1 deletion acceptance/testdata/pack_fixtures/report_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Pack:
Version: {{ .Version }}
OS/Arch: {{ .OS }}/{{ .Arch }}

Default Lifecycle Version: 0.16.0
Default Lifecycle Version: 0.17.0-pre.2

Supported Platform APIs: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 0.11, 0.12

Expand Down
2 changes: 1 addition & 1 deletion builder/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type RunConfig struct {
// RunImageConfig run image id and mirrors
type RunImageConfig struct {
Image string `toml:"image"`
Mirrors []string `toml:"run-image-mirrors,omitempty"`
Mirrors []string `toml:"mirrors,omitempty"`
}

// BuildConfig build image configuration
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ require (
github.com/Masterminds/semver v1.5.0
github.com/Microsoft/go-winio v0.6.1
github.com/apex/log v1.9.0
github.com/buildpacks/imgutil v0.0.0-20230412223147-81015c668834
github.com/buildpacks/lifecycle v0.17.0-pre.1
github.com/buildpacks/imgutil v0.0.0-20230428141433-24db5a78c900
github.com/buildpacks/lifecycle v0.17.0-pre.2
github.com/docker/cli v23.0.6+incompatible
github.com/docker/docker v23.0.6+incompatible
github.com/docker/go-connections v0.4.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230110223219-40efa3093a22 h1:Sq2n1xnF4uuEGNUVOLKHZXoL0CVdxIQOQTEZ7EW762Q=
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230110223219-40efa3093a22/go.mod h1:G93AFVEAkW0+tabIqmQCLN/r6sZgP4pFxfoiEzDeQNM=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/buildpacks/imgutil v0.0.0-20230412223147-81015c668834 h1:V3xhD9kbougG1QgtpA60UK6JnBPW7gX17zZ2ekXwUpo=
github.com/buildpacks/imgutil v0.0.0-20230412223147-81015c668834/go.mod h1:hgxVR7UpPvT5gATbRGM582oy048sUocDg6R6PMWAxow=
github.com/buildpacks/lifecycle v0.17.0-pre.1 h1:YE4961UxDaLhtKI45yznzqfkZDoHxiki/aoUx2igvRk=
github.com/buildpacks/lifecycle v0.17.0-pre.1/go.mod h1:yPCzhhQDBoXdrD/9yEBsZ7AXVNPUnX3a4gioZAK5CxI=
github.com/buildpacks/imgutil v0.0.0-20230428141433-24db5a78c900 h1:f6SrGzyotuJxn+BuIQC3ZBXQiNKgeXhWZLnAJEavaxI=
github.com/buildpacks/imgutil v0.0.0-20230428141433-24db5a78c900/go.mod h1:/xuDxsWO9JE/s95g+OfXB8C+G5TeHznq7vURY2s1yPM=
github.com/buildpacks/lifecycle v0.17.0-pre.2 h1:y6QUW2DWw6lgcaskFBA8ABt8xG+cgJfr0v20pr2RjjU=
github.com/buildpacks/lifecycle v0.17.0-pre.2/go.mod h1:YZMUvNOkwv7AsARB81GqcHANM4pLu4wP/qe5N4Kzmxs=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4=
Expand Down
16 changes: 11 additions & 5 deletions internal/build/lifecycle_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func apiIntersection(apisA, apisB []*api.Version) []*api.Version {
return apis
}

// public for unit test purposes but cmon you probably don't want to actually call this.
// FindLatestSupported finds the latest Platform API version supported by both the builder and the lifecycle.
func FindLatestSupported(builderapis []*api.Version, lifecycleapis []string) (*api.Version, error) {
var apis []*api.Version
// if a custom lifecycle image was used we need to take an intersection of its supported apis with the builder's supported apis.
Expand Down Expand Up @@ -239,6 +239,13 @@ func (l *LifecycleExecution) Run(ctx context.Context, phaseFactoryCreator PhaseF
})
}

currentRunImage := l.runImageAfterExtensions()
if currentRunImage != "" && currentRunImage != l.opts.RunImage {
if err := l.opts.FetchRunImage(currentRunImage); err != nil {
return err
}
}

if l.platformAPI.AtLeast("0.12") && l.hasExtensionsForRun() {
group.Go(func() error {
l.logger.Info(style.Step("EXTENDING (RUN)"))
Expand Down Expand Up @@ -832,8 +839,8 @@ type analyzedMD struct {
RunImage *runImage `toml:"run-image,omitempty"`
}
type runImage struct {
Extend bool `toml:"extend,omitempty"`
Reference string `toml:"reference"`
Extend bool `toml:"extend,omitempty"`
Image string `toml:"image"`
}

func (l *LifecycleExecution) hasExtensionsForRun() bool {
Expand All @@ -847,7 +854,6 @@ func (l *LifecycleExecution) hasExtensionsForRun() bool {
return amd.RunImage.Extend
}

// TODO: we might need to pull the run image at this stage, see https://github.com/buildpacks/pack/issues/1686
func (l *LifecycleExecution) runImageAfterExtensions() string {
var amd analyzedMD
if _, err := toml.DecodeFile(filepath.Join(l.tmpDir, "analyzed.toml"), &amd); err != nil {
Expand All @@ -857,7 +863,7 @@ func (l *LifecycleExecution) runImageAfterExtensions() string {
// this shouldn't be reachable
return l.opts.RunImage
}
return amd.RunImage.Reference
return amd.RunImage.Image
}

func (l *LifecycleExecution) appendLayoutOperations(opts []PhaseConfigProviderOperation) ([]PhaseConfigProviderOperation, error) {
Expand Down
Loading

0 comments on commit de9c113

Please sign in to comment.