Skip to content

Commit

Permalink
Merge pull request #138 from mallardduck/charts-debug
Browse files Browse the repository at this point in the history
  • Loading branch information
mallardduck authored Dec 20, 2024
2 parents cf096ea + d49d217 commit 7d2134f
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ dev/
kubeconfig*.yaml
get_helm.sh
Dockerfile.dapper*
!Dockerfile.dapper
!Dockerfile.dapper
/.debug
2 changes: 2 additions & 0 deletions cmd/prometheus-federator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
_ "net/http/pprof"
"os"

"github.com/rancher/prometheus-federator/pkg/debug"
"github.com/rancher/prometheus-federator/pkg/helm-project-operator/controllers/common"
"github.com/rancher/prometheus-federator/pkg/helm-project-operator/operator"
"github.com/rancher/prometheus-federator/pkg/version"
Expand Down Expand Up @@ -84,5 +85,6 @@ func main() {
Version: version.FriendlyVersion(),
})
cmd = command.AddDebug(cmd, &debugConfig)
cmd.AddCommand(debug.ChartDebugSubCommand(base64TgzChart))
command.Main(cmd)
}
167 changes: 167 additions & 0 deletions pkg/debug/chart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package debug

import (
"archive/tar"
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"io"
"os"
"path/filepath"

"github.com/sirupsen/logrus"

"github.com/spf13/cobra"
)

func ChartDebugSubCommand(base64ChartTarball string) *cobra.Command {
var chartOnly bool
chartDebug := &cobra.Command{
Use: "debug-chart",
Short: "This command helps debug the internal chart files",
RunE: func(_ *cobra.Command, _ []string) error {
if chartOnly {
logrus.Info("Only the embedded chart's `Chart.yaml` will be exported.")
} else {
logrus.Info("The entire embedded chart wil be exported.")
}

tarReader, err := readEmbeddedHelmChart(base64ChartTarball)
if err != nil {
return err
}

// Extract files to the current working directory
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting current working directory: %v", err)
}
debugDir := filepath.Join(cwd, ".debug")
// Ensure the .debug directory exists
if err := os.MkdirAll(debugDir, 0755); err != nil {
return fmt.Errorf("error creating .debug directory: %v", err)
}

err = extractChartData(tarReader, debugDir, chartOnly)
if err != nil {
return err
}

logrus.Infof("Chart files successfully extracted to: %s", debugDir)
return nil
},
}
chartDebug.Flags().BoolVarP(&chartOnly, "chart-only", "C", false, "When set, only the `Chart.yaml` will be exported.")
return chartDebug
}

func readEmbeddedHelmChart(base64ChartTarball string) (*tar.Reader, error) {
chartTarballData, err := base64.StdEncoding.DecodeString(base64ChartTarball)
if err != nil {
return nil, fmt.Errorf("error reading embedded chart data from base64: %v", err)
}

gzipReader, err := gzip.NewReader(bytes.NewReader(chartTarballData))
if err != nil {
return nil, fmt.Errorf("error creating gzip reader: %v", err)
}
defer gzipReader.Close()

// Create a tar reader
tarReader := tar.NewReader(gzipReader)
return tarReader, nil
}

func extractChartData(tarReader *tar.Reader, debugDir string, chartOnly bool) error {
// Extract files to the .debug directory
for {
header, err := tarReader.Next()
if err == io.EOF {
// End of archive
break
}
if err != nil {
return fmt.Errorf("error reading tarball: %v", err)
}

// Determine the path to extract the file to
filePath := filepath.Join(debugDir, header.Name)

if chartOnly {
err = extractChartYamlFile(tarReader, header, filePath)
} else {
err = extractAllChartData(tarReader, header, filePath)
}

if err != nil {
return err
}
}
return nil
}

func extractChartYamlFile(tarReader *tar.Reader, header *tar.Header, filePath string) error {
switch header.Typeflag {
case tar.TypeReg:
if header.Name == "rancher-project-monitoring/Chart.yaml" {
logrus.Info("Found a `Chart.yaml` file to export.")
// Ensure the parent directory exists
parentDir := filepath.Dir(filePath)
if err := os.MkdirAll(parentDir, 0755); err != nil {
return fmt.Errorf("error creating parent directory: %v", err)
}

// Create regular file
outFile, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("error creating file: %v", err)
}

// Copy file content
if _, err := io.Copy(outFile, tarReader); err != nil {
outFile.Close()
return fmt.Errorf("error writing file content: %v", err)
}
logrus.Info("The `Chart.yaml` file was exported")
outFile.Close()
} else {
logrus.Debugf("Skipping file: %s\n", header.Name)
}
default:
logrus.Debugf("Skipping file: %s\n", header.Name)
}
return nil
}

func extractAllChartData(tarReader *tar.Reader, header *tar.Header, filePath string) error {
switch header.Typeflag {
case tar.TypeDir:
// Create directory
if err := os.MkdirAll(filePath, os.FileMode(header.Mode)); err != nil {
return fmt.Errorf("error creating directory: %v", err)
}
case tar.TypeReg:
// Ensure the parent directory exists
parentDir := filepath.Dir(filePath)
if err := os.MkdirAll(parentDir, 0755); err != nil {
return fmt.Errorf("error creating parent directory: %v", err)
}

// Create regular file
outFile, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("error creating file: %v", err)
}

// Copy file content
if _, err := io.Copy(outFile, tarReader); err != nil {
outFile.Close()
return fmt.Errorf("error writing file content: %v", err)
}
outFile.Close()
default:
logrus.Debugf("Skipping unsupported file type: %s\n", header.Name)
}
return nil
}

0 comments on commit 7d2134f

Please sign in to comment.