ref(*): replace chart.config with []byte

pull/3945/head
Adam Reese 6 years ago
parent 1e2e65ce54
commit 4c95185164
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

@ -83,6 +83,6 @@ func (g *getValuesCmd) run() error {
return nil return nil
} }
fmt.Fprintln(g.out, res.Config.Raw) fmt.Fprintln(g.out, string(res.Config))
return nil return nil
} }

@ -237,7 +237,7 @@ func (i *inspectCmd) run() error {
if i.output == all { if i.output == all {
fmt.Fprintln(i.out, "---") fmt.Fprintln(i.out, "---")
} }
fmt.Fprintln(i.out, chrt.Values.Raw) fmt.Fprintln(i.out, string(chrt.Values))
} }
if i.output == readmeOnly || i.output == all { if i.output == readmeOnly || i.output == all {

@ -26,6 +26,7 @@ import (
"syscall" "syscall"
"github.com/Masterminds/semver" "github.com/Masterminds/semver"
"github.com/ghodss/yaml"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
@ -143,15 +144,15 @@ func (p *packageCmd) run() error {
if err != nil { if err != nil {
return err return err
} }
combinedVals, err := chartutil.CoalesceValues(ch, &chart.Config{Raw: string(overrideVals)}) combinedVals, err := chartutil.CoalesceValues(ch, overrideVals)
if err != nil { if err != nil {
return err return err
} }
newVals, err := combinedVals.YAML() newVals, err := yaml.Marshal(combinedVals)
if err != nil { if err != nil {
return err return err
} }
ch.Values = &chart.Config{Raw: newVals} ch.Values = newVals
// If version is set, modify the version. // If version is set, modify the version.
if len(p.version) != 0 { if len(p.version) != 0 {

@ -378,7 +378,7 @@ func getChartValues(chartPath string) (chartutil.Values, error) {
return nil, err return nil, err
} }
return chartutil.ReadValues([]byte(chart.Values.Raw)) return chartutil.ReadValues(chart.Values)
} }
func verifyValues(t *testing.T, actual, expected chartutil.Values) { func verifyValues(t *testing.T, actual, expected chartutil.Values) {

@ -30,7 +30,7 @@ var printReleaseTemplate = `REVISION: {{.Release.Version}}
RELEASED: {{.ReleaseDate}} RELEASED: {{.ReleaseDate}}
CHART: {{.Release.Chart.Metadata.Name}}-{{.Release.Chart.Metadata.Version}} CHART: {{.Release.Chart.Metadata.Name}}-{{.Release.Chart.Metadata.Version}}
USER-SUPPLIED VALUES: USER-SUPPLIED VALUES:
{{.Release.Config.Raw}} {{.Config}}
COMPUTED VALUES: COMPUTED VALUES:
{{.ComputedValues}} {{.ComputedValues}}
HOOKS: HOOKS:
@ -59,6 +59,7 @@ func printRelease(out io.Writer, rel *release.Release) error {
data := map[string]interface{}{ data := map[string]interface{}{
"Release": rel, "Release": rel,
"Config": string(rel.Config),
"ComputedValues": cfgStr, "ComputedValues": cfgStr,
"ReleaseDate": rel.Info.LastDeployed.Format(time.ANSIC), "ReleaseDate": rel.Info.LastDeployed.Format(time.ANSIC),
} }

@ -32,7 +32,6 @@ import (
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/engine" "k8s.io/helm/pkg/engine"
"k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
util "k8s.io/helm/pkg/releaseutil" util "k8s.io/helm/pkg/releaseutil"
"k8s.io/helm/pkg/tiller" "k8s.io/helm/pkg/tiller"
@ -150,11 +149,10 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
t.namespace = defaultNamespace() t.namespace = defaultNamespace()
} }
// get combined values and create config // get combined values and create config
rawVals, err := vals(t.valueFiles, t.values, t.stringValues) config, err := vals(t.valueFiles, t.values, t.stringValues)
if err != nil { if err != nil {
return err return err
} }
config := &chart.Config{Raw: string(rawVals), Values: map[string]*chart.Value{}}
// If template is specified, try to run the template. // If template is specified, try to run the template.
if t.nameTemplate != "" { if t.nameTemplate != "" {

@ -29,7 +29,7 @@ import (
) )
// APIVersionv1 is the API version number for version 1. // APIVersionv1 is the API version number for version 1.
const APIVersionv1 = "v1" // nolint const APIVersionv1 = "v1"
// UnmarshalChartfile takes raw Chart.yaml data and unmarshals it. // UnmarshalChartfile takes raw Chart.yaml data and unmarshals it.
func UnmarshalChartfile(data []byte) (*chart.Metadata, error) { func UnmarshalChartfile(data []byte) (*chart.Metadata, error) {

@ -307,7 +307,7 @@ func CreateFrom(chartfile *chart.Metadata, dest string, src string) error {
} }
schart.Templates = updatedTemplates schart.Templates = updatedTemplates
schart.Values = &chart.Config{Raw: string(Transform(schart.Values.Raw, "<CHARTNAME>", schart.Metadata.Name))} schart.Values = Transform(string(schart.Values), "<CHARTNAME>", schart.Metadata.Name)
return SaveDir(schart, dest) return SaveDir(schart, dest)
} }

@ -128,7 +128,7 @@ func TestCreateFrom(t *testing.T) {
} }
// Ensure we replace `<CHARTNAME>` // Ensure we replace `<CHARTNAME>`
if strings.Contains(mychart.Values.Raw, "<CHARTNAME>") { if strings.Contains(string(mychart.Values), "<CHARTNAME>") {
t.Errorf("Did not expect %s to be present in %s", "<CHARTNAME>", mychart.Values.Raw) t.Errorf("Did not expect %s to be present in %s", "<CHARTNAME>", string(mychart.Values))
} }
} }

@ -132,7 +132,7 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) {
} else if f.Name == "values.toml" { } else if f.Name == "values.toml" {
return c, errors.New("values.toml is illegal as of 2.0.0-alpha.2") return c, errors.New("values.toml is illegal as of 2.0.0-alpha.2")
} else if f.Name == "values.yaml" { } else if f.Name == "values.yaml" {
c.Values = &chart.Config{Raw: string(f.Data)} c.Values = f.Data
} else if strings.HasPrefix(f.Name, "templates/") { } else if strings.HasPrefix(f.Name, "templates/") {
c.Templates = append(c.Templates, &chart.File{Name: f.Name, Data: f.Data}) c.Templates = append(c.Templates, &chart.File{Name: f.Name, Data: f.Data})
} else if strings.HasPrefix(f.Name, "charts/") { } else if strings.HasPrefix(f.Name, "charts/") {

@ -89,7 +89,7 @@ icon: https://example.com/64x64.png
t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Metadata.Name) t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Metadata.Name)
} }
if c.Values.Raw != defaultValues { if string(c.Values) != defaultValues {
t.Error("Expected chart values to be populated with default values") t.Error("Expected chart values to be populated with default values")
} }

@ -133,7 +133,7 @@ func ProcessRequirementsConditions(reqs *Requirements, cvals Values) {
} }
for _, r := range reqs.Dependencies { for _, r := range reqs.Dependencies {
var hasTrue, hasFalse bool var hasTrue, hasFalse bool
cond = string(r.Condition) cond = r.Condition
// check for list // check for list
if len(cond) > 0 { if len(cond) > 0 {
if strings.Contains(cond, ",") { if strings.Contains(cond, ",") {
@ -247,7 +247,7 @@ func getAliasDependency(charts []*chart.Chart, aliasChart *Dependency) *chart.Ch
} }
// ProcessRequirementsEnabled removes disabled charts from dependencies // ProcessRequirementsEnabled removes disabled charts from dependencies
func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error { func ProcessRequirementsEnabled(c *chart.Chart, v []byte) error {
reqs, err := LoadRequirements(c) reqs, err := LoadRequirements(c)
if err != nil { if err != nil {
// if not just missing requirements file, return error // if not just missing requirements file, return error
@ -297,11 +297,10 @@ func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error {
return err return err
} }
// convert our values back into config // convert our values back into config
yvals, err := cvals.YAML() yvals, err := yaml.Marshal(cvals)
if err != nil { if err != nil {
return err return err
} }
cc := chart.Config{Raw: yvals}
// flag dependencies as enabled/disabled // flag dependencies as enabled/disabled
ProcessRequirementsTags(reqs, cvals) ProcessRequirementsTags(reqs, cvals)
ProcessRequirementsConditions(reqs, cvals) ProcessRequirementsConditions(reqs, cvals)
@ -324,7 +323,7 @@ func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error {
} }
// recursively call self to process sub dependencies // recursively call self to process sub dependencies
for _, t := range cd { for _, t := range cd {
err := ProcessRequirementsEnabled(t, &cc) err := ProcessRequirementsEnabled(t, yvals)
// if its not just missing requirements file, return error // if its not just missing requirements file, return error
if nerr, ok := err.(ErrNoRequirementsFile); !ok && err != nil { if nerr, ok := err.(ErrNoRequirementsFile); !ok && err != nil {
return nerr return nerr
@ -388,7 +387,7 @@ func processImportValues(c *chart.Chart) error {
return err return err
} }
// combine chart values and empty config to get Values // combine chart values and empty config to get Values
cvals, err := CoalesceValues(c, &chart.Config{}) cvals, err := CoalesceValues(c, []byte{})
if err != nil { if err != nil {
return err return err
} }
@ -441,7 +440,7 @@ func processImportValues(c *chart.Chart) error {
} }
// set the new values // set the new values
c.Values = &chart.Config{Raw: string(y)} c.Values = y
return nil return nil
} }

@ -45,7 +45,7 @@ func TestRequirementsTagsNonValue(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags with no effect // tags with no effect
v := &chart.Config{Raw: "tags:\n nothinguseful: false\n\n"} v := []byte("tags:\n nothinguseful: false\n\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subcharta", "subchartb"} e := []string{"parentchart", "subchart1", "subcharta", "subchartb"}
@ -57,7 +57,7 @@ func TestRequirementsTagsDisabledL1(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags disabling a group // tags disabling a group
v := &chart.Config{Raw: "tags:\n front-end: false\n\n"} v := []byte("tags:\n front-end: false\n\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart"} e := []string{"parentchart"}
@ -69,7 +69,7 @@ func TestRequirementsTagsEnabledL1(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags disabling a group and enabling a different group // tags disabling a group and enabling a different group
v := &chart.Config{Raw: "tags:\n front-end: false\n\n back-end: true\n"} v := []byte("tags:\n front-end: false\n\n back-end: true\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart2", "subchartb", "subchartc"} e := []string{"parentchart", "subchart2", "subchartb", "subchartc"}
@ -82,7 +82,7 @@ func TestRequirementsTagsDisabledL2(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags disabling only children, children still enabled since tag front-end=true in values.yaml // tags disabling only children, children still enabled since tag front-end=true in values.yaml
v := &chart.Config{Raw: "tags:\n subcharta: false\n\n subchartb: false\n"} v := []byte("tags:\n subcharta: false\n\n subchartb: false\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subcharta", "subchartb"} e := []string{"parentchart", "subchart1", "subcharta", "subchartb"}
@ -94,7 +94,7 @@ func TestRequirementsTagsDisabledL1Mixed(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags disabling all parents/children with additional tag re-enabling a parent // tags disabling all parents/children with additional tag re-enabling a parent
v := &chart.Config{Raw: "tags:\n front-end: false\n\n subchart1: true\n\n back-end: false\n"} v := []byte("tags:\n front-end: false\n\n subchart1: true\n\n back-end: false\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1"} e := []string{"parentchart", "subchart1"}
@ -106,7 +106,7 @@ func TestRequirementsConditionsNonValue(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags with no effect // tags with no effect
v := &chart.Config{Raw: "subchart1:\n nothinguseful: false\n\n"} v := []byte("subchart1:\n nothinguseful: false\n\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subcharta", "subchartb"} e := []string{"parentchart", "subchart1", "subcharta", "subchartb"}
@ -118,7 +118,7 @@ func TestRequirementsConditionsEnabledL1Both(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// conditions enabling the parent charts, but back-end (b, c) is still disabled via values.yaml // conditions enabling the parent charts, but back-end (b, c) is still disabled via values.yaml
v := &chart.Config{Raw: "subchart1:\n enabled: true\nsubchart2:\n enabled: true\n"} v := []byte("subchart1:\n enabled: true\nsubchart2:\n enabled: true\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subchart2", "subcharta", "subchartb"} e := []string{"parentchart", "subchart1", "subchart2", "subcharta", "subchartb"}
@ -130,7 +130,7 @@ func TestRequirementsConditionsDisabledL1Both(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// conditions disabling the parent charts, effectively disabling children // conditions disabling the parent charts, effectively disabling children
v := &chart.Config{Raw: "subchart1:\n enabled: false\nsubchart2:\n enabled: false\n"} v := []byte("subchart1:\n enabled: false\nsubchart2:\n enabled: false\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart"} e := []string{"parentchart"}
@ -143,7 +143,7 @@ func TestRequirementsConditionsSecond(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// conditions a child using the second condition path of child's condition // conditions a child using the second condition path of child's condition
v := &chart.Config{Raw: "subchart1:\n subcharta:\n enabled: false\n"} v := []byte("subchart1:\n subcharta:\n enabled: false\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subchartb"} e := []string{"parentchart", "subchart1", "subchartb"}
@ -155,7 +155,7 @@ func TestRequirementsCombinedDisabledL2(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags enabling a parent/child group with condition disabling one child // tags enabling a parent/child group with condition disabling one child
v := &chart.Config{Raw: "subchartc:\n enabled: false\ntags:\n back-end: true\n"} v := []byte("subchartc:\n enabled: false\ntags:\n back-end: true\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart", "subchart1", "subchart2", "subcharta", "subchartb", "subchartb"} e := []string{"parentchart", "subchart1", "subchart2", "subcharta", "subchartb", "subchartb"}
@ -167,14 +167,14 @@ func TestRequirementsCombinedDisabledL1(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
// tags will not enable a child if parent is explicitly disabled with condition // tags will not enable a child if parent is explicitly disabled with condition
v := &chart.Config{Raw: "subchart1:\n enabled: false\ntags:\n front-end: true\n"} v := []byte("subchart1:\n enabled: false\ntags:\n front-end: true\n")
// expected charts including duplicates in alphanumeric order // expected charts including duplicates in alphanumeric order
e := []string{"parentchart"} e := []string{"parentchart"}
verifyRequirementsEnabled(t, c, v, e) verifyRequirementsEnabled(t, c, v, e)
} }
func verifyRequirementsEnabled(t *testing.T, c *chart.Chart, v *chart.Config, e []string) { func verifyRequirementsEnabled(t *testing.T, c *chart.Chart, v []byte, e []string) {
out := []*chart.Chart{} out := []*chart.Chart{}
err := ProcessRequirementsEnabled(c, v) err := ProcessRequirementsEnabled(c, v)
if err != nil { if err != nil {
@ -216,7 +216,7 @@ func TestProcessRequirementsImportValues(t *testing.T) {
t.Fatalf("Failed to load testdata: %s", err) t.Fatalf("Failed to load testdata: %s", err)
} }
v := &chart.Config{Raw: ""} v := []byte{}
e := make(map[string]string) e := make(map[string]string)
@ -281,14 +281,13 @@ func TestProcessRequirementsImportValues(t *testing.T) {
verifyRequirementsImportValues(t, c, v, e) verifyRequirementsImportValues(t, c, v, e)
} }
func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Config, e map[string]string) { func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v []byte, e map[string]string) {
err := ProcessRequirementsImportValues(c) err := ProcessRequirementsImportValues(c)
if err != nil { if err != nil {
t.Errorf("Error processing import values requirements %v", err) t.Errorf("Error processing import values requirements %v", err)
} }
cv := c.Values cc, err := ReadValues(c.Values)
cc, err := ReadValues([]byte(cv.Raw))
if err != nil { if err != nil {
t.Errorf("Error reading import values %v", err) t.Errorf("Error reading import values %v", err)
} }

@ -46,9 +46,9 @@ func SaveDir(c *chart.Chart, dest string) error {
} }
// Save values.yaml // Save values.yaml
if c.Values != nil && len(c.Values.Raw) > 0 { if len(c.Values) > 0 {
vf := filepath.Join(outdir, ValuesfileName) vf := filepath.Join(outdir, ValuesfileName)
if err := ioutil.WriteFile(vf, []byte(c.Values.Raw), 0755); err != nil { if err := ioutil.WriteFile(vf, c.Values, 0755); err != nil {
return err return err
} }
} }
@ -170,8 +170,8 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
} }
// Save values.yaml // Save values.yaml
if c.Values != nil && len(c.Values.Raw) > 0 { if len(c.Values) > 0 {
if err := writeToTar(out, base+"/values.yaml", []byte(c.Values.Raw)); err != nil { if err := writeToTar(out, base+"/values.yaml", c.Values); err != nil {
return err return err
} }
} }

@ -17,6 +17,7 @@ limitations under the License.
package chartutil package chartutil
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
@ -37,9 +38,7 @@ func TestSave(t *testing.T) {
Name: "ahab", Name: "ahab",
Version: "1.2.3.4", Version: "1.2.3.4",
}, },
Values: &chart.Config{ Values: []byte("ship: Pequod"),
Raw: "ship: Pequod",
},
Files: []*chart.File{ Files: []*chart.File{
{Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")}, {Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")},
}, },
@ -64,7 +63,7 @@ func TestSave(t *testing.T) {
if c2.Metadata.Name != c.Metadata.Name { if c2.Metadata.Name != c.Metadata.Name {
t.Fatalf("Expected chart archive to have %q, got %q", c.Metadata.Name, c2.Metadata.Name) t.Fatalf("Expected chart archive to have %q, got %q", c.Metadata.Name, c2.Metadata.Name)
} }
if c2.Values.Raw != c.Values.Raw { if !bytes.Equal(c2.Values, c.Values) {
t.Fatal("Values data did not match") t.Fatal("Values data did not match")
} }
if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" { if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" {
@ -84,9 +83,7 @@ func TestSaveDir(t *testing.T) {
Name: "ahab", Name: "ahab",
Version: "1.2.3.4", Version: "1.2.3.4",
}, },
Values: &chart.Config{ Values: []byte("ship: Pequod"),
Raw: "ship: Pequod",
},
Files: []*chart.File{ Files: []*chart.File{
{Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")}, {Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")},
}, },
@ -104,7 +101,7 @@ func TestSaveDir(t *testing.T) {
if c2.Metadata.Name != c.Metadata.Name { if c2.Metadata.Name != c.Metadata.Name {
t.Fatalf("Expected chart archive to have %q, got %q", c.Metadata.Name, c2.Metadata.Name) t.Fatalf("Expected chart archive to have %q, got %q", c.Metadata.Name, c2.Metadata.Name)
} }
if c2.Values.Raw != c.Values.Raw { if !bytes.Equal(c2.Values, c.Values) {
t.Fatal("Values data did not match") t.Fatal("Values data did not match")
} }
if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" { if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" {

@ -142,12 +142,12 @@ func ReadValuesFile(filename string) (Values, error) {
// - Scalar values and arrays are replaced, maps are merged // - Scalar values and arrays are replaced, maps are merged
// - A chart has access to all of the variables for it, as well as all of // - A chart has access to all of the variables for it, as well as all of
// the values destined for its dependencies. // the values destined for its dependencies.
func CoalesceValues(chrt *chart.Chart, vals *chart.Config) (Values, error) { func CoalesceValues(chrt *chart.Chart, vals []byte) (Values, error) {
cvals := Values{} cvals := Values{}
// Parse values if not nil. We merge these at the top level because // Parse values if not nil. We merge these at the top level because
// the passed-in values are in the same namespace as the parent chart. // the passed-in values are in the same namespace as the parent chart.
if vals != nil { if vals != nil {
evals, err := ReadValues([]byte(vals.Raw)) evals, err := ReadValues(vals)
if err != nil { if err != nil {
return cvals, err return cvals, err
} }
@ -267,16 +267,16 @@ func copyMap(src map[string]interface{}) map[string]interface{} {
// Values in v will override the values in the chart. // Values in v will override the values in the chart.
func coalesceValues(c *chart.Chart, v map[string]interface{}) (map[string]interface{}, error) { func coalesceValues(c *chart.Chart, v map[string]interface{}) (map[string]interface{}, error) {
// If there are no values in the chart, we just return the given values // If there are no values in the chart, we just return the given values
if c.Values == nil || c.Values.Raw == "" { if len(c.Values) == 0 {
return v, nil return v, nil
} }
nv, err := ReadValues([]byte(c.Values.Raw)) nv, err := ReadValues(c.Values)
if err != nil { if err != nil {
// On error, we return just the overridden values. // On error, we return just the overridden values.
// FIXME: We should log this error. It indicates that the YAML data // FIXME: We should log this error. It indicates that the YAML data
// did not parse. // did not parse.
return v, fmt.Errorf("error reading default values (%s): %s", c.Values.Raw, err) return v, fmt.Errorf("error reading default values (%s): %s", c.Values, err)
} }
for key, val := range nv { for key, val := range nv {
@ -349,7 +349,7 @@ type ReleaseOptions struct {
// remain in the codebase to stay SemVer compliant. // remain in the codebase to stay SemVer compliant.
// //
// In Helm 3.0, this will be changed to accept Capabilities as a fourth parameter. // In Helm 3.0, this will be changed to accept Capabilities as a fourth parameter.
func ToRenderValues(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOptions) (Values, error) { func ToRenderValues(chrt *chart.Chart, chrtVals []byte, options ReleaseOptions) (Values, error) {
caps := &Capabilities{APIVersions: DefaultVersionSet} caps := &Capabilities{APIVersions: DefaultVersionSet}
return ToRenderValuesCaps(chrt, chrtVals, options, caps) return ToRenderValuesCaps(chrt, chrtVals, options, caps)
} }
@ -357,7 +357,7 @@ func ToRenderValues(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOp
// ToRenderValuesCaps composes the struct from the data coming from the Releases, Charts and Values files // ToRenderValuesCaps composes the struct from the data coming from the Releases, Charts and Values files
// //
// This takes both ReleaseOptions and Capabilities to merge into the render values. // This takes both ReleaseOptions and Capabilities to merge into the render values.
func ToRenderValuesCaps(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOptions, caps *Capabilities) (Values, error) { func ToRenderValuesCaps(chrt *chart.Chart, chrtVals []byte, options ReleaseOptions, caps *Capabilities) (Values, error) {
top := map[string]interface{}{ top := map[string]interface{}{
"Release": map[string]interface{}{ "Release": map[string]interface{}{

@ -89,18 +89,18 @@ where:
c := &chart.Chart{ c := &chart.Chart{
Metadata: &chart.Metadata{Name: "test"}, Metadata: &chart.Metadata{Name: "test"},
Templates: []*chart.File{}, Templates: []*chart.File{},
Values: &chart.Config{Raw: chartValues}, Values: []byte(chartValues),
Dependencies: []*chart.Chart{ Dependencies: []*chart.Chart{
{ {
Metadata: &chart.Metadata{Name: "where"}, Metadata: &chart.Metadata{Name: "where"},
Values: &chart.Config{Raw: ""}, Values: []byte{},
}, },
}, },
Files: []*chart.File{ Files: []*chart.File{
{Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")}, {Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")},
}, },
} }
v := &chart.Config{Raw: overideValues} v := []byte(overideValues)
o := ReleaseOptions{ o := ReleaseOptions{
Name: "Seven Voyages", Name: "Seven Voyages",
@ -305,9 +305,7 @@ func TestCoalesceValues(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
tvals := &chart.Config{Raw: testCoalesceValuesYaml} v, err := CoalesceValues(c, []byte(testCoalesceValuesYaml))
v, err := CoalesceValues(c, tvals)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -97,18 +97,15 @@ func TestRender(t *testing.T) {
{Name: "templates/test2", Data: []byte("{{.global.callme | lower }}")}, {Name: "templates/test2", Data: []byte("{{.global.callme | lower }}")},
{Name: "templates/test3", Data: []byte("{{.noValue}}")}, {Name: "templates/test3", Data: []byte("{{.noValue}}")},
}, },
Values: &chart.Config{ Values: []byte("outer: DEFAULT\ninner: DEFAULT"),
Raw: "outer: DEFAULT\ninner: DEFAULT",
},
} }
vals := &chart.Config{ vals := []byte(`
Raw: `
outer: spouter outer: spouter
inner: inn inner: inn
global: global:
callme: Ishmael callme: Ishmael
`} `)
e := New() e := New()
v, err := chartutil.CoalesceValues(c, vals) v, err := chartutil.CoalesceValues(c, vals)
@ -280,7 +277,7 @@ func TestRenderNestedValues(t *testing.T) {
{Name: deepestpath, Data: []byte(`And this same {{.Values.what}} that smiles {{.Values.global.when}}`)}, {Name: deepestpath, Data: []byte(`And this same {{.Values.what}} that smiles {{.Values.global.when}}`)},
{Name: checkrelease, Data: []byte(`Tomorrow will be {{default "happy" .Release.Name }}`)}, {Name: checkrelease, Data: []byte(`Tomorrow will be {{default "happy" .Release.Name }}`)},
}, },
Values: &chart.Config{Raw: `what: "milkshake"`}, Values: []byte(`what: "milkshake"`),
} }
inner := &chart.Chart{ inner := &chart.Chart{
@ -288,7 +285,7 @@ func TestRenderNestedValues(t *testing.T) {
Templates: []*chart.File{ Templates: []*chart.File{
{Name: innerpath, Data: []byte(`Old {{.Values.who}} is still a-flyin'`)}, {Name: innerpath, Data: []byte(`Old {{.Values.who}} is still a-flyin'`)},
}, },
Values: &chart.Config{Raw: `who: "Robert"`}, Values: []byte(`who: "Robert"`),
Dependencies: []*chart.Chart{deepest}, Dependencies: []*chart.Chart{deepest},
} }
@ -297,27 +294,23 @@ func TestRenderNestedValues(t *testing.T) {
Templates: []*chart.File{ Templates: []*chart.File{
{Name: outerpath, Data: []byte(`Gather ye {{.Values.what}} while ye may`)}, {Name: outerpath, Data: []byte(`Gather ye {{.Values.what}} while ye may`)},
}, },
Values: &chart.Config{ Values: []byte(`
Raw: `
what: stinkweed what: stinkweed
who: me who: me
herrick: herrick:
who: time`, who: time`),
},
Dependencies: []*chart.Chart{inner}, Dependencies: []*chart.Chart{inner},
} }
injValues := chart.Config{ injValues := []byte(`
Raw: `
what: rosebuds what: rosebuds
herrick: herrick:
deepest: deepest:
what: flower what: flower
global: global:
when: to-day`, when: to-day`)
}
tmp, err := chartutil.CoalesceValues(outer, &injValues) tmp, err := chartutil.CoalesceValues(outer, injValues)
if err != nil { if err != nil {
t.Fatalf("Failed to coalesce values: %s", err) t.Fatalf("Failed to coalesce values: %s", err)
} }
@ -365,7 +358,7 @@ func TestRenderBuiltinValues(t *testing.T) {
{Name: "templates/Lavinia", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)}, {Name: "templates/Lavinia", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)},
{Name: "templates/From", Data: []byte(`{{.Files.author | printf "%s"}} {{.Files.Get "book/title.txt"}}`)}, {Name: "templates/From", Data: []byte(`{{.Files.author | printf "%s"}} {{.Files.Get "book/title.txt"}}`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
Files: []*chart.File{ Files: []*chart.File{
{Name: "author", Data: []byte("Virgil")}, {Name: "author", Data: []byte("Virgil")},
@ -378,12 +371,12 @@ func TestRenderBuiltinValues(t *testing.T) {
Templates: []*chart.File{ Templates: []*chart.File{
{Name: "templates/Aeneas", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)}, {Name: "templates/Aeneas", Data: []byte(`{{.Template.Name}}{{.Chart.Name}}{{.Release.Name}}`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{inner}, Dependencies: []*chart.Chart{inner},
} }
inject := chartutil.Values{ inject := chartutil.Values{
"Values": &chart.Config{Raw: ""}, "Values": "",
"Chart": outer.Metadata, "Chart": outer.Metadata,
"Release": chartutil.Values{ "Release": chartutil.Values{
"Name": "Aeneid", "Name": "Aeneid",
@ -417,12 +410,12 @@ func TestAlterFuncMap(t *testing.T) {
{Name: "templates/quote", Data: []byte(`{{include "conrad/templates/_partial" . | indent 2}} dead.`)}, {Name: "templates/quote", Data: []byte(`{{include "conrad/templates/_partial" . | indent 2}} dead.`)},
{Name: "templates/_partial", Data: []byte(`{{.Release.Name}} - he`)}, {Name: "templates/_partial", Data: []byte(`{{.Release.Name}} - he`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
} }
v := chartutil.Values{ v := chartutil.Values{
"Values": &chart.Config{Raw: ""}, "Values": "",
"Chart": c.Metadata, "Chart": c.Metadata,
"Release": chartutil.Values{ "Release": chartutil.Values{
"Name": "Mistah Kurtz", "Name": "Mistah Kurtz",
@ -445,7 +438,7 @@ func TestAlterFuncMap(t *testing.T) {
{Name: "templates/quote", Data: []byte(`All your base are belong to {{ required "A valid 'who' is required" .Values.who }}`)}, {Name: "templates/quote", Data: []byte(`All your base are belong to {{ required "A valid 'who' is required" .Values.who }}`)},
{Name: "templates/bases", Data: []byte(`All {{ required "A valid 'bases' is required" .Values.bases }} of them!`)}, {Name: "templates/bases", Data: []byte(`All {{ required "A valid 'bases' is required" .Values.bases }} of them!`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
} }
@ -479,7 +472,7 @@ func TestAlterFuncMap(t *testing.T) {
Templates: []*chart.File{ Templates: []*chart.File{
{Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value}}" .}}`)}, {Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value}}" .}}`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
} }
@ -508,7 +501,7 @@ func TestAlterFuncMap(t *testing.T) {
Templates: []*chart.File{ Templates: []*chart.File{
{Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value | quote}}" .}}`)}, {Name: "templates/base", Data: []byte(`Evaluate tpl {{tpl "Value: {{ .Values.value | quote}}" .}}`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
} }
@ -538,7 +531,7 @@ func TestAlterFuncMap(t *testing.T) {
{Name: "templates/base", Data: []byte(`{{ tpl "{{include ` + "`" + `TplFunction/templates/_partial` + "`" + ` . | quote }}" .}}`)}, {Name: "templates/base", Data: []byte(`{{ tpl "{{include ` + "`" + `TplFunction/templates/_partial` + "`" + ` . | quote }}" .}}`)},
{Name: "templates/_partial", Data: []byte(`{{.Template.Name}}`)}, {Name: "templates/_partial", Data: []byte(`{{.Template.Name}}`)},
}, },
Values: &chart.Config{Raw: ``}, Values: []byte{},
Dependencies: []*chart.Chart{}, Dependencies: []*chart.Chart{},
} }
tplValueWithInclude := chartutil.Values{ tplValueWithInclude := chartutil.Values{

@ -10,7 +10,7 @@ type Chart struct {
// Charts that this chart depends on. // Charts that this chart depends on.
Dependencies []*Chart `json:"dependencies,omitempty"` Dependencies []*Chart `json:"dependencies,omitempty"`
// Default config for this template. // Default config for this template.
Values *Config `json:"values,omitempty"` Values []byte `json:"values,omitempty"`
// Miscellaneous files in a chart archive, // Miscellaneous files in a chart archive,
// e.g. README, LICENSE, etc. // e.g. README, LICENSE, etc.
Files []*File `json:"files,omitempty"` Files []*File `json:"files,omitempty"`

@ -1,12 +0,0 @@
package chart
// Config supplies values to the parametrizable templates of a chart.
type Config struct {
Raw string `json:"raw,omitempty"`
Values map[string]*Value `json:"values,omitempty"`
}
// Value describes a configuration value as a string.
type Value struct {
Value string `json:"value,omitempty"`
}

@ -13,7 +13,7 @@ type Release struct {
Chart *chart.Chart `json:"chart,omitempty"` Chart *chart.Chart `json:"chart,omitempty"`
// Config is the set of extra Values added to the chart. // Config is the set of extra Values added to the chart.
// These values override the default values inside of the chart. // These values override the default values inside of the chart.
Config *chart.Config `json:"config,omitempty"` Config []byte `json:"config,omitempty"`
// Manifest is the string representation of the rendered template. // Manifest is the string representation of the rendered template.
Manifest string `json:"manifest,omitempty"` Manifest string `json:"manifest,omitempty"`
// Hooks are all of the hooks declared for this release. // Hooks are all of the hooks declared for this release.

@ -110,7 +110,7 @@ type UpdateReleaseRequest struct {
// Chart is the protobuf representation of a chart. // Chart is the protobuf representation of a chart.
Chart *chart.Chart `json:"chart,omityempty"` Chart *chart.Chart `json:"chart,omityempty"`
// Values is a string containing (unparsed) YAML values. // Values is a string containing (unparsed) YAML values.
Values *chart.Config `json:"values,omityempty"` Values []byte `json:"values,omityempty"`
// dry_run, if true, will run through the release logic, but neither create // dry_run, if true, will run through the release logic, but neither create
DryRun bool `json:"dry_run,omityempty"` DryRun bool `json:"dry_run,omityempty"`
// DisableHooks causes the server to skip running any hooks for the upgrade. // DisableHooks causes the server to skip running any hooks for the upgrade.
@ -156,7 +156,7 @@ type InstallReleaseRequest struct {
// Chart is the protobuf representation of a chart. // Chart is the protobuf representation of a chart.
Chart *chart.Chart `json:"chart,omityempty"` Chart *chart.Chart `json:"chart,omityempty"`
// Values is a string containing (unparsed) YAML values. // Values is a string containing (unparsed) YAML values.
Values *chart.Config `json:"values,omityempty"` Values []byte `json:"values,omityempty"`
// DryRun, if true, will run through the release logic, but neither create // DryRun, if true, will run through the release logic, but neither create
// a release object nor deploy to Kubernetes. The release object returned // a release object nor deploy to Kubernetes. The release object returned
// in the response will be fake. // in the response will be fake.

@ -231,7 +231,7 @@ func ReleaseMock(opts *MockReleaseOptions) *release.Release {
Description: "Release mock", Description: "Release mock",
}, },
Chart: ch, Chart: ch,
Config: &chart.Config{Raw: `name: "value"`}, Config: []byte(`name: "value"`),
Version: version, Version: version,
Namespace: namespace, Namespace: namespace,
Hooks: []*release.Hook{ Hooks: []*release.Hook{

@ -109,7 +109,7 @@ func TestInstallRelease_VerifyOptions(t *testing.T) {
// Expected InstallReleaseRequest message // Expected InstallReleaseRequest message
exp := &hapi.InstallReleaseRequest{ exp := &hapi.InstallReleaseRequest{
Chart: loadChart(t, chartName), Chart: loadChart(t, chartName),
Values: &cpb.Config{Raw: string(overrides)}, Values: overrides,
DryRun: dryRun, DryRun: dryRun,
Name: releaseName, Name: releaseName,
DisableHooks: disableHooks, DisableHooks: disableHooks,
@ -202,7 +202,7 @@ func TestUpdateRelease_VerifyOptions(t *testing.T) {
exp := &hapi.UpdateReleaseRequest{ exp := &hapi.UpdateReleaseRequest{
Name: releaseName, Name: releaseName,
Chart: loadChart(t, chartName), Chart: loadChart(t, chartName),
Values: &cpb.Config{Raw: string(overrides)}, Values: overrides,
DryRun: dryRun, DryRun: dryRun,
DisableHooks: disableHooks, DisableHooks: disableHooks,
} }

@ -20,7 +20,6 @@ import (
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/helm/pkg/hapi" "k8s.io/helm/pkg/hapi"
cpb "k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/storage/driver" "k8s.io/helm/pkg/storage/driver"
"k8s.io/helm/pkg/tiller/environment" "k8s.io/helm/pkg/tiller/environment"
@ -154,7 +153,7 @@ type InstallOption func(*options)
// ValueOverrides specifies a list of values to include when installing. // ValueOverrides specifies a list of values to include when installing.
func ValueOverrides(raw []byte) InstallOption { func ValueOverrides(raw []byte) InstallOption {
return func(opts *options) { return func(opts *options) {
opts.instReq.Values = &cpb.Config{Raw: string(raw)} opts.instReq.Values = raw
} }
} }
@ -231,7 +230,7 @@ func RollbackWait(wait bool) RollbackOption {
// UpdateValueOverrides specifies a list of values to include when upgrading // UpdateValueOverrides specifies a list of values to include when upgrading
func UpdateValueOverrides(raw []byte) UpdateOption { func UpdateValueOverrides(raw []byte) UpdateOption {
return func(opts *options) { return func(opts *options) {
opts.updateReq.Values = &cpb.Config{Raw: string(raw)} opts.updateReq.Values = raw
} }
} }

@ -39,7 +39,7 @@ var (
nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml") nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
) )
var badChart, chatLoadRrr = chartutil.LoadChartfile(badChartFilePath) var badChart, _ = chartutil.LoadChartfile(badChartFilePath)
var goodChart, _ = chartutil.LoadChartfile(goodChartFilePath) var goodChart, _ = chartutil.LoadChartfile(goodChartFilePath)
// Validation functions Test // Validation functions Test

@ -27,7 +27,6 @@ import (
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/engine" "k8s.io/helm/pkg/engine"
cpb "k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/lint/support" "k8s.io/helm/pkg/lint/support"
tversion "k8s.io/helm/pkg/version" tversion "k8s.io/helm/pkg/version"
) )
@ -59,17 +58,16 @@ func Templates(linter *support.Linter, values []byte, namespace string, strict b
KubeVersion: chartutil.DefaultKubeVersion, KubeVersion: chartutil.DefaultKubeVersion,
TillerVersion: tversion.GetVersionProto(), TillerVersion: tversion.GetVersionProto(),
} }
cvals, err := chartutil.CoalesceValues(chart, &cpb.Config{Raw: string(values)}) cvals, err := chartutil.CoalesceValues(chart, values)
if err != nil { if err != nil {
return return
} }
// convert our values back into config // convert our values back into config
yvals, err := cvals.YAML() yvals, err := yaml.Marshal(cvals)
if err != nil { if err != nil {
return return
} }
cc := &cpb.Config{Raw: yvals} valuesToRender, err := chartutil.ToRenderValuesCaps(chart, yvals, options, caps)
valuesToRender, err := chartutil.ToRenderValuesCaps(chart, cc, options, caps)
if err != nil { if err != nil {
// FIXME: This seems to generate a duplicate, but I can't find where the first // FIXME: This seems to generate a duplicate, but I can't find where the first
// error is coming from. // error is coming from.

@ -29,16 +29,16 @@ import (
func Values(linter *support.Linter) { func Values(linter *support.Linter) {
file := "values.yaml" file := "values.yaml"
vf := filepath.Join(linter.ChartDir, file) vf := filepath.Join(linter.ChartDir, file)
fileExists := linter.RunLinterRule(support.InfoSev, file, validateValuesFileExistence(linter, vf)) fileExists := linter.RunLinterRule(support.InfoSev, file, validateValuesFileExistence(vf))
if !fileExists { if !fileExists {
return return
} }
linter.RunLinterRule(support.ErrorSev, file, validateValuesFile(linter, vf)) linter.RunLinterRule(support.ErrorSev, file, validateValuesFile(vf))
} }
func validateValuesFileExistence(linter *support.Linter, valuesPath string) error { func validateValuesFileExistence(valuesPath string) error {
_, err := os.Stat(valuesPath) _, err := os.Stat(valuesPath)
if err != nil { if err != nil {
return fmt.Errorf("file does not exist") return fmt.Errorf("file does not exist")
@ -46,7 +46,7 @@ func validateValuesFileExistence(linter *support.Linter, valuesPath string) erro
return nil return nil
} }
func validateValuesFile(linter *support.Linter, valuesPath string) error { func validateValuesFile(valuesPath string) error {
_, err := chartutil.ReadValuesFile(valuesPath) _, err := chartutil.ReadValuesFile(valuesPath)
if err != nil { if err != nil {
return fmt.Errorf("unable to parse YAML\n\t%s", err) return fmt.Errorf("unable to parse YAML\n\t%s", err)

@ -122,18 +122,19 @@ func (s *ReleaseServer) reuseValues(req *hapi.UpdateReleaseRequest, current *rel
s.Log("%s", err) s.Log("%s", err)
return err return err
} }
nv, err := oldVals.YAML() nv, err := yaml.Marshal(oldVals)
if err != nil { if err != nil {
return err return err
} }
// merge new values with current // merge new values with current
req.Values.Raw = current.Config.Raw + "\n" + req.Values.Raw b := append(current.Config, '\n')
req.Chart.Values = &chart.Config{Raw: nv} req.Values = append(b, req.Values...)
req.Chart.Values = nv
// yaml unmarshal and marshal to remove duplicate keys // yaml unmarshal and marshal to remove duplicate keys
y := map[string]interface{}{} y := map[string]interface{}{}
if err := yaml.Unmarshal([]byte(req.Values.Raw), &y); err != nil { if err := yaml.Unmarshal(req.Values, &y); err != nil {
return err return err
} }
data, err := yaml.Marshal(y) data, err := yaml.Marshal(y)
@ -141,16 +142,15 @@ func (s *ReleaseServer) reuseValues(req *hapi.UpdateReleaseRequest, current *rel
return err return err
} }
req.Values.Raw = string(data) req.Values = data
return nil return nil
} }
// If req.Values is empty, but current.Config is not, copy current into the // If req.Values is empty, but current.Config is not, copy current into the
// request. // request.
if (req.Values == nil || req.Values.Raw == "" || req.Values.Raw == "{}\n") && if (len(req.Values) == 0 || bytes.Equal(req.Values, []byte("{}\n"))) &&
current.Config != nil && len(current.Config) > 0 &&
current.Config.Raw != "" && !bytes.Equal(current.Config, []byte("{}\n")) {
current.Config.Raw != "{}\n" {
s.Log("copying values from %s (v%d) to new release.", current.Name, current.Version) s.Log("copying values from %s (v%d) to new release.", current.Name, current.Version)
req.Values = current.Config req.Values = current.Config
} }

@ -229,7 +229,7 @@ func namedReleaseStub(name string, status release.StatusCode) *release.Release {
Description: "Named Release Stub", Description: "Named Release Stub",
}, },
Chart: chartStub(), Chart: chartStub(),
Config: &chart.Config{Raw: `name: value`}, Config: []byte(`name: value`),
Version: 1, Version: 1,
Hooks: []*release.Hook{ Hooks: []*release.Hook{
{ {
@ -369,7 +369,7 @@ func releaseWithKeepStub(rlsName string) *release.Release {
Status: &release.Status{Code: release.Status_DEPLOYED}, Status: &release.Status{Code: release.Status_DEPLOYED},
}, },
Chart: ch, Chart: ch,
Config: &chart.Config{Raw: `name: value`}, Config: []byte(`name: value`),
Version: 1, Version: 1,
Manifest: manifestWithKeep, Manifest: manifestWithKeep,
} }

@ -17,7 +17,7 @@ limitations under the License.
package tiller package tiller
import ( import (
"fmt" "bytes"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -82,8 +82,8 @@ func TestUpdateRelease(t *testing.T) {
if res.Config == nil { if res.Config == nil {
t.Errorf("Got release without config: %#v", res) t.Errorf("Got release without config: %#v", res)
} else if res.Config.Raw != rel.Config.Raw { } else if !bytes.Equal(res.Config, rel.Config) {
t.Errorf("Expected release values %q, got %q", rel.Config.Raw, res.Config.Raw) t.Errorf("Expected release values %q, got %q", rel.Config, res.Config)
} }
if !strings.Contains(updated.Manifest, "---\n# Source: hello/templates/hello\nhello: world") { if !strings.Contains(updated.Manifest, "---\n# Source: hello/templates/hello\nhello: world") {
@ -120,8 +120,8 @@ func TestUpdateRelease_ResetValues(t *testing.T) {
t.Fatalf("Failed updated: %s", err) t.Fatalf("Failed updated: %s", err)
} }
// This should have been unset. Config: &chart.Config{Raw: `name: value`}, // This should have been unset. Config: &chart.Config{Raw: `name: value`},
if res.Config != nil && res.Config.Raw != "" { if len(res.Config) > 0 {
t.Errorf("Expected chart config to be empty, got %q", res.Config.Raw) t.Errorf("Expected chart config to be empty, got %q", res.Config)
} }
} }
@ -137,18 +137,17 @@ func TestUpdateRelease_ComplexReuseValues(t *testing.T) {
{Name: "templates/hello", Data: []byte("hello: world")}, {Name: "templates/hello", Data: []byte("hello: world")},
{Name: "templates/hooks", Data: []byte(manifestWithHook)}, {Name: "templates/hooks", Data: []byte(manifestWithHook)},
}, },
Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, Values: []byte("defaultFoo: defaultBar"),
}, },
Values: &chart.Config{Raw: "foo: bar"}, Values: []byte("foo: bar"),
} }
fmt.Println("Running Install release with foo: bar override") t.Log("Running Install release with foo: bar override")
installResp, err := rs.InstallRelease(installReq) rel, err := rs.InstallRelease(installReq)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
rel := installResp
req := &hapi.UpdateReleaseRequest{ req := &hapi.UpdateReleaseRequest{
Name: rel.Name, Name: rel.Name,
Chart: &chart.Chart{ Chart: &chart.Chart{
@ -157,22 +156,21 @@ func TestUpdateRelease_ComplexReuseValues(t *testing.T) {
{Name: "templates/hello", Data: []byte("hello: world")}, {Name: "templates/hello", Data: []byte("hello: world")},
{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
}, },
Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, Values: []byte("defaultFoo: defaultBar"),
}, },
} }
fmt.Println("Running Update release with no overrides and no reuse-values flag") t.Log("Running Update release with no overrides and no reuse-values flag")
res, err := rs.UpdateRelease(req) rel, err = rs.UpdateRelease(req)
if err != nil { if err != nil {
t.Fatalf("Failed updated: %s", err) t.Fatalf("Failed updated: %s", err)
} }
expect := "foo: bar" expect := "foo: bar"
if res.Config != nil && res.Config.Raw != expect { if rel.Config != nil && !bytes.Equal(rel.Config, []byte(expect)) {
t.Errorf("Expected chart values to be %q, got %q", expect, res.Config.Raw) t.Errorf("Expected chart values to be %q, got %q", expect, string(rel.Config))
} }
rel = res
req = &hapi.UpdateReleaseRequest{ req = &hapi.UpdateReleaseRequest{
Name: rel.Name, Name: rel.Name,
Chart: &chart.Chart{ Chart: &chart.Chart{
@ -181,13 +179,13 @@ func TestUpdateRelease_ComplexReuseValues(t *testing.T) {
{Name: "templates/hello", Data: []byte("hello: world")}, {Name: "templates/hello", Data: []byte("hello: world")},
{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
}, },
Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, Values: []byte("defaultFoo: defaultBar"),
}, },
Values: &chart.Config{Raw: "foo2: bar2"}, Values: []byte("foo2: bar2"),
ReuseValues: true, ReuseValues: true,
} }
fmt.Println("Running Update release with foo2: bar2 override and reuse-values") t.Log("Running Update release with foo2: bar2 override and reuse-values")
rel, err = rs.UpdateRelease(req) rel, err = rs.UpdateRelease(req)
if err != nil { if err != nil {
t.Fatalf("Failed updated: %s", err) t.Fatalf("Failed updated: %s", err)
@ -195,8 +193,8 @@ func TestUpdateRelease_ComplexReuseValues(t *testing.T) {
// This should have the newly-passed overrides. // This should have the newly-passed overrides.
expect = "foo: bar\nfoo2: bar2\n" expect = "foo: bar\nfoo2: bar2\n"
if rel.Config != nil && rel.Config.Raw != expect { if rel.Config != nil && !bytes.Equal(rel.Config, []byte(expect)) {
t.Errorf("Expected request config to be %q, got %q", expect, rel.Config.Raw) t.Errorf("Expected request config to be %q, got %q", expect, string(rel.Config))
} }
req = &hapi.UpdateReleaseRequest{ req = &hapi.UpdateReleaseRequest{
@ -207,20 +205,20 @@ func TestUpdateRelease_ComplexReuseValues(t *testing.T) {
{Name: "templates/hello", Data: []byte("hello: world")}, {Name: "templates/hello", Data: []byte("hello: world")},
{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
}, },
Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, Values: []byte("defaultFoo: defaultBar"),
}, },
Values: &chart.Config{Raw: "foo: baz"}, Values: []byte("foo: baz"),
ReuseValues: true, ReuseValues: true,
} }
fmt.Println("Running Update release with foo=baz override with reuse-values flag") t.Log("Running Update release with foo=baz override with reuse-values flag")
res, err = rs.UpdateRelease(req) rel, err = rs.UpdateRelease(req)
if err != nil { if err != nil {
t.Fatalf("Failed updated: %s", err) t.Fatalf("Failed updated: %s", err)
} }
expect = "foo: baz\nfoo2: bar2\n" expect = "foo: baz\nfoo2: bar2\n"
if res.Config != nil && res.Config.Raw != expect { if rel.Config != nil && !bytes.Equal(rel.Config, []byte(expect)) {
t.Errorf("Expected chart values to be %q, got %q", expect, res.Config.Raw) t.Errorf("Expected chart values to be %q, got %q", expect, rel.Config)
} }
} }
@ -238,9 +236,9 @@ func TestUpdateRelease_ReuseValues(t *testing.T) {
{Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)},
}, },
// Since reuseValues is set, this should get ignored. // Since reuseValues is set, this should get ignored.
Values: &chart.Config{Raw: "foo: bar\n"}, Values: []byte("foo: bar\n"),
}, },
Values: &chart.Config{Raw: "name2: val2"}, Values: []byte("name2: val2"),
ReuseValues: true, ReuseValues: true,
} }
res, err := rs.UpdateRelease(req) res, err := rs.UpdateRelease(req)
@ -249,13 +247,13 @@ func TestUpdateRelease_ReuseValues(t *testing.T) {
} }
// This should have been overwritten with the old value. // This should have been overwritten with the old value.
expect := "name: value\n" expect := "name: value\n"
if res.Chart.Values != nil && res.Chart.Values.Raw != expect { if res.Chart.Values != nil && !bytes.Equal(res.Chart.Values, []byte(expect)) {
t.Errorf("Expected chart values to be %q, got %q", expect, res.Chart.Values.Raw) t.Errorf("Expected chart values to be %q, got %q", expect, res.Chart.Values)
} }
// This should have the newly-passed overrides and any other computed values. `name: value` comes from release Config via releaseStub() // This should have the newly-passed overrides and any other computed values. `name: value` comes from release Config via releaseStub()
expect = "name: value\nname2: val2\n" expect = "name: value\nname2: val2\n"
if res.Config != nil && res.Config.Raw != expect { if res.Config != nil && !bytes.Equal(res.Config, []byte(expect)) {
t.Errorf("Expected request config to be %q, got %q", expect, res.Config.Raw) t.Errorf("Expected request config to be %q, got %q", expect, res.Config)
} }
compareStoredAndReturnedRelease(t, *rs, res) compareStoredAndReturnedRelease(t, *rs, res)
} }
@ -283,8 +281,8 @@ func TestUpdateRelease_ResetReuseValues(t *testing.T) {
t.Fatalf("Failed updated: %s", err) t.Fatalf("Failed updated: %s", err)
} }
// This should have been unset. Config: &chart.Config{Raw: `name: value`}, // This should have been unset. Config: &chart.Config{Raw: `name: value`},
if res.Config != nil && res.Config.Raw != "" { if len(res.Config) > 0 {
t.Errorf("Expected chart config to be empty, got %q", res.Config.Raw) t.Errorf("Expected chart config to be empty, got %q", res.Config)
} }
compareStoredAndReturnedRelease(t, *rs, res) compareStoredAndReturnedRelease(t, *rs, res)
} }

Loading…
Cancel
Save