提交 976eeeb1 编写于 作者: A Aaron Prindle

Added unit tests which cover localkube caching scenarios. Refactored

code to use localkube_caching.go and localkubeCacher.
上级 40545375
......@@ -19,7 +19,6 @@ package cluster
import (
"bytes"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
......@@ -39,7 +38,6 @@ import (
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/state"
"github.com/golang/glog"
"golang.org/x/crypto/ssh"
kubeApi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
......@@ -211,101 +209,14 @@ var assets = []fileToCopy{
},
}
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(k.KubernetesVersion,
constants.LocalkubeLinuxFilename)
if err != nil {
return err
}
resp, err = http.Get(url)
return err
}
if err = util.Retry(5, downloader); err != nil {
return err
}
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
}
return nil
}
func updateLocalkubeFromAsset(client *ssh.Client) error {
contents, err := Asset("out/localkube")
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
}
return nil
}
func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
client, err := sshutil.NewSSHClient(d)
if err != nil {
return err
}
if localkubeURLWasSpecified(config) {
if err = updateLocalkubeFromURL(config, client); err != nil {
lCacher := localkubeCacher{config}
if err = updateLocalkubeFromURL(lCacher, client); err != nil {
return err
}
} else {
......@@ -394,7 +305,6 @@ 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
......
......@@ -568,3 +568,48 @@ func TestUpdateKubernetesVersion(t *testing.T) {
t.Fatalf("File not copied. Expected transfers to contain: %s. It was: %s", contents, transferred)
}
}
type nopCloser struct {
io.Reader
}
func (nopCloser) Close() error { return nil }
func TestIsLocalkubeCached(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
inputArr := [...]string{
"v1.3.3",
"1.3.0",
"http://test-url.localkube.com/localkube-binary",
"file:///test/dir/to/localkube-binary",
}
readCloser := nopCloser{}
localkubeCacher := localkubeCacher{
k8sConf: KubernetesConfig{},
}
inner := func(input string) {
localkubeCacher.k8sConf = KubernetesConfig{
KubernetesVersion: input,
}
if localkubeCacher.isLocalkubeCached() {
t.Errorf("IsLocalKubeCached returned true even though %s was not cached",
localkubeCacher.getLocalkubeCacheFilepath())
}
readCloser = nopCloser{bytes.NewBufferString("test-localkube-binary-data")}
localkubeCacher.cacheLocalkube(readCloser)
if !localkubeCacher.isLocalkubeCached() {
t.Errorf("IsLocalKubeCached returned false even though %s was cached",
localkubeCacher.getLocalkubeCacheFilepath())
}
}
for _, input := range inputArr {
inner(input)
}
}
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
import (
"bytes"
"errors"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"github.com/golang/glog"
"golang.org/x/crypto/ssh"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/sshutil"
"k8s.io/minikube/pkg/util"
)
// localkubeCacher is a struct with methods designed for caching localkube
type localkubeCacher struct {
k8sConf KubernetesConfig
}
func (l *localkubeCacher) getLocalkubeCacheFilepath() string {
return filepath.Join(constants.Minipath, "cache", "localkube",
filepath.Base(url.QueryEscape("localkube-"+l.k8sConf.KubernetesVersion)))
}
func (l *localkubeCacher) isLocalkubeCached() bool {
if _, err := os.Stat(l.getLocalkubeCacheFilepath()); os.IsNotExist(err) {
return false
}
return true
}
func (l *localkubeCacher) cacheLocalkube(body io.ReadCloser) error {
// store localkube inside the .minikube dir
out, err := os.Create(l.getLocalkubeCacheFilepath())
if err != nil {
return err
}
defer out.Close()
defer body.Close()
if _, err = io.Copy(out, body); err != nil {
return err
}
return nil
}
func (l *localkubeCacher) downloadAndCacheLocalkube() error {
resp := &http.Response{}
err := errors.New("")
downloader := func() (err error) {
url, err := util.GetLocalkubeDownloadURL(l.k8sConf.KubernetesVersion,
constants.LocalkubeLinuxFilename)
if err != nil {
return err
}
resp, err = http.Get(url)
return err
}
if err = util.Retry(5, downloader); err != nil {
return err
}
if err = l.cacheLocalkube(resp.Body); err != nil {
return err
}
return nil
}
func updateLocalkubeFromURL(lCacher localkubeCacher, client *ssh.Client) error {
if !lCacher.isLocalkubeCached() {
if err := lCacher.downloadAndCacheLocalkube(); err != nil {
return err
}
}
if err := lCacher.transferCachedLocalkubeToVM(client); err != nil {
return err
}
return nil
}
func (l *localkubeCacher) transferCachedLocalkubeToVM(client *ssh.Client) error {
contents, err := ioutil.ReadFile(l.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
}
return nil
}
func updateLocalkubeFromAsset(client *ssh.Client) error {
contents, err := Asset("out/localkube")
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
}
return nil
}
......@@ -17,8 +17,6 @@ limitations under the License.
package util
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"net/url"
......@@ -107,7 +105,6 @@ 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
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册