From 405453758edde71120cbcac1110931914f511f49 Mon Sep 17 00:00:00 2001 From: Aaron Prindle Date: Mon, 1 Aug 2016 10:51:04 -0700 Subject: [PATCH] Added localkube caching functionality. Also cleanup up private/public functions in cluster.go, added v1.3.3 to k8s_releases.json and fixed link in LOCALKUBE_RELEASING.md. Fixed TestUpdatedKubernetesVersion to use tmp dir as caching is now used for localkube. --- LOCALKUBE_RELEASING.md | 8 +--- pkg/minikube/cluster/cluster.go | 62 ++++++++++++++++++++++++++-- pkg/minikube/cluster/cluster_test.go | 3 ++ pkg/util/utils.go | 8 ++++ 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/LOCALKUBE_RELEASING.md b/LOCALKUBE_RELEASING.md index c5a59f251224..b445c502f60b 100644 --- a/LOCALKUBE_RELEASING.md +++ b/LOCALKUBE_RELEASING.md @@ -30,11 +30,5 @@ This step makes the new release trigger update notifications in old versions of Use this command from a clean git repo: ```shell -gsutil cp deploy/minikube/releases.json gs://minikube/k8s_releases.json -``` - -## Mark the release as `latest` in GCS: - -```shell -gsutil cp -r gs://minikube/releases/$RELEASE gs://minikube/releases/latest +gsutil cp deploy/minikube/k8s_releases.json gs://minikube/k8s_releases.json ``` diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 2fd91defceca..f32e8bcc7fc7 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -211,11 +211,38 @@ var assets = []fileToCopy{ }, } -func updateLocalkubeFromURL(config KubernetesConfig, client *ssh.Client) error { +func (k *KubernetesConfig) getLocalkubeCacheFilepath() string { + return filepath.Join(constants.Minipath, "cache", "localkube", + filepath.Base("localkube-"+util.GetMD5Hash(k.KubernetesVersion))) +} + +func (k *KubernetesConfig) isLocalkubeCached() bool { + if _, err := os.Stat(k.getLocalkubeCacheFilepath()); os.IsNotExist(err) { + return false + } + return true +} + +func (k *KubernetesConfig) cacheLocalkube(response *http.Response) error { + // store localkube inside the .minikube dir + out, err := os.Create(k.getLocalkubeCacheFilepath()) + if err != nil { + + return err + } + defer out.Close() + defer response.Body.Close() + if _, err = io.Copy(out, response.Body); err != nil { + return err + } + return nil +} + +func (k *KubernetesConfig) downloadAndCacheLocalkube() error { resp := &http.Response{} err := errors.New("") downloader := func() (err error) { - url, err := util.GetLocalkubeDownloadURL(config.KubernetesVersion, + url, err := util.GetLocalkubeDownloadURL(k.KubernetesVersion, constants.LocalkubeLinuxFilename) if err != nil { return err @@ -227,7 +254,32 @@ func updateLocalkubeFromURL(config KubernetesConfig, client *ssh.Client) error { if err = util.Retry(5, downloader); err != nil { return err } - if err = sshutil.Transfer(resp.Body, int(resp.ContentLength), "/usr/local/bin", + if err = k.cacheLocalkube(resp); err != nil { + return err + } + return nil +} + +func updateLocalkubeFromURL(config KubernetesConfig, client *ssh.Client) error { + if !config.isLocalkubeCached() { + if err := config.downloadAndCacheLocalkube(); err != nil { + return err + } + } + if err := config.transferCachedLocalkubeToVM(client); err != nil { + return err + } + return nil +} + +func (k *KubernetesConfig) transferCachedLocalkubeToVM(client *ssh.Client) error { + contents, err := ioutil.ReadFile(k.getLocalkubeCacheFilepath()) + if err != nil { + glog.Infof("Error loading asset out/localkube: %s", err) + return err + } + + if err = sshutil.Transfer(bytes.NewReader(contents), len(contents), "/usr/local/bin", "localkube", "0777", client); err != nil { return err } @@ -342,11 +394,12 @@ func createVirtualboxHost(config MachineConfig) drivers.Driver { func (m *MachineConfig) CacheMinikubeISOFromURL() error { // store the miniube-iso inside the .minikube dir + // TODO(aprindle) put this in a retry loop? response, err := http.Get(m.MinikubeISO) if err != nil { return err } else { - out, err := os.Create(m.GetISOCacheFilepath()) + out, err := os.Create(m.getISOCacheFilepath()) if err != nil { return err } @@ -391,6 +444,7 @@ func (m *MachineConfig) GetISOFileURI() string { // As this is a file URL there should be no backslashes regardless of platform running on. return "file://" + filepath.ToSlash(isoPath) } + func (m *MachineConfig) IsMinikubeISOCached() bool { if _, err := os.Stat(m.GetISOCacheFilepath()); os.IsNotExist(err) { return false diff --git a/pkg/minikube/cluster/cluster_test.go b/pkg/minikube/cluster/cluster_test.go index 8ccd0e13e0f8..5bb3c8c5ad30 100644 --- a/pkg/minikube/cluster/cluster_test.go +++ b/pkg/minikube/cluster/cluster_test.go @@ -534,6 +534,9 @@ func (h *K8sVersionHandlerCorrect) ServeHTTP(w http.ResponseWriter, r *http.Requ } func TestUpdateKubernetesVersion(t *testing.T) { + tempDir := tests.MakeTempDir() + defer os.RemoveAll(tempDir) + s, _ := tests.NewSSHServer() port, err := s.Start() if err != nil { diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 6e93e725aa77..d5cd290fdf72 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -17,6 +17,8 @@ limitations under the License. package util import ( + "crypto/md5" + "encoding/hex" "fmt" "io" "net/url" @@ -105,6 +107,7 @@ func GetLocalkubeDownloadURL(versionOrURL string, filename string) (string, erro return fmt.Sprintf("%s%s/%s", constants.LocalkubeDownloadURLPrefix, versionOrURL, filename), nil } +<<<<<<< 38d0f083510df2b7b91dc59fdbc8517b8d02fbd1 type MultiError struct { Errors []error } @@ -126,3 +129,8 @@ func (m MultiError) ToError() error { } return fmt.Errorf(strings.Join(errStrings, "\n")) } + +func GetMD5Hash(text string) string { + hash := md5.Sum([]byte(text)) + return hex.EncodeToString(hash[:]) +}