Skip to content

Commit

Permalink
refactor: use existing chartutil.Save to package up the git based c…
Browse files Browse the repository at this point in the history
…hart

Addresses helm#11258 (comment)
Addresses helm#11258 (comment)

Signed-off-by: Dominykas Blyžė <hello@dominykas.com>
  • Loading branch information
dominykas committed Dec 21, 2023
1 parent e434808 commit d1afe2b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 154 deletions.
84 changes: 0 additions & 84 deletions internal/fileutil/fileutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ import (
"io"
"os"
"path/filepath"
"strings"
"time"

"archive/tar"
"bytes"
"compress/gzip"

"helm.sh/helm/v3/internal/third_party/dep/fs"
)
Expand Down Expand Up @@ -54,81 +48,3 @@ func AtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error

return fs.RenameWithFallback(tempName, filename)
}

func CompressDirToTgz(chartTmpDir, tmpdir string) (*bytes.Buffer, error) {

_, err := os.Stat(chartTmpDir)
if err != nil {
return nil, err
}

_, err = os.Stat(tmpdir)
if err != nil {
return nil, err
}

// tar => gzip => buf
buf := bytes.NewBuffer(nil)
zr := gzip.NewWriter(buf)

zr.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
zr.Header.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
zr.Header.OS = 3 // Unix
zr.OS = 3 //Unix
zr.Extra = nil

tw := tar.NewWriter(zr)

// walk through every file in the folder
walkErr := filepath.Walk(chartTmpDir, func(file string, fi os.FileInfo, err error) error {

// generate tar header
if err != nil {
return err
}

header, err := tar.FileInfoHeader(fi, strings.TrimPrefix(file, tmpdir+"/"))
if err != nil {
return err
}

// must provide real name
// (see https://golang.org/src/archive/tar/common.go?#L626)
header.Name = strings.TrimPrefix(filepath.ToSlash(file), tmpdir+"/")
header.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
header.AccessTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
header.ChangeTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
header.Format = tar.FormatPAX
header.PAXRecords = nil

// write header
if err := tw.WriteHeader(header); err != nil {
return err
}

// if not a dir, write file content
if !fi.IsDir() {
data, err := os.Open(file)
if err != nil {
return err
}
if _, err := io.Copy(tw, data); err != nil {
return err
}
}
return nil
})
if walkErr != nil {
return nil, walkErr
}

// produce tar
if err := tw.Close(); err != nil {
return nil, err
}
// produce gzip
if err := zr.Close(); err != nil {
return nil, err
}
return buf, nil
}
47 changes: 0 additions & 47 deletions internal/fileutil/fileutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ limitations under the License.
package fileutil

import (
"archive/tar"
"bytes"
"compress/gzip"
"io"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -58,47 +55,3 @@ func TestAtomicWriteFile(t *testing.T) {
mode, gotinfo.Mode())
}
}

func TestCompressDirToTgz(t *testing.T) {

testDataDir := "testdata"
chartTestDir := "testdata/testdir"

chartBytes, err := CompressDirToTgz(chartTestDir, testDataDir)
if err != nil {
t.Fatal(err)
}

// gzip read
gr, err := gzip.NewReader(chartBytes)
if err != nil {
t.Fatal(err)
}
defer gr.Close()

// tar read
tr := tar.NewReader(gr)
defer gr.Close()

found := false
fileBytes := bytes.NewBuffer(nil)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if hdr.Name == "testdir/testfile" {
found = true
_, err := io.Copy(fileBytes, tr)
if err != nil {
t.Fatal(err)
}
}
}
if !found {
t.Fatal("testdir/testfile not found")
}
if !bytes.Equal(fileBytes.Bytes(), []byte("helm")) {
t.Fatalf("testdir/testfile's content not match, excpcted %s, got %s", "helm", fileBytes.String())
}
}
35 changes: 12 additions & 23 deletions pkg/getter/gitgetter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import (
"os"
"path/filepath"

"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"

"github.com/Masterminds/vcs"

"helm.sh/helm/v3/internal/fileutil"
"helm.sh/helm/v3/internal/gitutil"
)

Expand All @@ -36,21 +38,6 @@ func (g *GitGetter) ChartName() string {
return g.opts.chartName
}

// ensureGitDirIgnored will append ".git/" to the .helmignore file in a directory.
// Create the .helmignore file if it does not exist.
func (g *GitGetter) ensureGitDirIgnored(repoPath string) error {
helmignorePath := filepath.Join(repoPath, ".helmignore")
f, err := os.OpenFile(helmignorePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
if _, err := f.WriteString("\n.git/\n"); err != nil {
return err
}
return nil
}

// Get performs a Get from repo.Getter and returns the body.
func (g *GitGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
for _, opt := range options {
Expand Down Expand Up @@ -88,16 +75,18 @@ func (g *GitGetter) get(href string) (*bytes.Buffer, error) {
return nil, err
}

// A .helmignore that includes an ignore for .git/ should be included in the git repo itself,
// but a lot of people will probably not think about that.
// To prevent the git history from bleeding into the charts archive, append/create .helmignore.
g.ensureGitDirIgnored(chartTmpDir)
ch, err := loader.LoadDir(chartTmpDir)
if err != nil {
return nil, err
}

buf, err := fileutil.CompressDirToTgz(chartTmpDir, tmpDir)
tarballPath, err := chartutil.Save(ch, tmpDir)
if err != nil {
return nil, fmt.Errorf("unable to tar and compress dir %s to tgz file. %s", tmpDir, err)
return nil, err
}
return buf, nil

buf, err := os.ReadFile(tarballPath)
return bytes.NewBuffer(buf), err
}

// NewGitGetter constructs a valid git client as a Getter
Expand Down

0 comments on commit d1afe2b

Please sign in to comment.