Skip to content

Commit

Permalink
Add basic support for OCI registry based charts
Browse files Browse the repository at this point in the history
until go-getter has native support we are using Helm for now to download
the charts from OCI registries.

Authentication for the OCI registry is not supported yet.
  • Loading branch information
thardeck committed Sep 15, 2022
1 parent 5b0bdeb commit b0a8190
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
3 changes: 2 additions & 1 deletion docs/gitrepo-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ kustomize:
dir: ./kustomize

helm:
# Use a custom location for the Helm chart. This can refer to any go-getter URL.
# Use a custom location for the Helm chart. This can refer to any go-getter URL or
# OCI registry based helm chart URL e.g. "oci://ghcr.io/fleetrepoci/guestbook".
# This allows one to download charts from most any location. Also know that
# go-getter URL supports adding a digest to validate the download. If repo
# is set below this field is the name of the chart to lookup
Expand Down
66 changes: 51 additions & 15 deletions pkg/bundle/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/url"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"sync"
Expand All @@ -21,6 +22,9 @@ import (
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/downloader"
helm_getter "helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"

"github.com/rancher/fleet/modules/cli/pkg/progress"
Expand Down Expand Up @@ -186,11 +190,12 @@ func addCharts(directories []directory, base string, charts []*fleet.HelmOptions
}

directories = append(directories, directory{
prefix: ChartPath(chart),
base: base,
path: chartURL,
key: ChartPath(chart),
auth: auth,
prefix: ChartPath(chart),
base: base,
path: chartURL,
key: ChartPath(chart),
auth: auth,
version: chart.Version,
})
}
}
Expand All @@ -216,11 +221,12 @@ func addDirectory(directories []directory, base, customDir, defaultDir string) (
}

type directory struct {
prefix string
base string
path string
key string
auth Auth
prefix string
base string
path string
key string
version string
auth Auth
}

func readDirectories(ctx context.Context, compress bool, directories ...directory) (map[string][]fleet.BundleResource, error) {
Expand All @@ -241,7 +247,7 @@ func readDirectories(ctx context.Context, compress bool, directories ...director
dir := dir
eg.Go(func() error {
defer sem.Release(1)
resources, err := readDirectory(ctx, compress, dir.prefix, dir.base, dir.path, dir.auth)
resources, err := readDirectory(ctx, compress, dir.prefix, dir.base, dir.path, dir.version, dir.auth)
if err != nil {
return err
}
Expand All @@ -261,10 +267,10 @@ func readDirectories(ctx context.Context, compress bool, directories ...director
return result, eg.Wait()
}

func readDirectory(ctx context.Context, compress bool, prefix, base, name string, auth Auth) ([]fleet.BundleResource, error) {
func readDirectory(ctx context.Context, compress bool, prefix, base, name, version string, auth Auth) ([]fleet.BundleResource, error) {
var resources []fleet.BundleResource

files, err := readContent(ctx, base, name, auth)
files, err := readContent(ctx, base, name, version, auth)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -295,21 +301,36 @@ func readDirectory(ctx context.Context, compress bool, prefix, base, name string
return resources, nil
}

func readContent(ctx context.Context, base, name string, auth Auth) (map[string][]byte, error) {
func readContent(ctx context.Context, base, name, version string, auth Auth) (map[string][]byte, error) {
temp, err := os.MkdirTemp("", "fleet")
if err != nil {
return nil, err
}
defer os.RemoveAll(temp)

src := name

// go-getter does not support downloading OCI registry based files yet
// until this is implemented we use Helm to download charts from OCI based registries
// and provide the downloaded file to go-getter locally
hasOCIURL, err := regexp.MatchString(`oci:\/\/`, name)
if err != nil {
return nil, err
}
if hasOCIURL {
src, err = downloadOCIChart(name, version, temp)
if err != nil {
return nil, err
}
}

temp = filepath.Join(temp, "content")

base, err = filepath.Abs(base)
if err != nil {
return nil, err
}

src := name
if auth.SSHPrivateKey != nil {
if !strings.ContainsAny(src, "?") {
src += "?"
Expand Down Expand Up @@ -387,6 +408,21 @@ func readContent(ctx context.Context, base, name string, auth Auth) (map[string]
return files, nil
}

// downloadOciChart uses Helm to download charts from OCI based registries
func downloadOCIChart(name, version, path string) (string, error) {
c := downloader.ChartDownloader{
Verify: downloader.VerifyNever,
Getters: helm_getter.All(&cli.EnvSettings{}),
}

saved, _, err := c.DownloadTo(name, version, path)
if err != nil {
return "", err
}

return saved, nil
}

func newHttpGetter(auth Auth) *getter.HttpGetter {
httpGetter := &getter.HttpGetter{
Client: &http.Client{},
Expand Down

0 comments on commit b0a8190

Please sign in to comment.