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

Multicall launcher #370

Merged
merged 12 commits into from
Aug 8, 2020
Merged

Multicall launcher #370

merged 12 commits into from
Aug 8, 2020

Conversation

ekcasey
Copy link
Member

@ekcasey ekcasey commented Aug 6, 2020

Multicall launcher in platform 0.4

@ekcasey ekcasey added this to the lifecycle-0.9.0 milestone Aug 6, 2020
@ekcasey ekcasey linked an issue Aug 6, 2020 that may be closed by this pull request
@ekcasey ekcasey mentioned this pull request Aug 7, 2020
@ekcasey ekcasey force-pushed the multicall-launcher branch from 9a50bfb to c40f8e6 Compare August 7, 2020 18:19
@ekcasey ekcasey marked this pull request as ready for review August 7, 2020 18:20
@ekcasey ekcasey requested a review from a team as a code owner August 7, 2020 18:20
Copy link
Member

@natalieparellano natalieparellano left a comment

Choose a reason for hiding this comment

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

Still reviewing this PR, but here is what I've accumulated so far...

acceptance/launcher_test.go Outdated Show resolved Hide resolved
acceptance/launcher_test.go Outdated Show resolved Hide resolved
when("Platform API >= 0.4", func() {
when("entrypoint is a process", func() {
it("launches that process", func() {
entrypoint := "/cnb/process/web"
Copy link
Member

Choose a reason for hiding this comment

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

If I'm understanding correctly, we need to prepend /cnb/process/ to web because launchImage was not built by the exporter. This feels okay to me... but I am wondering if there's a case to be made for building the test image the same way that it would be built in the wild.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, I'll add /cnb/process to the path in the Dockerfile

when("the process type has no args", func() {
it("runs command as script", func() {
h.SkipIf(t, runtime.GOOS == "windows", "scripts are unsupported on windows")
when("CNB_PROCESS_TYPE is set", func() {
Copy link
Member

Choose a reason for hiding this comment

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

Do we have any test that shows what happens when the process type is provided as a positional argument?

Copy link
Member Author

Choose a reason for hiding this comment

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

It shouldn't work, and I didn't necessary want to write an "it fails" test

cmd := exec.Command("docker", "run", "--rm",
"--entrypoint=/cnb/lifecycle/launcher",
"--env=CNB_PLATFORM_API=0.4",
launchImage, "--", "env")
Copy link
Member

Choose a reason for hiding this comment

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

Is there a case to be made for showing the non-direct version of a custom process?

Copy link
Member Author

Choose a reason for hiding this comment

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

To avoid testing the full combinatorial explosion of APIs/args/direct (we would have a lot of tests) I was going to let the platform 0.3 test handle that, knowing that we should be in the same code path at that point.

@@ -0,0 +1,592 @@
package launch_test
Copy link
Member

Choose a reason for hiding this comment

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

Do we intend to remove this file?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes! lol

thanks

exporter_test.go Outdated
Comment on lines 989 to 997
it("does not set CNB_PROCESS_TYPE", func() {
_, err := exporter.Export(opts)
h.AssertNil(t, err)

val, err := fakeAppImage.Env("CNB_PROCESS_TYPE")
h.AssertNil(t, err)
h.AssertEq(t, val, "")
})

Copy link
Member

Choose a reason for hiding this comment

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

I think this test is in the wrong context.

exporter_test.go Outdated
h.AssertNil(t, err)
h.AssertEq(t, val, "some-process-type")
it("sets CNB_PROCESS_TYPE", func() {
opts.DefaultProcessType = "some-process-type"
Copy link
Member

Choose a reason for hiding this comment

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

Can this be moved to the before? Otherwise we might forget to set it.

})

it("sets ENTRYPOINT to launcher", func() {
_, err := exporter.Export(opts)
Copy link
Member

Choose a reason for hiding this comment

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

This seems to test "no default process"

Copy link
Member Author

Choose a reason for hiding this comment

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

For API < 0.4 the launcher point should be launcher even when there is no default process. I implemented your suggestion to move the default process setup to the before (fixing the test and the inaccurate description here)

@@ -61,12 +65,13 @@ func (cm *CacheMetadata) MetadataForBuildpack(id string) BuildpackLayersMetadata

// NOTE: This struct MUST be kept in sync with `LayersMetadataCompat`
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to add ProcessTypes to LayersMetadataCompat then?

Copy link
Member Author

Choose a reason for hiding this comment

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

I suppose it does say MUST! :)

Copy link
Member

@natalieparellano natalieparellano left a comment

Choose a reason for hiding this comment

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

Adding a few more comments

"Path=some-path",
when("#NewLaunchEnv", func() {
when("process dir is the first element in PATH", func() {
it("strips it", func() {
Copy link
Member

@natalieparellano natalieparellano Aug 7, 2020

Choose a reason for hiding this comment

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

Where is /cnb/lifecycle stripped from the path? (Going off of https://github.com/buildpacks/rfcs/blob/main/text/0045-launcher-arguments.md )

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! missed that one

Comment on lines +71 to +79
Uid: 0,
Gid: 0,
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to also check the permissions?

process = launch.ShellProcess{
Script: true,
Command: `printf "SOME_VAR: '%s'" "$SOME_VAR"`,
Caller: "some-profile-argv0",
Copy link
Member

Choose a reason for hiding this comment

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

This caller name seems a little strange outside of the profiles context.

Copy link
Member Author

Choose a reason for hiding this comment

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

At first I called it ProfileArgv0 but that isn't true in cmd. I think it is no more confusing than self but tbf that was already a confusing name

Script: true,
Command: `printf "SOME_ARG: '%s'" "$1"`,
Args: []string{"", "some arg1"},
Caller: "some-profile-argv0",
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above.

process = launch.ShellProcess{
Script: true,
Command: `printf "SOME_ARG: '%s'" "$1"`,
Args: []string{"", "some arg1"},
Copy link
Member

Choose a reason for hiding this comment

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

Is the point of including the empty arg that it should be ignored? Maybe it's worth commenting about it in the it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Functionally it doesn't matter to this test we could have printed $0 and dropped the empty first arg. But because $0 is supposed to represent the process being invoked it feels weird to put an actual argument there. We could change $0 to bash to make it more realistic/readable.

Script: false,
Command: `printf`,
Args: []string{"SOME_VAR: '%s'", "$SOME_VAR"},
Caller: "some-profile-argv0",
Copy link
Member

Choose a reason for hiding this comment

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

Same comment :)

})
})

when("cmd contains more than one arg and does not start with --", func() {
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little confused... what happens when the cmd contains exactly one arg? Is that covered by these tests?

Copy link
Member Author

Choose a reason for hiding this comment

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

one vs many doesn't matter to cmd right now. I'll update the whens

launch/process_test.go Outdated Show resolved Hide resolved

when("linux", func() {
it.Before(func() {
h.SkipIf(t, runtime.GOOS == "windows", "windows test")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
h.SkipIf(t, runtime.GOOS == "windows", "windows test")
h.SkipIf(t, runtime.GOOS == "windows", "linux test")

h.SkipIf(t, runtime.GOOS == "windows", "linux test")
})

it("is script", func() {
Copy link
Member

Choose a reason for hiding this comment

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

I think I missed what it is that makes the process a script (it has args)... is that the default?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmmm the short when's might be confusing in the code but I wanted to make the go test output a bit more readable on the command line

Should hopefully tell you it is a script if it has no args and is linux:
LaunchProcess/Direct=false/buildpack-provided/buildpack_API_>=_0.4/has_no_args/linux/is_script

The link above didn't take me to a different test.

}
defer func() {
if closeErr := lw.Close(); err == nil {
err = closeErr
Copy link
Member

Choose a reason for hiding this comment

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

Needs named return param.

ekcasey and others added 12 commits August 7, 2020 19:19
Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>
* strip it out in the launch env

Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>
* Adds acceptance tests
* Refactors launcher

Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>

Co-authored-by: Natalie Arellano <narellano@vmware.com>
Signed-off-by: Emily Casey <ecasey@vmware.com>

Co-authored-by: Natalie Arellano <narellano@vmware.com>
* Set Platform API for build when creator is run

Signed-off-by: Emily Casey <ecasey@vmware.com>
* Add and strip lifecycle dir from path
* Don't use full paths in entrypoint in tests or warning text
* Test cleanup

Signed-off-by: Emily Casey <ecasey@vmware.com>
@ekcasey ekcasey force-pushed the multicall-launcher branch 3 times, most recently from 47810b2 to 190dff9 Compare August 8, 2020 00:42
@ekcasey ekcasey merged commit 7617cba into main Aug 8, 2020
@ekcasey ekcasey deleted the multicall-launcher branch August 8, 2020 00:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multicall launcher
3 participants