Merge pull request #7328 from dokku/k3s-command-once

Execute one-off commands with DOKKU_APP_SHELL as the initial command under the k3s scheduler
This commit is contained in:
Jose Diaz-Gonzalez
2024-11-04 14:36:01 -05:00
committed by GitHub
4 changed files with 46 additions and 80 deletions

View File

@@ -1,7 +1,6 @@
package appjson
import (
"context"
"encoding/json"
"errors"
"fmt"
@@ -12,7 +11,6 @@ import (
"github.com/dokku/dokku/plugins/common"
shellquote "github.com/kballard/go-shellquote"
"golang.org/x/sync/errgroup"
)
func constructScript(command string, shell string, isHerokuishImage bool, isCnbImage bool, dockerfileEntrypoint string) []string {
@@ -99,7 +97,7 @@ func getPhaseScript(appName string, phase string) (string, error) {
}
// getReleaseCommand extracts the release command from a given app's procfile
func getReleaseCommand(appName string, image string) string {
func getReleaseCommand(appName string) string {
processType := "release"
port := "5000"
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
@@ -109,40 +107,6 @@ func getReleaseCommand(appName string, image string) string {
return results.StdoutContents()
}
func getDokkuAppShell(appName string) string {
shell := "/bin/bash"
globalShell := ""
appShell := ""
ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error {
results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell = results.StdoutContents()
return nil
})
errs.Go(func() error {
results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell = results.StdoutContents()
return nil
})
errs.Wait()
if appShell != "" {
shell = appShell
} else if globalShell != "" {
shell = globalShell
}
return shell
}
func hasAppJSON(appName string) bool {
appJSONPath := getAppJSONPath(appName)
if common.FileExists(fmt.Sprintf("%s.%s.missing", appJSONPath, os.Getenv("DOKKU_PID"))) {
@@ -156,7 +120,7 @@ func hasAppJSON(appName string) bool {
return common.FileExists(appJSONPath)
}
func cleanupDeploymentContainer(appName string, containerID string, phase string) error {
func cleanupDeploymentContainer(containerID string, phase string) error {
if phase != "predeploy" {
os.Setenv("DOKKU_SKIP_IMAGE_RETIRE", "true")
}
@@ -177,7 +141,7 @@ func executeScript(appName string, image string, imageTag string, phase string)
command := ""
phaseSource := ""
if phase == "release" {
command = getReleaseCommand(appName, image)
command = getReleaseCommand(appName)
phaseSource = "Procfile"
} else {
var err error
@@ -207,7 +171,7 @@ func executeScript(appName string, image string, imageTag string, phase string)
dockerfileCommand, _ = getCommandFromImage(image)
}
dokkuAppShell := getDokkuAppShell(appName)
dokkuAppShell := common.GetDokkuAppShell(appName)
script := constructScript(command, dokkuAppShell, isHerokuishImage, isCnbImage, dockerfileEntrypoint)
imageSourceType := "dockerfile"
@@ -304,7 +268,7 @@ func executeScript(appName string, image string, imageTag string, phase string)
return fmt.Errorf("Failed to create %s execution container: %s", phase, err.Error())
}
defer cleanupDeploymentContainer(appName, containerID, phase)
defer cleanupDeploymentContainer(containerID, phase)
if !waitForExecution(containerID) {
common.LogInfo2Quiet(fmt.Sprintf("Start of %s %s task (%s) output", appName, phaseName, containerID[0:9]))
@@ -455,7 +419,7 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
return containerID, err
}
func setScale(appName string, image string) error {
func setScale(appName string) error {
appJSON, err := GetAppJSON(appName)
if err != nil {
return err

View File

@@ -226,7 +226,7 @@ func TriggerPostReleaseBuilder(builderType string, appName string, image string)
return err
}
if err := setScale(appName, image); err != nil {
if err := setScale(appName); err != nil {
return err
}

View File

@@ -285,6 +285,41 @@ func GetRunningImageTag(appName string, imageTag string) (string, error) {
return imageTag, nil
}
// GetDokkuAppShell returns the shell for a given app
func GetDokkuAppShell(appName string) string {
shell := "/bin/bash"
globalShell := ""
appShell := ""
ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error {
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell = results.StdoutContents()
return nil
})
errs.Go(func() error {
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell = results.StdoutContents()
return nil
})
errs.Wait()
if appShell != "" {
shell = appShell
} else if globalShell != "" {
shell = globalShell
}
return shell
}
// DokkuApps returns a list of all local apps
func DokkuApps() ([]string, error) {
apps, err := UnfilteredDokkuApps()

View File

@@ -788,24 +788,7 @@ func TriggerSchedulerEnter(scheduler string, appName string, processType string,
command := args
if len(args) == 0 {
command = []string{"/bin/bash"}
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell := results.StdoutContents()
if err == nil && globalShell != "" {
command = []string{globalShell}
}
results, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell := results.StdoutContents()
if err == nil && appShell != "" {
command = []string{appShell}
}
command = []string{common.GetDokkuAppShell(appName)}
}
entrypoint := ""
@@ -1071,25 +1054,9 @@ func TriggerSchedulerRun(scheduler string, appName string, envCount int, args []
// todo: do something with docker args
command := args
commandShell := common.GetDokkuAppShell(appName)
if len(args) == 0 {
command = []string{"/bin/bash"}
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell := results.StdoutContents()
if err == nil && globalShell != "" {
command = []string{globalShell}
}
results, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell := results.StdoutContents()
if err == nil && appShell != "" {
command = []string{appShell}
}
command = []string{commandShell}
} else if len(args) == 1 {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "procfile-get-command",
@@ -1135,7 +1102,7 @@ func TriggerSchedulerRun(scheduler string, appName string, envCount int, args []
workingDir := common.GetWorkingDir(appName, image)
job, err := templateKubernetesJob(Job{
AppName: appName,
Command: command,
Command: []string{commandShell},
DeploymentID: deploymentID,
Entrypoint: entrypoint,
Env: extraEnv,