Skip to content

Commit 1446364

Browse files
authored
a function to get a pod details from the support bundle (#476)
* a function to get a pod details from the support bundle
1 parent 45dd980 commit 1446364

File tree

4 files changed

+184
-0
lines changed

4 files changed

+184
-0
lines changed

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ require (
8181
github.com/docker/go-connections v0.4.0 // indirect
8282
github.com/docker/go-metrics v0.0.1 // indirect
8383
github.com/docker/go-units v0.4.0 // indirect
84+
github.com/dsnet/compress v0.0.1 // indirect
8485
github.com/evanphx/json-patch v4.11.0+incompatible // indirect
8586
github.com/felixge/httpsnoop v1.0.1 // indirect
8687
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
@@ -96,6 +97,7 @@ require (
9697
github.com/gogo/protobuf v1.3.2 // indirect
9798
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
9899
github.com/golang/protobuf v1.5.2 // indirect
100+
github.com/golang/snappy v0.0.4 // indirect
99101
github.com/google/btree v1.0.1 // indirect
100102
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
101103
github.com/google/uuid v1.1.2 // indirect
@@ -124,6 +126,7 @@ require (
124126
github.com/mattn/go-runewidth v0.0.9 // indirect
125127
github.com/mattn/go-shellwords v1.0.10 // indirect
126128
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
129+
github.com/mholt/archiver v3.1.1+incompatible // indirect
127130
github.com/mistifyio/go-zfs v2.1.1+incompatible // indirect
128131
github.com/mitchellh/go-homedir v1.1.0 // indirect
129132
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
@@ -135,6 +138,7 @@ require (
135138
github.com/modern-go/reflect2 v1.0.1 // indirect
136139
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
137140
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d // indirect
141+
github.com/nwaples/rardecode v1.1.2 // indirect
138142
github.com/onsi/ginkgo v1.16.4 // indirect
139143
github.com/opencontainers/go-digest v1.0.0 // indirect
140144
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 // indirect
@@ -144,6 +148,7 @@ require (
144148
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 // indirect
145149
github.com/pelletier/go-toml v1.9.3 // indirect
146150
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
151+
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
147152
github.com/pmezard/go-difflib v1.0.0 // indirect
148153
github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9 // indirect
149154
github.com/prometheus/client_golang v1.11.0 // indirect
@@ -159,6 +164,7 @@ require (
159164
github.com/ulikunitz/xz v0.5.9 // indirect
160165
github.com/vbatts/tar-split v0.11.1 // indirect
161166
github.com/willf/bitset v1.1.11 // indirect
167+
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
162168
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
163169
go.opencensus.io v0.23.0 // indirect
164170
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU
223223
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
224224
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
225225
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
226+
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
227+
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
228+
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
226229
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
227230
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
228231
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -389,6 +392,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
389392
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
390393
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
391394
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
395+
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
396+
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
392397
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
393398
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
394399
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
@@ -533,9 +538,11 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
533538
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
534539
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
535540
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
541+
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
536542
github.com/klauspost/compress v1.11.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
537543
github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=
538544
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
545+
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
539546
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
540547
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
541548
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -591,6 +598,8 @@ github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL
591598
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
592599
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
593600
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
601+
github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
602+
github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
594603
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
595604
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
596605
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
@@ -639,6 +648,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
639648
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
640649
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
641650
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
651+
github.com/nwaples/rardecode v1.1.2 h1:Cj0yZY6T1Zx1R7AhTbyGSALm44/Mmq+BAPc4B/p/d3M=
652+
github.com/nwaples/rardecode v1.1.2/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
642653
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
643654
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
644655
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@@ -687,6 +698,8 @@ github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5d
687698
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
688699
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
689700
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
701+
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
702+
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
690703
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
691704
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
692705
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -842,6 +855,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
842855
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
843856
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
844857
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
858+
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
845859
github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I=
846860
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
847861
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -859,6 +873,8 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
859873
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
860874
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
861875
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
876+
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
877+
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
862878
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
863879
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
864880
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=

pkg/supportbundle/parse.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package supportbundle
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
9+
"regexp"
10+
"strings"
11+
12+
"github.com/mholt/archiver"
13+
"github.com/pkg/errors"
14+
types "github.com/replicatedhq/troubleshoot/pkg/supportbundle/types"
15+
corev1 "k8s.io/api/core/v1"
16+
)
17+
18+
var (
19+
SupportBundleNameRegex = regexp.MustCompile(`^\/?support-bundle-(\d{4})-(\d{2})-(\d{2})T(\d{2})_(\d{2})_(\d{2})\/?`)
20+
)
21+
22+
func GetPodDetails(bundleArchive string, podNamespace string, podName string) (*types.PodDetails, error) {
23+
podDetails := types.PodDetails{}
24+
25+
nsPodsFilePath := filepath.Join("cluster-resources", "pods", fmt.Sprintf("%s.json", podNamespace))
26+
nsEventsFilePath := filepath.Join("cluster-resources", "events", fmt.Sprintf("%s.json", podNamespace))
27+
28+
files, err := GetFilesContents(bundleArchive, []string{nsPodsFilePath, nsEventsFilePath})
29+
if err != nil {
30+
return nil, errors.Wrap(err, "failed to get files contents")
31+
}
32+
33+
var nsEvents []corev1.Event
34+
if err := json.Unmarshal(files[nsEventsFilePath], &nsEvents); err != nil {
35+
return nil, errors.Wrap(err, "failed to unmarshal events")
36+
}
37+
podEvents := []corev1.Event{}
38+
for _, event := range nsEvents {
39+
if event.InvolvedObject.Kind == "Pod" && event.InvolvedObject.Name == podName && event.InvolvedObject.Namespace == podNamespace {
40+
podEvents = append(podEvents, event)
41+
}
42+
}
43+
podDetails.PodEvents = podEvents
44+
45+
var podsArr []corev1.Pod
46+
if err := json.Unmarshal(files[nsPodsFilePath], &podsArr); err != nil {
47+
return nil, errors.Wrap(err, "failed to unmarshal pods")
48+
}
49+
for _, pod := range podsArr {
50+
if pod.Name == podName && pod.Namespace == podNamespace {
51+
podDetails.PodDefinition = pod
52+
podDetails.PodContainers = []types.PodContainer{}
53+
for _, i := range pod.Spec.InitContainers {
54+
podDetails.PodContainers = append(podDetails.PodContainers, types.PodContainer{
55+
Name: i.Name,
56+
LogsFilePath: filepath.Join("cluster-resources", "pods", "logs", pod.Namespace, pod.Name, fmt.Sprintf("%s.log", i.Name)),
57+
IsInitContainer: true,
58+
})
59+
}
60+
for _, c := range pod.Spec.Containers {
61+
podDetails.PodContainers = append(podDetails.PodContainers, types.PodContainer{
62+
Name: c.Name,
63+
LogsFilePath: filepath.Join("cluster-resources", "pods", "logs", pod.Namespace, pod.Name, fmt.Sprintf("%s.log", c.Name)),
64+
IsInitContainer: false,
65+
})
66+
}
67+
break
68+
}
69+
}
70+
71+
return &podDetails, nil
72+
}
73+
74+
// GetFilesContents will return the file contents for filenames matching the filenames parameter.
75+
func GetFilesContents(bundleArchive string, filenames []string) (map[string][]byte, error) {
76+
bundleDir, err := ioutil.TempDir("", "troubleshoot")
77+
if err != nil {
78+
return nil, errors.Wrap(err, "failed to create tmp dir")
79+
}
80+
defer os.RemoveAll(bundleDir)
81+
82+
tarGz := archiver.TarGz{
83+
Tar: &archiver.Tar{
84+
ImplicitTopLevelFolder: false,
85+
},
86+
}
87+
if err := tarGz.Unarchive(bundleArchive, bundleDir); err != nil {
88+
return nil, errors.Wrap(err, "failed to unarchive")
89+
}
90+
91+
files := map[string][]byte{}
92+
err = filepath.Walk(bundleDir, func(path string, info os.FileInfo, err error) error {
93+
if err != nil {
94+
return err
95+
}
96+
97+
if len(path) <= len(bundleDir) {
98+
return nil
99+
}
100+
101+
if info.IsDir() {
102+
return nil
103+
}
104+
105+
// the following tries to find the actual file path of the desired files in the support bundle
106+
// this is needed to handle old and new support bundle formats
107+
// where old support bundles don't include a top level subdirectory and the new ones do
108+
// this basically compares file paths after trimming the subdirectory path from both (if exists)
109+
// for example: "support-bundle-2021-09-10T18_50_35/support-bundle-2021-09-10T18_50_35/path/to/file"
110+
relPath, err := filepath.Rel(bundleDir, path) // becomes: "support-bundle-2021-09-10T18_50_35/path/to/file"
111+
if err != nil {
112+
return errors.Wrap(err, "failed to get relative path")
113+
}
114+
115+
trimmedRelPath := SupportBundleNameRegex.ReplaceAllString(relPath, "") // becomes: "path/to/file"
116+
trimmedRelPath = strings.TrimPrefix(trimmedRelPath, string(os.PathSeparator)) // extra measure to ensure no leading slashes. for example: "/path/to/file"
117+
if trimmedRelPath == "" {
118+
return nil
119+
}
120+
121+
for _, filename := range filenames {
122+
trimmedFileName := SupportBundleNameRegex.ReplaceAllString(filename, "")
123+
trimmedFileName = strings.TrimPrefix(trimmedFileName, string(os.PathSeparator))
124+
if trimmedFileName == "" {
125+
continue
126+
}
127+
if trimmedRelPath == trimmedFileName {
128+
content, err := ioutil.ReadFile(path)
129+
if err != nil {
130+
return errors.Wrap(err, "failed to read file")
131+
}
132+
133+
files[filename] = content
134+
return nil
135+
}
136+
}
137+
138+
return nil
139+
})
140+
if err != nil {
141+
return nil, errors.Wrap(err, "failed to walk")
142+
}
143+
144+
return files, nil
145+
}

pkg/supportbundle/types/types.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package types
2+
3+
import (
4+
corev1 "k8s.io/api/core/v1"
5+
)
6+
7+
type PodDetails struct {
8+
PodDefinition corev1.Pod `json:"podDefinition"`
9+
PodEvents []corev1.Event `json:"podEvents"`
10+
PodContainers []PodContainer `json:"podContainers"`
11+
}
12+
13+
type PodContainer struct {
14+
Name string `json:"name"`
15+
LogsFilePath string `json:"logsFilePath"`
16+
IsInitContainer bool `json:"isInitContainer"`
17+
}

0 commit comments

Comments
 (0)