Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 11 additions & 9 deletions radar.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func writeRadarMeta(zw *zip.Writer) error {
}
}

w, err := zw.Create("radar.out")
w, err := zw.CreateHeader(archiveHeader("radar.out"))
if err != nil {
return err
}
Expand Down Expand Up @@ -143,6 +143,14 @@ type CollectionTask struct {
Collector func(*Config, io.Writer) error
}

func archiveHeader(name string) *zip.FileHeader {
return &zip.FileHeader{
Name: name,
Method: DefaultCompressionMethod,
Modified: time.Now(),
}
}

// lazyZipWriter defers ZIP entry creation until first Write()
// This prevents empty files in the archive when collectors produce no output
type lazyZipWriter struct {
Expand Down Expand Up @@ -288,7 +296,7 @@ func main() {
if cfg.Verbose {
infoLog.Printf("Creating archive: %s", outputFile)
}
outFile, err := os.Create(outputFile)
outFile, err := os.OpenFile(outputFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
if err != nil {
errorLog.Printf("Failed to create output file: %v", err)
os.Exit(ExitCollectError)
Expand Down Expand Up @@ -592,14 +600,8 @@ func collect(cfg *Config, zipWriter *zip.Writer, tasks []CollectionTask) int {
collected := 0

for _, task := range tasks {
header := &zip.FileHeader{
Name: task.ArchivePath,
Method: DefaultCompressionMethod,
Modified: time.Now(),
}

// Use lazy writer - only creates ZIP entry on first Write()
lazy := &lazyZipWriter{zipWriter: zipWriter, header: header}
lazy := &lazyZipWriter{zipWriter: zipWriter, header: archiveHeader(task.ArchivePath)}

err := task.Collector(cfg, lazy)
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions test-radar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ validate_zip() {

echo " PostgreSQL: $pg_count, System: $sys_count, pg_statviz: $statviz_count, Empty files: $empty_count"

# The archive is owner-only: it holds pg_hba.conf, connection details and
# query text, and is written into a directory other local users can read.
local mode=$(stat -c %a "$zip_file")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if [ "$mode" != "600" ]; then
echo -e "${RED}✗ $scenario FAILED: archive mode $mode, expected 600${NC}"
return 1
fi

# Check for empty files (should be 0)
if [ "$empty_count" -gt 0 ]; then
echo -e "${RED}✗ $scenario FAILED: Found $empty_count empty files in archive${NC}"
Expand Down
Loading