From 342dd95347d3a87c17924b237c674a231657f16c Mon Sep 17 00:00:00 2001 From: Diogo Souza Date: Fri, 12 Jan 2024 18:47:22 -0300 Subject: [PATCH] downloading icons when running make charts --- main.go | 6 ++++- pkg/charts/additionalchart.go | 4 ++-- pkg/charts/chart.go | 4 ++-- pkg/charts/package.go | 6 ++--- pkg/helm/export.go | 28 +++++++++++++++++++++- pkg/icons/icons.go | 45 +++++++++++++++++++++++++++++++++++ pkg/path/path.go | 3 +++ 7 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 pkg/icons/icons.go diff --git a/main.go b/main.go index 2b1abbd4..f3006573 100644 --- a/main.go +++ b/main.go @@ -290,9 +290,13 @@ func generateCharts(c *cli.Context) { logrus.Infof("No packages found.") return } + validateOnly := false + if c.Command.Name == "validate" { + validateOnly = true + } chartsScriptOptions := parseScriptOptions() for _, p := range packages { - if err := p.GenerateCharts(chartsScriptOptions.OmitBuildMetadataOnExport); err != nil { + if err := p.GenerateCharts(chartsScriptOptions.OmitBuildMetadataOnExport, validateOnly); err != nil { logrus.Fatal(err) } } diff --git a/pkg/charts/additionalchart.go b/pkg/charts/additionalchart.go index f103a7e5..ffec5697 100644 --- a/pkg/charts/additionalchart.go +++ b/pkg/charts/additionalchart.go @@ -214,11 +214,11 @@ func (c *AdditionalChart) GeneratePatch(rootFs, pkgFs billy.Filesystem) error { } // GenerateChart generates the chart and stores it in the assets and charts directory -func (c *AdditionalChart) GenerateChart(rootFs, pkgFs billy.Filesystem, packageVersion *int, version *semver.Version, omitBuildMetadataOnExport bool) error { +func (c *AdditionalChart) GenerateChart(rootFs, pkgFs billy.Filesystem, packageVersion *int, version *semver.Version, omitBuildMetadataOnExport, validateOnly bool) error { if c.upstreamChartVersion == nil { return fmt.Errorf("cannot generate chart since it has never been prepared: upstreamChartVersion is not set") } - if err := helm.ExportHelmChart(rootFs, pkgFs, c.WorkingDir, packageVersion, version, *c.upstreamChartVersion, omitBuildMetadataOnExport); err != nil { + if err := helm.ExportHelmChart(rootFs, pkgFs, c.WorkingDir, packageVersion, version, *c.upstreamChartVersion, omitBuildMetadataOnExport, validateOnly); err != nil { return fmt.Errorf("encountered error while trying to export Helm chart for %s: %s", c.WorkingDir, err) } return nil diff --git a/pkg/charts/chart.go b/pkg/charts/chart.go index 54321f92..3a10ee65 100644 --- a/pkg/charts/chart.go +++ b/pkg/charts/chart.go @@ -103,11 +103,11 @@ func (c *Chart) GeneratePatch(rootFs, pkgFs billy.Filesystem) error { } // GenerateChart generates the chart and stores it in the assets and charts directory -func (c *Chart) GenerateChart(rootFs, pkgFs billy.Filesystem, packageVersion *int, version *semver.Version, omitBuildMetadataOnExport bool) error { +func (c *Chart) GenerateChart(rootFs, pkgFs billy.Filesystem, packageVersion *int, version *semver.Version, omitBuildMetadataOnExport, validateOnly bool) error { if c.upstreamChartVersion == nil { return fmt.Errorf("cannot generate chart since it has never been prepared: upstreamChartVersion is not set") } - if err := helm.ExportHelmChart(rootFs, pkgFs, c.WorkingDir, packageVersion, version, *c.upstreamChartVersion, omitBuildMetadataOnExport); err != nil { + if err := helm.ExportHelmChart(rootFs, pkgFs, c.WorkingDir, packageVersion, version, *c.upstreamChartVersion, omitBuildMetadataOnExport, validateOnly); err != nil { return fmt.Errorf("encountered error while trying to export Helm chart for %s: %s", c.WorkingDir, err) } return nil diff --git a/pkg/charts/package.go b/pkg/charts/package.go index 4f0fdc09..481a812e 100644 --- a/pkg/charts/package.go +++ b/pkg/charts/package.go @@ -86,7 +86,7 @@ func (p *Package) GeneratePatch() error { } // GenerateCharts creates Helm chart archives for each chart after preparing it -func (p *Package) GenerateCharts(omitBuildMetadataOnExport bool) error { +func (p *Package) GenerateCharts(omitBuildMetadataOnExport bool, validateOnly bool) error { if p.DoNotRelease { logrus.Infof("Skipping package marked doNotRelease") return nil @@ -95,12 +95,12 @@ func (p *Package) GenerateCharts(omitBuildMetadataOnExport bool) error { return fmt.Errorf("encountered error while trying to prepare package: %s", err) } // Add PackageVersion to format - err := p.Chart.GenerateChart(p.rootFs, p.fs, p.PackageVersion, p.Version, omitBuildMetadataOnExport) + err := p.Chart.GenerateChart(p.rootFs, p.fs, p.PackageVersion, p.Version, omitBuildMetadataOnExport, validateOnly) if err != nil { return fmt.Errorf("encountered error while exporting main chart: %s", err) } for _, additionalChart := range p.AdditionalCharts { - err = additionalChart.GenerateChart(p.rootFs, p.fs, p.PackageVersion, p.Version, omitBuildMetadataOnExport) + err = additionalChart.GenerateChart(p.rootFs, p.fs, p.PackageVersion, p.Version, omitBuildMetadataOnExport, validateOnly) if err != nil { return fmt.Errorf("encountered error while exporting %s: %s", additionalChart.WorkingDir, err) } diff --git a/pkg/helm/export.go b/pkg/helm/export.go index c7cf1920..cdaf5041 100644 --- a/pkg/helm/export.go +++ b/pkg/helm/export.go @@ -3,9 +3,13 @@ package helm import ( "fmt" "math" + "net/url" "os" "path/filepath" + "github.com/rancher/charts-build-scripts/pkg/icons" + "helm.sh/helm/v3/pkg/chartutil" + "github.com/blang/semver" "github.com/go-git/go-billy/v5" "github.com/rancher/charts-build-scripts/pkg/filesystem" @@ -26,7 +30,7 @@ var ( // ExportHelmChart creates a Helm chart archive and an unarchived Helm chart at RepositoryAssetDirpath and RepositoryChartDirPath // helmChartPath is a relative path (rooted at the package level) that contains the chart. -func ExportHelmChart(rootFs, fs billy.Filesystem, helmChartPath string, packageVersion *int, version *semver.Version, upstreamChartVersion string, omitBuildMetadata bool) error { +func ExportHelmChart(rootFs, fs billy.Filesystem, helmChartPath string, packageVersion *int, version *semver.Version, upstreamChartVersion string, omitBuildMetadata, validateOnly bool) error { // Try to load the chart to see if it can be exported absHelmChartPath := filesystem.GetAbsPath(fs, helmChartPath) chart, err := helmLoader.Load(absHelmChartPath) @@ -59,6 +63,28 @@ func ExportHelmChart(rootFs, fs billy.Filesystem, helmChartPath string, packageV } chartVersion := chartVersionSemver.String() + // If its not only validation then download icons + if !validateOnly { + //checking if icon is pointing to a valid http/https url + u, err := url.Parse(chart.Metadata.Icon) + if err == nil && (u.Scheme == "http" || u.Scheme == "https") { + logrus.Infof("Chart icon is pointing to a remote url. Downloading it...") + // download icon and change the icon property to point to it + p, err := icons.Download(rootFs, chart.Metadata) + if err == nil { // managed to download the icon and save it locally + chart.Metadata.Icon = fmt.Sprintf("file://%s", p) + } else { + logrus.Errorf("failed to download icon for chart %s, err: %s", chart.Name(), err) + } + } + } + + chartYamlPath := fmt.Sprintf("%s/Chart.yaml", absHelmChartPath) + err = chartutil.SaveChartfile(chartYamlPath, chart.Metadata) + if err != nil { + return err + } + // Assets are indexed by chart name, independent of which package that chart is contained within chartAssetsDirpath := filepath.Join(path.RepositoryAssetsDir, chart.Metadata.Name) // All generated charts are indexed by chart name and version diff --git a/pkg/icons/icons.go b/pkg/icons/icons.go new file mode 100644 index 00000000..55d4fb1b --- /dev/null +++ b/pkg/icons/icons.go @@ -0,0 +1,45 @@ +package icons + +import ( + "fmt" + "io" + "mime" + "net/http" + + "github.com/rancher/charts-build-scripts/pkg/path" + + "github.com/go-git/go-billy/v5" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/chart" +) + +// Download receives a chart metadata and the filesystem pointing to the root of the project. +// From the metadata, gets the icon and name of the chart. +// It downloads the icon, infers the type using the content-type header from the response +// and saves the file locally to path.RepositoryLogosDir using the name of the chart as the file name. +func Download(rootFs billy.Filesystem, metadata *chart.Metadata) (string, error) { + icon, err := http.Get(metadata.Icon) + if err != nil { + logrus.Errorf(err.Error()) + return "", fmt.Errorf("err: %w", err) + } + + byType, err := mime.ExtensionsByType(icon.Header.Get("Content-Type")) + if err != nil || len(byType) == 0 || icon.StatusCode != http.StatusOK { + return "", fmt.Errorf("invalid icon") + } + path := fmt.Sprintf("%s/%s%s", path.RepositoryLogosDir, metadata.Name, byType[0]) + create, err := rootFs.Create(path) + if err != nil { + logrus.Errorf(err.Error()) + return "", fmt.Errorf("err: %w", err) + } + defer create.Close() + _, err = io.Copy(create, icon.Body) + defer icon.Body.Close() + if err != nil { + logrus.Errorf(err.Error()) + return "", fmt.Errorf("err: %w", err) + } + return path, nil +} diff --git a/pkg/path/path.go b/pkg/path/path.go index 79f44a5b..b48b4c4b 100644 --- a/pkg/path/path.go +++ b/pkg/path/path.go @@ -46,4 +46,7 @@ const ( // DefaultCachePath represents the default place to put a cache on pulled values DefaultCachePath = ".charts-build-scripts/.cache" + + // RepositoryLogosDir is a directory on your Staging/Live branch that contains the files with the logos of each chart + RepositoryLogosDir = "assets/logos" )