Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download icons locally when running make charts #124

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/charts/additionalchart.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions pkg/charts/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions pkg/charts/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand Down
28 changes: 27 additions & 1 deletion pkg/helm/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
45 changes: 45 additions & 0 deletions pkg/icons/icons.go
Original file line number Diff line number Diff line change
@@ -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
}
3 changes: 3 additions & 0 deletions pkg/path/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Loading