func()

in plugins/teststeps/cmd/cmd.go [96:158]


func (ts *Cmd) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
	log := ctx.Logger()

	if err := ts.validateAndPopulate(params); err != nil {
		return nil, err
	}
	f := func(ctx xcontext.Context, target *target.Target) error {
		// expand args
		var args []string
		for _, arg := range ts.args {
			expArg, err := arg.Expand(target)
			if err != nil {
				return fmt.Errorf("failed to expand argument '%s': %v", arg, err)
			}
			args = append(args, expArg)
		}
		cmd := exec.CommandContext(ctx, ts.executable, args...)
		pwd, err := ts.dir.Expand(target)
		if err != nil {
			return fmt.Errorf("failed to expand argument dir '%s': %v", ts.dir, err)
		}
		cmd.Dir = pwd
		var stdout, stderr bytes.Buffer
		cmd.Stdout, cmd.Stderr = &stdout, &stderr
		cmd.SysProcAttr = &syscall.SysProcAttr{
			// Put the command into a separate session (and group) so signals do not propagate directly to it.
			Setsid: true,
		}
		if cmd.Dir != "" {
			log.Debugf("Running command '%+v' in directory '%+v'", cmd, cmd.Dir)
		} else {
			log.Debugf("Running command '%+v'", cmd)
		}

		// Emit EventCmdStart
		if err := emitEvent(ctx, EventCmdStart, eventCmdStartPayload{Path: cmd.Path, Args: cmd.Args, Dir: cmd.Dir}, target, ev); err != nil {
			log.Warnf("Failed to emit event: %v", err)
		}

		runErr := cmd.Run()

		if err := emitEvent(ctx, EventCmdEnd, nil, target, ev); err != nil {
			log.Warnf("Failed to emit event: %v", err)
		}
		if ts.emitStdout {
			log.Infof("Emitting stdout event")
			if err := emitEvent(ctx, EventCmdStdout, eventCmdStdoutPayload{Msg: stdout.String()}, target, ev); err != nil {
				log.Warnf("Failed to emit event: %v", err)
			}
		}
		if ts.emitStderr {
			log.Infof("Emitting stderr event")
			if err := emitEvent(ctx, EventCmdStderr, eventCmdStderrPayload{Msg: stderr.String()}, target, ev); err != nil {
				log.Warnf("Failed to emit event: %v", err)
			}
		}

		log.Infof("Command's '%s' with args '%s' stdout '%s', stderr is '%s', run err: '%v'",
			cmd.Path, cmd.Args, stdout.Bytes(), stderr.Bytes(), runErr)
		return runErr
	}
	return teststeps.ForEachTarget(Name, ctx, ch, f)
}