Skip to content

Commit

Permalink
fix(ci): buildtools handle helm chart app version change (#1241)
Browse files Browse the repository at this point in the history
  • Loading branch information
emosbaugh authored Oct 15, 2024
1 parent c08b81c commit 393accf
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
3 changes: 0 additions & 3 deletions cmd/buildtools/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ This script uses the following environment variables:
- CHARTS_REGISTRY_SERVER: the registry server to push the chart to (e.g. index.docker.io)
- CHARTS_REGISTRY_USER: the username to authenticate with.
- CHARTS_REGISTRY_PASS: the password to authenticate with.
- IMAGES_REGISTRY_SERVER: the registry server to push the images to (e.g. index.docker.io)
- IMAGES_REGISTRY_USER: the username to authenticate with.
- IMAGES_REGISTRY_PASS: the password to authenticate with.
- CHARTS_DESTINATION: the destination repository to push the chart to (e.g. ttl.sh/embedded-cluster-charts)
`

Expand Down
26 changes: 23 additions & 3 deletions cmd/buildtools/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/replicatedhq/embedded-cluster/pkg/helm"
"github.com/replicatedhq/embedded-cluster/pkg/release"
"github.com/sirupsen/logrus"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/repo"
)

Expand Down Expand Up @@ -442,6 +443,16 @@ func GetImagesFromOCIChart(url, name, version string, values map[string]interfac
return helm.ExtractImagesFromOCIChart(hcli, url, name, version, values)
}

func GetOCIChartMetadata(url, name, version string) (*chart.Metadata, error) {
hcli, err := NewHelm()
if err != nil {
return nil, fmt.Errorf("create helm client: %w", err)
}
defer hcli.Close()

return helm.GetOCIChartMetadata(hcli, url, name, version)
}

func MirrorChart(repo *repo.Entry, name, ver string) error {
hcli, err := NewHelm()
if err != nil {
Expand All @@ -463,6 +474,11 @@ func MirrorChart(repo *repo.Entry, name, ver string) error {
logrus.Infof("downloaded %s chart: %s", name, chpath)
defer os.Remove(chpath)

srcMeta, err := hcli.GetChartMetadata(chpath)
if err != nil {
return fmt.Errorf("get source chart metadata: %w", err)
}

if val := os.Getenv("CHARTS_REGISTRY_SERVER"); val != "" {
logrus.Infof("authenticating with %q", os.Getenv("CHARTS_REGISTRY_SERVER"))
if err := hcli.RegistryAuth(
Expand All @@ -475,13 +491,17 @@ func MirrorChart(repo *repo.Entry, name, ver string) error {
}

dst := fmt.Sprintf("oci://%s", os.Getenv("CHARTS_DESTINATION"))
chartURL := fmt.Sprintf("%s/%s", dst, name)
logrus.Infof("verifying if destination tag already exists")
tmpf, err := hcli.Pull(dst, name, ver)
dstMeta, err := GetOCIChartMetadata(chartURL, name, ver)
if err != nil && !strings.HasSuffix(err.Error(), "not found") {
return fmt.Errorf("verify tag exists: %w", err)
} else if err == nil {
os.Remove(tmpf)
logrus.Warnf("cowardly refusing to override dst (tag %s already exist)", ver)
if srcMeta.AppVersion == dstMeta.AppVersion {
logrus.Infof("cowardly refusing to override dst (tag %s already exist)", ver)
return nil
}
logrus.Warnf("dst tag exists but app versions do not match (src: %s, dst: %s)", srcMeta.AppVersion, dstMeta.AppVersion)
return nil
}
logrus.Infof("destination tag does not exist")
Expand Down
10 changes: 10 additions & 0 deletions pkg/helm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/Masterminds/semver/v3"
"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/downloader"
Expand Down Expand Up @@ -214,6 +215,15 @@ func (h *Helm) Push(path, dst string) error {
return up.UploadTo(path, dst)
}

func (h *Helm) GetChartMetadata(chartPath string) (*chart.Metadata, error) {
chartRequested, err := loader.Load(chartPath)
if err != nil {
return nil, fmt.Errorf("load chart: %w", err)
}

return chartRequested.Metadata, nil
}

func (h *Helm) Render(chartName string, chartPath string, vals map[string]interface{}, namespace string) ([][]byte, error) {
cfg := &action.Configuration{}

Expand Down
24 changes: 24 additions & 0 deletions pkg/helm/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package helm

import (
"fmt"
"os"
"slices"
"sort"

"github.com/distribution/reference"
"github.com/replicatedhq/embedded-cluster/pkg/helpers"
"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/chart"
)

type reducedResource struct {
Expand Down Expand Up @@ -39,6 +41,7 @@ func ExtractImagesFromOCIChart(hcli *Helm, url, name, version string, values map
if err != nil {
return nil, fmt.Errorf("pull oci: %w", err)
}
defer os.RemoveAll(chartPath)

return ExtractImagesFromLocalChart(hcli, name, chartPath, values)
}
Expand All @@ -48,6 +51,7 @@ func ExtractImagesFromChart(hcli *Helm, repo, name, version string, values map[s
if err != nil {
return nil, fmt.Errorf("pull: %w", err)
}
defer os.RemoveAll(chartPath)

return ExtractImagesFromLocalChart(hcli, name, chartPath, values)
}
Expand All @@ -73,6 +77,26 @@ func ExtractImagesFromLocalChart(hcli *Helm, name, path string, values map[strin
return images, nil
}

func GetOCIChartMetadata(hcli *Helm, url, name, version string) (*chart.Metadata, error) {
chartPath, err := hcli.PullOCI(url, version)
if err != nil {
return nil, fmt.Errorf("pull oci: %w", err)
}
defer os.RemoveAll(chartPath)

return hcli.GetChartMetadata(chartPath)
}

func GetChartMetadata(hcli *Helm, repo, name, version string) (*chart.Metadata, error) {
chartPath, err := hcli.Pull(repo, name, version)
if err != nil {
return nil, fmt.Errorf("pull oci: %w", err)
}
defer os.RemoveAll(chartPath)

return hcli.GetChartMetadata(chartPath)
}

func extractImagesFromK8sManifest(resource []byte) ([]string, error) {
images := []string{}

Expand Down

0 comments on commit 393accf

Please sign in to comment.