Skip to content

Commit c6da43b

Browse files
committed
Run in the CLI, not in the cluster
1 parent 4d61c49 commit c6da43b

File tree

1 file changed

+20
-165
lines changed

1 file changed

+20
-165
lines changed

cmd/troubleshoot/cli/run_nocrd.go

Lines changed: 20 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package cli
22

33
import (
4-
"bytes"
5-
"context"
64
"encoding/base64"
75
"encoding/json"
86
"fmt"
9-
"io"
107
"io/ioutil"
118
"net/http"
129
"os"
@@ -16,20 +13,10 @@ import (
1613
"github.com/ahmetalpbalkan/go-cursor"
1714
"github.com/mholt/archiver"
1815
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"
2117
"github.com/spf13/viper"
2218
"github.com/tj/go-spin"
2319
"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"
3320
)
3421

3522
func runTroubleshootNoCRD(v *viper.Viper, arg string) error {
@@ -119,185 +106,53 @@ the %s Admin Console to begin analysis.`
119106
}
120107

121108
func runCollectors(v *viper.Viper, collector troubleshootv1beta1.Collector, progressChan chan string) (string, error) {
122-
cfg, err := config.GetConfig()
109+
bundlePath, err := ioutil.TempDir("", "troubleshoot")
123110
if err != nil {
124111
return "", err
125112
}
113+
defer os.RemoveAll(bundlePath)
126114

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)
132116
if err != nil {
133117
return "", err
134118
}
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-
}
147119

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
170120
desiredCollectors := make([]*troubleshootv1beta1.Collect, 0, 0)
171121
for _, definedCollector := range collector.Spec {
172122
desiredCollectors = append(desiredCollectors, definedCollector)
173123
}
174124
desiredCollectors = ensureCollectorInList(desiredCollectors, troubleshootv1beta1.Collect{ClusterInfo: &troubleshootv1beta1.ClusterInfo{}})
175125
desiredCollectors = ensureCollectorInList(desiredCollectors, troubleshootv1beta1.Collect{ClusterResources: &troubleshootv1beta1.ClusterResources{}})
176126

177-
podsCreated := make([]*corev1.Pod, 0, 0)
178-
podsDeleted := make([]*corev1.Pod, 0, 0)
179-
180127
collectorDirs := []string{}
181128

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+
}
273135

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()
278137
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)
280139
continue
281140
}
282-
podsCreated = append(podsCreated, pod)
283-
}
284141

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
290146
}
291147

292-
if len(podsDeleted) == len(podsCreated) {
293-
break
148+
if collectorDir == "" {
149+
continue
294150
}
295151

296-
time.Sleep(time.Millisecond * 200)
152+
progressChan <- collectorDir
153+
collectorDirs = append(collectorDirs, collectorDir)
297154
}
298155

299-
ctx.Done()
300-
301156
tarGz := archiver.TarGz{
302157
Tar: &archiver.Tar{
303158
ImplicitTopLevelFolder: false,

0 commit comments

Comments
 (0)