Merge pull request #6591 from dokku/6422-more-sh-cleanup

Always capture stdout/stderr when executing subprocesses
This commit is contained in:
Jose Diaz-Gonzalez
2024-02-12 22:13:47 -05:00
committed by GitHub
29 changed files with 95 additions and 162 deletions

View File

@@ -33,10 +33,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -50,10 +50,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -33,10 +33,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -38,10 +38,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -21,10 +21,9 @@ func ContainerIsRunning(containerID string) bool {
// ContainerRemove runs 'docker container remove' against an existing container
func ContainerRemove(containerID string) bool {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{"container", "remove", "-f", containerID},
CaptureOutput: false,
StreamStdio: false,
Command: DockerBin(),
Args: []string{"container", "remove", "-f", containerID},
StreamStderr: true,
})
if err != nil {
return false
@@ -35,10 +34,8 @@ func ContainerRemove(containerID string) bool {
// ContainerExists checks to see if a container exists
func ContainerExists(containerID string) bool {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{"container", "inspect", containerID},
CaptureOutput: false,
StreamStdio: false,
Command: DockerBin(),
Args: []string{"container", "inspect", containerID},
})
if err != nil {
return false
@@ -135,10 +132,8 @@ func CopyFromImage(appName string, image string, source string, destination stri
// add trailing newline for certain places where file parsing depends on it
result, err := CallExecCommand(ExecCommandInput{
Command: "tail",
Args: []string{"-c1", destination},
CaptureOutput: true,
StreamStdio: false,
Command: "tail",
Args: []string{"-c1", destination},
})
if err != nil || result.ExitCode != 0 {
return fmt.Errorf("Unable to append trailing newline to copied file: %v", result.Stderr)
@@ -247,10 +242,8 @@ func DockerContainerCreate(image string, containerCreateArgs []string) (string,
// DockerInspect runs an inspect command with a given format against a container or image ID
func DockerInspect(containerOrImageID, format string) (output string, err error) {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{"inspect", "--format", format, containerOrImageID},
CaptureOutput: true,
StreamStdio: false,
Command: DockerBin(),
Args: []string{"inspect", "--format", format, containerOrImageID},
})
if err != nil {
return "", err
@@ -277,9 +270,8 @@ func GetWorkingDir(appName string, image string) string {
func IsComposeInstalled() bool {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{"info", "--format", "{{range .ClientInfo.Plugins}}{{if eq .Name \"compose\"}}true{{end}}{{end}}')"},
CaptureOutput: true,
Command: DockerBin(),
Args: []string{"info", "--format", "{{range .ClientInfo.Plugins}}{{if eq .Name \"compose\"}}true{{end}}{{end}}')"},
})
return err == nil && result.ExitCode == 0
}

View File

@@ -23,8 +23,8 @@ type ExecCommandInput struct {
// Args are the arguments to pass to the command
Args []string
// CaptureOutput determines whether to capture the output of the command
CaptureOutput bool
// DisableStdioBuffer disables the stdio buffer
DisableStdioBuffer bool
// Env is the environment variables to pass to the command
Env map[string]string
@@ -95,7 +95,7 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
// being captured, then color output can be forced.
isatty := !color.NoColor
env := os.Environ()
if isatty && !input.CaptureOutput {
if isatty && input.DisableStdioBuffer {
env = append(env, "FORCE_TTY=1")
}
if input.Env != nil {
@@ -115,7 +115,7 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
Command: command,
Args: commandArgs,
Env: env,
DisableStdioBuffer: !input.CaptureOutput,
DisableStdioBuffer: input.DisableStdioBuffer,
}
if os.Getenv("DOKKU_TRACE") == "1" {

View File

@@ -10,8 +10,8 @@ type PlugnTriggerInput struct {
// Args are the arguments to pass to the trigger
Args []string
// CaptureOutput determines whether to capture the output of the trigger
CaptureOutput bool
// DisableStdioBuffer disables the stdio buffer
DisableStdioBuffer bool
// Env is the environment variables to pass to the trigger
Env map[string]string
@@ -42,13 +42,13 @@ func CallPlugnTriggerWithContext(ctx context.Context, input PlugnTriggerInput) (
args := []string{"trigger", input.Trigger}
args = append(args, input.Args...)
return CallExecCommandWithContext(ctx, ExecCommandInput{
Command: "plugn",
Args: args,
CaptureOutput: input.CaptureOutput,
Env: input.Env,
Stdin: input.Stdin,
StreamStdio: input.StreamStdio,
StreamStdout: input.StreamStdout,
StreamStderr: input.StreamStderr,
Command: "plugn",
Args: args,
DisableStdioBuffer: input.DisableStdioBuffer,
Env: input.Env,
Stdin: input.Stdin,
StreamStdio: input.StreamStdio,
StreamStdout: input.StreamStdout,
StreamStderr: input.StreamStderr,
})
}

View File

@@ -31,8 +31,8 @@ type SshCommandInput struct {
// Args are the arguments to pass to the command.
Args []string
// CaptureOutput saves any output from in the TaskResult
CaptureOutput bool
// DisableStdioBuffer disables the stdio buffer
DisableStdioBuffer bool
// Env is a list of environment variables to add to the current environment
Env map[string]string
@@ -137,7 +137,7 @@ func CallSshCommandWithContext(ctx context.Context, input SshCommandInput) (SshR
Command: input.Command,
Args: input.Args,
Env: env,
DisableStdioBuffer: !input.CaptureOutput,
DisableStdioBuffer: input.DisableStdioBuffer,
AllowUknownHosts: input.AllowUknownHosts,
Hostname: u.Hostname(),
Port: uint(port),

View File

@@ -54,10 +54,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -34,10 +34,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -38,8 +38,7 @@ const vectorOldContainerName = "vector"
func getComposeFile() ([]byte, error) {
result, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "vector-template-source",
CaptureOutput: true,
Trigger: "vector-template-source",
})
if err == nil && result.ExitCode == 0 && strings.TrimSpace(result.Stdout) != "" {
contents, err := os.ReadFile(strings.TrimSpace(result.Stdout))

View File

@@ -60,10 +60,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -46,10 +46,8 @@ func TriggerDockerArgsProcessDeploy(appName string) error {
if !hasDriverOpt {
result, _ := common.CallExecCommand(common.ExecCommandInput{
Command: common.DockerBin(),
Args: []string{"system", "info", "--format", "{{ .LoggingDriver }}"},
CaptureOutput: true,
StreamStdio: false,
Command: common.DockerBin(),
Args: []string{"system", "info", "--format", "{{ .LoggingDriver }}"},
})
if !allowedDrivers[result.StdoutContents()] {

View File

@@ -59,10 +59,8 @@ func attachAppToNetwork(containerID string, networkName string, appName string,
// isContainerInNetwork returns true if the container is already attached to the specified network
func isContainerInNetwork(containerID string, networkName string) bool {
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: common.DockerBin(),
Args: []string{"container", "inspect", "--format", "{{range $net, $v := .NetworkSettings.Networks}}{{println $net}}{{end}}", containerID},
CaptureOutput: true,
StreamStdio: false,
Command: common.DockerBin(),
Args: []string{"container", "inspect", "--format", "{{range $net, $v := .NetworkSettings.Networks}}{{println $net}}{{end}}", containerID},
})
if err != nil {
@@ -130,10 +128,8 @@ func networkExists(networkName string) (bool, error) {
// listNetworks returns a list of docker networks
func listNetworks() ([]string, error) {
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: common.DockerBin(),
Args: []string{"network", "ls", "--format", "{{ .Name }}"},
CaptureOutput: true,
StreamStdio: false,
Command: common.DockerBin(),
Args: []string{"network", "ls", "--format", "{{ .Name }}"},
})
if err != nil {
common.LogVerboseQuiet(result.StderrContents())

View File

@@ -40,10 +40,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -37,10 +37,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -37,10 +37,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -40,10 +40,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -103,10 +103,8 @@ func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
}
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "procfile-util",
Args: []string{"check", "-P", processSpecificProcfile},
CaptureOutput: true,
StreamStdio: false,
Command: "procfile-util",
Args: []string{"check", "-P", processSpecificProcfile},
})
if err != nil {
return fmt.Errorf(result.StderrContents())

View File

@@ -124,20 +124,18 @@ func pushToRegistry(appName string, tag int, imageID string, imageRepo string) e
func dockerTag(imageID string, imageTag string) bool {
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: common.DockerBin(),
Args: []string{"image", "tag", imageID, imageTag},
CaptureOutput: false,
StreamStdio: true,
Command: common.DockerBin(),
Args: []string{"image", "tag", imageID, imageTag},
StreamStdio: true,
})
return err == nil && result.ExitCode == 0
}
func dockerPush(imageTag string) bool {
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: common.DockerBin(),
Args: []string{"image", "push", imageTag},
CaptureOutput: false,
StreamStdio: true,
Command: common.DockerBin(),
Args: []string{"image", "push", imageTag},
StreamStdio: true,
})
return err == nil && result.ExitCode == 0
}

View File

@@ -34,10 +34,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -54,10 +54,9 @@ func CommandLogin(server string, username string, password string, passwordStdin
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-registry-login",
Args: []string{server, username},
StreamStdio: true,
CaptureOutput: false,
Trigger: "post-registry-login",
Args: []string{server, username},
StreamStdio: true,
Env: map[string]string{
"DOCKER_REGISTRY_PASS": password,
},

View File

@@ -33,10 +33,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -36,10 +36,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -335,10 +335,8 @@ func extractStartCommand(input StartCommandInput) string {
}
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_START_CMD"},
CaptureOutput: true,
StreamStdio: false,
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_START_CMD"},
})
if err == nil && resp.ExitCode == 0 && len(resp.Stdout) > 0 {
command = strings.TrimSpace(resp.Stdout)
@@ -346,10 +344,8 @@ func extractStartCommand(input StartCommandInput) string {
if input.ImageSourceType == "dockerfile" {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_DOCKERFILE_START_CMD"},
CaptureOutput: true,
StreamStdio: false,
Trigger: "config-get",
Args: []string{input.AppName, "DOKKU_DOCKERFILE_START_CMD"},
})
if err == nil && resp.ExitCode == 0 && len(resp.Stdout) > 0 {
command = strings.TrimSpace(resp.Stdout)

View File

@@ -43,10 +43,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)

View File

@@ -356,10 +356,7 @@ func CommandClusterAdd(role string, remoteHost string, serverIP string, allowUkn
k3sVersionCmd, err := common.CallExecCommand(common.ExecCommandInput{
Command: "k3s",
Args: []string{
"--version",
},
CaptureOutput: true,
Args: []string{"--version"},
})
if err != nil {
return fmt.Errorf("Unable to call k3s version command: %w", err)

View File

@@ -531,20 +531,18 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e
common.LogInfo1("Running post-deploy")
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Args: []string{appName, "", "", imageTag},
CaptureOutput: false,
StreamStdio: true,
Trigger: "core-post-deploy",
Args: []string{appName, "", "", imageTag},
StreamStdio: true,
Trigger: "core-post-deploy",
})
if err != nil {
return fmt.Errorf("Error running core-post-deploy: %w", err)
}
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Args: []string{appName, "", "", imageTag},
CaptureOutput: false,
StreamStdio: true,
Trigger: "post-deploy",
Args: []string{appName, "", "", imageTag},
StreamStdio: true,
Trigger: "post-deploy",
})
if err != nil {
return fmt.Errorf("Error running post-deploy: %w", err)
@@ -803,17 +801,13 @@ func TriggerSchedulerRun(scheduler string, appName string, envCount int, args []
dokkuRmContainer := os.Getenv("DOKKU_RM_CONTAINER")
if dokkuRmContainer == "" {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_RM_CONTAINER"},
CaptureOutput: true,
StreamStdio: false,
Trigger: "config-get",
Args: []string{appName, "DOKKU_RM_CONTAINER"},
})
if err != nil {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_RM_CONTAINER"},
CaptureOutput: true,
StreamStdio: false,
Trigger: "config-get-global",
Args: []string{"DOKKU_RM_CONTAINER"},
})
if err == nil {
dokkuRmContainer = strings.TrimSpace(resp.Stdout)
@@ -862,10 +856,8 @@ func TriggerSchedulerRun(scheduler string, appName string, envCount int, args []
}
} else if len(args) == 1 {
resp, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "procfile-get-command",
Args: []string{appName, args[0], "5000"},
CaptureOutput: true,
StreamStdio: false,
Trigger: "procfile-get-command",
Args: []string{appName, args[0], "5000"},
})
if err == nil && resp.Stdout != "" {
common.LogInfo1Quiet(fmt.Sprintf("Found '%s' in Procfile, running that command", args[0]))

View File

@@ -33,10 +33,8 @@ func main() {
usage()
case "help":
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
CaptureOutput: true,
StreamStdio: false,
Command: "ps",
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
})
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
fmt.Println(helpContent)