pkg/commandhandler/cmd.go (78 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package commandhandler import ( "github.com/Azure/azure-extension-platform/pkg/constants" "github.com/Azure/azure-extension-platform/pkg/logging" "github.com/pkg/errors" "io" "os" "os/exec" "path/filepath" ) type ICommandHandler interface { Execute(command string, workingDir, logDir string, waitForCompletion bool, el logging.ILogger) (returnCode int, err error) } type ICommandHandlerWithEnvVariables interface { ExecuteWithEnvVariables(command string, workingDir, logDir string, waitForCompletion bool, el logging.ILogger, params *map[string]string) (returnCode int, err error) } func (commandHandler *CommandHandler) ExecuteWithEnvVariables(command string, workingDir, logDir string, waitForCompletion bool, el logging.ILogger, params *map[string]string) (returnCode int, err error) { return execCmdInDirWithAction(command, workingDir, logDir, waitForCompletion, el, params) } type CommandHandler struct { } func New() *CommandHandler { return &CommandHandler{} } func (commandHandler *CommandHandler) Execute(command string, workingDir, logDir string, waitForCompletion bool, el logging.ILogger) (returnCode int, err error) { return execCmdInDirWithAction(command, workingDir, logDir, waitForCompletion, el, nil) } var execWaitFunctionToCall func(cmd string, workingDir string, stdout, stderr io.WriteCloser) (int, error) = execWait var execDontWaitFunctionToCall func(cmd string, workingDir string) (int, error) = execDontWait var execWaitFunctionWithParams = execWaitWithEnvVariables var execDontWaitFunctionWithParams = execDontWaitWithEnvVariables func execCmdInDirWithAction(cmd, workingDir, logDir string, waitForCompletion bool, el logging.ILogger, params *map[string]string) (int, error) { var exitCode int var execErr error err := os.MkdirAll(workingDir, constants.FilePermissions_UserOnly_ReadWriteExecute) if err != nil { return -1, errors.Wrapf(err, "error while creating/accessing directory %s", workingDir) } if waitForCompletion { outFileName, errFileName := logPaths(logDir) outF, err := os.OpenFile(outFileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, constants.FilePermissions_UserOnly_ReadWrite) if err != nil { return -1, errors.Wrapf(err, "failed to open stdout file") } errF, err := os.OpenFile(errFileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, constants.FilePermissions_UserOnly_ReadWrite) if err != nil { return -1, errors.Wrapf(err, "failed to open stderr file") } exitCode, execErr = execWaitFunctionWithParams(cmd, workingDir, outF, errF, params) // add the output of the command to the log file el.Info("command: %s", cmd) stdOutFile, err2 := os.OpenFile(outFileName, os.O_RDONLY, constants.FilePermissions_UserOnly_ReadWrite) if err2 == nil { el.InfoFromStream("stdout:", stdOutFile) stdOutFile.Close() } stdErrFile, err3 := os.OpenFile(errFileName, os.O_RDONLY, constants.FilePermissions_UserOnly_ReadWrite) if err3 == nil { el.InfoFromStream("stderr:", stdErrFile) stdErrFile.Close() } } else { exitCode, execErr = execDontWaitFunctionWithParams(cmd, workingDir, params) } return exitCode, execErr } // logPaths returns stdout and stderr file paths for the specified output // directory. It does not create the files. func logPaths(dir string) (stdout string, stderr string) { stdout = filepath.Join(dir, "stdout") stderr = filepath.Join(dir, "stderr") return } func addEnvVariables(params *map[string]string, command *exec.Cmd) { if params != nil && len(*params) > 0 { for name, value := range *params { envVar := string("CustomAction_" + name + "=" + value) (command).Env = append((command).Env, envVar) } } }