mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
chore: log provider stack traces on text file busy (#15078)
re: #14726 If we see "text file busy" in the errors while initializing terraform, attempt to query the pprof endpoint set up by https://github.com/coder/terraform-provider-coder/pull/295 and log at CRITICAL. --------- Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
@ -200,6 +200,15 @@ func versionFromBinaryPath(ctx context.Context, binaryPath string) (*version.Ver
|
||||
return version.NewVersion(vj.Version)
|
||||
}
|
||||
|
||||
type textFileBusyError struct {
|
||||
exitErr *exec.ExitError
|
||||
stderr string
|
||||
}
|
||||
|
||||
func (e *textFileBusyError) Error() string {
|
||||
return "text file busy: " + e.exitErr.String()
|
||||
}
|
||||
|
||||
func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
|
||||
ctx, span := e.server.startTrace(ctx, tracing.FuncName())
|
||||
defer span.End()
|
||||
@ -216,13 +225,24 @@ func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
|
||||
<-doneErr
|
||||
}()
|
||||
|
||||
// As a special case, we want to look for the error "text file busy" in the stderr output of
|
||||
// the init command, so we also take a copy of the stderr into an in memory buffer.
|
||||
errBuf := newBufferedWriteCloser(errWriter)
|
||||
|
||||
args := []string{
|
||||
"init",
|
||||
"-no-color",
|
||||
"-input=false",
|
||||
}
|
||||
|
||||
return e.execWriteOutput(ctx, killCtx, args, e.basicEnv(), outWriter, errWriter)
|
||||
err := e.execWriteOutput(ctx, killCtx, args, e.basicEnv(), outWriter, errBuf)
|
||||
var exitErr *exec.ExitError
|
||||
if xerrors.As(err, &exitErr) {
|
||||
if bytes.Contains(errBuf.b.Bytes(), []byte("text file busy")) {
|
||||
return &textFileBusyError{exitErr: exitErr, stderr: errBuf.b.String()}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getPlanFilePath(workdir string) string {
|
||||
@ -707,3 +727,26 @@ func (sw syncWriter) Write(p []byte) (n int, err error) {
|
||||
defer sw.mut.Unlock()
|
||||
return sw.w.Write(p)
|
||||
}
|
||||
|
||||
type bufferedWriteCloser struct {
|
||||
wc io.WriteCloser
|
||||
b bytes.Buffer
|
||||
}
|
||||
|
||||
func newBufferedWriteCloser(wc io.WriteCloser) *bufferedWriteCloser {
|
||||
return &bufferedWriteCloser{
|
||||
wc: wc,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bufferedWriteCloser) Write(p []byte) (int, error) {
|
||||
n, err := b.b.Write(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
return b.wc.Write(p)
|
||||
}
|
||||
|
||||
func (b *bufferedWriteCloser) Close() error {
|
||||
return b.wc.Close()
|
||||
}
|
||||
|
Reference in New Issue
Block a user