예제 #1
0
파일: executor.go 프로젝트: xsb/dog
func gatherCmdOutput(taskName string, cmd *exec.Cmd, eventsChan chan *types.Event) error {
	stdoutReader, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

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

	stdoutScanner := bufio.NewScanner(stdoutReader)
	stderrScanner := bufio.NewScanner(stderrReader)
	go func() {
		for stdoutScanner.Scan() {
			eventsChan <- types.NewOutputEvent(taskName, stdoutScanner.Bytes())
		}
	}()

	go func() {
		for stderrScanner.Scan() {
			eventsChan <- types.NewOutputEvent(taskName, stderrScanner.Bytes())
		}
	}()

	return nil
}
예제 #2
0
파일: executor.go 프로젝트: xsb/dog
// Exec executes the created tmp script and writes the output to the writer.
func (ex *Executor) Exec(t *types.Task, eventsChan chan *types.Event) error {
	f, err := writeTempFile("", "dog", t.Run)
	if err != nil {
		return err
	}

	defer func() {
		if err := os.Remove(f.Name()); err != nil {
			eventsChan <- types.NewOutputEvent(t.Name, []byte(err.Error()))
		}
	}()

	binary, err := exec.LookPath(ex.cmd)
	if err != nil {
		return err
	}

	if t.Workdir != "" {
		if err := os.Chdir(t.Workdir); err != nil {
			return err
		}
	}

	cmd := exec.Command(binary, f.Name())

	if err := gatherCmdOutput(t.Name, cmd, eventsChan); err != nil {
		return err
	}

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

	eventsChan <- types.NewStartEvent(t.Name)

	statusCode := 0
	if err := cmd.Wait(); err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); !ok {
				// For unknown error status codes set it to 1
				statusCode = 1
			} else {
				statusCode = waitStatus.ExitStatus()
			}
		}
	}

	eventsChan <- types.NewEndEvent(t.Name, statusCode)

	return nil
}