From 21cc65eff97c02c64cc5ae15a3e557d215541d6d Mon Sep 17 00:00:00 2001 From: Kunming Qu <37601826+kunmingg@users.noreply.github.com> Date: Fri, 10 Jan 2020 13:53:37 -0800 Subject: [PATCH] fix kfctl (#169) * fix kfctl * add support when manifests is local dir --- go.mod | 2 +- go.sum | 3 ++ pkg/kfconfig/types.go | 95 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index d04e7f99..e1efec1a 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/kubernetes-sigs/application v0.8.0 github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/onrik/logrus v0.2.1 - github.com/otiai10/copy v1.0.1 + github.com/otiai10/copy v1.0.2 github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 // indirect github.com/pkg/errors v0.8.1 github.com/prometheus/common v0.2.0 diff --git a/go.sum b/go.sum index 4bc17e11..a8377559 100644 --- a/go.sum +++ b/go.sum @@ -367,10 +367,13 @@ github.com/opencontainers/selinux v0.0.0-20170621221121-4a2974bf1ee9/go.mod h1:+ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/otiai10/copy v1.0.1 h1:gtBjD8aq4nychvRZ2CyJvFWAw0aja+VHazDdruZKGZA= github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= +github.com/otiai10/copy v1.0.2 h1:DDNipYy6RkIkjMwy+AWzgKiNTyj2RUI9yEMeETEpVyc= +github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= diff --git a/pkg/kfconfig/types.go b/pkg/kfconfig/types.go index 6e6ba3d1..03579c77 100644 --- a/pkg/kfconfig/types.go +++ b/pkg/kfconfig/types.go @@ -1,21 +1,27 @@ package kfconfig import ( + "archive/tar" + "bytes" + "compress/gzip" "fmt" + "io" "io/ioutil" + "net/http" "os" "path" + "path/filepath" "strings" "github.com/ghodss/yaml" - gogetter "github.com/hashicorp/go-getter" "github.com/hashicorp/go-getter/helper/url" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "github.com/otiai10/copy" ) const ( @@ -485,11 +491,38 @@ func (c *KfConfig) SyncCache() error { } log.Infof("Fetching %v to %v", r.URI, cacheDir) - tarballUrlErr := gogetter.GetAny(cacheDir, r.URI) - if tarballUrlErr != nil { - return &kfapis.KfError{ - Code: int(kfapis.INVALID_ARGUMENT), - Message: fmt.Sprintf("couldn't download URI %v Error %v", r.URI, tarballUrlErr), + if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil { + log.Errorf("Could not create dir %v; error %v", cacheDir, err) + return errors.WithStack(err) + } + + // Manifests are local dir + if fi, err := os.Stat(r.URI); err == nil && fi.Mode().IsDir() { + if err := copy.Copy(r.URI, cacheDir); err != nil { + return errors.WithStack(err) + } + } else { + t := &http.Transport{} + t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) + t.RegisterProtocol("", http.NewFileTransport(http.Dir("/"))) + hclient := &http.Client{Transport: t} + resp, err := hclient.Get(r.URI) + if err != nil { + return &kfapis.KfError{ + Code: int(kfapis.INVALID_ARGUMENT), + Message: fmt.Sprintf("couldn't download URI %v Error %v", r.URI, err), + } + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Errorf("Could not read response body; error %v", err) + return errors.WithStack(err) + } + if err := untar(body, cacheDir); err != nil { + log.Errorf("Could not untar file %v; error %v", r.URI, err) + return errors.WithStack(err) } } @@ -530,6 +563,54 @@ func (c *KfConfig) SyncCache() error { return nil } +func untar(body []byte, cacheDir string) error { + gzf, err := gzip.NewReader(bytes.NewReader(body)) + if err != nil { + return err + } + + tarReader := tar.NewReader(gzf) + for { + header, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + if header == nil { + continue + } + + target := filepath.Join(cacheDir, header.Name) + + switch header.Typeflag { + + case tar.TypeDir: + if _, err := os.Stat(target); err != nil { + if err := os.MkdirAll(target, 0755); err != nil { + return err + } + } + + case tar.TypeReg: + f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) + if err != nil { + return err + } + + if _, err := io.Copy(f, tarReader); err != nil { + return err + } + + if err := f.Close(); err != nil { + return err + } + } + } + return nil +} + // GetSecret returns the specified secret or an error if the secret isn't specified. func (c *KfConfig) GetSecret(name string) (string, error) { for _, s := range c.Spec.Secrets {