Skip to content

Commit

Permalink
feat: support the new OCI implementation from helm 3.7.0
Browse files Browse the repository at this point in the history
Signed-off-by: Luis Davim <[email protected]>
  • Loading branch information
luisdavim committed Sep 17, 2021
1 parent 6338cad commit 72652c0
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
11 changes: 11 additions & 0 deletions internal/app/helm_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func updateChartDep(chartPath string) error {
}

// helmExportChart pulls chart and exports it to the specified destination
// this is only compatible with hlem versions lower than 3.0.7
func helmExportChart(chart, dest string) error {
cmd := helmCmd([]string{"chart", "pull", chart}, "Pulling chart [ "+chart+" ] to local registry cache")
if _, err := cmd.Exec(); err != nil {
Expand All @@ -123,6 +124,16 @@ func helmExportChart(chart, dest string) error {
return nil
}

// helmPullChart pulls chart and exports it to the specified destination
// this should only be used with helm versions greater or equal to 3.7.0
func helmPullChart(chart, dest string) error {
cmd := helmCmd([]string{"chart", "pull", chart, "-d", dest}, "Pulling chart [ "+chart+" ] to "+dest)
if _, err := cmd.Exec(); err != nil {
return err
}
return nil
}

// addHelmRepos adds repositories to Helm if they don't exist already.
// Helm does not mind if a repo with the same name exists. It treats it as an update.
func addHelmRepos(repos map[string]string) error {
Expand Down
40 changes: 36 additions & 4 deletions internal/app/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"time"
"unicode/utf8"

"github.com/Masterminds/semver"
"github.com/Praqma/helmsman/internal/aws"
Expand Down Expand Up @@ -198,6 +199,25 @@ func sliceContains(slice []string, s string) bool {
return false
}

// replaceAtIndex replaces the charecter at the given index in the string with the given rune
func replaceAtIndex(in string, r rune, i int) (string, error) {
if i < 0 || i >= utf8.RuneCountInString(in) {
return in, fmt.Errorf("index out of bounds")
}
out := []rune(in)
out[i] = r
return string(out), nil
}

// ociRefToFilename computes the helm package filename for a given OCI ref
func ociRefToFilename(ref string) (string, error) {
var err error
fileName := filepath.Base(ref)
i := strings.LastIndex(fileName, ":")
fileName, err = replaceAtIndex(fileName, '-', i)
return fmt.Sprintf("%s.tgz", fileName), err
}

// downloadFile downloads a file from a URL, GCS, Azure or AWS buckets and saves it with a
// given outfile name and in a given dir
// If the file path is local file system path, it returns the absolute path to the file
Expand All @@ -210,11 +230,23 @@ func downloadFile(file string, dir string, outfile string) string {
switch u.Scheme {
case "oci":
dest := filepath.Dir(outfile)
fileName := strings.Split(filepath.Base(file), ":")[0]
if err := helmExportChart(strings.ReplaceAll(file, "oci://", ""), dest); err != nil {
log.Fatal(err.Error())
switch {
case checkHelmVersion("<3.7.0"):
fileName := strings.Split(filepath.Base(file), ":")[0]
if err := helmExportChart(strings.ReplaceAll(file, "oci://", ""), dest); err != nil {
log.Fatal(err.Error())
}
return filepath.Join(dest, fileName)
default:
fileName, err := ociRefToFilename(file)
if err != nil {
log.Fatal(err.Error())
}
if err := helmPullChart(file, dest); err != nil {
log.Fatal(err.Error())
}
return filepath.Join(dest, fileName)
}
return filepath.Join(dest, fileName)
case "https", "http":
if err := downloadFileFromURL(file, outfile); err != nil {
log.Fatal(err.Error())
Expand Down
40 changes: 40 additions & 0 deletions internal/app/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,46 @@ import (
"testing"
)

func TestOciRefToFilename(t *testing.T) {
tests := []struct {
name string
in string
want string
}{
{
name: "no_repo",
in: "my-chart:1.2.3",
want: "my-chart-1.2.3.tgz",
},
{
name: "two_colons",
in: "my:chart:1.2.3",
want: "my:chart-1.2.3.tgz",
},
{
name: "with_Host",
in: "my-repo.example.com/charts/my-chart:1.2.3",
want: "my-chart-1.2.3.tgz",
},
{
name: "full_url",
in: "oci://my-repo.example.com/charts/my-chart:1.2.3",
want: "my-chart-1.2.3.tgz",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ociRefToFilename(tt.in)
if err != nil {
t.Errorf("ociRefToFilename() unexpected error: %v", err)
}
if got != tt.want {
t.Errorf("ociRefToFilename() got = %v, want %v", got, tt.want)
}
})
}
}

func Test_isOfType(t *testing.T) {
type args struct {
filename string
Expand Down

0 comments on commit 72652c0

Please sign in to comment.