mirror of
https://github.com/helm/helm.git
synced 2026-05-28 04:35:48 -04:00
Merge pull request #642 from vaikas-google/master
Add support for fetching full urls.
This commit is contained in:
commit
f7272f43a7
3 changed files with 135 additions and 19 deletions
|
|
@ -4,8 +4,12 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kubernetes/helm/pkg/chart"
|
||||
"github.com/kubernetes/helm/pkg/repo"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -14,33 +18,92 @@ func init() {
|
|||
}
|
||||
|
||||
var fetchCmd = &cobra.Command{
|
||||
Use: "fetch",
|
||||
Short: "Download a chart from a repository and unpack it in local directory.",
|
||||
Use: "fetch [chart URL | repo/chartname]",
|
||||
Short: "Download a chart from a repository and (optionally) unpack it in local directory.",
|
||||
Long: "",
|
||||
RunE: fetch,
|
||||
}
|
||||
|
||||
func fetch(cmd *cobra.Command, args []string) error {
|
||||
// parse args
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("This command needs at least one argument, url or repo/name of the chart.")
|
||||
}
|
||||
|
||||
f, err := repo.LoadRepositoriesFile(repositoriesFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get download url
|
||||
// call download url
|
||||
out, err := os.Create("nginx-2.0.0.tgz")
|
||||
u, err := mapRepoArg(args[0], f.Repositories)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := http.Get(u.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("Failed to fetch %s : %s", u.String(), resp.Status)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
// TODO(vaikas): Implement untar / flag
|
||||
untar := false
|
||||
if untar {
|
||||
return untarChart(resp.Body)
|
||||
}
|
||||
p := strings.Split(u.String(), "/")
|
||||
return saveChartFile(p[len(p)-1], resp.Body)
|
||||
}
|
||||
|
||||
// mapRepoArg figures out which format the argument is given, and creates a fetchable
|
||||
// url from it.
|
||||
func mapRepoArg(arg string, r map[string]string) (*url.URL, error) {
|
||||
// See if it's already a full URL.
|
||||
u, err := url.ParseRequestURI(arg)
|
||||
if err == nil {
|
||||
// If it has a scheme and host and path, it's a full URL
|
||||
if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 {
|
||||
return u, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Invalid chart url format: %s", arg)
|
||||
}
|
||||
// See if it's of the form: repo/path_to_chart
|
||||
p := strings.Split(arg, "/")
|
||||
if len(p) > 1 {
|
||||
if baseURL, ok := r[p[0]]; ok {
|
||||
if !strings.HasSuffix(baseURL, "/") {
|
||||
baseURL = baseURL + "/"
|
||||
}
|
||||
return url.ParseRequestURI(baseURL + strings.Join(p[1:], "/"))
|
||||
}
|
||||
return nil, fmt.Errorf("No such repo: %s", p[0])
|
||||
}
|
||||
return nil, fmt.Errorf("Invalid chart url format: %s", arg)
|
||||
}
|
||||
|
||||
func untarChart(r io.Reader) error {
|
||||
c, err := chart.LoadDataFromReader(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c == nil {
|
||||
return fmt.Errorf("Failed to untar the chart")
|
||||
}
|
||||
return fmt.Errorf("Not implemented yee")
|
||||
|
||||
}
|
||||
|
||||
func saveChartFile(c string, r io.Reader) error {
|
||||
// Grab the chart name that we'll use for the name of the file to download to.
|
||||
out, err := os.Create(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
resp, err := http.Get("http://localhost:8879/charts/nginx-2.0.0.tgz")
|
||||
fmt.Println("after req")
|
||||
// unpack file
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err = io.Copy(out, r)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
53
cmd/helm/fetch_test.go
Normal file
53
cmd/helm/fetch_test.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// "io"
|
||||
// "net/http"
|
||||
//"net/url"
|
||||
// "os"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
in string
|
||||
expectedErr error
|
||||
expectedOut string
|
||||
}
|
||||
|
||||
var repos = map[string]string{
|
||||
"local": "http://localhost:8879/charts",
|
||||
"someother": "http://storage.googleapis.com/mycharts",
|
||||
}
|
||||
|
||||
var testCases = []testCase{
|
||||
{"bad", fmt.Errorf("Invalid chart url format: bad"), ""},
|
||||
{"http://", fmt.Errorf("Invalid chart url format: http://"), ""},
|
||||
{"http://example.com", fmt.Errorf("Invalid chart url format: http://example.com"), ""},
|
||||
{"http://example.com/foo/bar", nil, "http://example.com/foo/bar"},
|
||||
{"local/nginx-2.0.0.tgz", nil, "http://localhost:8879/charts/nginx-2.0.0.tgz"},
|
||||
{"nonexistentrepo/nginx-2.0.0.tgz", fmt.Errorf("No such repo: nonexistentrepo"), ""},
|
||||
}
|
||||
|
||||
func testRunner(t *testing.T, tc testCase) {
|
||||
u, err := mapRepoArg(tc.in, repos)
|
||||
if (tc.expectedErr == nil && err != nil) ||
|
||||
(tc.expectedErr != nil && err == nil) ||
|
||||
(tc.expectedErr != nil && err != nil && tc.expectedErr.Error() != err.Error()) {
|
||||
t.Errorf("Expected mapRepoArg to fail with input %s %v but got %v", tc.in, tc.expectedErr, err)
|
||||
}
|
||||
|
||||
if (u == nil && len(tc.expectedOut) != 0) ||
|
||||
(u != nil && len(tc.expectedOut) == 0) ||
|
||||
(u != nil && tc.expectedOut != u.String()) {
|
||||
t.Errorf("Expected %s to map to fetch url %v but got %v", tc.in, tc.expectedOut, u)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMappings(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
testRunner(t, tc)
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ func ensureHome() error {
|
|||
if _, err := os.Create(repoFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := insertRepoLine("local", "localhost:8879/charts"); err != nil {
|
||||
if err := insertRepoLine("local", "http://localhost:8879/charts"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if fi.IsDir() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue