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

Dockerfiles phase 1 (detect changes) #860

Merged
merged 61 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
5a4832b
Acceptance tests pass with creator commented out
natalieparellano Feb 22, 2022
ed1b3a7
Fix creator
natalieparellano Feb 22, 2022
fc4a7e3
Add unit tests for analyze inputs
natalieparellano Feb 22, 2022
2b505c6
Add scaffold for analyzer builder unit tests
natalieparellano Feb 22, 2022
6fef994
Add many unit tests, still have some TODOs
natalieparellano Feb 23, 2022
043974b
Address most TODOs
natalieparellano Feb 23, 2022
02a5c74
Acceptance tests pass
natalieparellano Feb 23, 2022
785d81a
A few more TODOs
natalieparellano Feb 23, 2022
e58d007
Bring back go 1.16
natalieparellano Feb 23, 2022
125f01f
Add unit test
natalieparellano Feb 23, 2022
4b4e816
Fix acceptance tests
natalieparellano Feb 24, 2022
8294ea5
Fix units
natalieparellano Feb 24, 2022
fd6beb3
Remove nolint
natalieparellano Feb 24, 2022
8335a56
Remove unneeded things
natalieparellano Feb 24, 2022
9ee1dfd
Use operations pattern
natalieparellano Mar 3, 2022
d21352f
Refactor tests to take advantage of operations pattern
natalieparellano Mar 3, 2022
d81cb6c
Add missing tests
natalieparellano Mar 4, 2022
d815707
Fix lint
natalieparellano Mar 4, 2022
46a24ae
Analyzer factory assigns "nop" services by default
natalieparellano Mar 4, 2022
fe83502
Try to fix registry handler test
natalieparellano Mar 4, 2022
f72848d
Move new package from cmd/lifecycle/platform to platform/inputs
natalieparellano Mar 8, 2022
a457244
Merge branch 'main' into cmd-package
natalieparellano Mar 30, 2022
c828d03
Updates per PR review
natalieparellano Apr 26, 2022
e0e8d8a
Test the platform instead of the exiter
natalieparellano Apr 26, 2022
0af8ab2
Combine cmd/lifecycle/platform and platform
natalieparellano Apr 27, 2022
fcac2e3
Clean up constructors
natalieparellano Apr 27, 2022
59097ca
Remove ForAnalyzer struct
natalieparellano Apr 27, 2022
76811ce
Combine cmd/launcher/platform and platform
natalieparellano Apr 27, 2022
2d4a9bc
Remove comment
natalieparellano Apr 27, 2022
e06cb9c
Remove spec alias
natalieparellano Apr 27, 2022
c982fb1
Move cache metadata back to platform
natalieparellano Apr 28, 2022
4aa3115
Add comment and remove unused vars
natalieparellano Apr 28, 2022
2078007
Merge branch 'main' into cmd-package
natalieparellano Apr 28, 2022
f358c2d
Move buildpack store and make it hold extensions also
natalieparellano Apr 28, 2022
462bf4e
WIP: detector units pass
natalieparellano Apr 29, 2022
476d407
Rename GroupBuildpack to GroupElement
natalieparellano Apr 29, 2022
ecec7a8
Move Buildpack interface to buildpack package and rename BuildModule
natalieparellano Apr 29, 2022
42a9351
WIP
natalieparellano May 3, 2022
c693e7d
WIP
natalieparellano May 3, 2022
61abad0
WIP
natalieparellano May 6, 2022
d6a0204
WIP
natalieparellano May 7, 2022
81408eb
WIP
natalieparellano May 7, 2022
788999e
WIP
natalieparellano May 7, 2022
e93fc73
WIP
natalieparellano May 7, 2022
35b6f7b
Merge branch 'main' into dockerfiles-phase-1-detect
natalieparellano May 7, 2022
4189ea3
Verify buildpack apis when reading order
natalieparellano May 24, 2022
8155aae
Update comment
natalieparellano May 24, 2022
f71def2
Remove comment
natalieparellano May 24, 2022
ff567c8
Decouple config handler and api verifier
natalieparellano May 26, 2022
d070f0a
Move var to file where it is used
natalieparellano May 26, 2022
38287b8
Add tests
natalieparellano May 26, 2022
0b6cf13
Add TODO
natalieparellano Jun 2, 2022
0a54192
Merge branch 'main' into dockerfiles-phase-1-detect
natalieparellano Jun 3, 2022
e92a8b7
Updates per PR review
natalieparellano Jun 7, 2022
c518697
Don't fail detect if /bin/detect and plan.toml are both missing
natalieparellano Jun 7, 2022
46375d0
Fix cherry pick
natalieparellano Jun 7, 2022
3eb9961
APIVerifier takes a kind
natalieparellano Jun 7, 2022
3a0218d
DirStore takes a kind
natalieparellano Jun 7, 2022
7130656
detect_test.go uses kind
natalieparellano Jun 7, 2022
0a358b4
Ensure that optional information is preserved
natalieparellano Jun 7, 2022
bc0a646
Remove ToGroupElement() weirdness and fix comparison
natalieparellano Jun 8, 2022
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
56 changes: 53 additions & 3 deletions acceptance/detector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
)
output, err := command.CombinedOutput()
h.AssertNotNil(t, err)
expected := "failed to read buildpack order file"
expected := "failed to initialize detector: reading buildpack order file"
h.AssertStringContains(t, string(output), expected)
})
})
Expand Down Expand Up @@ -290,7 +290,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
"-order=/custom/order.toml")
output, err := command.CombinedOutput()
h.AssertNotNil(t, err)
expected := "failed to read buildpack order file: open /custom/order.toml: no such file or directory"
expected := "failed to initialize detector: reading buildpack order file: open /custom/order.toml: no such file or directory"
h.AssertStringContains(t, string(output), expected)
})
})
Expand Down Expand Up @@ -435,13 +435,63 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
"--rm", detectImage)
output, err := command.CombinedOutput()
h.AssertNotNil(t, err)
expected := "failed to read buildpack order file: open /cnb/order.toml: no such file or directory"
expected := "failed to initialize detector: reading buildpack order file: open /cnb/order.toml: no such file or directory"
h.AssertStringContains(t, string(output), expected)
})
})
})
})

when("-order contains extensions", func() {
var containerName, copyDir, orderPath string

it.Before(func() {
containerName = "test-container-" + h.RandString(10)
var err error
copyDir, err = ioutil.TempDir("", "test-docker-copy-")
h.AssertNil(t, err)
orderPath, err = filepath.Abs(filepath.Join("testdata", "detector", "container", "cnb", "orders", "order_with_ext.toml"))
h.AssertNil(t, err)
})

it.After(func() {
if h.DockerContainerExists(t, containerName) {
h.Run(t, exec.Command("docker", "rm", containerName))
}
os.RemoveAll(copyDir)
})

it("processes the provided order.toml", func() {
h.DockerRunAndCopy(t,
containerName,
copyDir,
"/layers",
detectImage,
h.WithFlags(
"--user", userID,
"--volume", orderPath+":/layers/order.toml",
"--env", "CNB_PLATFORM_API="+latestPlatformAPI,
),
h.WithArgs(
"-extensions=/cnb/extensions",
"-log-level=debug",
),
)

// check group.toml
tempGroupToml := filepath.Join(copyDir, "layers", "group.toml")
var buildpackGroup buildpack.Group
_, err := toml.DecodeFile(tempGroupToml, &buildpackGroup)
h.AssertNil(t, err)
h.AssertEq(t, buildpackGroup.Group[0].ID, "simple_extension")
h.AssertEq(t, buildpackGroup.Group[0].Version, "simple_extension_version")
h.AssertEq(t, buildpackGroup.Group[0].Extension, true)
h.AssertEq(t, buildpackGroup.Group[1].ID, "buildpack_for_ext")
h.AssertEq(t, buildpackGroup.Group[1].Version, "buildpack_for_ext_version")
h.AssertEq(t, buildpackGroup.Group[1].Extension, false)
})
})

when("platform api < 0.6", func() {
when("no buildpack group passed detection", func() {
it("errors", func() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

plan_path=$2

cat >> "${plan_path}" <<EOL
[[requires]]
name = "some_requirement"
[requires.metadata]
version = "some_version" # Optional
some_metadata_key = "some_metadata_val" # Optional
EOL
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
api = "0.3"
[buildpack]
id = "buildpack_for_ext"
version = "buildpack_for_ext_version"
name = "Buildpack for Extensions"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

plan_path=$2

cat >> "${plan_path}" <<EOL
[[provides]]
name = "some_requirement"
EOL
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
api = "0.9"
[extension]
id = "simple_extension"
version = "simple_extension_version"
name = "Simple Extension"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[order]]
[[order.group]]
id = "buildpack_for_ext"
version = "buildpack_for_ext_version"

[[order-ext]]
[[order-ext.group]]
id = "simple_extension"
version = "simple_extension_version"
23 changes: 15 additions & 8 deletions analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,26 @@ import (
"github.com/buildpacks/lifecycle/platform"
)

type Platform interface {
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
API() *api.Version
}

type AnalyzerFactory struct {
platformAPI *api.Version
apiVerifier APIVerifier
cacheHandler CacheHandler
configHandler ConfigHandler
imageHandler ImageHandler
registryHandler RegistryHandler
}

func NewAnalyzerFactory(platformAPI *api.Version, cacheHandler CacheHandler, configHandler ConfigHandler, imageHandler ImageHandler, registryHandler RegistryHandler) *AnalyzerFactory {
func NewAnalyzerFactory(
platformAPI *api.Version,
apiVerifier APIVerifier,
cacheHandler CacheHandler,
configHandler ConfigHandler,
imageHandler ImageHandler,
registryHandler RegistryHandler,
) *AnalyzerFactory {
return &AnalyzerFactory{
platformAPI: platformAPI,
apiVerifier: apiVerifier,
cacheHandler: cacheHandler,
configHandler: configHandler,
imageHandler: imageHandler,
Expand All @@ -41,7 +46,7 @@ type Analyzer struct {
SBOMRestorer layer.SBOMRestorer

// Platform API < 0.7
Buildpacks []buildpack.GroupBuildpack
Buildpacks []buildpack.GroupElement
Cache Cache
LayerMetadataRestorer layer.MetadataRestorer
RestoresLayerMetadata bool
Expand Down Expand Up @@ -128,8 +133,10 @@ func (f *AnalyzerFactory) setBuildpacks(analyzer *Analyzer, group buildpack.Grou
return nil
}
var err error
analyzer.Buildpacks, err = f.configHandler.ReadGroup(path)
return err
if analyzer.Buildpacks, err = f.configHandler.ReadGroup(path); err != nil {
return err
}
return f.apiVerifier.VerifyBuildpackAPIsForGroup(analyzer.Buildpacks)
}

func (f *AnalyzerFactory) setCache(analyzer *Analyzer, imageRef string, dir string) error {
Expand Down
41 changes: 15 additions & 26 deletions analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {
when("#NewAnalyzer", func() {
var (
analyzerFactory *lifecycle.AnalyzerFactory
fakeAPIVerifier *testmock.MockAPIVerifier
fakeCacheHandler *testmock.MockCacheHandler
fakeConfigHandler *testmock.MockConfigHandler
fakeImageHandler *testmock.MockImageHandler
Expand All @@ -49,6 +50,7 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {

it.Before(func() {
mockController = gomock.NewController(t)
fakeAPIVerifier = testmock.NewMockAPIVerifier(mockController)
fakeCacheHandler = testmock.NewMockCacheHandler(mockController)
fakeConfigHandler = testmock.NewMockConfigHandler(mockController)
fakeImageHandler = testmock.NewMockImageHandler(mockController)
Expand All @@ -66,13 +68,7 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {

when("platform api >= 0.8", func() {
it.Before(func() {
analyzerFactory = lifecycle.NewAnalyzerFactory(
api.Platform.Latest(),
fakeCacheHandler,
fakeConfigHandler,
fakeImageHandler,
fakeRegistryHandler,
)
analyzerFactory = lifecycle.NewAnalyzerFactory(api.Platform.Latest(), fakeAPIVerifier, fakeCacheHandler, fakeConfigHandler, fakeImageHandler, fakeRegistryHandler)
})

it("configures the analyzer", func() {
Expand Down Expand Up @@ -164,13 +160,7 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {

when("platform api = 0.7", func() {
it.Before(func() {
analyzerFactory = lifecycle.NewAnalyzerFactory(
api.MustParse("0.7"),
fakeCacheHandler,
fakeConfigHandler,
fakeImageHandler,
fakeRegistryHandler,
)
analyzerFactory = lifecycle.NewAnalyzerFactory(api.MustParse("0.7"), fakeAPIVerifier, fakeCacheHandler, fakeConfigHandler, fakeImageHandler, fakeRegistryHandler)
})

it("configures the analyzer", func() {
Expand Down Expand Up @@ -235,13 +225,7 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {

when("platform api < 0.7", func() {
it.Before(func() {
analyzerFactory = lifecycle.NewAnalyzerFactory(
api.MustParse("0.6"),
fakeCacheHandler,
fakeConfigHandler,
fakeImageHandler,
fakeRegistryHandler,
)
analyzerFactory = lifecycle.NewAnalyzerFactory(api.MustParse("0.6"), fakeAPIVerifier, fakeCacheHandler, fakeConfigHandler, fakeImageHandler, fakeRegistryHandler)
})

it("configures the analyzer", func() {
Expand All @@ -251,7 +235,9 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {
t.Log("does not ensure registry access")

t.Log("processes group")
fakeConfigHandler.EXPECT().ReadGroup("some-legacy-group-path")
group := []buildpack.GroupElement{{ID: "some-buildpack-id", Version: "some-buildpack-version", API: "0.2"}}
fakeConfigHandler.EXPECT().ReadGroup("some-legacy-group-path").Return(group, nil)
fakeAPIVerifier.EXPECT().VerifyBuildpackAPIsForGroup(group)

t.Log("processes cache")
fakeCacheHandler.EXPECT().InitCache("some-cache-image-ref", "some-legacy-cache-dir")
Expand Down Expand Up @@ -291,7 +277,9 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {
t.Log("does not ensure registry access")

t.Log("processes group")
fakeConfigHandler.EXPECT().ReadGroup("some-legacy-group-path")
group := []buildpack.GroupElement{{ID: "some-buildpack-id", Version: "some-buildpack-version", API: "0.2"}}
fakeConfigHandler.EXPECT().ReadGroup("some-legacy-group-path").Return(group, nil)
fakeAPIVerifier.EXPECT().VerifyBuildpackAPIsForGroup(group)

t.Log("processes cache")
fakeCacheHandler.EXPECT().InitCache("some-cache-image-ref", "some-legacy-cache-dir")
Expand Down Expand Up @@ -319,7 +307,8 @@ func testAnalyzerFactory(t *testing.T, when spec.G, it spec.S) {
fakeImageHandler.EXPECT().Docker()
fakeImageHandler.EXPECT().InitImage(gomock.Any())

providedGroup := buildpack.Group{Group: []buildpack.GroupBuildpack{{ID: "some-buildpack-id"}}}
providedGroup := buildpack.Group{Group: []buildpack.GroupElement{{ID: "some-buildpack-id"}}}

analyzer, err := analyzerFactory.NewAnalyzer([]string{"some-additional-tag"}, "some-cache-image-ref", "some-launch-cache-dir", "some-layers-dir", "some-legacy-cache-dir", providedGroup, "some-legacy-group-path", "some-output-image-ref", "some-previous-image-ref", "some-run-image-ref", false, nil)
h.AssertNil(t, err)

Expand Down Expand Up @@ -375,7 +364,7 @@ func testAnalyzer(platformAPI string) func(t *testing.T, when spec.G, it spec.S)
PreviousImage: image,
Logger: &discardLogger,
SBOMRestorer: sbomRestorer,
Buildpacks: []buildpack.GroupBuildpack{
Buildpacks: []buildpack.GroupElement{
{ID: "metadata.buildpack", API: api.Buildpack.Latest().String()},
{ID: "no.cache.buildpack", API: api.Buildpack.Latest().String()},
{ID: "no.metadata.buildpack", API: api.Buildpack.Latest().String()},
Expand Down Expand Up @@ -444,7 +433,7 @@ func testAnalyzer(platformAPI string) func(t *testing.T, when spec.G, it spec.S)
h.AssertNil(t, testCache.SetMetadata(expectedCacheMetadata))
h.AssertNil(t, testCache.Commit())

analyzer.Buildpacks = append(analyzer.Buildpacks, buildpack.GroupBuildpack{ID: "escaped/buildpack/id", API: api.Buildpack.Latest().String()})
analyzer.Buildpacks = append(analyzer.Buildpacks, buildpack.GroupElement{ID: "escaped/buildpack/id", API: api.Buildpack.Latest().String()})
expectRestoresLayerMetadataIfSupported()
})

Expand Down
4 changes: 2 additions & 2 deletions api/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

var (
Platform = newApisMustParse([]string{"0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9"}, nil)
Buildpack = newApisMustParse([]string{"0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8"}, nil)
Platform = newApisMustParse([]string{"0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "0.10"}, nil)
Buildpack = newApisMustParse([]string{"0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9"}, nil)
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
)

type APIs struct {
Expand Down
2 changes: 1 addition & 1 deletion auth/env_keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func EnvKeychain(envVar string) (authn.Keychain, error) {

// InMemoryKeychain resolves credentials for the given images from the given keychain and returns a new keychain
// that stores the pre-resolved credentials in memory and returns them on demand. This is useful in cases where the
// backing credential store may become inaccessible in the the future.
// backing credential store may become inaccessible in the future.
func InMemoryKeychain(keychain authn.Keychain, images ...string) authn.Keychain {
return &ResolvedKeychain{
Auths: buildAuthMap(keychain, images...),
Expand Down
35 changes: 17 additions & 18 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,32 @@ import (
"github.com/buildpacks/lifecycle/platform"
)

type Platform interface {
API() *api.Version
}

type BuildEnv interface {
AddRootDir(baseDir string) error
AddEnvDir(envDir string, defaultAction env.ActionType) error
WithPlatform(platformDir string) ([]string, error)
List() []string
}

type BuildpackStore interface {
Lookup(bpID, bpVersion string) (buildpack.Buildpack, error)
}

type Buildpack interface {
Build(bpPlan buildpack.Plan, config buildpack.BuildConfig, bpEnv buildpack.BuildEnv) (buildpack.BuildResult, error)
ConfigFile() *buildpack.Descriptor
Detect(config *buildpack.DetectConfig, bpEnv buildpack.BuildEnv) buildpack.DetectRun
type DirStore interface {
LookupBp(bpID, bpVersion string) (buildpack.BuildModule, error)
LookupExt(bpID, bpVersion string) (buildpack.BuildModule, error)
}

type Builder struct {
AppDir string
LayersDir string
PlatformDir string
Platform Platform
Group buildpack.Group
Plan platform.BuildPlan
Out, Err io.Writer
Logger Logger
BuildpackStore BuildpackStore
AppDir string
LayersDir string
PlatformDir string
Platform Platform
Group buildpack.Group
Plan platform.BuildPlan
Out, Err io.Writer
Logger Logger
DirStore DirStore
}

func (b *Builder) Build() (*platform.BuildMetadata, error) {
Expand Down Expand Up @@ -75,7 +74,7 @@ func (b *Builder) Build() (*platform.BuildMetadata, error) {
b.Logger.Debugf("Running build for buildpack %s", bp)

b.Logger.Debug("Looking up buildpack")
bpTOML, err := b.BuildpackStore.Lookup(bp.ID, bp.Version)
bpTOML, err := b.DirStore.LookupBp(bp.ID, bp.Version)
if err != nil {
return nil, err
}
Expand Down
Loading