|
|
@ -13,28 +13,32 @@ See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
package downloader
|
|
|
|
package getter
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
|
|
|
|
"bytes"
|
|
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
|
|
|
|
"helm.sh/helm/v3/pkg/chart/loader"
|
|
|
|
"helm.sh/helm/v3/internal/fileutil"
|
|
|
|
"helm.sh/helm/v3/pkg/chartutil"
|
|
|
|
|
|
|
|
"helm.sh/helm/v3/pkg/gitutil"
|
|
|
|
"helm.sh/helm/v3/pkg/gitutil"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Assigned here so it can be overridden for testing.
|
|
|
|
// Assigned here so it can be overridden for testing.
|
|
|
|
var gitCloneTo = gitutil.CloneTo
|
|
|
|
var gitCloneTo = gitutil.CloneTo
|
|
|
|
|
|
|
|
|
|
|
|
// GitDownloader handles downloading a chart from a git url.
|
|
|
|
// GITGetter is the default HTTP(/S) backend handler
|
|
|
|
type GitDownloader struct{}
|
|
|
|
type GITGetter struct {
|
|
|
|
|
|
|
|
opts options
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ensureGitDirIgnored will append ".git/" to the .helmignore file in a directory.
|
|
|
|
// ensureGitDirIgnored will append ".git/" to the .helmignore file in a directory.
|
|
|
|
// Create the .helmignore file if it does not exist.
|
|
|
|
// Create the .helmignore file if it does not exist.
|
|
|
|
func (g *GitDownloader) ensureGitDirIgnored(repoPath string) error {
|
|
|
|
func (g *GITGetter) ensureGitDirIgnored(repoPath string) error {
|
|
|
|
helmignorePath := filepath.Join(repoPath, ".helmignore")
|
|
|
|
helmignorePath := filepath.Join(repoPath, ".helmignore")
|
|
|
|
f, err := os.OpenFile(helmignorePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
|
|
f, err := os.OpenFile(helmignorePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -47,17 +51,34 @@ func (g *GitDownloader) ensureGitDirIgnored(repoPath string) error {
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DownloadTo will create a temp directory, then fetch a git repo into it.
|
|
|
|
//Get performs a Get from repo.Getter and returns the body.
|
|
|
|
// The git repo will be archived into a chart and copied to the destPath.
|
|
|
|
func (g *GITGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
|
|
|
|
func (g *GitDownloader) DownloadTo(gitURL string, ref string, destPath string) error {
|
|
|
|
for _, opt := range options {
|
|
|
|
|
|
|
|
opt(&g.opts)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return g.get(href)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (g *GITGetter) get(href string) (*bytes.Buffer, error) {
|
|
|
|
|
|
|
|
gitURL := strings.TrimPrefix(href, "git:")
|
|
|
|
|
|
|
|
version := g.opts.version
|
|
|
|
|
|
|
|
chartName := g.opts.chartName
|
|
|
|
|
|
|
|
if version == "" {
|
|
|
|
|
|
|
|
return nil, fmt.Errorf("The version must be a valid tag or branch name for the git repo, not nil")
|
|
|
|
|
|
|
|
}
|
|
|
|
tmpDir, err := ioutil.TempDir("", "helm")
|
|
|
|
tmpDir, err := ioutil.TempDir("", "helm")
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
chartTmpDir := filepath.Join(tmpDir, chartName)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err := os.MkdirAll(chartTmpDir, 0755); err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
|
|
|
|
|
|
if err = gitCloneTo(gitURL, ref, tmpDir); err != nil {
|
|
|
|
if err = gitCloneTo(gitURL, version, chartTmpDir); err != nil {
|
|
|
|
return fmt.Errorf("Unable to retrieve git repo. %s", err)
|
|
|
|
return nil, fmt.Errorf("Unable to retrieve git repo. %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// A .helmignore that includes an ignore for .git/ should be included in the git repo itself,
|
|
|
|
// A .helmignore that includes an ignore for .git/ should be included in the git repo itself,
|
|
|
@ -65,14 +86,21 @@ func (g *GitDownloader) DownloadTo(gitURL string, ref string, destPath string) e
|
|
|
|
// To prevent the git history from bleeding into the charts archive, append/create .helmignore.
|
|
|
|
// To prevent the git history from bleeding into the charts archive, append/create .helmignore.
|
|
|
|
g.ensureGitDirIgnored(tmpDir)
|
|
|
|
g.ensureGitDirIgnored(tmpDir)
|
|
|
|
|
|
|
|
|
|
|
|
// Turn the extracted git archive into a chart and move it into the charts directory.
|
|
|
|
buf, err := fileutil.CompressDirToTgz(chartTmpDir, tmpDir)
|
|
|
|
// This is using chartutil.Save() so that .helmignore logic is applied.
|
|
|
|
if err != nil {
|
|
|
|
loadedChart, loadErr := loader.LoadDir(tmpDir)
|
|
|
|
return nil, fmt.Errorf("Unable to tar and compress dir %s to tgz file. %s", tmpDir, err)
|
|
|
|
if loadErr != nil {
|
|
|
|
|
|
|
|
return fmt.Errorf("Unable to process the git repo %s as a chart. %s", gitURL, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, saveErr := chartutil.Save(loadedChart, destPath); saveErr != nil {
|
|
|
|
return buf, nil
|
|
|
|
return fmt.Errorf("Unable to save the git repo %s as a chart. %s", gitURL, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NewGITGetter constructs a valid http/https client as a Getter
|
|
|
|
|
|
|
|
func NewGITGetter(ops ...Option) (Getter, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client := GITGetter{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, opt := range ops {
|
|
|
|
|
|
|
|
opt(&client.opts)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
|
|
|
|
|
|
|
|
return &client, nil
|
|
|
|
}
|
|
|
|
}
|