11package cli
22
33import (
4- "bytes"
5- "context"
64 "encoding/base64"
75 "encoding/json"
86 "fmt"
9- "io"
107 "io/ioutil"
118 "net/http"
129 "os"
@@ -18,22 +15,11 @@ import (
1815 "github.com/pkg/errors"
1916 analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
2017 troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
21- collectrunner "github.com/replicatedhq/troubleshoot/pkg/collect"
18+ "github.com/replicatedhq/troubleshoot/pkg/collect"
2219 "github.com/replicatedhq/troubleshoot/pkg/logger"
2320 "github.com/spf13/viper"
2421 "github.com/tj/go-spin"
2522 "gopkg.in/yaml.v2"
26- corev1 "k8s.io/api/core/v1"
27- kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
28- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29- "k8s.io/apimachinery/pkg/fields"
30- "k8s.io/apimachinery/pkg/runtime"
31- "k8s.io/apimachinery/pkg/runtime/schema"
32- types "k8s.io/apimachinery/pkg/types"
33- "k8s.io/client-go/kubernetes"
34- "k8s.io/client-go/tools/cache"
35- "sigs.k8s.io/controller-runtime/pkg/client"
36- "sigs.k8s.io/controller-runtime/pkg/client/config"
3723)
3824
3925func runPreflightsNoCRD (v * viper.Viper , arg string ) error {
@@ -143,174 +129,36 @@ func runPreflightsNoCRD(v *viper.Viper, arg string) error {
143129}
144130
145131func runCollectors (v * viper.Viper , preflight troubleshootv1beta1.Preflight ) (map [string ][]byte , error ) {
146- cfg , err := config .GetConfig ()
147- if err != nil {
148- return nil , err
149- }
150-
151- client , err := client .New (cfg , client.Options {})
152- if err != nil {
153- return nil , err
154- }
155- clientset , err := kubernetes .NewForConfig (cfg )
156- if err != nil {
157- return nil , err
158- }
159- restClient := clientset .CoreV1 ().RESTClient ()
160-
161- serviceAccountName := v .GetString ("serviceaccount" )
162- if serviceAccountName == "" {
163- generatedServiceAccountName , err := createServiceAccount (preflight , v .GetString ("namespace" ), clientset )
164- if err != nil {
165- return nil , err
166- }
167- defer removeServiceAccount (generatedServiceAccountName , v .GetString ("namespace" ), clientset )
168-
169- serviceAccountName = generatedServiceAccountName
170- }
171-
172- // deploy an object that "owns" everything to aid in cleanup
173- configMapNamespacedName := types.NamespacedName {
174- Name : fmt .Sprintf ("preflight-%s-owner" , preflight .Name ),
175- Namespace : v .GetString ("namespace" ),
176- }
177-
178- foundConfigMap := & corev1.ConfigMap {}
179- err = client .Get (context .Background (), configMapNamespacedName , foundConfigMap )
180- if err == nil || ! kuberneteserrors .IsNotFound (err ) {
181- return nil , errors .Wrap (err , "failed to get existing config map" )
182- }
183- owner := corev1.ConfigMap {
184- ObjectMeta : metav1.ObjectMeta {
185- Name : configMapNamespacedName .Name ,
186- Namespace : configMapNamespacedName .Namespace ,
187- },
188- TypeMeta : metav1.TypeMeta {
189- APIVersion : "v1" ,
190- Kind : "ConfigMap" ,
191- },
192- Data : make (map [string ]string ),
193- }
194- if err := client .Create (context .Background (), & owner ); err != nil {
195- return nil , errors .Wrap (err , "failed to create config map" )
196- }
197- defer func () {
198- if err := client .Delete (context .Background (), & owner ); err != nil {
199- fmt .Println ("failed to clean up preflight." )
200- }
201- }()
202-
203- // deploy all collectors
204132 desiredCollectors := make ([]* troubleshootv1beta1.Collect , 0 , 0 )
205133 for _ , definedCollector := range preflight .Spec .Collectors {
206134 desiredCollectors = append (desiredCollectors , definedCollector )
207135 }
208136 desiredCollectors = ensureCollectorInList (desiredCollectors , troubleshootv1beta1.Collect {ClusterInfo : & troubleshootv1beta1.ClusterInfo {}})
209137 desiredCollectors = ensureCollectorInList (desiredCollectors , troubleshootv1beta1.Collect {ClusterResources : & troubleshootv1beta1.ClusterResources {}})
210138
211- podsCreated := make ([]* corev1.Pod , 0 , 0 )
212- podsDeleted := make ([]* corev1.Pod , 0 , 0 )
213139 allCollectedData := make (map [string ][]byte )
214140
215- resyncPeriod := time .Second
216- ctx := context .Background ()
217- watchList := cache .NewListWatchFromClient (restClient , "pods" , "" , fields .Everything ())
218- _ , controller := cache .NewInformer (watchList , & corev1.Pod {}, resyncPeriod ,
219- cache.ResourceEventHandlerFuncs {
220- UpdateFunc : func (oldObj interface {}, newObj interface {}) {
221- newPod , ok := newObj .(* corev1.Pod )
222- if ! ok {
223- return
224- }
225- oldPod , ok := oldObj .(* corev1.Pod )
226- if ! ok {
227- return
228- }
229- labels := newPod .Labels
230- troubleshootRole , ok := labels ["troubleshoot-role" ]
231- if ! ok || troubleshootRole != "preflight" {
232- return
233- }
234- preflightName , ok := labels ["preflight" ]
235- if ! ok || preflightName != preflight .Name {
236- return
237- }
238-
239- if oldPod .Status .Phase == newPod .Status .Phase {
240- return
241- }
242-
243- if newPod .Status .Phase == corev1 .PodFailed {
244- podsDeleted = append (podsDeleted , newPod )
245- return
246- }
247-
248- if newPod .Status .Phase != corev1 .PodSucceeded {
249- return
250- }
251-
252- podLogOpts := corev1.PodLogOptions {}
253-
254- req := clientset .CoreV1 ().Pods (newPod .Namespace ).GetLogs (newPod .Name , & podLogOpts )
255- podLogs , err := req .Stream ()
256- if err != nil {
257- fmt .Println ("get stream" )
258- return
259- }
260- defer podLogs .Close ()
261-
262- buf := new (bytes.Buffer )
263- _ , err = io .Copy (buf , podLogs )
264- if err != nil {
265- fmt .Println ("copy logs" )
266- return
267- }
268-
269- collectedData , err := parseCollectorOutput (buf .String ())
270- if err != nil {
271- logger .Printf ("parse collected data: %v\n " , err )
272- return
273- }
274- for k , v := range collectedData {
275- allCollectedData [k ] = v
276- }
277-
278- if err := client .Delete (context .Background (), newPod ); err != nil {
279- fmt .Println ("delete pod" )
280- }
281- podsDeleted = append (podsDeleted , newPod )
282- },
283- })
284- go func () {
285- controller .Run (ctx .Done ())
286- }()
141+ // Run preflights collectors synchronously
142+ for _ , desiredCollector := range desiredCollectors {
143+ collector := collect.Collector {
144+ Redact : true ,
145+ Collect : desiredCollector ,
146+ }
287147
288- s := runtime .NewScheme ()
289- s .AddKnownTypes (schema.GroupVersion {Group : "" , Version : "v1" }, & corev1.ConfigMap {})
290- for _ , collector := range desiredCollectors {
291- _ , pod , err := collectrunner .CreateCollector (client , s , & owner , preflight .Name , v .GetString ("namespace" ), serviceAccountName , "preflight" , collector , v .GetString ("image" ), v .GetString ("pullpolicy" ))
148+ result , err := collector .RunCollectorSync ()
292149 if err != nil {
293- return nil , errors .Wrap (err , "failed to create collector" )
150+ return nil , errors .Wrap (err , "failed to run collector" )
294151 }
295- podsCreated = append (podsCreated , pod )
296- }
297152
298- start := time .Now ()
299- for {
300- if start .Add (time .Second * 30 ).Before (time .Now ()) {
301- fmt .Println ("timeout running preflight" )
302- return nil , err
153+ output , err := parseCollectorOutput (string (result ))
154+ if err != nil {
155+ return nil , errors .Wrap (err , "failed to parse collector output" )
303156 }
304-
305- if len (podsDeleted ) == len (podsCreated ) {
306- break
157+ for k , v := range output {
158+ allCollectedData [k ] = v
307159 }
308-
309- time .Sleep (time .Millisecond * 200 )
310160 }
311161
312- ctx .Done ()
313-
314162 return allCollectedData , nil
315163}
316164
0 commit comments