// must be called at the end of the command, when there is nothing more to
// read from stdout and stderr
// will send a success or a failure report message through the given chanel
func pushEndReport(cmd *exec.Cmd, jobId int64, reportChan chan message.Report) {
	if err := cmd.Wait(); err != nil {
		// we have a failure for the command.
		// we will now try to get the exit code
		if exiterr, ok := err.(*exec.ExitError); ok {
			// the error from cmd.Wait is an *exec.ExitError. It means that the
			// exit status is != 0

			/*
			 * here is a interesting comments getting from stackoverflow. I let it
			 *
			 */
			// This works on both Unix and Windows. Although package
			// syscall is generally platform dependent, WaitStatus is
			// defined for both Unix and Windows and in both cases has
			// an ExitStatus() method with the same signature.
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				errMesg := fmt.Sprintf("Exit Status: %d", status.ExitStatus())
				reportChan <- message.Report{jobId, message.FAILED, []string{errMesg}}
			}
		} else {
			errMesg := fmt.Sprintf("Unknow error : %v", err)
			reportChan <- message.Report{jobId, message.FAILED, []string{errMesg}}
		}
	} else {
		// the command is in success state.
		reportChan <- message.Report{jobId, message.SUCCESS, []string{}}
	}
}
Beispiel #2
0
func RunAndListen(cmd *exec.Cmd, fn func(s string)) error {
	var stderr bytes.Buffer
	cmd.Stderr = &stderr

	r, err := cmd.StdoutPipe()
	if err != nil {
		return fmt.Errorf("%s: %s", err, stderr.String())
	}

	scanner := bufio.NewScanner(r)
	go func() {
		for scanner.Scan() {
			fn(scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		return fmt.Errorf("%s: %s", err, stderr.String())
	}

	err = cmd.Wait()
	if err != nil {
		return fmt.Errorf("%s: %s", err, stderr.String())
	}
	return nil
}
Beispiel #3
0
// timedCommand executes the given command, terminating it forcefully
// if it is still running after the given timeout elapses.
func (e *executor) timedCommand(timeout time.Duration, opts opts, command *exec.Cmd) error {
	// Make the process of this command a new process group leader
	// to facilitate clean up of processes that time out.
	command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	// Kill this process group explicitly when receiving SIGTERM
	// or SIGINT signals.
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		<-sigchan
		e.terminateProcessGroup(opts, command)
	}()
	if err := command.Start(); err != nil {
		e.printf(e.verboseStdout(opts), "FAILED: %v", err)
		return err
	}
	done := make(chan error, 1)
	go func() {
		done <- command.Wait()
	}()
	select {
	case <-time.After(timeout):
		// The command has timed out.
		e.terminateProcessGroup(opts, command)
		// Allow goroutine to exit.
		<-done
		e.printf(e.verboseStdout(opts), "TIMED OUT")
		return commandTimedOutErr
	case err := <-done:
		e.printf(e.verboseStdout(opts), okOrFailed(err))
		return err
	}
}
Beispiel #4
0
func CmdStream(cmd *exec.Cmd) (io.Reader, error) {
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}
	pipeR, pipeW := io.Pipe()
	go func() {
		_, err := io.Copy(pipeW, stdout)
		if err != nil {
			pipeW.CloseWithError(err)
		}
		errText, e := ioutil.ReadAll(stderr)
		if e != nil {
			errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")")
		}
		if err := cmd.Wait(); err != nil {
			// FIXME: can this block if stderr outputs more than the size of StderrPipe()'s buffer?
			pipeW.CloseWithError(errors.New(err.Error() + ": " + string(errText)))
		} else {
			pipeW.Close()
		}
	}()
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	return pipeR, nil
}
Beispiel #5
0
// cmdTimeout runs the command c and returns a timeout if it doesn't complete
// after time t. If a timeout occurs, cmdTimeout will kill the process. Blocks
// until the process terminates.
func cmdTimeout(c *exec.Cmd, t time.Duration) error {
	log.Debug("cmdTimeout: %v", c)

	start := time.Now()
	if err := c.Start(); err != nil {
		return fmt.Errorf("cmd start: %v", err)
	}

	done := make(chan error)
	go func() {
		done <- c.Wait()
		close(done)
	}()

	select {
	case <-time.After(t):
		log.Debug("killing cmd %v", c)
		err := c.Process.Kill()
		// Receive from done so that we don't leave the goroutine hanging
		err2 := <-done
		// Kill error takes precedence as they should be unexpected
		if err != nil {
			return err
		}
		return err2
	case err := <-done:
		log.Debug("cmd %v completed in %v", c, time.Now().Sub(start))
		return err
	}
}
Beispiel #6
0
func wait(proc *exec.Cmd, ch chan *exec.Cmd) {
	err := proc.Wait()
	if err != nil {
		log.Fatal(err)
	}
	ch <- proc
}
// Publish prints the result of a check to stdout.
func (p *ExecPublisher) Publish(result *CheckResult) error {
	var cmd *exec.Cmd
	if len(p.cmd) > 1 {
		cmd = exec.Command(p.cmd[0], p.cmd[1:]...)
	} else {
		cmd = exec.Command(p.cmd[0])
	}
	var b bytes.Buffer
	cmd.Stdout = &b
	cmd.Stderr = &b
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return err
	}
	if err = cmd.Start(); err != nil {
		p.log.Error("Exec failed", "error", err)
		return err
	}
	if err = p.stdinTemplate.Execute(stdin, result); err != nil {
		p.log.Error("Failed to write template data to stdin", "error", err)
		return err
	}
	stdin.Close()
	if err = cmd.Wait(); err != nil {
		p.log.Error("Exec failed", "error", err, "output", b.String())
		return err
	}
	return nil
}
Beispiel #8
0
func (c Command) Run(s HookState) error {
	b, err := json.Marshal(s)
	if err != nil {
		return err
	}
	cmd := exec.Cmd{
		Path:  c.Path,
		Args:  c.Args,
		Env:   c.Env,
		Stdin: bytes.NewReader(b),
	}
	errC := make(chan error, 1)
	go func() {
		out, err := cmd.CombinedOutput()
		if err != nil {
			err = fmt.Errorf("%s: %s", err, out)
		}
		errC <- err
	}()
	if c.Timeout != nil {
		select {
		case err := <-errC:
			return err
		case <-time.After(*c.Timeout):
			cmd.Process.Kill()
			cmd.Wait()
			return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
		}
	}
	return <-errC
}
Beispiel #9
0
func callCont(c *exec.Cmd, cont func(io.Reader) error) error {
	_, callerFile, callerLine, _ := runtime.Caller(1)
	log.Printf("%15s:%.3d -> %s", path.Base(callerFile), callerLine, strings.Join(c.Args, " "))
	var reader io.Reader
	var err error
	if cont != nil {
		reader, err = c.StdoutPipe()
		if err != nil {
			return err
		}
	}
	stderr, err := c.StderrPipe()
	if err != nil {
		return err
	}
	if err = c.Start(); err != nil {
		return err
	}
	if cont != nil {
		if err = cont(reader); err != nil {
			return err
		}
	}
	buffer := bytes.NewBuffer(nil)
	buffer.ReadFrom(stderr)
	if buffer.Len() != 0 {
		log.Print("Command had output on stderr.\n Cmd: ", strings.Join(c.Args, " "), "\nstderr: ", buffer)
	}
	return c.Wait()
}
Beispiel #10
0
// runCommand runs the command with the given timeout, and returns any errors encountered and whether
// the command timed out or not
func runCommand(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
	out := make(chan error)
	go func() {
		if err := cmd.Start(); err != nil {
			glog.V(4).Infof("Error starting execution: %v", err)
		}
		out <- cmd.Wait()
	}()

	if timeout == noCommandTimeout {
		select {
		case err := <-out:
			if err != nil {
				glog.V(4).Infof("Error executing command: %v", err)
			}
			return err, false
		}
	} else {
		select {
		case err := <-out:
			if err != nil {
				glog.V(4).Infof("Error executing command: %v", err)
			}
			return err, false
		case <-time.After(timeout):
			glog.V(4).Infof("Command execution timed out after %s", timeout)
			return nil, true
		}
	}
}
Beispiel #11
0
// RunCommandWithStdoutStderr execs a command and returns its output.
func RunCommandWithStdoutStderr(cmd *exec.Cmd) (bytes.Buffer, bytes.Buffer, error) {
	var stdout, stderr bytes.Buffer
	stderrPipe, err := cmd.StderrPipe()
	stdoutPipe, err := cmd.StdoutPipe()

	cmd.Env = os.Environ()
	if err != nil {
		fmt.Println("error at io pipes")
	}

	err = cmd.Start()
	if err != nil {
		fmt.Println("error at command start")
	}

	go func() {
		streamOutput(stdoutPipe, &stdout, os.Stdout)
	}()
	go func() {
		streamOutput(stderrPipe, &stderr, os.Stderr)
	}()
	err = cmd.Wait()
	if err != nil {
		fmt.Println("error at command wait")
	}
	return stdout, stderr, err
}
Beispiel #12
0
// WaitCode gets the exit code for a running command
//
// Normally returns exit code, nil
//
// Error Conditions:
// WaitCode takes err, so that it can be used on the result of Run{Cmd/Bash}.
// All failures to run the process manifest as an exit code of -1, with additional error info
func WaitCode(c *exec.Cmd, e error) (int, error) {
	if c == nil {
		return -1, e
	}

	return getCode(c.Wait())
}
Beispiel #13
0
func rsyncWebsocket(cmd *exec.Cmd, conn *websocket.Conn) error {
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return err
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

	stderr, err := cmd.StderrPipe()
	if err != nil {
		return err
	}

	if err := cmd.Start(); err != nil {
		return err
	}

	shared.WebsocketMirror(conn, stdin, stdout)
	data, err2 := ioutil.ReadAll(stderr)
	if err2 != nil {
		shared.Debugf("error reading rsync stderr: %s", err2)
		return err2
	}
	shared.Debugf("Stderr from rsync: %s", data)

	err = cmd.Wait()
	if err != nil {
		shared.Debugf("rsync recv error %s: %s", err, string(data))
	}

	return err
}
func TestServerWithBasicAuth(t *testing.T) {
	cmd := exec.Cmd{
		Path: os.Getenv("GOPATH") + "/bin/docker-builder",
		Args: []string{"docker-builder", "serve", "--username", "foo", "--password", "bar"},
	}
	if err := cmd.Start(); err != nil {
		t.Errorf("error start server: %s\n", err.Error())
	}

	go func() {
		time.Sleep(100 * time.Millisecond)
		syscall.Kill(cmd.Process.Pid, syscall.SIGUSR1)
		time.Sleep(100 * time.Millisecond)
		syscall.Kill(cmd.Process.Pid, syscall.SIGTERM)
	}()

	if err := cmd.Wait(); err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				if status.ExitStatus() != 166 {
					t.Errorf("server exited unexpectedly and/or did not start correctly")
				}
			} else {
				t.Errorf("unable to get process exit code")
			}
		} else {
			t.Errorf("error waiting on server: %s\n", err.Error())
		}
	}
}
Beispiel #15
0
func execCommand(cmd *exec.Cmd) error {
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
		return err
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("docker build out | %s\n", scanner.Text())
		}
	}()

	var stderr bytes.Buffer
	cmd.Stdout = os.Stdout
	cmd.Stderr = &stderr

	err = cmd.Start()
	if err != nil {
		fmt.Printf("docker build out | %s\n", stderr.String())
		return err
	}

	err = cmd.Wait()
	if err != nil {
		fmt.Printf("docker build out | %s\n", stderr.String())
		return err
	}
	return err
}
Beispiel #16
0
// send produces a binary diff stream and passes it to cont
func send(repo, commit string, cont func(io.Reader) error) error {
	parent := GetMeta(path.Join(repo, commit), "parent")
	var cmd *exec.Cmd
	if parent == "" {
		cmd = exec.Command("btrfs", "send", FilePath(path.Join(repo, commit)))
	} else {
		cmd = exec.Command("btrfs", "send", "-p", FilePath(path.Join(repo, parent)), FilePath(path.Join(repo, commit)))
	}
	stdin, stdout := io.Pipe()
	stderr := bytes.NewBuffer(nil)
	cmd.Stdout = stdout
	if err := cmd.Start(); err != nil {
		return err
	}
	errC := make(chan error, 1)
	go func() {
		errC <- cont(stdin)
	}()
	waitErr := cmd.Wait()
	closeErr := stdout.Close()
	if waitErr != nil {
		return fmt.Errorf("%s %s", waitErr.Error(), stderr.String())
	}
	if closeErr != nil {
		return closeErr
	}
	return <-errC
}
Beispiel #17
0
func (c *EtcdAdapter) ExecWithLog(cmd *exec.Cmd, i int) {
	stdoutPipe, err := cmd.StdoutPipe()
	check(err)
	stderrPipe, err := cmd.StderrPipe()
	check(err)

	outFile, err := os.Create(fmt.Sprintf("/tmp/etcd_%d.out", i))
	check(err)
	errFile, err := os.Create(fmt.Sprintf("/tmp/etcd_%d.err", i))
	check(err)

	outWriter := bufio.NewWriter(outFile)
	errWriter := bufio.NewWriter(errFile)

	defer outWriter.Flush()
	defer errWriter.Flush()

	// Start the command
	err = cmd.Start()
	check(err)

	go io.Copy(outWriter, stdoutPipe)
	go io.Copy(errWriter, stderrPipe)

	c.launchProcess <- cmd.Process

	cmd.Wait()
}
Beispiel #18
0
func (this *Start) reloadHAproxy() (err error) {
	var cmd *exec.Cmd = nil
	waitStartCh := make(chan struct{})
	if this.starting {
		log.Info("haproxy starting")
		cmd = exec.Command(this.command, "-f", configFile) // TODO use absolute path
		this.starting = false

		go func() {
			<-waitStartCh
			log.Info("haproxy started")
			if err := cmd.Wait(); err != nil {
				log.Error("haproxy: %v", err)
			}
		}()
	} else {
		shellScript := fmt.Sprintf("%s -f %s/%s -sf `cat %s/%s`",
			this.command, this.root, configFile, this.root, haproxyPidFile)
		log.Info("haproxy reloading: %s", shellScript)
		cmd = exec.Command("/bin/sh", "-c", shellScript)
		go func() {
			<-waitStartCh
			log.Info("haproxy reloaded")
			if err := cmd.Wait(); err != nil {
				log.Error("haproxy: %v", err)
			}
		}()
	}

	if err = cmd.Start(); err == nil {
		waitStartCh <- struct{}{}
	}

	return err
}
Beispiel #19
0
// Run() an instance of this container and return it's exec.Command reference and a
// channel that sends the exit code, when the container exits
func (c *Container) run() (*exec.Cmd, chan error) {

	// the container name is semi random because containers can get wedged
	// in docker and can not be removed until a reboot (or aufs trickery)
	containerName := c.Name + "-" + uuid()

	exitChan := make(chan error, 1)
	args := make([]string, 0)
	args = append(args, "run", "-rm", "-name", containerName)

	// attach all exported ports
	for _, port := range c.Ports {
		args = append(args, "-p", fmt.Sprintf("%d:%d", port, port))
	}

	// attach resources directory to all containers
	args = append(args, "-v", resourcesDir()+":"+"/usr/local/serviced/resources")

	// attach all exported volumes
	for name, volume := range c.Volumes {
		hostDir := path.Join(c.VolumesDir(), c.Name, name)
		if exists, _ := isDir(hostDir); !exists {
			if err := os.MkdirAll(hostDir, 0777); err != nil {
				glog.Errorf("could not create %s on host: %s", hostDir, err)
				exitChan <- err
				return nil, exitChan
			}
		}
		args = append(args, "-v", hostDir+":"+volume)
	}

	// set the image and command to run
	args = append(args, c.Repo+":"+c.Tag, "/bin/sh", "-c", c.Command)

	glog.V(1).Infof("Executing docker %s", args)
	var cmd *exec.Cmd
	tries := 5
	var err error
	for {
		if tries > 0 {
			cmd = exec.Command("docker", args...)
			if err := cmd.Start(); err != nil {
				glog.Errorf("Could not start: %s", c.Name)
				c.stop()
				c.rm()
				time.Sleep(time.Second * 1)
			} else {
				break
			}
		} else {
			exitChan <- err
			return cmd, exitChan
		}
		tries = -1
	}
	go func() {
		exitChan <- cmd.Wait()
	}()
	return cmd, exitChan
}
Beispiel #20
0
func writeGitRepositoryArchive(w io.Writer, path string, ref GitCommitRef) error {
	var cmd *exec.Cmd
	// TODO: Stream as tar with gzip
	if ref == EmptyGitCommitRef {
		cmd = exec.Command("/usr/bin/git", "archive", "--format", "zip", "master")
	} else {
		cmd = exec.Command("/usr/bin/git", "archive", "--format", "zip", string(ref))
	}
	cmd.Env = []string{}
	cmd.Dir = path
	var stderr bytes.Buffer
	cmd.Stderr = utils.LimitWriter(&stderr, 20*1024)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	if err := cmd.Start(); err != nil {
		return err
	}
	io.Copy(w, stdout)
	if err := cmd.Wait(); err != nil {
		return errors.New(fmt.Sprintf("Failed to archive repository: %s\n", err.Error()) + stderr.String())
	}
	return nil
}
Beispiel #21
0
// "run" let's the user execute arbitrary commands
func runFn(args []interface{}) (interface{}, error) {
	if len(args) < 1 {
		return nil, errors.New("run takes at least one argument")
	}

	commands := []string{}
	for _, arg := range args {
		if s, ok := arg.(string); ok {
			commands = append(commands, s)
		} else {
			return nil, errors.New("run only takes string arguments")
		}
	}

	var cmd *exec.Cmd
	if len(commands) == 1 {
		cmd = exec.Command(commands[0])
	} else {
		cmd = exec.Command(commands[0], commands[1:]...)
	}
	log.Printf("executing command '%s' with arguments: %s\n", commands[0], strings.Join(commands[1:], ","))

	if err := cmd.Run(); err == nil {
		cmd.Wait()
	}

	return nil, nil
}
Beispiel #22
0
// cmdStream executes a command, and returns its stdout as a stream.
// If the command fails to run or doesn't complete successfully, an error
// will be returned, including anything written on stderr.
func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, <-chan struct{}, error) {
	chdone := make(chan struct{})
	cmd.Stdin = input
	pipeR, pipeW := io.Pipe()
	cmd.Stdout = pipeW
	var errBuf bytes.Buffer
	cmd.Stderr = &errBuf

	// Run the command and return the pipe
	if err := cmd.Start(); err != nil {
		return nil, nil, err
	}

	// Copy stdout to the returned pipe
	go func() {
		if err := cmd.Wait(); err != nil {
			pipeW.CloseWithError(fmt.Errorf("%s: %s", err, errBuf.String()))
		} else {
			pipeW.Close()
		}
		close(chdone)
	}()

	return pipeR, chdone, nil
}
Beispiel #23
0
// RunCommandWithStdoutStderr execs a command and returns its output.
func RunCommandWithStdoutStderr(cmd *exec.Cmd) (bytes.Buffer, bytes.Buffer, error) {
	var stdout, stderr bytes.Buffer
	stderrPipe, err := cmd.StderrPipe()
	stdoutPipe, err := cmd.StdoutPipe()

	cmd.Env = os.Environ()
	if err != nil {
		fmt.Println("error at io pipes")
	}

	err = cmd.Start()
	if err != nil {
		fmt.Println("error at command start")
	}

	go func() {
		io.Copy(&stdout, stdoutPipe)
		fmt.Println(stdout.String())
	}()
	go func() {
		io.Copy(&stderr, stderrPipe)
		fmt.Println(stderr.String())
	}()
	time.Sleep(2000 * time.Millisecond)
	err = cmd.Wait()
	if err != nil {
		fmt.Println("error at command wait")
	}
	return stdout, stderr, err
}
Beispiel #24
0
func waitSimple(command *Command, cmd *osexec.Cmd) error {
	err := cmd.Wait()
	if err != nil {
		glog.Errorf("Command exited with %s: %s", err, DebugString(command))
	}
	return err
}
Beispiel #25
0
func runTest(test test) (passed bool, err error) {
	prog := path.Join(*buildDir, test[0])
	args := test[1:]
	var cmd *exec.Cmd
	if *useValgrind {
		cmd = valgrindOf(false, prog, args...)
	} else {
		cmd = exec.Command(prog, args...)
	}
	var stdoutBuf bytes.Buffer
	cmd.Stdout = &stdoutBuf
	cmd.Stderr = os.Stderr

	if err := cmd.Start(); err != nil {
		return false, err
	}
	if err := cmd.Wait(); err != nil {
		return false, err
	}

	// Account for Windows line-endings.
	stdout := bytes.Replace(stdoutBuf.Bytes(), []byte("\r\n"), []byte("\n"), -1)

	if bytes.HasSuffix(stdout, []byte("PASS\n")) &&
		(len(stdout) == 5 || stdout[len(stdout)-6] == '\n') {
		return true, nil
	}
	return false, nil
}
Beispiel #26
0
// runInContext runs a command in the context of a Vagrantfile (from the same dir)
func runInContext(cmd *exec.Cmd) error {

	// run the command from ~/.nanobox/apps/<config.App>. Running the command from
	// the directory that contains the Vagratfile ensure that the command can
	// atleast run (especially in cases like 'create' where a VM hadn't been created
	// yet, and a UUID isn't available)
	setContext(config.AppDir)

	//
	handleCMDout(cmd)

	// start the command; we need this to 'fire and forget' so that we can manually
	// capture and modify the commands output above
	if err := cmd.Start(); err != nil {
		return err
	}

	// wait for the command to complete/fail and exit, giving us a chance to scan
	// the output
	if err := cmd.Wait(); err != nil {
		return err
	}

	// switch back to project dir
	setContext(config.CWDir)

	return nil
}
Beispiel #27
0
func (w *Worker) CmdRunWithTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
	done := make(chan error)
	go func() {
		done <- cmd.Wait()
	}()

	var err error
	select {
	case <-time.After(timeout):
		// timeout
		if err = cmd.Process.Kill(); err != nil {
			golog.Error("worker", "CmdRunTimeout", "kill error", 0,
				"path", cmd.Path,
				"error", err.Error(),
			)
		}
		golog.Info("worker", "CmdRunWithTimeout", "kill process", 0,
			"path", cmd.Path,
			"error", errors.ErrExecTimeout.Error(),
		)
		go func() {
			<-done // allow goroutine to exit
		}()
		return errors.ErrExecTimeout, true
	case err = <-done:
		return err, false
	}
}
Beispiel #28
0
func (run execCmdRunner) runCmd(cmd *exec.Cmd) (stdout, stderr string, err error) {
	cmdString := strings.Join(cmd.Args, " ")

	run.logger.Debug("Cmd Runner", "Running command: %s", cmdString)

	stdoutWriter := bytes.NewBufferString("")
	stderrWriter := bytes.NewBufferString("")
	cmd.Stdout = stdoutWriter
	cmd.Stderr = stderrWriter

	err = cmd.Start()
	if err != nil {
		err = bosherr.WrapError(err, "Starting command %s", cmdString)
		return
	}

	err = cmd.Wait()
	stdout = string(stdoutWriter.Bytes())
	stderr = string(stderrWriter.Bytes())

	run.logger.Debug("Cmd Runner", "Stdout: %s", stdout)
	run.logger.Debug("Cmd Runner", "Stderr: %s", stderr)
	run.logger.Debug("Cmd Runner", "Successful: %t", err == nil)

	if err != nil {
		err = bosherr.WrapError(err, "Running command: '%s', stdout: '%s', stderr: '%s'", cmdString, stdout, stderr)
	}
	return
}
Beispiel #29
0
func execCommand(cmd *exec.Cmd, prefix string, name string) (bool, *string, *string) {
	out, err := cmd.StdoutPipe()
	outE, errE := cmd.StderrPipe()

	if err != nil {
		log.Warnf("[command] %s err: %s", prefix, out)
		log.Warnf("[command] %s err: %s", prefix, err)
		return false, nil, nil
	}

	if errE != nil {
		log.Warnf("[command] %s err: %s", prefix, outE)
		log.Warnf("[command] %s err: %s", prefix, errE)
		return false, nil, nil
	}

	err = cmd.Start()
	if err != nil {
		log.Warnf("[command] %s err: %s", prefix, err)
		return false, nil, nil
	}
	outResult := copyStream(out, prefix, name)
	errResult := copyStream(outE, prefix, name)

	err = cmd.Wait()
	if err != nil {
		log.Warnf("[command] %s err: %s", prefix, err)
		return false, &outResult, &errResult
	}
	return true, &outResult, &errResult
}
Beispiel #30
-1
// Run runs the command and returns a channel of output lines, errors and result of cmd.Wait
func Run(cmd *exec.Cmd, lines chan string) (error, error) {
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}

	err = cmd.Start()
	if err != nil {
		return nil, err
	}

	var wg sync.WaitGroup
	errCh := make(chan error, 2)
	wg.Add(2)
	go tailReader(bufio.NewReader(stdout), lines, errCh, &wg)
	go tailReader(bufio.NewReader(stderr), lines, errCh, &wg)
	wg.Wait()
	select {
	case err := <-errCh:
		return nil, err
	default:
	}
	return cmd.Wait(), nil
}