diff --git a/Taskfile.yml b/Taskfile.yml index e9d44c23e..f62112f68 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -18,13 +18,6 @@ tasks: - golangci-lint run ./... - helm lint helm/pv-migrate - update-chart: - desc: update the helm chart - cmds: - - helm-docs -c helm/pv-migrate/ - - helm package helm/pv-migrate/ - - mv pv-migrate-*.tgz migrator/helm-chart.tgz - clean: desc: clean cmds: diff --git a/helm/helm.go b/helm/helm.go new file mode 100644 index 000000000..c70845f05 --- /dev/null +++ b/helm/helm.go @@ -0,0 +1,73 @@ +package helm + +import ( + "embed" + "fmt" + "io/fs" + "path/filepath" + + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/chart/loader" +) + +// chartFS is the embedded Helm chart. +// +// Note: The prefix "all:" is important here, as otherwise the files starting with "." or "_" will be ignored. +// +// See: https://github.com/golang/go/issues/44393 +// +//go:embed all:pv-migrate +var chartFS embed.FS + +const rootDir = "pv-migrate" + +// LoadChart loads the embedded Helm chart. +func LoadChart() (*chart.Chart, error) { + files, err := chartAsBufferedFiles() + if err != nil { + return nil, fmt.Errorf("failed to get chart files: %w", err) + } + + helmChart, err := loader.LoadFiles(files) + if err != nil { + return nil, fmt.Errorf("failed to load chart: %w", err) + } + + return helmChart, nil +} + +func chartAsBufferedFiles() ([]*loader.BufferedFile, error) { + var files []*loader.BufferedFile + + err := fs.WalkDir(chartFS, rootDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + data, err := chartFS.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read file %q in chart: %w", path, err) + } + + relativePath, err := filepath.Rel(rootDir, path) + if err != nil { + return fmt.Errorf("failed to relativize path %q: %w", path, err) + } + + files = append(files, &loader.BufferedFile{ + Name: relativePath, + Data: data, + }) + + return nil + }) + if err != nil { + return nil, fmt.Errorf("failed to walk chart directory: %w", err) + } + + return files, nil +} diff --git a/helm/helm_test.go b/helm/helm_test.go new file mode 100644 index 000000000..8368067a7 --- /dev/null +++ b/helm/helm_test.go @@ -0,0 +1,22 @@ +package helm_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/utkuozdemir/pv-migrate/helm" +) + +func TestLoadChart(t *testing.T) { + t.Parallel() + + chart, err := helm.LoadChart() + require.NoError(t, err) + + assert.Equal(t, "pv-migrate", chart.Metadata.Name) + assert.NotEmpty(t, chart.Metadata.Version, "chart version should not be empty") + assert.NotEmpty(t, chart.Values, "chart values should not be empty") + assert.NotEmpty(t, chart.Templates, "chart templates should not be empty") +} diff --git a/migrator/helm-chart.tgz b/migrator/helm-chart.tgz deleted file mode 100644 index 63468afca..000000000 Binary files a/migrator/helm-chart.tgz and /dev/null differ diff --git a/migrator/migrator.go b/migrator/migrator.go index 720f494db..a84c0d9bf 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -1,16 +1,14 @@ package migrator import ( - "bytes" "context" - _ "embed" // we embed the helm chart "errors" "fmt" "strings" log "github.com/sirupsen/logrus" - "helm.sh/helm/v3/pkg/chart/loader" + "github.com/utkuozdemir/pv-migrate/helm" "github.com/utkuozdemir/pv-migrate/k8s" "github.com/utkuozdemir/pv-migrate/migration" "github.com/utkuozdemir/pv-migrate/pvc" @@ -18,9 +16,6 @@ import ( "github.com/utkuozdemir/pv-migrate/util" ) -//go:embed helm-chart.tgz -var chartBytes []byte - const ( attemptIDLength = 5 ) @@ -97,7 +92,7 @@ func (m *Migrator) Run(ctx context.Context, request *migration.Request) error { } func (m *Migrator) buildMigration(ctx context.Context, request *migration.Request) (*migration.Migration, error) { - chart, err := loader.LoadArchive(bytes.NewReader(chartBytes)) + chart, err := helm.LoadChart() if err != nil { return nil, fmt.Errorf("failed to load helm chart: %w", err) }