11package supportbundle
22
33import (
4+ "fmt"
45 "io/ioutil"
56 "net/http"
67 "os"
78 "path/filepath"
89 "strings"
910 "time"
1011
12+ cursor "github.com/ahmetalpbalkan/go-cursor"
13+ "github.com/fatih/color"
1114 "github.com/pkg/errors"
1215 analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
1316 troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
@@ -22,19 +25,20 @@ type SupportBundleCreateOpts struct {
2225 Namespace string
2326 ProgressChan chan interface {}
2427 SinceTime * time.Time
28+ FromCLI bool
2529}
2630
2731type SupportBundleResponse struct {
2832 AnalyzerResults []* analyzer.AnalyzeResult
2933 ArchivePath string
30- fileUploaded bool
34+ FileUploaded bool
3135}
3236
33- // SupportBundleCollectAnalyzeProcess collects support bundle from start to finish, including running
37+ // CollectSupportBundleFromSpec collects support bundle from start to finish, including running
3438// collectors, analyzers and after collection steps. Input arguments are specifications.
35- // The support bundle is archived in the OS temp folder (os.TempDir()) .
36- func SupportBundleCollectAnalyzeProcess ( spec * troubleshootv1beta2. SupportBundleSpec , additionalRedactors * troubleshootv1beta2. Redactor , opts SupportBundleCreateOpts ) ( * SupportBundleResponse , error ) {
37-
39+ // if FromCLI option is set to true, the output is the name of the archive on disk in the cwd .
40+ // if FromCLI option is set to false, the support bundle is archived in the OS temp folder (os.TempDir()).
41+ func CollectSupportBundleFromSpec ( spec * troubleshootv1beta2. SupportBundleSpec , additionalRedactors * troubleshootv1beta2. Redactor , opts SupportBundleCreateOpts ) ( * SupportBundleResponse , error ) {
3842 resultsResponse := SupportBundleResponse {}
3943
4044 if opts .KubernetesRestConfig == nil {
@@ -51,7 +55,11 @@ func SupportBundleCollectAnalyzeProcess(spec *troubleshootv1beta2.SupportBundleS
5155 }
5256 defer os .RemoveAll (tmpDir )
5357
54- basename := filepath .Join (os .TempDir (), "support-bundle-" + time .Now ().Format ("2006-01-02T15_04_05" ))
58+ basename := fmt .Sprintf ("support-bundle-%s" , time .Now ().Format ("2006-01-02T15_04_05" ))
59+ if ! opts .FromCLI {
60+ basename = filepath .Join (os .TempDir (), basename )
61+ }
62+
5563 filename , err := findFileName (basename , "tar.gz" )
5664 if err != nil {
5765 return nil , errors .Wrap (err , "find file name" )
@@ -74,21 +82,38 @@ func SupportBundleCollectAnalyzeProcess(spec *troubleshootv1beta2.SupportBundleS
7482 }
7583
7684 // Run Analyzers
77- analyzeResults , err := AnalyzeSupportBundle (spec , tmpDir )
85+ analyzeResults , err := AnalyzeSupportBundle (spec , bundlePath )
7886 if err != nil {
79- return nil , errors .Wrap (err , "failed to run analysis" )
87+ if opts .FromCLI {
88+ c := color .New (color .FgHiRed )
89+ c .Printf ("%s\r * %v\n " , cursor .ClearEntireLine (), err )
90+ // don't die
91+ } else {
92+ return nil , errors .Wrap (err , "failed to run analysis" )
93+ }
8094 }
8195 resultsResponse .AnalyzerResults = analyzeResults
8296
97+ // Add the analysis to the support bundle
98+ if err = writeAnalysisFile (bundlePath , analyzeResults ); err != nil {
99+ return nil , errors .Wrap (err , "write version file" )
100+ }
101+
83102 if err := tarSupportBundleDir (bundlePath , filename ); err != nil {
84103 return nil , errors .Wrap (err , "create bundle file" )
85104 }
86105
87106 fileUploaded , err := ProcessSupportBundleAfterCollection (spec , filename )
88107 if err != nil {
89- return nil , errors .Wrap (err , "failed to process bundle after collection" )
108+ if opts .FromCLI {
109+ c := color .New (color .FgHiRed )
110+ c .Printf ("%s\r * %v\n " , cursor .ClearEntireLine (), err )
111+ // don't die
112+ } else {
113+ return nil , errors .Wrap (err , "failed to process bundle after collection" )
114+ }
90115 }
91- resultsResponse .fileUploaded = fileUploaded
116+ resultsResponse .FileUploaded = fileUploaded
92117
93118 return & resultsResponse , nil
94119}
@@ -97,7 +122,6 @@ func SupportBundleCollectAnalyzeProcess(spec *troubleshootv1beta2.SupportBundleS
97122// collectors, analyzers and after collection steps. Input arguments are the URIs of the support bundle and redactor specs.
98123// The support bundle is archived in the OS temp folder (os.TempDir()).
99124func CollectSupportBundleFromURI (specURI string , redactorURIs []string , opts SupportBundleCreateOpts ) (* SupportBundleResponse , error ) {
100-
101125 supportbundle , err := GetSupportBundleFromURI (specURI )
102126 if err != nil {
103127 return nil , errors .Wrap (err , "could not bundle from URI" )
@@ -115,53 +139,7 @@ func CollectSupportBundleFromURI(specURI string, redactorURIs []string, opts Sup
115139 }
116140 }
117141
118- return SupportBundleCollectAnalyzeProcess (& supportbundle .Spec , additionalRedactors , opts )
119- }
120-
121- // CollectSupportBundleFromSpec run the support bundle collectors and creates an archive. The output is the name of the archive on disk
122- // in the pwd (the caller must remove)
123- func CollectSupportBundleFromSpec (spec * troubleshootv1beta2.SupportBundleSpec , additionalRedactors * troubleshootv1beta2.Redactor , opts SupportBundleCreateOpts ) (string , error ) {
124-
125- if opts .KubernetesRestConfig == nil {
126- return "" , errors .New ("did not receive kube rest config" )
127- }
128-
129- if opts .ProgressChan == nil {
130- return "" , errors .New ("did not receive collector progress chan" )
131- }
132-
133- tmpDir , err := ioutil .TempDir ("" , "supportbundle" )
134- if err != nil {
135- return "" , errors .Wrap (err , "create temp dir" )
136- }
137- defer os .RemoveAll (tmpDir )
138-
139- // Do we need to put this in some kind of swap space?
140- filename , err := findFileName ("support-bundle-" + time .Now ().Format ("2006-01-02T15_04_05" ), "tar.gz" )
141- if err != nil {
142- return "" , errors .Wrap (err , "find file name" )
143- }
144-
145- bundlePath := filepath .Join (tmpDir , strings .TrimSuffix (filename , ".tar.gz" ))
146- if err := os .MkdirAll (bundlePath , 0777 ); err != nil {
147- return "" , errors .Wrap (err , "create bundle dir" )
148- }
149-
150- if err = writeVersionFile (bundlePath ); err != nil {
151- return "" , errors .Wrap (err , "write version file" )
152- }
153-
154- // Run collectors
155- err = runCollectors (spec .Collectors , additionalRedactors , filename , bundlePath , opts )
156- if err != nil {
157- return "" , errors .Wrap (err , "run collectors" )
158- }
159-
160- if err := tarSupportBundleDir (bundlePath , filename ); err != nil {
161- return "" , errors .Wrap (err , "create bundle file" )
162- }
163-
164- return filename , nil
142+ return CollectSupportBundleFromSpec (& supportbundle .Spec , additionalRedactors , opts )
165143}
166144
167145// ProcessSupportBundleAfterCollection performs the after collection actions, like Callbacks and sending the archive to a remote server.
@@ -185,49 +163,15 @@ func ProcessSupportBundleAfterCollection(spec *troubleshootv1beta2.SupportBundle
185163 return fileUploaded , nil
186164}
187165
188- // AnalyzeAndExtractSupportBundle performs analysis on a support bundle using the archive and spec.
189- func AnalyzeAndExtractSupportBundle (spec * troubleshootv1beta2.SupportBundleSpec , archivePath string ) ([]* analyzer.AnalyzeResult , error ) {
190-
191- var analyzeResults []* analyzer.AnalyzeResult
192-
193- if len (spec .Analyzers ) > 0 {
194-
195- tmpDir , err := ioutil .TempDir ("" , "troubleshoot" )
196- if err != nil {
197- return analyzeResults , errors .Wrap (err , "failed to make directory for analysis" )
198- }
199- defer os .RemoveAll (tmpDir )
200-
201- f , err := os .Open (archivePath )
202- if err != nil {
203- return analyzeResults , errors .Wrap (err , "failed to open support bundle for analysis" )
204- }
205- defer f .Close ()
206-
207- if err := analyzer .ExtractTroubleshootBundle (f , tmpDir ); err != nil {
208- return analyzeResults , errors .Wrap (err , "failed to extract support bundle for analysis" )
209- }
210-
211- analyzeResults , err = analyzer .AnalyzeLocal (tmpDir , spec .Analyzers )
212- if err != nil {
213- return analyzeResults , errors .Wrap (err , "failed to analyze support bundle" )
214- }
215- }
216- return analyzeResults , nil
217- }
218-
219166// AnalyzeSupportBundle performs analysis on a support bundle using the support bundle spec and an already unpacked support
220167// bundle on disk
221168func AnalyzeSupportBundle (spec * troubleshootv1beta2.SupportBundleSpec , tmpDir string ) ([]* analyzer.AnalyzeResult , error ) {
222-
223- var analyzeResults []* analyzer.AnalyzeResult
224-
225- if len (spec .Analyzers ) > 0 {
226-
227- analyzeResults , err := analyzer .AnalyzeLocal (tmpDir , spec .Analyzers )
228- if err != nil {
229- return analyzeResults , errors .Wrap (err , "failed to analyze support bundle" )
230- }
169+ if len (spec .Analyzers ) == 0 {
170+ return nil , nil
171+ }
172+ analyzeResults , err := analyzer .AnalyzeLocal (tmpDir , spec .Analyzers )
173+ if err != nil {
174+ return nil , errors .Wrap (err , "failed to analyze support bundle" )
231175 }
232176 return analyzeResults , nil
233177}
0 commit comments