Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,15 @@ func (b *lockedBuffer) Tail(maxBytes int) string {
return string(content[len(content)-maxBytes:])
}

// custodianCachePath returns a writable path for c7n's resource cache file.
// c7n defaults to ~/.cache/cloud-custodian.cache, which is unwritable when the
// container runs with a read-only root filesystem and no writable HOME.
// os.TempDir resolves to $TMPDIR or /tmp; the agent deployment mounts /tmp as a
// writable emptyDir, so the cache lands somewhere always writable and ephemeral.
func custodianCachePath() string {
return filepath.Join(os.TempDir(), "cloud-custodian.cache")
}
Comment on lines +375 to +377

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use a run-scoped cache path instead of a shared global temp file.

Line 375 and Line 507 currently force every execution to the same cache file (/tmp/cloud-custodian.cache or $TMPDIR/...). That introduces cross-run cache sharing and potential contention/stale data between checks or concurrent plugin executions. Prefer a per-execution cache file under req.OutputDir so isolation and cleanup are automatic.

Suggested diff
-func custodianCachePath() string {
-	return filepath.Join(os.TempDir(), "cloud-custodian.cache")
+func custodianCachePath(outputDir string) string {
+	return filepath.Join(outputDir, "cloud-custodian.cache")
 }
@@
-	args = append(args, "--dryrun", "-s", req.OutputDir, "--cache", custodianCachePath(), policyPath)
+	args = append(args, "--dryrun", "-s", req.OutputDir, "--cache", custodianCachePath(req.OutputDir), policyPath)

Also applies to: 507-507

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.go` around lines 375 - 377, custodianCachePath currently returns a
global temp file which causes cross-run contention; change it to produce a
per-run cache file under the run's output directory (use req.OutputDir) instead
of os.TempDir(). For example, modify custodianCachePath to accept an outputDir
parameter (or remove it and inline a new join using req.OutputDir where called)
and return filepath.Join(outputDir, "cloud-custodian.cache"); update all call
sites (the locations that call custodianCachePath() around the uses at/near
custodianCachePath and the caller at line ~507) to pass req.OutputDir so each
run gets an isolated cache file that is automatically within the run's output
directory.


func custodianDiagnosticInterval(timeout time.Duration) time.Duration {
if timeout <= 0 {
return custodianWatchInterval
Expand Down Expand Up @@ -490,7 +499,12 @@ func (e *CommandCustodianExecutor) Execute(ctx context.Context, req CustodianExe
if req.Verbose {
args = append(args, "-v")
}
args = append(args, "--dryrun", "-s", req.OutputDir, policyPath)
// Pin c7n's resource cache to a writable, ephemeral location. By default
// c7n writes to ~/.cache/cloud-custodian.cache; with no HOME set and a
// read-only root filesystem that makedirs fails with "Read-only file
// system". os.TempDir honors TMPDIR and otherwise resolves to /tmp, which
// the agent deployment mounts as a writable emptyDir.
args = append(args, "--dryrun", "-s", req.OutputDir, "--cache", custodianCachePath(), policyPath)
if strings.EqualFold(req.Check.Provider, "aws") {
for _, region := range regions {
args = append(args, "--region", region)
Expand Down
Loading