ref(chartutil): introduce chartutil.Save

chartutil.Save has been renamed to chartutil.SaveArchive.

chartutil.Save accepts a chart and an io.Writer, wrapping the logic around serializing a chart to an io.Writer.

This allows other packages to write higher-level abstractions above chart.Save. For example, streaming a chart to a *bytes.Buffer.

Signed-off-by: Matthew Fisher <matt.fisher@microsoft.com>
pull/5873/head
Matthew Fisher 6 years ago
parent f109b1ba5c
commit 16ee16be8e
No known key found for this signature in database
GPG Key ID: 92AA783CBAAE8E3B

@ -94,7 +94,7 @@ func (p *Package) Run(path string) (string, error) {
dest = p.Destination
}
name, err := chartutil.Save(ch, dest)
name, err := chartutil.SaveArchive(ch, dest)
if err != nil {
return "", errors.Wrap(err, "failed to save")
}

@ -20,6 +20,7 @@ import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -33,6 +34,11 @@ import (
var headerBytes = []byte("+aHR0cHM6Ly95b3V0dS5iZS96OVV6MWljandyTQo=")
// SaveDir saves a chart as files in a directory.
//
// This takes an existing chart and a destination directory.
//
// If the directory is /foo, and the chart is named bar, with version 1.0.0, this
// will generate /foo/bar/Chart.yaml, /foo/bar/values.yaml, etc.
func SaveDir(c *chart.Chart, dest string) error {
// Create the chart directory
outdir := filepath.Join(dest, c.Name())
@ -89,14 +95,28 @@ func SaveDir(c *chart.Chart, dest string) error {
base := filepath.Join(outdir, ChartsDir)
for _, dep := range c.Dependencies() {
// Here, we write each dependency as a tar file.
if _, err := Save(dep, base); err != nil {
if _, err := SaveArchive(dep, base); err != nil {
return err
}
}
return nil
}
// Save creates an archived chart to the given directory.
// Save creates an archived chart and writes it to w.
func Save(c *chart.Chart, w io.Writer) error {
zipper := gzip.NewWriter(w)
defer zipper.Close()
zipper.Header.Extra = headerBytes
zipper.Header.Comment = "Helm"
// Wrap in tar writer
twriter := tar.NewWriter(zipper)
defer twriter.Close()
return writeTarContents(twriter, c, "")
}
// SaveArchive creates an archived chart to the given directory.
//
// This takes an existing chart and a destination directory.
//
@ -104,7 +124,7 @@ func SaveDir(c *chart.Chart, dest string) error {
// will generate /foo/bar-1.0.0.tgz.
//
// This returns the absolute path to the chart archive file.
func Save(c *chart.Chart, outDir string) (string, error) {
func SaveArchive(c *chart.Chart, outDir string) (string, error) {
// Create archive
if fi, err := os.Stat(outDir); err != nil {
return "", err
@ -131,24 +151,15 @@ func Save(c *chart.Chart, outDir string) (string, error) {
return "", err
}
// Wrap in gzip writer
zipper := gzip.NewWriter(f)
zipper.Header.Extra = headerBytes
zipper.Header.Comment = "Helm"
// Wrap in tar writer
twriter := tar.NewWriter(zipper)
rollback := false
defer func() {
twriter.Close()
zipper.Close()
f.Close()
if rollback {
os.Remove(filename)
}
}()
if err := writeTarContents(twriter, c, ""); err != nil {
if err := Save(c, f); err != nil {
rollback = true
}
return filename, err

@ -17,6 +17,7 @@ limitations under the License.
package chartutil
import (
"bytes"
"io/ioutil"
"os"
"strings"
@ -27,6 +28,36 @@ import (
)
func TestSave(t *testing.T) {
c := &chart.Chart{
Metadata: &chart.Metadata{
APIVersion: chart.APIVersionV1,
Name: "ahab",
Version: "1.2.3",
},
Files: []*chart.File{
{Name: "scheherazade/shahryar.txt", Data: []byte("1,001 Nights")},
},
}
buf := bytes.NewBuffer(nil)
if err := Save(c, buf); err != nil {
t.Fatalf("Failed to save: %s", err)
}
c2, err := loader.LoadArchive(buf)
if err != nil {
t.Fatal(err)
}
if c2.Name() != c.Name() {
t.Fatalf("Expected chart archive to have %q, got %q", c.Name(), c2.Name())
}
if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" {
t.Fatal("Files data did not match")
}
}
func TestSaveArchive(t *testing.T) {
tmp, err := ioutil.TempDir("", "helm-")
if err != nil {
t.Fatal(err)
@ -44,7 +75,7 @@ func TestSave(t *testing.T) {
},
}
where, err := Save(c, tmp)
where, err := SaveArchive(c, tmp)
if err != nil {
t.Fatalf("Failed to save: %s", err)
}

@ -623,7 +623,7 @@ func tarFromLocalDir(chartpath, name, repo, version string) (string, error) {
}
if constraint.Check(v) {
_, err = chartutil.Save(ch, destPath)
_, err = chartutil.SaveArchive(ch, destPath)
return ch.Metadata.Version, err
}

@ -113,7 +113,7 @@ func (cache *filesystemCache) ChartToLayers(ch *chart.Chart) ([]ocispec.Descript
metaLayer := cache.store.Add(HelmChartMetaFileName, HelmChartMetaMediaType, metaJSONRaw)
// Create content layer
// TODO: something better than this hack. Currently needed for chartutil.Save()
// TODO: something better than this hack. Currently needed for chartutil.SaveArchive()
// If metadata does not contain Name or Version, an error is returned
// such as "no chart name specified (Chart.yaml)"
ch.Metadata = &chart.Metadata{
@ -122,7 +122,7 @@ func (cache *filesystemCache) ChartToLayers(ch *chart.Chart) ([]ocispec.Descript
Version: "0.1.0",
}
destDir := mkdir(filepath.Join(cache.rootDir, "blobs", ".build"))
tmpFile, err := chartutil.Save(ch, destDir)
tmpFile, err := chartutil.SaveArchive(ch, destDir)
defer os.Remove(tmpFile)
if err != nil {
return nil, errors.Wrap(err, "failed to save")

Loading…
Cancel
Save