fix: pass command directly to entrypoint

Closes #3706
This commit is contained in:
Jose Diaz-Gonzalez
2020-08-31 18:36:07 -04:00
parent 7fe69fa269
commit 2b65def123
4 changed files with 59 additions and 19 deletions

View File

@@ -32,6 +32,8 @@ Each "phase" has different expectations and limitations:
- Priming or invalidating cache stores
- Running database migrations
Additionally, if using a Dockerfile with an `ENTRYPOINT`, the deployment task is passed to that entrypoint as is.
Please keep the above in mind when utilizing deployment tasks.
> To execute commands on the host during a release phase, see the [plugin creation documentation](/docs/development/plugin-creation.md) docs for more information on building your own custom plugin.

View File

@@ -22,7 +22,11 @@ type AppJson struct {
} `json:"scripts"`
}
func constructScript(command string, isHerokuishImage bool) string {
func constructScript(command string, shell string, isHerokuishImage bool, hasEntrypoint bool) []string {
if hasEntrypoint {
return []string{command}
}
script := []string{"set -eo pipefail;"}
if os.Getenv("DOKKU_TRACE") == "1" {
script = append(script, "set -x;")
@@ -65,7 +69,7 @@ func constructScript(command string, isHerokuishImage bool) string {
}...)
}
return strings.Join(script, " ")
return []string{shell, "-c", strings.Join(script, " ")}
}
// getPhaseScript extracts app.json from app image and returns the appropriate json key/value
@@ -106,7 +110,12 @@ func getPhaseScript(appName string, image string, phase string) (string, error)
// getReleaseCommand extracts the release command from a given app's procfile
func getReleaseCommand(appName string, image string) string {
forceExtract := "true"
if err := common.PlugnTrigger("procfile-extract", []string{appName, image, forceExtract}...); err != nil {
err := common.SuppressOutput(func() error {
return common.PlugnTrigger("procfile-extract", []string{appName, image, forceExtract}...)
})
if err != nil {
return ""
}
@@ -116,6 +125,19 @@ func getReleaseCommand(appName string, image string) string {
return strings.TrimSpace(string(b[:]))
}
func getDokkuAppShell(appName string) string {
dokkuAppShell := "/bin/bash"
if b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_APP_SHELL"}...); strings.TrimSpace(string(b[:])) != "" {
dokkuAppShell = strings.TrimSpace(string(b[:]))
}
if b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_SHELL"}...); strings.TrimSpace(string(b[:])) != "" {
dokkuAppShell = strings.TrimSpace(string(b[:]))
}
return dokkuAppShell
}
func executeScript(appName string, imageTag string, phase string) error {
image := common.GetDeployingAppImageName(appName, imageTag, "")
command := ""
@@ -137,7 +159,16 @@ func executeScript(appName string, imageTag string, phase string) error {
common.LogInfo1(fmt.Sprintf("Executing %s task from %s: %s", phase, phaseSource, command))
isHerokuishImage := common.IsImageHerokuishBased(image, appName)
script := constructScript(command, isHerokuishImage)
dockerfileEntrypoint := ""
dockerfileCommand := ""
if !isHerokuishImage {
dockerfileEntrypoint, _ = getEntrypointFromImage(image)
dockerfileCommand, _ = getCommandFromImage(image)
}
hasEntrypoint := dockerfileEntrypoint != ""
dokkuAppShell := getDokkuAppShell(appName)
script := constructScript(command, dokkuAppShell, isHerokuishImage, hasEntrypoint)
imageSourceType := "dockerfile"
if isHerokuishImage {
@@ -189,17 +220,7 @@ func executeScript(appName string, imageTag string, phase string) error {
dockerArgs = append(dockerArgs, "--env", "DOKKU_TRACE="+os.Getenv("DOKKU_TRACE"))
}
dokkuAppShell := "/bin/bash"
if b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_APP_SHELL"}...); strings.TrimSpace(string(b[:])) != "" {
dokkuAppShell = strings.TrimSpace(string(b[:]))
}
if b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_SHELL"}...); strings.TrimSpace(string(b[:])) != "" {
dokkuAppShell = strings.TrimSpace(string(b[:]))
}
containerCommand := []string{dokkuAppShell, "-c", script}
containerID, err := createdContainerID(appName, dockerArgs, image, containerCommand, phase)
containerID, err := createdContainerID(appName, dockerArgs, image, script, phase)
if err != nil {
common.LogFail(fmt.Sprintf("Failed to create %s execution container: %s", phase, err.Error()))
}
@@ -221,12 +242,10 @@ func executeScript(appName string, imageTag string, phase string) error {
commitArgs := []string{"container", "commit"}
if !isHerokuishImage {
dockerfileEntrypoint, _ := getEntrypointFromImage(image)
if dockerfileEntrypoint != "" {
commitArgs = append(commitArgs, "--change", dockerfileEntrypoint)
}
dockerfileCommand, _ := getCommandFromImage(image)
if dockerfileCommand != "" {
commitArgs = append(commitArgs, "--change", dockerfileCommand)
}

View File

@@ -1,4 +1,9 @@
#!/bin/bash
set -o pipefail
echo "entrypoint script started with arguments $@"
exec "$@"
if [[ "$1" == touch* ]]; then
echo "entrypoint script started with arguments $@"
touch "$(echo $@ | awk '{print $2}')"
else
exec "$@"
fi

View File

@@ -101,3 +101,17 @@ teardown() {
assert_output_contains "SECRET_KEY: fjdkslafjdk"
assert_success
}
@test "(app-json) app.json dockerfile entrypoint" {
run deploy_app dockerfile-entrypoint
echo "output: $output"
echo "status: $status"
assert_output_contains "Executing predeploy task from app.json"
assert_output_contains "entrypoint script started with arguments touch /app/predeploy.test"
assert_success
run /bin/bash -c "dokku --rm run $TEST_APP ls /app/predeploy.test"
echo "output: $output"
echo "status: $status"
assert_success
}