1
1
package cli
2
2
3
3
import (
4
- "bytes"
5
- "context"
6
4
"encoding/base64"
7
5
"encoding/json"
8
6
"fmt"
9
- "io"
10
7
"io/ioutil"
11
8
"net/http"
12
9
"os"
@@ -16,20 +13,10 @@ import (
16
13
"github.com/ahmetalpbalkan/go-cursor"
17
14
"github.com/mholt/archiver"
18
15
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
19
- collectrunner "github.com/replicatedhq/troubleshoot/pkg/collect"
20
- "github.com/replicatedhq/troubleshoot/pkg/logger"
16
+ "github.com/replicatedhq/troubleshoot/pkg/collect"
21
17
"github.com/spf13/viper"
22
18
"github.com/tj/go-spin"
23
19
"gopkg.in/yaml.v2"
24
- corev1 "k8s.io/api/core/v1"
25
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
- "k8s.io/apimachinery/pkg/fields"
27
- "k8s.io/apimachinery/pkg/runtime"
28
- "k8s.io/apimachinery/pkg/runtime/schema"
29
- "k8s.io/client-go/kubernetes"
30
- "k8s.io/client-go/tools/cache"
31
- "sigs.k8s.io/controller-runtime/pkg/client"
32
- "sigs.k8s.io/controller-runtime/pkg/client/config"
33
20
)
34
21
35
22
func runTroubleshootNoCRD (v * viper.Viper , arg string ) error {
@@ -119,185 +106,53 @@ the %s Admin Console to begin analysis.`
119
106
}
120
107
121
108
func runCollectors (v * viper.Viper , collector troubleshootv1beta1.Collector , progressChan chan string ) (string , error ) {
122
- cfg , err := config . GetConfig ( )
109
+ bundlePath , err := ioutil . TempDir ( "" , "troubleshoot" )
123
110
if err != nil {
124
111
return "" , err
125
112
}
113
+ defer os .RemoveAll (bundlePath )
126
114
127
- client , err := client .New (cfg , client.Options {})
128
- if err != nil {
129
- return "" , err
130
- }
131
- clientset , err := kubernetes .NewForConfig (cfg )
115
+ versionFilename , err := writeVersionFile (bundlePath )
132
116
if err != nil {
133
117
return "" , err
134
118
}
135
- restClient := clientset .CoreV1 ().RESTClient ()
136
-
137
- serviceAccountName := v .GetString ("serviceaccount" )
138
- if serviceAccountName == "" {
139
- generatedServiceAccountName , err := createServiceAccount (collector , v .GetString ("namespace" ), clientset )
140
- if err != nil {
141
- return "" , err
142
- }
143
- defer removeServiceAccount (generatedServiceAccountName , v .GetString ("namespace" ), clientset )
144
-
145
- serviceAccountName = generatedServiceAccountName
146
- }
147
119
148
- // deploy an object that "owns" everything to aid in cleanup
149
- owner := corev1.ConfigMap {
150
- ObjectMeta : metav1.ObjectMeta {
151
- Name : fmt .Sprintf ("troubleshoot-%s-owner" , collector .Name ),
152
- Namespace : v .GetString ("namespace" ),
153
- },
154
- TypeMeta : metav1.TypeMeta {
155
- APIVersion : "v1" ,
156
- Kind : "ConfigMap" ,
157
- },
158
- Data : make (map [string ]string ),
159
- }
160
- if err := client .Create (context .Background (), & owner ); err != nil {
161
- return "" , err
162
- }
163
- defer func () {
164
- if err := client .Delete (context .Background (), & owner ); err != nil {
165
- fmt .Println ("failed to clean up preflight." )
166
- }
167
- }()
168
-
169
- // deploy all collectors
170
120
desiredCollectors := make ([]* troubleshootv1beta1.Collect , 0 , 0 )
171
121
for _ , definedCollector := range collector .Spec {
172
122
desiredCollectors = append (desiredCollectors , definedCollector )
173
123
}
174
124
desiredCollectors = ensureCollectorInList (desiredCollectors , troubleshootv1beta1.Collect {ClusterInfo : & troubleshootv1beta1.ClusterInfo {}})
175
125
desiredCollectors = ensureCollectorInList (desiredCollectors , troubleshootv1beta1.Collect {ClusterResources : & troubleshootv1beta1.ClusterResources {}})
176
126
177
- podsCreated := make ([]* corev1.Pod , 0 , 0 )
178
- podsDeleted := make ([]* corev1.Pod , 0 , 0 )
179
-
180
127
collectorDirs := []string {}
181
128
182
- bundlePath , err := ioutil .TempDir ("" , "troubleshoot" )
183
- if err != nil {
184
- return "" , err
185
- }
186
- defer os .RemoveAll (bundlePath )
187
-
188
- versionFilename , err := writeVersionFile (bundlePath )
189
- if err != nil {
190
- return "" , err
191
- }
192
-
193
- resyncPeriod := time .Second
194
- ctx := context .Background ()
195
- watchList := cache .NewListWatchFromClient (restClient , "pods" , "" , fields .Everything ())
196
- _ , controller := cache .NewInformer (watchList , & corev1.Pod {}, resyncPeriod ,
197
- cache.ResourceEventHandlerFuncs {
198
- UpdateFunc : func (oldObj interface {}, newObj interface {}) {
199
- newPod , ok := newObj .(* corev1.Pod )
200
- if ! ok {
201
- return
202
- }
203
- oldPod , ok := oldObj .(* corev1.Pod )
204
- if ! ok {
205
- return
206
- }
207
- labels := newPod .Labels
208
-
209
- troubleshootRole , ok := labels ["troubleshoot-role" ]
210
- if ! ok || troubleshootRole != "troubleshoot" {
211
- return
212
- }
213
-
214
- collectorName , ok := labels ["troubleshoot" ]
215
- if ! ok || collectorName != collector .Name {
216
- return
217
- }
218
-
219
- if oldPod .Status .Phase == newPod .Status .Phase {
220
- return
221
- }
222
-
223
- if newPod .Status .Phase == corev1 .PodFailed {
224
- podsDeleted = append (podsDeleted , newPod )
225
- return
226
- }
227
-
228
- if newPod .Status .Phase != corev1 .PodSucceeded {
229
- return
230
- }
231
-
232
- podLogOpts := corev1.PodLogOptions {}
233
-
234
- req := clientset .CoreV1 ().Pods (newPod .Namespace ).GetLogs (newPod .Name , & podLogOpts )
235
- podLogs , err := req .Stream ()
236
- if err != nil {
237
- fmt .Println ("get stream" )
238
- return
239
- }
240
- defer podLogs .Close ()
241
-
242
- buf := new (bytes.Buffer )
243
- _ , err = io .Copy (buf , podLogs )
244
- if err != nil {
245
- fmt .Println ("copy logs" )
246
- return
247
- }
248
-
249
- collectorDir , err := parseAndSaveCollectorOutput (buf .String (), bundlePath )
250
- if err != nil {
251
- logger .Printf ("parse collected data: %v\n " , err )
252
- return
253
- }
254
-
255
- // empty dir name will make tar fail
256
- if collectorDir == "" {
257
- logger .Printf ("pod %s did not return any files\n " , newPod .Name )
258
- return
259
- }
260
-
261
- progressChan <- collectorDir
262
- collectorDirs = append (collectorDirs , collectorDir )
263
-
264
- if err := client .Delete (context .Background (), newPod ); err != nil {
265
- fmt .Println ("delete pod error" , err )
266
- }
267
- podsDeleted = append (podsDeleted , newPod )
268
- },
269
- })
270
- go func () {
271
- controller .Run (ctx .Done ())
272
- }()
129
+ // Run preflights collectors synchronously
130
+ for _ , desiredCollector := range desiredCollectors {
131
+ collector := collect.Collector {
132
+ Redact : true ,
133
+ Collect : desiredCollector ,
134
+ }
273
135
274
- s := runtime .NewScheme ()
275
- s .AddKnownTypes (schema.GroupVersion {Group : "" , Version : "v1" }, & corev1.ConfigMap {})
276
- for _ , collect := range desiredCollectors {
277
- _ , pod , err := collectrunner .CreateCollector (client , s , & owner , collector .Name , v .GetString ("namespace" ), serviceAccountName , "troubleshoot" , collect , v .GetString ("image" ), v .GetString ("pullpolicy" ))
136
+ result , err := collector .RunCollectorSync ()
278
137
if err != nil {
279
- logger . Printf ( "A collector pod cannot be created: %v \n " , err )
138
+ progressChan <- fmt . Sprintf ( "failed to run collector %v " , collector )
280
139
continue
281
140
}
282
- podsCreated = append (podsCreated , pod )
283
- }
284
141
285
- start := time .Now ()
286
- for {
287
- if start .Add (time .Second * 30 ).Before (time .Now ()) {
288
- fmt .Println ("timeout running troubleshoot" )
289
- return "" , err
142
+ collectorDir , err := parseAndSaveCollectorOutput (string (result ), bundlePath )
143
+ if err != nil {
144
+ progressChan <- fmt .Sprintf ("failed to parse collector spec: %v" , collector )
145
+ continue
290
146
}
291
147
292
- if len ( podsDeleted ) == len ( podsCreated ) {
293
- break
148
+ if collectorDir == "" {
149
+ continue
294
150
}
295
151
296
- time .Sleep (time .Millisecond * 200 )
152
+ progressChan <- collectorDir
153
+ collectorDirs = append (collectorDirs , collectorDir )
297
154
}
298
155
299
- ctx .Done ()
300
-
301
156
tarGz := archiver.TarGz {
302
157
Tar : & archiver.Tar {
303
158
ImplicitTopLevelFolder : false ,
0 commit comments