Skip to content

Commit 7d2134f

Browse files
authored
Merge pull request #138 from mallardduck/charts-debug
2 parents cf096ea + d49d217 commit 7d2134f

File tree

3 files changed

+171
-1
lines changed

3 files changed

+171
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ dev/
1818
kubeconfig*.yaml
1919
get_helm.sh
2020
Dockerfile.dapper*
21-
!Dockerfile.dapper
21+
!Dockerfile.dapper
22+
/.debug

cmd/prometheus-federator/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
_ "net/http/pprof"
1010
"os"
1111

12+
"github.com/rancher/prometheus-federator/pkg/debug"
1213
"github.com/rancher/prometheus-federator/pkg/helm-project-operator/controllers/common"
1314
"github.com/rancher/prometheus-federator/pkg/helm-project-operator/operator"
1415
"github.com/rancher/prometheus-federator/pkg/version"
@@ -84,5 +85,6 @@ func main() {
8485
Version: version.FriendlyVersion(),
8586
})
8687
cmd = command.AddDebug(cmd, &debugConfig)
88+
cmd.AddCommand(debug.ChartDebugSubCommand(base64TgzChart))
8789
command.Main(cmd)
8890
}

pkg/debug/chart.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package debug
2+
3+
import (
4+
"archive/tar"
5+
"bytes"
6+
"compress/gzip"
7+
"encoding/base64"
8+
"fmt"
9+
"io"
10+
"os"
11+
"path/filepath"
12+
13+
"github.com/sirupsen/logrus"
14+
15+
"github.com/spf13/cobra"
16+
)
17+
18+
func ChartDebugSubCommand(base64ChartTarball string) *cobra.Command {
19+
var chartOnly bool
20+
chartDebug := &cobra.Command{
21+
Use: "debug-chart",
22+
Short: "This command helps debug the internal chart files",
23+
RunE: func(_ *cobra.Command, _ []string) error {
24+
if chartOnly {
25+
logrus.Info("Only the embedded chart's `Chart.yaml` will be exported.")
26+
} else {
27+
logrus.Info("The entire embedded chart wil be exported.")
28+
}
29+
30+
tarReader, err := readEmbeddedHelmChart(base64ChartTarball)
31+
if err != nil {
32+
return err
33+
}
34+
35+
// Extract files to the current working directory
36+
cwd, err := os.Getwd()
37+
if err != nil {
38+
return fmt.Errorf("error getting current working directory: %v", err)
39+
}
40+
debugDir := filepath.Join(cwd, ".debug")
41+
// Ensure the .debug directory exists
42+
if err := os.MkdirAll(debugDir, 0755); err != nil {
43+
return fmt.Errorf("error creating .debug directory: %v", err)
44+
}
45+
46+
err = extractChartData(tarReader, debugDir, chartOnly)
47+
if err != nil {
48+
return err
49+
}
50+
51+
logrus.Infof("Chart files successfully extracted to: %s", debugDir)
52+
return nil
53+
},
54+
}
55+
chartDebug.Flags().BoolVarP(&chartOnly, "chart-only", "C", false, "When set, only the `Chart.yaml` will be exported.")
56+
return chartDebug
57+
}
58+
59+
func readEmbeddedHelmChart(base64ChartTarball string) (*tar.Reader, error) {
60+
chartTarballData, err := base64.StdEncoding.DecodeString(base64ChartTarball)
61+
if err != nil {
62+
return nil, fmt.Errorf("error reading embedded chart data from base64: %v", err)
63+
}
64+
65+
gzipReader, err := gzip.NewReader(bytes.NewReader(chartTarballData))
66+
if err != nil {
67+
return nil, fmt.Errorf("error creating gzip reader: %v", err)
68+
}
69+
defer gzipReader.Close()
70+
71+
// Create a tar reader
72+
tarReader := tar.NewReader(gzipReader)
73+
return tarReader, nil
74+
}
75+
76+
func extractChartData(tarReader *tar.Reader, debugDir string, chartOnly bool) error {
77+
// Extract files to the .debug directory
78+
for {
79+
header, err := tarReader.Next()
80+
if err == io.EOF {
81+
// End of archive
82+
break
83+
}
84+
if err != nil {
85+
return fmt.Errorf("error reading tarball: %v", err)
86+
}
87+
88+
// Determine the path to extract the file to
89+
filePath := filepath.Join(debugDir, header.Name)
90+
91+
if chartOnly {
92+
err = extractChartYamlFile(tarReader, header, filePath)
93+
} else {
94+
err = extractAllChartData(tarReader, header, filePath)
95+
}
96+
97+
if err != nil {
98+
return err
99+
}
100+
}
101+
return nil
102+
}
103+
104+
func extractChartYamlFile(tarReader *tar.Reader, header *tar.Header, filePath string) error {
105+
switch header.Typeflag {
106+
case tar.TypeReg:
107+
if header.Name == "rancher-project-monitoring/Chart.yaml" {
108+
logrus.Info("Found a `Chart.yaml` file to export.")
109+
// Ensure the parent directory exists
110+
parentDir := filepath.Dir(filePath)
111+
if err := os.MkdirAll(parentDir, 0755); err != nil {
112+
return fmt.Errorf("error creating parent directory: %v", err)
113+
}
114+
115+
// Create regular file
116+
outFile, err := os.Create(filePath)
117+
if err != nil {
118+
return fmt.Errorf("error creating file: %v", err)
119+
}
120+
121+
// Copy file content
122+
if _, err := io.Copy(outFile, tarReader); err != nil {
123+
outFile.Close()
124+
return fmt.Errorf("error writing file content: %v", err)
125+
}
126+
logrus.Info("The `Chart.yaml` file was exported")
127+
outFile.Close()
128+
} else {
129+
logrus.Debugf("Skipping file: %s\n", header.Name)
130+
}
131+
default:
132+
logrus.Debugf("Skipping file: %s\n", header.Name)
133+
}
134+
return nil
135+
}
136+
137+
func extractAllChartData(tarReader *tar.Reader, header *tar.Header, filePath string) error {
138+
switch header.Typeflag {
139+
case tar.TypeDir:
140+
// Create directory
141+
if err := os.MkdirAll(filePath, os.FileMode(header.Mode)); err != nil {
142+
return fmt.Errorf("error creating directory: %v", err)
143+
}
144+
case tar.TypeReg:
145+
// Ensure the parent directory exists
146+
parentDir := filepath.Dir(filePath)
147+
if err := os.MkdirAll(parentDir, 0755); err != nil {
148+
return fmt.Errorf("error creating parent directory: %v", err)
149+
}
150+
151+
// Create regular file
152+
outFile, err := os.Create(filePath)
153+
if err != nil {
154+
return fmt.Errorf("error creating file: %v", err)
155+
}
156+
157+
// Copy file content
158+
if _, err := io.Copy(outFile, tarReader); err != nil {
159+
outFile.Close()
160+
return fmt.Errorf("error writing file content: %v", err)
161+
}
162+
outFile.Close()
163+
default:
164+
logrus.Debugf("Skipping unsupported file type: %s\n", header.Name)
165+
}
166+
return nil
167+
}

0 commit comments

Comments
 (0)