Commit eadd830d authored by Matt Butcher's avatar Matt Butcher Committed by GitHub

Merge pull request #1940 from wilkers-steve/fix/miss_dep_warning

fix(helm): add warnings for missing chart dependencies
parents 5618afe3 91e82032
......@@ -34,9 +34,11 @@ import (
"k8s.io/helm/cmd/helm/helmpath"
"k8s.io/helm/cmd/helm/strvals"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/downloader"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release"
)
......@@ -199,6 +201,13 @@ func (i *installCmd) run() error {
fmt.Printf("FINAL NAME: %s\n", i.name)
}
// Check chart requirements to make sure all dependencies are present in /charts
if c, err := chartutil.Load(i.chartPath); err == nil {
if req, err := chartutil.LoadRequirements(c); err == nil {
checkDependencies(c, req, i.out)
}
}
res, err := i.client.InstallRelease(
i.chartPath,
i.namespace,
......@@ -388,3 +397,19 @@ func defaultNamespace() string {
}
return "default"
}
func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements, out io.Writer) {
deps := ch.GetDependencies()
for _, r := range reqs.Dependencies {
found := false
for _, d := range deps {
if d.Metadata.Name == r.Name {
found = true
break
}
}
if !found {
fmt.Fprintf(out, "Warning: %s is in requirements.yaml but not in the charts/ directory!\n", r.Name)
}
}
}
......@@ -132,6 +132,12 @@ func TestInstall(t *testing.T) {
args: []string{"testdata/testcharts/signtest-0.1.0.tgz"},
flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "),
},
// Install, chart with missing dependencies in /charts
{
name: "install chart with missing dependencies",
args: []string{"testdata/testcharts/chart-missing-deps"},
expected: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!",
},
}
runReleaseCases(t, tests, func(c *fakeReleaseClient, out io.Writer) *cobra.Command {
......
......@@ -125,6 +125,10 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
return fmt.Errorf("directory name (%s) and Chart.yaml name (%s) must match", filepath.Base(path), ch.Metadata.Name)
}
if reqs, err := chartutil.LoadRequirements(ch); err == nil {
checkDependencies(ch, reqs, p.out)
}
// Save to the current working directory.
cwd, err := os.Getwd()
if err != nil {
......
......@@ -101,6 +101,12 @@ func TestPackage(t *testing.T) {
expect: "",
hasfile: "alpine-0.1.0.tgz",
},
{
name: "package testdata/testcharts/chart-missing-deps",
args: []string{"testdata/testcharts/chart-missing-deps"},
expect: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!\n",
hasfile: "chart-missing-deps-0.1.0.tgz",
},
}
// Because these tests are destructive, we run them in a tempdir.
......
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
description: A Helm chart for Kubernetes
name: chart-missing-deps
version: 0.1.0
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
description: A Helm chart for Kubernetes
name: reqsubchart
version: 0.1.0
# Default values for reqsubchart.
# This is a YAML-formatted file.
# Declare name/value pairs to be passed into your templates.
# name: value
dependencies:
- name: reqsubchart
version: 0.1.0
repository: "https://example.com/charts"
- name: reqsubchart2
version: 0.2.0
repository: "https://example.com/charts"
# Default values for reqtest.
# This is a YAML-formatted file.
# Declare name/value pairs to be passed into your templates.
# name: value
......@@ -26,6 +26,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/helm/cmd/helm/strvals"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/storage/driver"
)
......@@ -160,6 +161,13 @@ func (u *upgradeCmd) run() error {
return err
}
// Check chart requirements to make sure all dependencies are present in /charts
if ch, err := chartutil.Load(chartPath); err == nil {
if req, err := chartutil.LoadRequirements(ch); err == nil {
checkDependencies(ch, req, u.out)
}
}
resp, err := u.client.UpdateRelease(
u.release,
chartPath,
......
......@@ -20,6 +20,7 @@ import (
"io"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/spf13/cobra"
......@@ -79,6 +80,14 @@ func TestUpgradeCmd(t *testing.T) {
t.Errorf("Error loading updated chart: %v", err)
}
originalDepsPath := filepath.Join("testdata/testcharts/reqtest")
missingDepsPath := filepath.Join("testdata/testcharts/chart-missing-deps")
var ch3 *chart.Chart
ch3, err = chartutil.Load(originalDepsPath)
if err != nil {
t.Errorf("Error loading chart with missing dependencies: %v", err)
}
tests := []releaseCase{
{
name: "upgrade a release",
......@@ -121,6 +130,12 @@ func TestUpgradeCmd(t *testing.T) {
resp: releaseMock(&releaseOptions{name: "crazy-bunny", version: 2, chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
},
{
name: "upgrade a release with missing dependencies",
args: []string{"bonkers-bunny", missingDepsPath},
resp: releaseMock(&releaseOptions{name: "bonkers-bunny", version: 1, chart: ch3}),
expected: "Warning: reqsubchart2 is in requirements.yaml but not in the charts/ directory!",
},
}
cmd := func(c *fakeReleaseClient, out io.Writer) *cobra.Command {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment