expose LoadFiles as a usable function

In third-party libraries, charts can be embedded in memory rather than in files, directories or
tarballs. Exposing LoadFiles allows a third-party library the ability to load static templates
in and spit out a *chart.Chart.
pull/2042/head
Matthew Fisher 8 years ago
parent 90befab86b
commit de6fb23e7a

@ -53,10 +53,10 @@ func Load(name string) (*chart.Chart, error) {
return LoadFile(name)
}
// afile represents an archive file buffered for later processing.
type afile struct {
name string
data []byte
// BufferedFile represents an archive file buffered for later processing.
type BufferedFile struct {
Name string
Data []byte
}
// LoadArchive loads from a reader containing a compressed tar archive.
@ -67,7 +67,7 @@ func LoadArchive(in io.Reader) (*chart.Chart, error) {
}
defer unzipped.Close()
files := []*afile{}
files := []*BufferedFile{}
tr := tar.NewReader(unzipped)
for {
b := bytes.NewBuffer(nil)
@ -105,7 +105,7 @@ func LoadArchive(in io.Reader) (*chart.Chart, error) {
return &chart.Chart{}, err
}
files = append(files, &afile{name: n, data: b.Bytes()})
files = append(files, &BufferedFile{Name: n, Data: b.Bytes()})
b.Reset()
}
@ -113,41 +113,42 @@ func LoadArchive(in io.Reader) (*chart.Chart, error) {
return nil, errors.New("no files in chart archive")
}
return loadFiles(files)
return LoadFiles(files)
}
func loadFiles(files []*afile) (*chart.Chart, error) {
// LoadFiles loads from in-memory files.
func LoadFiles(files []*BufferedFile) (*chart.Chart, error) {
c := &chart.Chart{}
subcharts := map[string][]*afile{}
subcharts := map[string][]*BufferedFile{}
for _, f := range files {
if f.name == "Chart.yaml" {
m, err := UnmarshalChartfile(f.data)
if f.Name == "Chart.yaml" {
m, err := UnmarshalChartfile(f.Data)
if err != nil {
return c, err
}
c.Metadata = m
} 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")
} else if f.name == "values.yaml" {
c.Values = &chart.Config{Raw: string(f.data)}
} else if strings.HasPrefix(f.name, "templates/") {
c.Templates = append(c.Templates, &chart.Template{Name: f.name, Data: f.data})
} else if strings.HasPrefix(f.name, "charts/") {
if filepath.Ext(f.name) == ".prov" {
c.Files = append(c.Files, &any.Any{TypeUrl: f.name, Value: f.data})
} else if f.Name == "values.yaml" {
c.Values = &chart.Config{Raw: string(f.Data)}
} else if strings.HasPrefix(f.Name, "templates/") {
c.Templates = append(c.Templates, &chart.Template{Name: f.Name, Data: f.Data})
} else if strings.HasPrefix(f.Name, "charts/") {
if filepath.Ext(f.Name) == ".prov" {
c.Files = append(c.Files, &any.Any{TypeUrl: f.Name, Value: f.Data})
continue
}
cname := strings.TrimPrefix(f.name, "charts/")
cname := strings.TrimPrefix(f.Name, "charts/")
if strings.IndexAny(cname, "._") == 0 {
// Ignore charts/ that start with . or _.
continue
}
parts := strings.SplitN(cname, "/", 2)
scname := parts[0]
subcharts[scname] = append(subcharts[scname], &afile{name: cname, data: f.data})
subcharts[scname] = append(subcharts[scname], &BufferedFile{Name: cname, Data: f.Data})
} else {
c.Files = append(c.Files, &any.Any{TypeUrl: f.name, Value: f.data})
c.Files = append(c.Files, &any.Any{TypeUrl: f.Name, Value: f.Data})
}
}
@ -166,25 +167,25 @@ func loadFiles(files []*afile) (*chart.Chart, error) {
continue
} else if filepath.Ext(n) == ".tgz" {
file := files[0]
if file.name != n {
return c, fmt.Errorf("error unpacking tar in %s: expected %s, got %s", c.Metadata.Name, n, file.name)
if file.Name != n {
return c, fmt.Errorf("error unpacking tar in %s: expected %s, got %s", c.Metadata.Name, n, file.Name)
}
// Untar the chart and add to c.Dependencies
b := bytes.NewBuffer(file.data)
b := bytes.NewBuffer(file.Data)
sc, err = LoadArchive(b)
} else {
// We have to trim the prefix off of every file, and ignore any file
// that is in charts/, but isn't actually a chart.
buff := make([]*afile, 0, len(files))
buff := make([]*BufferedFile, 0, len(files))
for _, f := range files {
parts := strings.SplitN(f.name, "/", 2)
parts := strings.SplitN(f.Name, "/", 2)
if len(parts) < 2 {
continue
}
f.name = parts[1]
f.Name = parts[1]
buff = append(buff, f)
}
sc, err = loadFiles(buff)
sc, err = LoadFiles(buff)
}
if err != nil {
@ -237,7 +238,7 @@ func LoadDir(dir string) (*chart.Chart, error) {
}
rules.AddDefaults()
files := []*afile{}
files := []*BufferedFile{}
topdir += string(filepath.Separator)
err = symwalk.Walk(topdir, func(name string, fi os.FileInfo, err error) error {
@ -268,12 +269,12 @@ func LoadDir(dir string) (*chart.Chart, error) {
return fmt.Errorf("error reading %s: %s", n, err)
}
files = append(files, &afile{name: n, data: data})
files = append(files, &BufferedFile{Name: n, Data: data})
return nil
})
if err != nil {
return c, err
}
return loadFiles(files)
return LoadFiles(files)
}

@ -17,6 +17,7 @@ limitations under the License.
package chartutil
import (
"path"
"testing"
"k8s.io/helm/pkg/proto/hapi/chart"
@ -42,6 +43,83 @@ func TestLoadFile(t *testing.T) {
verifyRequirements(t, c)
}
func TestLoadFiles(t *testing.T) {
goodFiles := []*BufferedFile{
{
Name: ChartfileName,
Data: []byte(`apiVersion: v1
name: frobnitz
description: This is a frobnitz.
version: "1.2.3"
keywords:
- frobnitz
- sprocket
- dodad
maintainers:
- name: The Helm Team
email: helm@example.com
- name: Someone Else
email: nobody@example.com
sources:
- https://example.com/foo/bar
home: http://example.com
icon: https://example.com/64x64.png
`),
},
{
Name: ValuesfileName,
Data: []byte(defaultValues),
},
{
Name: path.Join("templates", DeploymentName),
Data: []byte(defaultDeployment),
},
{
Name: path.Join("templates", ServiceName),
Data: []byte(defaultService),
},
}
c, err := LoadFiles(goodFiles)
if err != nil {
t.Errorf("Expected good files to be loaded, got %v", err)
}
if c.Metadata.Name != "frobnitz" {
t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Metadata.Name)
}
if c.Values.Raw != defaultValues {
t.Error("Expected chart values to be populated with default values")
}
if len(c.Templates) != 2 {
t.Errorf("Expected number of templates == 2, got %d", len(c.Templates))
}
c, err = LoadFiles([]*BufferedFile{})
if err == nil {
t.Fatal("Expected err to be non-nil")
}
if err.Error() != "chart metadata (Chart.yaml) missing" {
t.Errorf("Expected chart metadata missing error, got '%s'", err.Error())
}
// legacy check
c, err = LoadFiles([]*BufferedFile{
{
Name: "values.toml",
Data: []byte{},
},
})
if err == nil {
t.Fatal("Expected err to be non-nil")
}
if err.Error() != "values.toml is illegal as of 2.0.0-alpha.2" {
t.Errorf("Expected values.toml to be illegal, got '%s'", err.Error())
}
}
// Packaging the chart on a Windows machine will produce an
// archive that has \\ as delimiters. Test that we support these archives
func TestLoadFileBackslash(t *testing.T) {

Loading…
Cancel
Save