Skip to content

Commit

Permalink
Helm 3 support (#50)
Browse files Browse the repository at this point in the history
* remove vendor dir

Signed-off-by: Josh Dolitsky <[email protected]>

* update modules, install both helm 2 & 3

Signed-off-by: Josh Dolitsky <[email protected]>

* run install test on both helm 2 & 3

Signed-off-by: Josh Dolitsky <[email protected]>

* test break appropriately on helm 3

Signed-off-by: Josh Dolitsky <[email protected]>

* fix broken unit tests

Signed-off-by: Josh Dolitsky <[email protected]>

* key on helm version

Signed-off-by: Josh Dolitsky <[email protected]>

* acceptance tests passing for v2 and v3

Signed-off-by: Josh Dolitsky <[email protected]>

* cleanup of imports, validate xdg/helm2 homes

Signed-off-by: Josh Dolitsky <[email protected]>

* fix for unit tests

Signed-off-by: Josh Dolitsky <[email protected]>

* update to golang 1.13

Signed-off-by: Josh Dolitsky <[email protected]>
  • Loading branch information
jdolitsky authored Dec 15, 2019
1 parent 9788743 commit f5a169b
Show file tree
Hide file tree
Showing 297 changed files with 1,200 additions and 57,196 deletions.
2 changes: 1 addition & 1 deletion .codefresh/master.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '1.0'
steps:
setup_build_test_release:
image: golang:1.12
image: golang:1.13
description: Setup env, unit test, build, release artifacts...
working_directory: /go/src/github.com/chartmuseum
commands:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
**/*.tgz.prov
.chartmuseum.log
.cover/
.helm/
.helm2/
.helm3/
.idea/
.robot/
.venv/
bin/
dist/
releases/
testbin/
vendor/
23 changes: 22 additions & 1 deletion acceptance_tests/helm.robot → acceptance_tests/01-helm.robot
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ Suite Setup Suite Setup
Suite Teardown Suite Teardown

*** Test Cases ***
Plugin installs on Helm 2
Test plugin installation 2

Plugin installs on Helm 3
Test plugin installation 3

*** Keywords ***
Test plugin installation
[Arguments] ${version}
set helm version ${version}
helm-push can be installed as a Helm plugin
helm-push is listed as a Helm plugin after install
helm-push can be run as a Helm plugin
helm-push can be removed
helm-push is not listed as a Helm plugin after removal

helm-push can be installed as a Helm plugin
install helm plugin
return code should be 0
Expand All @@ -26,9 +42,14 @@ helm-push is not listed as a Helm plugin after removal
check helm plugin
return code should not be 0

*** Keywords ***
Suite Setup
set helm version 3
remove helm plugin
set helm version 2
remove helm plugin

Suite Teardown
set helm version 3
remove helm plugin
set helm version 2
remove helm plugin
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ Suite Setup Suite Setup
Suite Teardown Suite Teardown

*** Test Cases ***
Plugin works with ChartMuseum on Helm 2
Test ChartMuseum integration 2

Plugin works with ChartMuseum on Helm 3
Test ChartMuseum integration 3

*** Keywords ***
Test ChartMuseum integration
[Arguments] ${version}
set helm version ${version}
install helm plugin
helm major version detected by plugin is ${version}
Chart directory can be pushed to ChartMuseum
Chart directory can be pushed to ChartMuseum with custom version
Chart package can be pushed to ChartMuseum
Chart package can be pushed to ChartMuseum with custom version

Chart directory can be pushed to ChartMuseum
# Repo name
push chart directory
Expand Down Expand Up @@ -68,14 +85,24 @@ Chart package can be pushed to ChartMuseum with custom version
ChartMuseum.return code should be 0
clear chartmuseum storage

*** Keywords ***
Suite Setup
set helm version 3
remove helm plugin
set helm version 2
remove helm plugin
remove chartmuseum logs
start chartmuseum
Sleep 2
set helm version 2
add chart repo
set helm version 3
add chart repo

Suite Teardown
set helm version 3
remove helm plugin
set helm version 2
remove helm plugin
remove chart repo
stop chartmuseum
print chartmuseum logs
26 changes: 19 additions & 7 deletions acceptance_tests/lib/Helm.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import common
import os

import common

class Helm(common.CommandRunner):
def set_helm_version(self, version):
version = str(version)
if version == '2':
common.HELM_EXE = 'HELM_HOME=%s helm2' % os.getenv('TEST_V2_HELM_HOME', '')
elif version == '3':
common.HELM_EXE = 'XDG_CACHE_HOME=%s XDG_CONFIG_HOME=%s XDG_DATA_HOME=%s helm3' % \
(os.getenv('TEST_V3_XDG_CACHE_HOME', ''), os.getenv('TEST_V3_XDG_CONFIG_HOME', ''),
os.getenv('TEST_V3_XDG_DATA_HOME', ''))
else:
raise Exception('invalid Helm version provided: %s' % version)

def add_chart_repo(self):
self.remove_chart_repo()
self.run_command('helm repo add %s %s' % (common.HELM_REPO_NAME, common.HELM_REPO_URL))
self.run_command('%s repo add %s %s' % (common.HELM_EXE, common.HELM_REPO_NAME, common.HELM_REPO_URL))

def remove_chart_repo(self):
self.run_command('helm repo remove %s' % common.HELM_REPO_NAME)
self.run_command('%s repo remove %s' % (common.HELM_EXE, common.HELM_REPO_NAME))

def install_helm_plugin(self):
self.run_command('helm plugin install %s' % self.rootdir)
self.run_command('%s plugin install %s' % (common.HELM_EXE, self.rootdir))

def check_helm_plugin(self):
self.run_command('helm plugin list | grep ^push')
self.run_command('%s plugin list | grep ^push' % common.HELM_EXE)

def run_helm_plugin(self):
self.run_command('helm push --help')
self.run_command('%s push --help' % common.HELM_EXE)

def remove_helm_plugin(self):
self.run_command('helm plugin remove push')
self.run_command('%s plugin remove push' % common.HELM_EXE)
18 changes: 14 additions & 4 deletions acceptance_tests/lib/HelmPush.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,36 @@


class HelmPush(common.CommandRunner):
def _testchart_path(self):
if 'helm3' in common.HELM_EXE:
return '%s/helm3/my-v3-chart' % common.TESTCHARTS_DIR
return '%s/helm2/mychart' % common.TESTCHARTS_DIR

def helm_major_version_detected_by_plugin_is(self, version):
cmd = '%s push --check-helm-version' % common.HELM_EXE
self.run_command(cmd)
self.output_contains(version)

def push_chart_directory(self, version=''):
cmd = 'helmpush %s/mychart %s' % (common.TESTCHARTS_DIR, common.HELM_REPO_NAME)
cmd = '%s push %s %s' % (common.HELM_EXE, self._testchart_path(), common.HELM_REPO_NAME)
if version:
cmd += " --version=\"%s\"" % version
self.run_command(cmd)

def push_chart_directory_to_url(self, version=''):
cmd = 'helmpush %s/mychart %s' % (common.TESTCHARTS_DIR, common.HELM_REPO_URL)
cmd = '%s push %s %s' % (common.HELM_EXE, self._testchart_path(), common.HELM_REPO_URL)
if version:
cmd += " --version=\"%s\"" % version
self.run_command(cmd)

def push_chart_package(self, version=''):
cmd = 'helmpush %s/mychart/*.tgz %s' % (common.TESTCHARTS_DIR, common.HELM_REPO_NAME)
cmd = '%s push %s/*.tgz %s' % (common.HELM_EXE, self._testchart_path(), common.HELM_REPO_NAME)
if version:
cmd += " --version=\"%s\"" % version
self.run_command(cmd)

def push_chart_package_to_url(self, version=''):
cmd = 'helmpush %s/mychart %s' % (common.TESTCHARTS_DIR, common.HELM_REPO_URL)
cmd = '%s push %s %s' % (common.HELM_EXE, self._testchart_path(), common.HELM_REPO_URL)
if version:
cmd += " --version=\"%s\"" % version
self.run_command(cmd)
1 change: 1 addition & 0 deletions acceptance_tests/lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ACCEPTANCE_DIR = '.acceptance/'
STORAGE_DIR = os.path.join(ACCEPTANCE_DIR, 'storage/')
LOGFILE = '.chartmuseum.log'
HELM_EXE = 'HELM_HOME=%s helm2' % os.getenv('TEST_HELM_HOME', '')


class CommandRunner(object):
Expand Down
70 changes: 47 additions & 23 deletions cmd/helmpush/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ import (
"strconv"
"strings"

"k8s.io/helm/pkg/chartutil"

cm "github.com/chartmuseum/helm-push/pkg/chartmuseum"
"github.com/chartmuseum/helm-push/pkg/helm"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/downloader"
"k8s.io/helm/pkg/getter"
helmEnv "k8s.io/helm/pkg/helm/environment"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
v2downloader "k8s.io/helm/pkg/downloader"
v2getter "k8s.io/helm/pkg/getter"
v2environment "k8s.io/helm/pkg/helm/environment"
)

type (
Expand All @@ -39,6 +41,7 @@ type (
contextPath string
forceUpload bool
useHTTP bool
checkHelmVersion bool
caFile string
certFile string
keyFile string
Expand All @@ -60,7 +63,8 @@ type (
)

var (
settings helmEnv.EnvSettings
v2settings v2environment.EnvSettings
settings = cli.New()
globalUsage = `Helm plugin to push chart package to ChartMuseum
Examples:
Expand All @@ -81,6 +85,12 @@ func newPushCmd(args []string) *cobra.Command {
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {

// If the --check-helm-version flag is provided, short circuit
if p.checkHelmVersion {
fmt.Println(helm.HelmMajorVersionCurrent())
return nil
}

p.out = cmd.OutOrStdout()

// If there are 4 args, this is likely being used as a downloader for cm:// protocol
Expand Down Expand Up @@ -112,11 +122,12 @@ func newPushCmd(args []string) *cobra.Command {
f.BoolVarP(&p.insecureSkipVerify, "insecure", "", false, "Connect to server with an insecure way by skipping certificate verification [$HELM_REPO_INSECURE]")
f.BoolVarP(&p.forceUpload, "force", "f", false, "Force upload even if chart version exists")
f.BoolVarP(&p.dependencyUpdate, "dependency-update", "d", false, `update dependencies from "requirements.yaml" to dir "charts/" before packaging`)
f.BoolVarP(&p.checkHelmVersion, "check-helm-version", "", false, `outputs either "2" or "3" indicating the current Helm major version`)

f.Parse(args)

settings.AddFlags(f)
settings.Init(f)
v2settings.AddFlags(f)
v2settings.Init(f)

return cmd
}
Expand Down Expand Up @@ -191,7 +202,7 @@ func (p *pushCmd) push() error {
// instead of looking for the entry in the local repository list
if regexp.MustCompile(`^https?://`).MatchString(p.repoName) {
repo, err = helm.TempRepoFromURL(p.repoName)
p.repoName = repo.URL
p.repoName = repo.Config.URL
} else {
repo, err = helm.GetRepoByName(p.repoName)
}
Expand All @@ -214,16 +225,29 @@ func (p *pushCmd) push() error {
if err != nil {
return err
}
downloadManager := &downloader.Manager{
Out: p.out,
ChartPath: chartPath,
HelmHome: settings.Home,
Keyring: p.keyring,
Getters: getter.All(settings),
Debug: settings.Debug,
}
if err := downloadManager.Update(); err != nil {
return err
if helm.HelmMajorVersionCurrent() == helm.HelmMajorVersion2 {
v2downloadManager := &v2downloader.Manager{
Out: p.out,
ChartPath: chartPath,
HelmHome: v2settings.Home,
Keyring: p.keyring,
Getters: v2getter.All(v2settings),
Debug: v2settings.Debug,
}
if err := v2downloadManager.Update(); err != nil {
return err
}
} else {
downloadManager := &downloader.Manager{
Out: p.out,
ChartPath: chartPath,
Keyring: p.keyring,
Getters: getter.All(settings),
Debug: v2settings.Debug,
}
if err := downloadManager.Update(); err != nil {
return err
}
}
}
}
Expand All @@ -239,8 +263,8 @@ func (p *pushCmd) push() error {
}

// username/password override(s)
username := repo.Username
password := repo.Password
username := repo.Config.Username
password := repo.Config.Password
if p.username != "" {
username = p.username
}
Expand All @@ -251,9 +275,9 @@ func (p *pushCmd) push() error {
// in case the repo is stored with cm:// protocol, remove it
var url string
if p.useHTTP {
url = strings.Replace(repo.URL, "cm://", "http://", 1)
url = strings.Replace(repo.Config.URL, "cm://", "http://", 1)
} else {
url = strings.Replace(repo.URL, "cm://", "https://", 1)
url = strings.Replace(repo.Config.URL, "cm://", "https://", 1)
}

client, err := cm.NewClient(
Expand Down
6 changes: 3 additions & 3 deletions cmd/helmpush/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

var (
testTarballPath = "../../testdata/charts/mychart/mychart-0.1.0.tgz"
testTarballPath = "../../testdata/charts/helm2/mychart/mychart-0.1.0.tgz"
testCertPath = "../../testdata/tls/test_cert.crt"
testKeyPath = "../../testdata/tls/test_key.key"
testCAPath = "../../testdata/tls/ca.crt"
Expand Down Expand Up @@ -49,7 +49,7 @@ func TestPushCmd(t *testing.T) {
entry.Name = "helm-push-test"
entry.URL = ts.URL

_, err = repo.NewChartRepository(&entry, getter.All(settings))
_, err = repo.NewChartRepository(&entry, getter.All(v2settings))
if err != nil {
t.Error("unexpected error created test repository", err)
}
Expand Down Expand Up @@ -193,7 +193,7 @@ func TestPushCmdWithTlsEnabledServer(t *testing.T) {
entry.Name = "helm-push-test"
entry.URL = ts.URL

_, err = repo.NewChartRepository(&entry, getter.All(settings))
_, err = repo.NewChartRepository(&entry, getter.All(v2settings))
if err != nil {
t.Error("unexpected error created test repository", err)
}
Expand Down
Loading

0 comments on commit f5a169b

Please sign in to comment.