Move iso download funcs to interface for testing

Also reorg types found in cluster.go into types.go
pull/1053/head
Matt Rickard 2017-01-30 14:30:03 -08:00
parent ceb25dfd43
commit 1fbd936b39
8 changed files with 178 additions and 108 deletions

View File

@ -36,6 +36,7 @@ import (
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/util"
pkgutil "k8s.io/minikube/pkg/util"
)
const (
@ -96,6 +97,7 @@ func runStart(cmd *cobra.Command, args []string) {
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
HypervVirtualSwitch: viper.GetString(hypervVirtualSwitch),
KvmNetwork: viper.GetString(kvmNetwork),
Downloader: pkgutil.DefaultDownloader{},
}
var host *host.Host

View File

@ -18,7 +18,6 @@ package cluster
import (
"bytes"
"crypto"
"encoding/json"
"flag"
"fmt"
@ -38,7 +37,6 @@ import (
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/state"
"github.com/golang/glog"
download "github.com/jimmidyson/go-download"
"github.com/pkg/browser"
"github.com/pkg/errors"
"k8s.io/client-go/1.5/kubernetes"
@ -178,31 +176,6 @@ type sshAble interface {
RunSSHCommand(string) (string, error)
}
// MachineConfig contains the parameters used to start a cluster.
type MachineConfig struct {
MinikubeISO string
Memory int
CPUs int
DiskSize int
VMDriver string
DockerEnv []string // Each entry is formatted as KEY=VALUE.
InsecureRegistry []string
RegistryMirror []string
HostOnlyCIDR string // Only used by the virtualbox driver
HypervVirtualSwitch string
KvmNetwork string // Only used by the KVM driver
}
// KubernetesConfig contains the parameters used to configure the VM Kubernetes.
type KubernetesConfig struct {
KubernetesVersion string
NodeIP string
ContainerRuntime string
NetworkPlugin string
FeatureGates string
ExtraOptions util.ExtraOptionSlice
}
// StartCluster starts a k8s cluster on the specified Host.
func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error {
startCommand, err := GetStartCommand(kubernetesConfig)
@ -315,7 +288,7 @@ func engineOptions(config MachineConfig) *engine.Options {
func createVirtualboxHost(config MachineConfig) drivers.Driver {
d := virtualbox.NewDriver(constants.MachineName, constants.Minipath)
d.Boot2DockerURL = config.GetISOFileURI()
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
d.Memory = config.Memory
d.CPU = config.CPUs
d.DiskSize = int(config.DiskSize)
@ -323,77 +296,11 @@ func createVirtualboxHost(config MachineConfig) drivers.Driver {
return d
}
func (m *MachineConfig) CacheMinikubeISOFromURL() error {
options := download.FileOptions{
Mkdirs: download.MkdirAll,
Options: download.Options{
ProgressBars: &download.ProgressBarOptions{
MaxWidth: 80,
},
},
}
// Validate the ISO if it was the default URL, before writing it to disk.
if m.MinikubeISO == constants.DefaultIsoUrl {
options.Checksum = constants.DefaultIsoShaUrl
options.ChecksumHash = crypto.SHA256
}
fmt.Println("Downloading Minikube ISO")
if err := download.ToFile(m.MinikubeISO, m.GetISOCacheFilepath(), options); err != nil {
return errors.Wrap(err, "Error downloading Minikube ISO")
}
return nil
}
func (m *MachineConfig) ShouldCacheMinikubeISO() bool {
// store the miniube-iso inside the .minikube dir
urlObj, err := url.Parse(m.MinikubeISO)
if err != nil {
return false
}
if urlObj.Scheme == fileScheme {
return false
}
if m.IsMinikubeISOCached() {
return false
}
return true
}
func (m *MachineConfig) GetISOCacheFilepath() string {
return filepath.Join(constants.Minipath, "cache", "iso", filepath.Base(m.MinikubeISO))
}
func (m *MachineConfig) GetISOFileURI() string {
urlObj, err := url.Parse(m.MinikubeISO)
if err != nil {
return m.MinikubeISO
}
if urlObj.Scheme == fileScheme {
return m.MinikubeISO
}
isoPath := filepath.Join(constants.Minipath, "cache", "iso", filepath.Base(m.MinikubeISO))
// 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
}
return true
}
func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
var driver interface{}
if config.ShouldCacheMinikubeISO() {
if err := config.CacheMinikubeISOFromURL(); err != nil {
return nil, errors.Wrap(err, "Error attempting to cache minikube iso from url")
}
if err := config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO); err != nil {
return nil, errors.Wrap(err, "Error attempting to cache minikube ISO from URL")
}
switch config.VMDriver {
@ -510,11 +417,6 @@ func CreateSSHShell(api libmachine.API, args []string) error {
return client.Shell(strings.Join(args, " "))
}
type ipPort struct {
IP string
Port int32
}
func GetServiceURLsForService(api libmachine.API, namespace, service string, t *template.Template) ([]string, error) {
host, err := CheckIfApiExistsAndLoad(api)
if err != nil {
@ -547,7 +449,13 @@ func getServiceURLsWithClient(client *kubernetes.Clientset, ip, namespace, servi
for _, port := range ports {
var doc bytes.Buffer
err = t.Execute(&doc, ipPort{ip, port})
err = t.Execute(&doc, struct {
IP string
Port int32
}{
ip,
port,
})
if err != nil {
return nil, err
}

View File

@ -24,7 +24,7 @@ import (
func createVMwareFusionHost(config MachineConfig) drivers.Driver {
d := vmwarefusion.NewDriver(constants.MachineName, constants.Minipath).(*vmwarefusion.Driver)
d.Boot2DockerURL = config.GetISOFileURI()
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
d.Memory = config.Memory
d.CPU = config.CPUs
d.DiskSize = config.DiskSize
@ -60,7 +60,7 @@ func createXhyveHost(config MachineConfig) *xhyveDriver {
},
Memory: config.Memory,
CPU: config.CPUs,
Boot2DockerURL: config.GetISOFileURI(),
Boot2DockerURL: config.Downloader.GetISOFileURI(config.MinikubeISO),
BootCmd: "loglevel=3 user=docker console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10 base host=" + constants.MachineName,
DiskSize: int64(config.DiskSize),
Virtio9p: true,

View File

@ -49,7 +49,7 @@ func createKVMHost(config MachineConfig) *kvmDriver {
CPU: config.CPUs,
Network: config.KvmNetwork,
PrivateNetwork: "docker-machines",
Boot2DockerURL: config.GetISOFileURI(),
Boot2DockerURL: config.Downloader.GetISOFileURI(config.MinikubeISO),
DiskSize: config.DiskSize,
DiskPath: filepath.Join(constants.Minipath, "machines", constants.MachineName, fmt.Sprintf("%s.img", constants.MachineName)),
ISO: filepath.Join(constants.Minipath, "machines", constants.MachineName, "boot2docker.iso"),

View File

@ -42,9 +42,15 @@ import (
"k8s.io/minikube/pkg/minikube/tests"
)
type MockDownloader struct{}
func (d MockDownloader) GetISOFileURI(isoURL string) string { return "" }
func (d MockDownloader) CacheMinikubeISOFromURL(isoURL string) error { return nil }
var defaultMachineConfig = MachineConfig{
VMDriver: constants.DefaultVMDriver,
MinikubeISO: constants.DefaultIsoUrl,
Downloader: MockDownloader{},
}
func TestCreateHost(t *testing.T) {
@ -227,6 +233,7 @@ func TestStartHostConfig(t *testing.T) {
config := MachineConfig{
VMDriver: constants.DefaultVMDriver,
DockerEnv: []string{"FOO=BAR"},
Downloader: MockDownloader{},
}
h, err := StartHost(api, config)

View File

@ -24,7 +24,7 @@ import (
func createHypervHost(config MachineConfig) drivers.Driver {
d := hyperv.NewDriver(constants.MachineName, constants.Minipath)
d.Boot2DockerURL = config.GetISOFileURI()
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
d.VSwitch = config.HypervVirtualSwitch
d.MemSize = config.Memory
d.CPU = config.CPUs

View File

@ -0,0 +1,45 @@
/*
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 "k8s.io/minikube/pkg/util"
// MachineConfig contains the parameters used to start a cluster.
type MachineConfig struct {
MinikubeISO string
Memory int
CPUs int
DiskSize int
VMDriver string
DockerEnv []string // Each entry is formatted as KEY=VALUE.
InsecureRegistry []string
RegistryMirror []string
HostOnlyCIDR string // Only used by the virtualbox driver
HypervVirtualSwitch string
KvmNetwork string // Only used by the KVM driver
Downloader util.ISODownloader
}
// KubernetesConfig contains the parameters used to configure the VM Kubernetes.
type KubernetesConfig struct {
KubernetesVersion string
NodeIP string
ContainerRuntime string
NetworkPlugin string
FeatureGates string
ExtraOptions util.ExtraOptionSlice
}

108
pkg/util/downloader.go Normal file
View File

@ -0,0 +1,108 @@
/*
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 util
import (
"crypto"
"fmt"
"net/url"
"os"
"path/filepath"
"github.com/golang/glog"
download "github.com/jimmidyson/go-download"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/constants"
)
const fileScheme = "file"
type ISODownloader interface {
GetISOFileURI(isoURL string) string
CacheMinikubeISOFromURL(isoURL string) error
}
type DefaultDownloader struct{}
func (f DefaultDownloader) GetISOFileURI(isoURL string) string {
urlObj, err := url.Parse(isoURL)
if err != nil {
return isoURL
}
if urlObj.Scheme == fileScheme {
return isoURL
}
isoPath := filepath.Join(constants.Minipath, "cache", "iso", filepath.Base(isoURL))
// As this is a file URL there should be no backslashes regardless of platform running on.
return "file://" + filepath.ToSlash(isoPath)
}
func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
if !f.shouldCacheMinikubeISO(isoURL) {
glog.Infof("Not caching ISO, using %s", isoURL)
return nil
}
options := download.FileOptions{
Mkdirs: download.MkdirAll,
Options: download.Options{
ProgressBars: &download.ProgressBarOptions{
MaxWidth: 80,
},
},
}
// Validate the ISO if it was the default URL, before writing it to disk.
if isoURL == constants.DefaultIsoUrl {
options.Checksum = constants.DefaultIsoShaUrl
options.ChecksumHash = crypto.SHA256
}
fmt.Println("Downloading Minikube ISO")
if err := download.ToFile(isoURL, f.getISOCacheFilepath(isoURL), options); err != nil {
return errors.Wrap(err, "Error downloading Minikube ISO")
}
return nil
}
func (f DefaultDownloader) shouldCacheMinikubeISO(isoURL string) bool {
// store the miniube-iso inside the .minikube dir
urlObj, err := url.Parse(isoURL)
if err != nil {
return false
}
if urlObj.Scheme == fileScheme {
return false
}
if f.isMinikubeISOCached(isoURL) {
return false
}
return true
}
func (f DefaultDownloader) getISOCacheFilepath(isoURL string) string {
return filepath.Join(constants.Minipath, "cache", "iso", filepath.Base(isoURL))
}
func (f DefaultDownloader) isMinikubeISOCached(isoURL string) bool {
if _, err := os.Stat(f.getISOCacheFilepath(isoURL)); os.IsNotExist(err) {
return false
}
return true
}