From e09ed446a447581c836b89d5806e2f2d62ca9810 Mon Sep 17 00:00:00 2001 From: Mike Lundy Date: Wed, 13 Jan 2021 11:41:50 -0800 Subject: [PATCH] fix report concurrency crash when helm-diff used as a library the Manifests codepath was calling setupReportFormat on a mutable global map, which means that calling Manifests from different gothreads is an error, and can produce a panic with this (abbreviated) traceback: fatal error: concurrent map writes goroutine 668 [running]: runtime.throw(0x27cb973, 0x15) /usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc003a8c710 sp=0xc003a8c6e0 pc=0x437892 runtime.mapassign_faststr(0x23fc3a0, 0xc019650120, 0x27a837d, 0x6, 0xc00012f408) /usr/local/go/src/runtime/map_faststr.go:211 +0x3f1 fp=0xc003a8c778 sp=0xc003a8c710 pc=0x414811 github.com/databus23/helm-diff/v3/diff.setupDiffReport(...) /go/pkg/mod/github.com/databus23/helm-diff/v3@v3.1.3/diff/report.go:99 github.com/databus23/helm-diff/v3/diff.(*Report).setupReportFormat(0x3dafe80, 0x27a5ada, 0x4) /go/pkg/mod/github.com/databus23/helm-diff/v3@v3.1.3/diff/report.go:67 +0x111 fp=0xc003a8c7b0 sp=0xc003a8c778 pc=0x20e7291 github.com/databus23/helm-diff/v3/diff.Manifests(0xc009ffaf60, 0xc009ffb3e0, 0xc0061f73e0, 0x1, 0x1, 0xc0061f7300, 0x5, 0x27a5ada, 0x4, 0x2b26460, ...) --- diff/diff.go | 3 ++- diff/report.go | 12 +++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/diff/diff.go b/diff/diff.go index bce80e86..c4634c84 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -20,6 +20,7 @@ import ( // Manifests diff on manifests func Manifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedKinds []string, showSecrets bool, context int, output string, stripTrailingCR bool, to io.Writer) bool { + report := Report{} report.setupReportFormat(output) seenAnyChanges := false emptyMapping := &manifest.MappingResult{} @@ -148,7 +149,7 @@ func Releases(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedK return Manifests(oldIndex, newIndex, suppressedKinds, showSecrets, context, output, stripTrailingCR, to) } -func diffMappingResults(oldContent *manifest.MappingResult, newContent *manifest.MappingResult, stripTrailingCR bool ) []difflib.DiffRecord { +func diffMappingResults(oldContent *manifest.MappingResult, newContent *manifest.MappingResult, stripTrailingCR bool) []difflib.DiffRecord { return diffStrings(oldContent.Content, newContent.Content, stripTrailingCR) } diff --git a/diff/report.go b/diff/report.go index 4bfd830c..4a1c8bd3 100644 --- a/diff/report.go +++ b/diff/report.go @@ -52,19 +52,17 @@ type ReportTemplateSpec struct { Change string } -var report Report - // setupReportFormat: process output argument. func (r *Report) setupReportFormat(format string) { switch format { case "simple": - setupSimpleReport(&report) + setupSimpleReport(r) case "template": - setupTemplateReport(&report) + setupTemplateReport(r) case "json": - setupJSONReport(&report) + setupJSONReport(r) default: - setupDiffReport(&report) + setupDiffReport(r) } } @@ -126,7 +124,7 @@ func printSimpleReport(r *Report, to io.Writer) { "MODIFY": 0, } for _, entry := range r.entries { - fmt.Fprintf(to, ansi.Color("%s %s", report.format.changestyles[entry.changeType].color)+"\n", + fmt.Fprintf(to, ansi.Color("%s %s", r.format.changestyles[entry.changeType].color)+"\n", entry.key, r.format.changestyles[entry.changeType].message, )