MCPcopy Index your code
hub / github.com/coder/coder / execWriteOutput

Method execWriteOutput

provisioner/terraform/executor.go:63–118  ·  view source on GitHub ↗

execWriteOutput must only be called while the lock is held.

(ctx, killCtx context.Context, args, env []string, stdOutWriter, stdErrWriter io.WriteCloser)

Source from the content-addressed store, hash-verified

61
62// execWriteOutput must only be called while the lock is held.
63func (e *executor) execWriteOutput(ctx, killCtx context.Context, args, env []string, stdOutWriter, stdErrWriter io.WriteCloser) (err error) {
64 ctx, span := e.server.startTrace(ctx, fmt.Sprintf("exec - terraform %s", args[0]))
65 defer span.End()
66 span.SetAttributes(attribute.StringSlice("args", args))
67 e.logger.Debug(ctx, "starting command", slog.F("args", args))
68
69 defer func() {
70 e.logger.Debug(ctx, "closing writers", slog.Error(err))
71 closeErr := stdOutWriter.Close()
72 if err == nil && closeErr != nil {
73 err = closeErr
74 }
75 closeErr = stdErrWriter.Close()
76 if err == nil && closeErr != nil {
77 err = closeErr
78 }
79 }()
80 if ctx.Err() != nil {
81 e.logger.Debug(ctx, "context canceled before command started", slog.F("args", args))
82 return ctx.Err()
83 }
84
85 if isCanarySet(env) {
86 return xerrors.New("environment variables not sanitized, this is a bug within Coder")
87 }
88
89 // #nosec
90 cmd := exec.CommandContext(killCtx, e.binaryPath, args...)
91 cmd.Dir = e.files.WorkDirectory()
92 if env == nil {
93 // We don't want to passthrough host env when unset.
94 env = []string{}
95 }
96 cmd.Env = env
97
98 // We want logs to be written in the correct order, so we wrap all logging
99 // in a sync.Mutex.
100 mut := &sync.Mutex{}
101 cmd.Stdout = syncWriter{mut, stdOutWriter}
102 cmd.Stderr = syncWriter{mut, stdErrWriter}
103
104 e.server.logger.Debug(ctx, "executing terraform command",
105 slog.F("binary_path", e.binaryPath),
106 slog.F("args", args),
107 )
108 err = cmd.Start()
109 if err != nil {
110 e.logger.Debug(ctx, "failed to start command", slog.F("args", args))
111 return err
112 }
113 interruptCommandOnCancel(ctx, killCtx, e.logger, cmd)
114
115 err = cmd.Wait()
116 e.logger.Debug(ctx, "command done", slog.F("args", args), slog.Error(err))
117 return err
118}
119
120// execParseJSON must only be called while the lock is held.

Callers 4

initMethod · 0.95
planMethod · 0.95
showPlanMethod · 0.95
applyMethod · 0.95

Calls 11

isCanarySetFunction · 0.85
interruptCommandOnCancelFunction · 0.85
ErrMethod · 0.80
WorkDirectoryMethod · 0.80
CloseMethod · 0.65
NewMethod · 0.65
CommandContextMethod · 0.65
StartMethod · 0.65
WaitMethod · 0.65
startTraceMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected