fix(agent/agentscripts): create missing log_path parent directory - #28166
Conversation
A coder_script whose log_path points under a directory that does not exist failed before execution because OpenFile creates the log file but not its parent directories. Create the parent directory with MkdirAll before opening the log file.
| logger.Info(ctx, "running agent script", slog.F("script", script.Script)) | ||
|
|
||
| logDir := filepath.Dir(logPath) | ||
| if err = r.Filesystem.MkdirAll(logDir, 0o700); err != nil { |
There was a problem hiding this comment.
NIT: Just wondering if we could define a constant for 0o700. Also, should we make this configurable via an environment variable or config option, with 0o700 as the default?
There was a problem hiding this comment.
Just wondering if we could define a constant for 0o700
0o700 states the exact permission bits, it feels more intuitive/easier to read.
should we make this configurable via an environment variable or config option, with 0o700 as the default
0o700 seems like a safe private default, the workspace owner can chmod it afterward if they need looser perms. We can revisit this if a use case like this comes up.
BobbyHo
left a comment
There was a problem hiding this comment.
lgtm, just left a NIT comment (non-blocking)
Previously, a
coder_scriptwhoselog_pathpointed under a directory that did not yet exist failed before the script ran, with no per-script log output.OpenFile(logPath, O_CREATE|O_RDWR, 0o600)creates the log file but not its parent directories, so the open returnedENOENT. The failure only surfaced in the agent log (startup script(s) failed/shutdown script(s) failed) and never reached the script's own UI logs, which made it look like a silent failure.This creates the resolved parent directory with
MkdirAll(filepath.Dir(logPath), 0o700)before opening the log file, so the script runs and its log is written.0o700matches the existing script data-dir and secret-file directory conventions in this package. Resolution of~, environment variables, and paths relative toLogDiris unchanged; only the parent directory is now created.Fixes #21986
Implementation notes and validation
Change
agent/agentscripts/agentscripts.go: in(*Runner).run, after the fulllogPathresolution and beforeOpenFile, create the parent directory:Regression test
agent/agentscripts/agentscripts_test.go:TestExecuteCreatesMissingLogDirruns a script with a nested, nonexistentLogPathand asserts the streamed output and that the log file is created.afero.NewOsFs()on purpose:afero.NewMemMapFs()auto-creates parent directories onOpenFile, so it cannot reproduce the reported failure.open .../does/not/exist/install.log: no such file or directory) and green with it.Local validation
gofmtclean,go vet,go build,golangci-lint runon the package, andgo test -race ./agent/agentscripts/all pass.End-to-end
coder_script.log_pathtargets a nested directory that does not exist. The agent created the parents with mode0700and wrote the log file; the workspace agent reported healthy.Prior attempts
0o700and adding a regression test.Raised on behalf of @35C4n0r by Coder Agents.