From 1593ecc76fa5c8aae976afb40ac805101ffa4304 Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 13 Dec 2024 00:09:46 -0700 Subject: [PATCH 1/5] feat: add images from helm chart template --- cmd/hauler/cli/store.go | 2 +- cmd/hauler/cli/store/add.go | 57 +++++++++++++++++++++++++----------- cmd/hauler/cli/store/sync.go | 3 +- internal/flags/add.go | 4 +++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/cmd/hauler/cli/store.go b/cmd/hauler/cli/store.go index 872769c4..576630e6 100644 --- a/cmd/hauler/cli/store.go +++ b/cmd/hauler/cli/store.go @@ -367,7 +367,7 @@ hauler store add chart rancher --repo https://releases.rancher.com/server-charts return err } - return store.AddChartCmd(ctx, o, s, args[0]) + return store.AddChartCmd(ctx, o, s, args[0], rso, ro) }, } o.AddFlags(cmd) diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index 1d6aed25..1c11f054 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -3,11 +3,14 @@ package store import ( "context" "os" + "slices" + "strings" "github.com/google/go-containerregistry/pkg/name" "hauler.dev/go/hauler/pkg/artifacts/file/getter" "hauler.dev/go/hauler/pkg/consts" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/engine" "hauler.dev/go/hauler/internal/flags" "hauler.dev/go/hauler/pkg/apis/hauler.cattle.io/v1alpha1" @@ -111,27 +114,16 @@ func storeImage(ctx context.Context, s *store.Layout, i v1alpha1.Image, platform return nil } -func AddChartCmd(ctx context.Context, o *flags.AddChartOpts, s *store.Layout, chartName string) error { - // TODO: Reduce duplicates between api chart and upstream helm opts - cfg := v1alpha1.Chart{ - Name: chartName, - RepoURL: o.ChartOpts.RepoURL, - Version: o.ChartOpts.Version, - } - - return storeChart(ctx, s, cfg, o.ChartOpts) +func AddChartCmd(ctx context.Context, o *flags.AddChartOpts, s *store.Layout, chartName string, rso *flags.StoreRootOpts, ro *flags.CliRootOpts) error { + return storeChart(ctx, s, chartName, o, rso, ro) } -func storeChart(ctx context.Context, s *store.Layout, cfg v1alpha1.Chart, opts *action.ChartPathOptions) error { +func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *flags.AddChartOpts, rso *flags.StoreRootOpts, ro *flags.CliRootOpts) error { l := log.FromContext(ctx) - l.Infof("adding 'chart' [%s] to the store", cfg.Name) - - // TODO: This shouldn't be necessary - opts.RepoURL = cfg.RepoURL - opts.Version = cfg.Version + l.Infof("adding 'chart' [%s] to the store", chartName) - chrt, err := chart.NewChart(cfg.Name, opts) + chrt, err := chart.NewChart(chartName, opts.ChartOpts) if err != nil { return err } @@ -151,5 +143,36 @@ func storeChart(ctx context.Context, s *store.Layout, cfg v1alpha1.Chart, opts * } l.Infof("successfully added 'chart' [%s]", ref.Name()) + + if opts.AddImages { + values, err := chartutil.ToRenderValues(c, c.Values, chartutil.ReleaseOptions{Namespace: "hauler"}, &chartutil.Capabilities{}) + if err != nil { + return err + } + + template, err := engine.Render(c, values) + if err != nil { + return err + } + + images := []string{} + + for _, manifest := range template { + m := strings.Split(manifest, "\n") + for _, l := range m { + l := strings.ReplaceAll(l, " ", "") + if strings.HasPrefix(l, "image:") { + images = append(images, l[6:]) + } + } + } + + slices.Sort(images) + images = slices.Compact(images) + for _, image := range images { + storeImage(ctx, s, v1alpha1.Image{Name: image}, "", rso, ro) + } + } + return nil } diff --git a/cmd/hauler/cli/store/sync.go b/cmd/hauler/cli/store/sync.go index 2505161a..ed0f77c1 100644 --- a/cmd/hauler/cli/store/sync.go +++ b/cmd/hauler/cli/store/sync.go @@ -204,7 +204,8 @@ func processContent(ctx context.Context, fi *os.File, o *flags.SyncOpts, s *stor for _, ch := range cfg.Spec.Charts { // TODO: Provide a way to configure syncs - err := storeChart(ctx, s, ch, &action.ChartPathOptions{}) + + err := storeChart(ctx, s, ch.Name, &flags.AddChartOpts{ChartOpts: &action.ChartPathOptions{RepoURL: ch.RepoURL, Version: ch.Version}}, rso, ro) if err != nil { return err } diff --git a/internal/flags/add.go b/internal/flags/add.go index feb43d13..dbdeaa54 100644 --- a/internal/flags/add.go +++ b/internal/flags/add.go @@ -32,6 +32,8 @@ type AddChartOpts struct { *StoreRootOpts ChartOpts *action.ChartPathOptions + + AddImages bool } func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { @@ -46,4 +48,6 @@ func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { f.StringVar(&o.ChartOpts.KeyFile, "key-file", "", "(Optional) Location of the TLS Key to use for client authenication") f.BoolVar(&o.ChartOpts.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "(Optional) Skip TLS certificate verification") f.StringVar(&o.ChartOpts.CaFile, "ca-file", "", "(Optional) Location of CA Bundle to enable certification verification") + + f.BoolVar(&o.AddImages, "add-images", false, "(Optional) Add images referenced in helm template") } From 8d561975e61d7ada39ba9bf5c134c893edf4ef51 Mon Sep 17 00:00:00 2001 From: Will Date: Sun, 15 Dec 2024 20:29:12 -0700 Subject: [PATCH 2/5] fix: remove quotes in image reference --- cmd/hauler/cli/store/add.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index 1c11f054..618de9eb 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -161,6 +161,7 @@ func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *fl m := strings.Split(manifest, "\n") for _, l := range m { l := strings.ReplaceAll(l, " ", "") + l = strings.ReplaceAll(l, "\"", "") if strings.HasPrefix(l, "image:") { images = append(images, l[6:]) } From 7428614d04f5afd91ff0a1fedea1c4f5b65b055e Mon Sep 17 00:00:00 2001 From: Will Date: Sun, 15 Dec 2024 20:58:16 -0700 Subject: [PATCH 3/5] fix: semverCompare call --- .gitignore | 1 + cmd/hauler/cli/store/add.go | 13 ++++++++++++- internal/flags/add.go | 5 ++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 82a28ddb..311ede5a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ fileserver/ cmd/hauler/binaries testdata/certs/ coverage.out +ebug diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index 618de9eb..869dbaf7 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -145,7 +145,18 @@ func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *fl l.Infof("successfully added 'chart' [%s]", ref.Name()) if opts.AddImages { - values, err := chartutil.ToRenderValues(c, c.Values, chartutil.ReleaseOptions{Namespace: "hauler"}, &chartutil.Capabilities{}) + if opts.HelmValues != "" { + values, err := chartutil.ReadValuesFile(opts.HelmValues) + if err != nil { + return err + } + c.Values = values + } + + // mock kubeversion? + kubeversion := chartutil.KubeVersion{Version: "1", Major: "31", Minor: "0"} + + values, err := chartutil.ToRenderValues(c, c.Values, chartutil.ReleaseOptions{Namespace: "hauler"}, &chartutil.Capabilities{KubeVersion: kubeversion}) if err != nil { return err } diff --git a/internal/flags/add.go b/internal/flags/add.go index dbdeaa54..ce262f84 100644 --- a/internal/flags/add.go +++ b/internal/flags/add.go @@ -33,7 +33,8 @@ type AddChartOpts struct { ChartOpts *action.ChartPathOptions - AddImages bool + AddImages bool + HelmValues string } func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { @@ -50,4 +51,6 @@ func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { f.StringVar(&o.ChartOpts.CaFile, "ca-file", "", "(Optional) Location of CA Bundle to enable certification verification") f.BoolVar(&o.AddImages, "add-images", false, "(Optional) Add images referenced in helm template") + f.StringVarP(&o.HelmValues, "values", "f", "", "(Optional) Specify values in a YAML file or a URL (can specify multiple)") + } From 55b6451b696443bbe02b5ebf3a4ba1c11bba43f0 Mon Sep 17 00:00:00 2001 From: Zack Brady Date: Tue, 17 Dec 2024 21:31:36 -0500 Subject: [PATCH 4/5] small updates to formatting/implementation --- cmd/hauler/cli/store/add.go | 9 ++++++--- internal/flags/add.go | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index 869dbaf7..f2a19253 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -153,10 +153,10 @@ func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *fl c.Values = values } - // mock kubeversion? - kubeversion := chartutil.KubeVersion{Version: "1", Major: "31", Minor: "0"} + kubeVersion := chartutil.KubeVersion{Version: "1", Major: "31", Minor: "3"} + l.Debugf("setting kubernetes version... [v%s.%s.%s]", kubeVersion.Version, kubeVersion.Major, kubeVersion.Minor) - values, err := chartutil.ToRenderValues(c, c.Values, chartutil.ReleaseOptions{Namespace: "hauler"}, &chartutil.Capabilities{KubeVersion: kubeversion}) + values, err := chartutil.ToRenderValues(c, c.Values, chartutil.ReleaseOptions{Namespace: "hauler"}, &chartutil.Capabilities{KubeVersion: kubeVersion}) if err != nil { return err } @@ -181,6 +181,9 @@ func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *fl slices.Sort(images) images = slices.Compact(images) + + l.Infof("successfully found images... %v", images) + for _, image := range images { storeImage(ctx, s, v1alpha1.Image{Name: image}, "", rso, ro) } diff --git a/internal/flags/add.go b/internal/flags/add.go index ce262f84..84b04550 100644 --- a/internal/flags/add.go +++ b/internal/flags/add.go @@ -50,7 +50,7 @@ func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { f.BoolVar(&o.ChartOpts.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "(Optional) Skip TLS certificate verification") f.StringVar(&o.ChartOpts.CaFile, "ca-file", "", "(Optional) Location of CA Bundle to enable certification verification") - f.BoolVar(&o.AddImages, "add-images", false, "(Optional) Add images referenced in helm template") - f.StringVarP(&o.HelmValues, "values", "f", "", "(Optional) Specify values in a YAML file or a URL (can specify multiple)") + f.BoolVar(&o.AddImages, "add-images", false, "(Optional) Fetch images referenced in a helm chart (tech preview)") + f.StringVar(&o.HelmValues, "values", "", "(Optional) Specify helm chart values when fetching images (tech preview)") } From 9630c7f46b6a224738f1e0b911c608668a9f6c8b Mon Sep 17 00:00:00 2001 From: Will Date: Wed, 15 Jan 2025 09:07:29 -0700 Subject: [PATCH 5/5] feat: add platform flag to helm add --- cmd/hauler/cli/store/add.go | 2 +- internal/flags/add.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index e8a138ee..56821a2c 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -187,7 +187,7 @@ func storeChart(ctx context.Context, s *store.Layout, chartName string, opts *fl l.Infof("successfully found images... %v", images) for _, image := range images { - storeImage(ctx, s, v1alpha1.Image{Name: image}, "", rso, ro) + storeImage(ctx, s, v1alpha1.Image{Name: image, Platform: opts.Platform}, "", rso, ro) } } diff --git a/internal/flags/add.go b/internal/flags/add.go index 84b04550..6911f28f 100644 --- a/internal/flags/add.go +++ b/internal/flags/add.go @@ -35,6 +35,7 @@ type AddChartOpts struct { AddImages bool HelmValues string + Platform string } func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { @@ -52,5 +53,5 @@ func (o *AddChartOpts) AddFlags(cmd *cobra.Command) { f.BoolVar(&o.AddImages, "add-images", false, "(Optional) Fetch images referenced in a helm chart (tech preview)") f.StringVar(&o.HelmValues, "values", "", "(Optional) Specify helm chart values when fetching images (tech preview)") - + f.StringVarP(&o.Platform, "platform", "p", "", "(Optional) Specifiy the platform of the image... i.e. linux/amd64 (defaults to all)") }