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

Adds -run as an input to the analyzer #1005

Merged
merged 1 commit into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions acceptance/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})
})

when("group path is provided", func() {
it("uses the provided group path", func() {
when("called with group (on older platforms)", func() {
it("uses the provided group.toml path", func() {
h.SkipIf(t, api.MustParse(platformAPI).AtLeast("0.7"), "Platform API >= 0.7 does not accept a -group flag")

h.DockerSeedRunAndCopy(t,
Expand Down Expand Up @@ -228,8 +228,8 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})
})

when("analyzed path is provided", func() {
it("uses the provided analyzed path", func() {
when("called with analyzed", func() {
it("uses the provided analyzed.toml path", func() {
analyzeFlags := []string{"-analyzed", ctrPath("/some-dir/some-analyzed.toml")}
if api.MustParse(platformAPI).AtLeast("0.7") {
analyzeFlags = append(analyzeFlags, "-run-image", analyzeRegFixtures.ReadOnlyRunImage)
Expand All @@ -256,6 +256,27 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})
})

when("called with run", func() {
it("uses the provided run.toml path", func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.12"), "Platform API < 0.12 does not accept -run")
cmd := exec.Command(
"docker", "run", "--rm",
"--env", "CNB_PLATFORM_API="+platformAPI,
"--env", "CNB_REGISTRY_AUTH="+analyzeRegAuthConfig,
"--network", analyzeRegNetwork,
analyzeImage,
ctrPath(analyzerPath),
"-run", "/cnb/run.toml",
analyzeRegFixtures.SomeAppImage,
) // #nosec G204
output, err := cmd.CombinedOutput()

h.AssertNotNil(t, err)
expected := "ensure registry read access to some-run-image-from-run-toml"
h.AssertStringContains(t, string(output), expected)
})
})

it("drops privileges", func() {
h.SkipIf(t, runtime.GOOS == "windows", "Not relevant on Windows")

Expand Down Expand Up @@ -357,7 +378,7 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})

when("app image exists", func() {
it("does not restore app metadata", func() {
it("does not restore app metadata to the layers directory", func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.7"), "Platform API < 0.7 restores app metadata")

analyzeFlags := []string{"-daemon", "-run-image", "some-run-image"}
Expand All @@ -381,7 +402,7 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
assertNoRestoreOfAppMetadata(t, copyDir, output)
})

it("restores app metadata", func() {
it("restores app metadata to the layers directory (on older platforms)", func() {
h.SkipIf(t, api.MustParse(platformAPI).AtLeast("0.7"), "Platform API >= 0.7 does not restore app metadata")
output := h.DockerRunAndCopy(t,
containerName,
Expand Down Expand Up @@ -428,7 +449,7 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})
})

when("cache is provided", func() {
when("cache is provided (on older platforms)", func() {
when("cache image case", func() {
when("cache image is in a daemon", func() {
it("ignores the cache", func() {
Expand Down Expand Up @@ -830,7 +851,7 @@ func testAnalyzerFunc(platformAPI string) func(t *testing.T, when spec.G, it spe
})
})

when("cache is provided", func() {
when("cache is provided (on older platforms)", func() {
when("cache image case", func() {
when("auth registry", func() {
when("registry creds are provided in CNB_REGISTRY_AUTH", func() {
Expand Down
21 changes: 21 additions & 0 deletions acceptance/creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ func testCreatorFunc(platformAPI string) func(t *testing.T, when spec.G, it spec
return func(t *testing.T, when spec.G, it spec.S) {
var createdImageName string

when("called with run", func() {
it("uses the provided run.toml path", func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.12"), "Platform API < 0.12 does not accept -run")
cmd := exec.Command(
"docker", "run", "--rm",
"--env", "CNB_PLATFORM_API="+platformAPI,
"--env", "CNB_REGISTRY_AUTH="+createRegAuthConfig,
"--network", createRegNetwork,
createImage,
ctrPath(creatorPath),
"-run", "/cnb/run.toml",
createRegFixtures.SomeAppImage,
) // #nosec G204
output, err := cmd.CombinedOutput()

h.AssertNotNil(t, err)
expected := "ensure registry read access to some-run-image-from-run-toml"
h.AssertStringContains(t, string(output), expected)
})
})

when("daemon case", func() {
it.After(func() {
h.DockerImageRemove(t, createdImageName)
Expand Down
5 changes: 5 additions & 0 deletions acceptance/testdata/analyzer/container/cnb/run.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[[image]]
image = "some-run-image-from-run-toml"

[[image]]
image = "some-other-run-image"
5 changes: 5 additions & 0 deletions acceptance/testdata/creator/container/cnb/run.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[[image]]
image = "some-run-image-from-run-toml"

[[image]]
image = "some-other-run-image"
2 changes: 1 addition & 1 deletion api/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

var (
Platform = newApisMustParse([]string{"0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "0.10", "0.11"}, []string{"0.3", "0.4", "0.5", "0.6"})
Platform = newApisMustParse([]string{"0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "0.10", "0.11", "0.12"}, []string{"0.3", "0.4", "0.5", "0.6"})
Buildpack = newApisMustParse([]string{"0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9"}, []string{"0.2", "0.3", "0.4", "0.5", "0.6"})
)

Expand Down
18 changes: 6 additions & 12 deletions cmd/lifecycle/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,14 @@ type analyzeCmd struct {

// DefineFlags defines the flags that are considered valid and reads their values (if provided).
func (a *analyzeCmd) DefineFlags() {
switch {
case a.PlatformAPI.AtLeast("0.9"):
cli.FlagAnalyzedPath(&a.AnalyzedPath)
cli.FlagCacheImage(&a.CacheImageRef)
cli.FlagGID(&a.GID)
if a.PlatformAPI.AtLeast("0.12") {
cli.FlagRunPath(&a.RunPath)
}
if a.PlatformAPI.AtLeast("0.9") {
cli.FlagLaunchCacheDir(&a.LaunchCacheDir)
cli.FlagLayersDir(&a.LayersDir)
cli.FlagPreviousImage(&a.PreviousImageRef)
cli.FlagRunImage(&a.RunImageRef)
cli.FlagSkipLayers(&a.SkipLayers)
cli.FlagStackPath(&a.StackPath)
cli.FlagTags(&a.AdditionalTags)
cli.FlagUID(&a.UID)
cli.FlagUseDaemon(&a.UseDaemon)
}
switch {
case a.PlatformAPI.AtLeast("0.7"):
cli.FlagAnalyzedPath(&a.AnalyzedPath)
cli.FlagCacheImage(&a.CacheImageRef)
Expand Down
4 changes: 4 additions & 0 deletions cmd/lifecycle/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ func FlagRunImage(runImage *string) {
flagSet.StringVar(runImage, "run-image", *runImage, "reference to run image")
}

func FlagRunPath(runPath *string) {
flagSet.StringVar(runPath, "run", *runPath, "path to run.toml")
}

func FlagSkipLayers(skipLayers *bool) {
flagSet.BoolVar(skipLayers, "skip-layers", *skipLayers, "do not provide layer metadata to buildpacks")
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/lifecycle/creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type createCmd struct {

// DefineFlags defines the flags that are considered valid and reads their values (if provided).
func (c *createCmd) DefineFlags() {
if c.PlatformAPI.AtLeast("0.12") {
cli.FlagRunPath(&c.RunPath)
}
if c.PlatformAPI.AtLeast("0.11") {
cli.FlagBuildConfigDir(&c.BuildConfigDir)
cli.FlagLauncherSBOMDir(&c.LauncherSBOMDir)
Expand Down
2 changes: 1 addition & 1 deletion exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func testExporter(t *testing.T, when spec.G, it spec.S) {

it("saves run image metadata to the resulting image", func() {
opts.Stack = platform.StackMetadata{
RunImage: platform.StackRunImageMetadata{
RunImage: platform.RunImageMetadata{
Image: "some/run",
Mirrors: []string{"registry.example.com/some/run", "other.example.com/some/run"},
},
Expand Down
21 changes: 16 additions & 5 deletions platform/analyze_inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
func DefaultAnalyzeInputs(platformAPI *api.Version) LifecycleInputs {
var inputs LifecycleInputs
switch {
case platformAPI.AtLeast("0.9"):
case platformAPI.AtLeast("0.12"):
inputs = defaultAnalyzeInputs()
case platformAPI.AtLeast("0.9"):
inputs = defaultAnalyzeInputs09To011()
case platformAPI.AtLeast("0.7"):
inputs = defaultAnalyzeInputs07()
inputs = defaultAnalyzeInputs07To08()
case platformAPI.AtLeast("0.5"):
inputs = defaultAnalyzeInputs05To06()
default:
Expand All @@ -27,12 +29,18 @@ func DefaultAnalyzeInputs(platformAPI *api.Version) LifecycleInputs {
}

func defaultAnalyzeInputs() LifecycleInputs {
ai := defaultAnalyzeInputs07()
ai := defaultAnalyzeInputs09To011()
ai.RunPath = envOrDefault(EnvRunPath, DefaultRunPath)
return ai
}

func defaultAnalyzeInputs09To011() LifecycleInputs {
ai := defaultAnalyzeInputs07To08()
ai.LaunchCacheDir = os.Getenv(EnvLaunchCacheDir)
return ai
}

func defaultAnalyzeInputs07() LifecycleInputs {
func defaultAnalyzeInputs07To08() LifecycleInputs {
ai := defaultAnalyzeInputs05To06()
ai.AdditionalTags = str.Slice{}
ai.CacheDir = "" // removed
Expand Down Expand Up @@ -72,5 +80,8 @@ func FillAnalyzeImages(i *LifecycleInputs, logger log.Logger) error {
if i.PlatformAPI.LessThan("0.7") {
return nil
}
return fillRunImageFromStackTOMLIfNeeded(i, logger)
if i.PlatformAPI.LessThan("0.12") {
return fillRunImageFromStackTOMLIfNeeded(i, logger)
}
return fillRunImageFromRunTOMLIfNeeded(i, logger)
}
96 changes: 73 additions & 23 deletions platform/analyze_inputs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/sclevine/spec/report"

"github.com/buildpacks/lifecycle/api"
"github.com/buildpacks/lifecycle/internal/path"
"github.com/buildpacks/lifecycle/internal/str"
llog "github.com/buildpacks/lifecycle/log"
"github.com/buildpacks/lifecycle/platform"
Expand Down Expand Up @@ -38,8 +39,51 @@ func testAnalyzeInputs(platformAPI string) func(t *testing.T, when spec.G, it sp
})

when("latest Platform API(s)", func() {
it.Before(func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.12"), "")
inputs.RunImageRef = "some-run-image" // satisfy validation
})

when("run image", func() {
when("not provided", func() {
it.Before(func() {
inputs.RunImageRef = ""
})

it("falls back to run.toml", func() {
inputs.RunPath = filepath.Join("testdata", "cnb", "run.toml")
err := platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertNil(t, err)
h.AssertEq(t, inputs.RunImageRef, "some-run-image")
})

when("run.toml", func() {
when("not provided", func() {
it("defaults to /cnb/run.toml", func() {
_ = platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertEq(t, inputs.RunPath, filepath.Join(path.RootDir, "cnb", "run.toml"))
})
})

when("not exists", func() {
it("errors", func() {
inputs.RunImageRef = ""
inputs.RunPath = "not-exist-run.toml"
err := platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertNotNil(t, err)
expected := "-run-image is required when there is no run metadata available"
h.AssertStringContains(t, err.Error(), expected)
})
})
})
})
})
})

when("Platform API 0.7 to 0.11", func() {
it.Before(func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.7"), "")
h.SkipIf(t, api.MustParse(platformAPI).AtLeast("0.12"), "")
inputs.RunImageRef = "some-run-image" // satisfy validation
})

Expand All @@ -53,18 +97,34 @@ func testAnalyzeInputs(platformAPI string) func(t *testing.T, when spec.G, it sp
h.AssertEq(t, inputs.RunImageRef, "some-run-image")
})

when("stack.toml not present", func() {
it("errors", func() {
inputs.RunImageRef = ""
inputs.StackPath = "not-exist-stack.toml"
err := platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertNotNil(t, err)
expected := "-run-image is required when there is no stack metadata available"
h.AssertStringContains(t, err.Error(), expected)
when("stack.toml", func() {
when("not provided", func() {
it("defaults to /cnb/stack.toml", func() {
_ = platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertEq(t, inputs.StackPath, filepath.Join(path.RootDir, "cnb", "stack.toml"))
})
})

when("not exists", func() {
it("errors", func() {
inputs.RunImageRef = ""
inputs.StackPath = "not-exist-stack.toml"
err := platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertNotNil(t, err)
expected := "-run-image is required when there is no stack metadata available"
h.AssertStringContains(t, err.Error(), expected)
})
})
})
})
})
})

when("Platform API >= 0.7", func() {
it.Before(func() {
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.7"), "")
inputs.RunImageRef = "some-run-image" // satisfy validation
})

when("provided destination tags are on different registries", func() {
it("errors", func() {
Expand All @@ -79,15 +139,6 @@ func testAnalyzeInputs(platformAPI string) func(t *testing.T, when spec.G, it sp
h.AssertStringContains(t, err.Error(), expected)
})
})

when("layers directory is provided", func() {
it("writes analyzed.toml at the layers directory", func() {
inputs.LayersDir = "some-layers-dir"
err := platform.ResolveInputs(platform.Analyze, &inputs, logger)
h.AssertNil(t, err)
h.AssertEq(t, inputs.AnalyzedPath, filepath.Join("some-layers-dir", "analyzed.toml"))
})
})
Comment on lines -82 to -90
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was repeated in this file

})

when("Platform API < 0.7", func() {
Expand Down Expand Up @@ -119,13 +170,12 @@ func testAnalyzeInputs(platformAPI string) func(t *testing.T, when spec.G, it sp
})
})

when("Platform API 0.5 to 0.6", func() {
when("Platform API >= 0.5", func() {
it.Before(func() {
h.SkipIf(
t,
!(api.MustParse(platformAPI).Equal(api.MustParse("0.5")) || api.MustParse(platformAPI).Equal(api.MustParse("0.6"))),
"",
)
h.SkipIf(t, api.MustParse(platformAPI).LessThan("0.5"), "")
if api.MustParse(platformAPI).AtLeast("0.7") {
inputs.RunImageRef = "some-run-image" // satisfy validation
}
})

when("layers directory is provided", func() {
Expand Down
Loading