Merge master

pull/6043/head
Thomas Stromberg 2019-12-10 14:07:02 -08:00
commit 661ebf843f
36 changed files with 230 additions and 105 deletions

View File

@ -76,7 +76,7 @@ var ProfileCmd = &cobra.Command{
if err != nil {
exit.WithError("Setting profile failed", err)
}
cc, err := pkgConfig.Load()
cc, err := pkgConfig.Load(profile)
// might err when loading older version of cfg file that doesn't have KeepContext field
if err != nil && !os.IsNotExist(err) {
out.ErrT(out.Sad, `Error loading profile config: {{.error}}`, out.V{"error": err})

View File

@ -23,6 +23,7 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/command"
@ -137,7 +138,7 @@ func EnableOrDisableAddon(name string, val string) error {
return nil
}
cfg, err := config.Load()
cfg, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil && !os.IsNotExist(err) {
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err})
}

View File

@ -26,6 +26,7 @@ import (
units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/cruntime"
@ -158,7 +159,7 @@ func IsValidRuntime(name string, runtime string) error {
// IsContainerdRuntime is a validator which returns an error if the current runtime is not containerd
func IsContainerdRuntime(_, _ string) error {
config, err := config.Load()
config, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
return fmt.Errorf("config.Load: %v", err)
}

View File

@ -32,9 +32,11 @@ import (
"github.com/pkg/browser"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
configcmd "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
@ -57,7 +59,7 @@ var dashboardCmd = &cobra.Command{
Short: "Access the kubernetes dashboard running within the minikube cluster",
Long: `Access the kubernetes dashboard running within the minikube cluster`,
Run: func(cmd *cobra.Command, args []string) {
cc, err := pkg_config.Load()
cc, err := pkg_config.Load(viper.GetString(config.MachineProfile))
if err != nil && !os.IsNotExist(err) {
exit.WithError("Error loading profile config", err)
}

View File

@ -163,7 +163,7 @@ func DeleteProfiles(profiles []*pkg_config.Profile) []error {
err := deleteProfile(profile)
if err != nil {
mm, loadErr := cluster.LoadMachine(profile.Name)
mm, loadErr := machine.Load(profile.Name)
if !profile.IsValid() || (loadErr != nil || !mm.IsValid()) {
invalidProfileDeletionErrs := deleteInvalidProfile(profile)
@ -187,8 +187,7 @@ func deleteProfile(profile *pkg_config.Profile) error {
return DeletionError{Err: delErr, Errtype: Fatal}
}
defer api.Close()
cc, err := pkg_config.Load()
cc, err := pkg_config.Load(profile.Name)
if err != nil && !os.IsNotExist(err) {
delErr := profileDeletionErr(profile.Name, fmt.Sprintf("error loading profile config: %v", err))
return DeletionError{Err: delErr, Errtype: MissingProfile}
@ -263,7 +262,7 @@ func deleteInvalidProfile(profile *pkg_config.Profile) []error {
}
}
pathToMachine := cluster.MachinePath(profile.Name, localpath.MiniPath())
pathToMachine := localpath.MachinePath(profile.Name, localpath.MiniPath())
if _, err := os.Stat(pathToMachine); !os.IsNotExist(err) {
err := os.RemoveAll(pathToMachine)
if err != nil {

View File

@ -26,7 +26,6 @@ import (
"github.com/otiai10/copy"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/localpath"
)
@ -117,7 +116,7 @@ func TestDeleteProfile(t *testing.T) {
t.Errorf("Profile folder of profile \"%s\" was not deleted", profile.Name)
}
pathToMachine := cluster.MachinePath(profile.Name, localpath.MiniPath())
pathToMachine := localpath.MachinePath(profile.Name, localpath.MiniPath())
if _, err := os.Stat(pathToMachine); !os.IsNotExist(err) {
t.Errorf("Profile folder of profile \"%s\" was not deleted", profile.Name)
}

View File

@ -340,7 +340,7 @@ var dockerEnvCmd = &cobra.Command{
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load()
cc, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}

View File

@ -20,6 +20,7 @@ import (
"github.com/docker/machine/libmachine/mcnerror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
@ -38,7 +39,7 @@ var ipCmd = &cobra.Command{
}
defer api.Close()
cc, err := config.Load()
cc, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}

View File

@ -25,6 +25,8 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
@ -48,7 +50,7 @@ kubectl get pods --namespace kube-system`,
}
defer api.Close()
cc, err := pkg_config.Load()
cc, err := pkg_config.Load(viper.GetString(config.MachineProfile))
if err != nil && !os.IsNotExist(err) {
out.ErrLn("Error loading profile config: %v", err)
}

View File

@ -47,7 +47,7 @@ var logsCmd = &cobra.Command{
Short: "Gets the logs of the running instance, used for debugging minikube, not user code.",
Long: `Gets the logs of the running instance, used for debugging minikube, not user code.`,
Run: func(cmd *cobra.Command, args []string) {
cfg, err := config.Load()
cfg, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}

View File

@ -29,6 +29,7 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
@ -102,7 +103,7 @@ var mountCmd = &cobra.Command{
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load()
cc, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}

View File

@ -20,6 +20,7 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
@ -32,7 +33,7 @@ var sshKeyCmd = &cobra.Command{
Short: "Retrieve the ssh identity key path of the specified cluster",
Long: "Retrieve the ssh identity key path of the specified cluster.",
Run: func(cmd *cobra.Command, args []string) {
cc, err := config.Load()
cc, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Getting machine config failed", err)
}

View File

@ -42,7 +42,7 @@ var sshCmd = &cobra.Command{
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load()
cc, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}

View File

@ -51,6 +51,7 @@ import (
"k8s.io/minikube/pkg/minikube/bootstrapper/kubeadm"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
@ -287,7 +288,7 @@ func runStart(cmd *cobra.Command, args []string) {
registryMirror = viper.GetStringSlice("registry_mirror")
}
existing, err := cfg.Load()
existing, err := cfg.Load(viper.GetString(config.MachineProfile))
if err != nil && !os.IsNotExist(err) {
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err})
}
@ -352,7 +353,7 @@ func runStart(cmd *cobra.Command, args []string) {
}
// setup kubeadm (must come after setupKubeconfig)
bs := setupKubeAdm(machineAPI, config.KubernetesConfig)
bs := setupKubeAdm(machineAPI, config)
// pull images or restart cluster
bootstrapCluster(bs, cr, mRunner, config.KubernetesConfig, preExists, isUpgrade)
@ -729,7 +730,7 @@ func validateUser(drvName string) {
if !useForce {
os.Exit(exit.Permissions)
}
_, err = cfg.Load()
_, err = cfg.Load(viper.GetString(config.MachineProfile))
if err == nil || !os.IsNotExist(err) {
out.T(out.Tip, "Tip: To remove this root owned cluster, run: sudo {{.cmd}} delete", out.V{"cmd": minikubeCmd()})
}
@ -1188,7 +1189,7 @@ func getKubernetesVersion(old *cfg.MachineConfig) (string, bool) {
}
// setupKubeAdm adds any requested files into the VM before Kubernetes is started
func setupKubeAdm(mAPI libmachine.API, kc cfg.KubernetesConfig) bootstrapper.Bootstrapper {
func setupKubeAdm(mAPI libmachine.API, config cfg.MachineConfig) bootstrapper.Bootstrapper {
bs, err := getClusterBootstrapper(mAPI, viper.GetString(cmdcfg.Bootstrapper))
if err != nil {
exit.WithError("Failed to get bootstrapper", err)
@ -1197,10 +1198,10 @@ func setupKubeAdm(mAPI libmachine.API, kc cfg.KubernetesConfig) bootstrapper.Boo
out.T(out.Option, "{{.extra_option_component_name}}.{{.key}}={{.value}}", out.V{"extra_option_component_name": eo.Component, "key": eo.Key, "value": eo.Value})
}
// Loads cached images, generates config files, download binaries
if err := bs.UpdateCluster(kc); err != nil {
if err := bs.UpdateCluster(config); err != nil {
exit.WithError("Failed to update cluster", err)
}
if err := bs.SetupCerts(kc); err != nil {
if err := bs.SetupCerts(config.KubernetesConfig); err != nil {
exit.WithError("Failed to setup certs", err)
}
return bs

View File

@ -24,6 +24,7 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
@ -76,11 +77,11 @@ var tunnelCmd = &cobra.Command{
cancel()
}()
cc, err := config.Load()
cfg, err := config.Load(viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting config", err)
}
done, err := manager.StartTunnel(ctx, cc.Name, api, config.DefaultLoader, clientset.CoreV1())
done, err := manager.StartTunnel(ctx, cfg.Name, api, config.DefaultLoader, clientset.CoreV1())
if err != nil {
exit.WithError("error starting tunnel", err)
}

View File

@ -268,6 +268,7 @@ CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_BRIDGE=m
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_CLS_U32=m
CONFIG_NET_CLS_CGROUP=y

View File

@ -38,7 +38,7 @@ type Bootstrapper interface {
// PullImages pulls images necessary for a cluster. Success should not be required.
PullImages(config.KubernetesConfig) error
StartCluster(config.KubernetesConfig) error
UpdateCluster(config.KubernetesConfig) error
UpdateCluster(config.MachineConfig) error
DeleteCluster(config.KubernetesConfig) error
WaitForCluster(config.KubernetesConfig, time.Duration) error
// LogCommands returns a map of log type to a command which will display that log.

View File

@ -629,36 +629,37 @@ func NewKubeletConfig(k8s config.KubernetesConfig, r cruntime.Manager) ([]byte,
}
// UpdateCluster updates the cluster
func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
images, err := images.Kubeadm(cfg.ImageRepository, cfg.KubernetesVersion)
func (k *Bootstrapper) UpdateCluster(cfg config.MachineConfig) error {
images, err := images.Kubeadm(cfg.KubernetesConfig.ImageRepository, cfg.KubernetesConfig.KubernetesVersion)
if err != nil {
return errors.Wrap(err, "kubeadm images")
}
if cfg.ShouldLoadCachedImages {
if err := machine.LoadImages(k.c, images, constants.ImageCacheDir); err != nil {
if cfg.KubernetesConfig.ShouldLoadCachedImages {
if err := machine.LoadImages(&cfg, k.c, images, constants.ImageCacheDir); err != nil {
out.FailureT("Unable to load cached images: {{.error}}", out.V{"error": err})
}
}
r, err := cruntime.New(cruntime.Config{Type: cfg.ContainerRuntime, Socket: cfg.CRISocket})
r, err := cruntime.New(cruntime.Config{Type: cfg.ContainerRuntime, Socket: cfg.KubernetesConfig.CRISocket})
if err != nil {
return errors.Wrap(err, "runtime")
}
kubeadmCfg, err := generateConfig(cfg, r)
kubeadmCfg, err := generateConfig(cfg.KubernetesConfig, r)
if err != nil {
return errors.Wrap(err, "generating kubeadm cfg")
}
kubeletCfg, err := NewKubeletConfig(cfg, r)
kubeletCfg, err := NewKubeletConfig(cfg.KubernetesConfig, r)
if err != nil {
return errors.Wrap(err, "generating kubelet config")
}
kubeletService, err := NewKubeletService(cfg)
kubeletService, err := NewKubeletService(cfg.KubernetesConfig)
if err != nil {
return errors.Wrap(err, "generating kubelet service")
}
glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg)
glog.Infof("kubelet %s config:\n%+v", kubeletCfg, cfg.KubernetesConfig)
stopCmd := exec.Command("/bin/bash", "-c", "pgrep kubelet && sudo systemctl stop kubelet")
// stop kubelet to avoid "Text File Busy" error
@ -666,11 +667,11 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output())
}
if err := transferBinaries(cfg, k.c); err != nil {
if err := transferBinaries(cfg.KubernetesConfig, k.c); err != nil {
return errors.Wrap(err, "downloading binaries")
}
files := configFiles(cfg, kubeadmCfg, kubeletCfg, kubeletService)
if err := addAddons(&files, assets.GenerateTemplateData(cfg)); err != nil {
files := configFiles(cfg.KubernetesConfig, kubeadmCfg, kubeletCfg, kubeletService)
if err := addAddons(&files, assets.GenerateTemplateData(cfg.KubernetesConfig)); err != nil {
return errors.Wrap(err, "adding addons")
}
for _, f := range files {

View File

@ -66,7 +66,7 @@ Wants=crio.service
[Service]
ExecStart=
ExecStart=/var/lib/minikube/binaries/v1.17.0-rc.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
ExecStart=/var/lib/minikube/binaries/v1.17.0/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
[Install]
`,
@ -84,7 +84,7 @@ Wants=containerd.service
[Service]
ExecStart=
ExecStart=/var/lib/minikube/binaries/v1.17.0-rc.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
ExecStart=/var/lib/minikube/binaries/v1.17.0/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
[Install]
`,
@ -109,7 +109,7 @@ Wants=containerd.service
[Service]
ExecStart=
ExecStart=/var/lib/minikube/binaries/v1.17.0-rc.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.200 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
ExecStart=/var/lib/minikube/binaries/v1.17.0/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.200 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
[Install]
`,
@ -128,7 +128,7 @@ Wants=docker.socket
[Service]
ExecStart=
ExecStart=/var/lib/minikube/binaries/v1.17.0-rc.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.1 --pod-manifest-path=/etc/kubernetes/manifests
ExecStart=/var/lib/minikube/binaries/v1.17.0/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --config=/var/lib/kubelet/config.yaml --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.1 --pod-manifest-path=/etc/kubernetes/manifests
[Install]
`,

View File

@ -24,7 +24,6 @@ import (
"io/ioutil"
"os"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/localpath"
)
@ -124,9 +123,8 @@ func encode(w io.Writer, m MinikubeConfig) error {
}
// Load loads the kubernetes and machine config for the current machine
func Load() (*MachineConfig, error) {
machine := viper.GetString(MachineProfile)
return DefaultLoader.LoadConfigFromFile(machine)
func Load(profile string) (*MachineConfig, error) {
return DefaultLoader.LoadConfigFromFile(profile)
}
// Loader loads the kubernetes and machine config based on the machine profile name

View File

@ -65,10 +65,10 @@ var DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.i
var DefaultISOSHAURL = DefaultISOURL + SHASuffix
// DefaultKubernetesVersion is the default kubernetes version
var DefaultKubernetesVersion = "v1.17.0-rc.1"
var DefaultKubernetesVersion = "v1.17.0"
// NewestKubernetesVersion is the newest Kubernetes version to test against
var NewestKubernetesVersion = "v1.17.0-rc.1"
var NewestKubernetesVersion = "v1.17.0"
// OldestKubernetesVersion is the oldest Kubernetes version to test against
var OldestKubernetesVersion = "v1.11.10"

View File

@ -221,6 +221,15 @@ func (r *Containerd) Disable() error {
return nil
}
// ImageExists checks if an image exists, expected input format
func (r *Containerd) ImageExists(name string, sha string) bool {
c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ctr -n=k8s.io images check | grep %s | grep %s", name, sha))
if _, err := r.Runner.RunCmd(c); err != nil {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *Containerd) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -119,6 +119,20 @@ func (r *CRIO) Disable() error {
return nil
}
// ImageExists checks if an image exists
func (r *CRIO) ImageExists(name string, sha string) bool {
// expected output looks like [NAME@sha256:SHA]
c := exec.Command("sudo", "podman", "inspect", "--format='{{.Id}}'", name)
rr, err := r.Runner.RunCmd(c)
if err != nil {
return false
}
if !strings.Contains(rr.Output(), sha) {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *CRIO) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -59,6 +59,9 @@ type Manager interface {
// Load an image idempotently into the runtime on a host
LoadImage(string) error
// ImageExists takes image name and image sha checks if an it exists
ImageExists(string, string) bool
// ListContainers returns a list of managed by this container runtime
ListContainers(string) ([]string, error)
// KillContainers removes containers based on ID

View File

@ -102,6 +102,20 @@ func (r *Docker) Disable() error {
return nil
}
// ImageExists checks if an image exists
func (r *Docker) ImageExists(name string, sha string) bool {
// expected output looks like [SHA_ALGO:SHA]
c := exec.Command("docker", "inspect", "--format='{{.Id}}'", name)
rr, err := r.Runner.RunCmd(c)
if err != nil {
return false
}
if !strings.Contains(rr.Output(), sha) {
return false
}
return true
}
// LoadImage loads an image into this runtime
func (r *Docker) LoadImage(path string) error {
glog.Infof("Loading image: %s", path)

View File

@ -23,7 +23,7 @@ import (
"k8s.io/client-go/util/homedir"
)
// MinikubeHome is the name of the minikube home directory variable.
// MinikubeHome is the name of the minikube home directory environment variable.
const MinikubeHome = "MINIKUBE_HOME"
// ConfigFile is the path of the config file
@ -46,3 +46,12 @@ func MakeMiniPath(fileName ...string) string {
args = append(args, fileName...)
return filepath.Join(args...)
}
// MachinePath returns the Minikube machine path of a machine
func MachinePath(machine string, miniHome ...string) string {
miniPath := MiniPath()
if len(miniHome) > 0 {
miniPath = miniHome[0]
}
return filepath.Join(miniPath, "machines", machine)
}

View File

@ -27,6 +27,7 @@ import (
"sync"
"time"
"github.com/docker/machine/libmachine/state"
"github.com/golang/glog"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
@ -38,6 +39,7 @@ import (
"golang.org/x/sync/errgroup"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
@ -95,24 +97,38 @@ func CacheImages(images []string, cacheDir string) error {
}
// LoadImages loads previously cached images into the container runtime
func LoadImages(cmd command.Runner, images []string, cacheDir string) error {
func LoadImages(cc *config.MachineConfig, runner command.Runner, images []string, cacheDir string) error {
glog.Infof("LoadImages start: %s", images)
defer glog.Infof("LoadImages end")
var g errgroup.Group
// Load profile cluster config from file
cc, err := config.Load()
if err != nil && !os.IsNotExist(err) {
glog.Errorln("Error loading profile config: ", err)
cr, err := cruntime.New(cruntime.Config{Type: cc.ContainerRuntime, Runner: runner})
if err != nil {
return errors.Wrap(err, "runtime")
}
for _, image := range images {
image := image
g.Go(func() error {
src := filepath.Join(cacheDir, image)
src = sanitizeCacheDir(src)
if err := transferAndLoadImage(cmd, cc.KubernetesConfig, src); err != nil {
glog.Warningf("Failed to load %s: %v", src, err)
return errors.Wrapf(err, "loading image %s", src)
ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil {
return errors.Wrap(err, "image name reference")
}
img, err := retrieveImage(ref)
if err != nil {
return errors.Wrap(err, "fetching image")
}
cf, err := img.ConfigName()
hash := cf.Hex
if err != nil {
glog.Infof("error retrieving image manifest for %s to check if it already exists: %v", image, err)
} else if cr.ImageExists(image, hash) {
glog.Infof("skipping re-loading image %q because sha %q already exists ", image, hash)
return nil
}
if err := transferAndLoadImage(runner, cc.KubernetesConfig, image, cacheDir); err != nil {
glog.Warningf("Failed to load %s: %v", image, err)
return errors.Wrapf(err, "loading image %s", image)
}
return nil
})
@ -124,7 +140,7 @@ func LoadImages(cmd command.Runner, images []string, cacheDir string) error {
return nil
}
// CacheAndLoadImages caches and loads images
// CacheAndLoadImages caches and loads images to all profiles
func CacheAndLoadImages(images []string) error {
if err := CacheImages(images, constants.ImageCacheDir); err != nil {
return err
@ -134,20 +150,38 @@ func CacheAndLoadImages(images []string) error {
return err
}
defer api.Close()
cc, err := config.Load()
profiles, _, err := config.ListProfiles() // need to load image to all profiles
if err != nil {
return err
return errors.Wrap(err, "list profiles")
}
h, err := api.Load(cc.Name)
if err != nil {
return err
for _, p := range profiles { // adding images to all the profiles
pName := p.Name // capture the loop variable
status, err := cluster.GetHostStatus(api, pName)
if err != nil {
glog.Warningf("skipping loading cache for profile %s", pName)
glog.Errorf("error getting status for %s: %v", pName, err)
continue // try next machine
}
if status == state.Running.String() { // the not running hosts will load on next start
h, err := api.Load(pName)
if err != nil {
return err
}
cr, err := CommandRunner(h)
if err != nil {
return err
}
c, err := config.Load(pName)
if err != nil {
return err
}
err = LoadImages(c, cr, images, constants.ImageCacheDir)
if err != nil {
glog.Warningf("Failed to load cached images for profile %s. make sure the profile is running. %v", pName, err)
}
}
}
runner, err := CommandRunner(h)
if err != nil {
return err
}
return LoadImages(runner, images, constants.ImageCacheDir)
return err
}
// # ParseReference cannot have a : in the directory path
@ -214,7 +248,13 @@ func getWindowsVolumeNameCmd(d string) (string, error) {
}
// transferAndLoadImage transfers and loads a single image from the cache
func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src string) error {
func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, imgName string, cacheDir string) error {
r, err := cruntime.New(cruntime.Config{Type: k8s.ContainerRuntime, Runner: cr})
if err != nil {
return errors.Wrap(err, "runtime")
}
src := filepath.Join(cacheDir, imgName)
src = sanitizeCacheDir(src)
glog.Infof("Loading image from cache: %s", src)
filename := filepath.Base(src)
if _, err := os.Stat(src); err != nil {
@ -229,10 +269,6 @@ func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src st
return errors.Wrap(err, "transferring cached image")
}
r, err := cruntime.New(cruntime.Config{Type: k8s.ContainerRuntime, Runner: cr})
if err != nil {
return errors.Wrap(err, "runtime")
}
loadImageLock.Lock()
defer loadImageLock.Unlock()
@ -334,6 +370,12 @@ func CacheImage(image, dst string) error {
if err != nil {
return err
}
defer func() { // clean up temp files
err := os.Remove(f.Name())
if err != nil {
glog.Infof("Failed to clean up the temp file %s : %v", f.Name(), err)
}
}()
tag, err := name.NewTag(image, name.WeakValidation)
if err != nil {
return err

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
package machine
import (
"io/ioutil"
@ -23,8 +23,8 @@ import (
"github.com/docker/machine/libmachine/host"
"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/machine"
)
// Machine contains information about a machine
@ -60,15 +60,15 @@ func (h *Machine) IsValid() bool {
return true
}
// ListMachines return all valid and invalid machines
// List return all valid and invalid machines
// If a machine is valid or invalid is determined by the cluster.IsValid function
func ListMachines(miniHome ...string) (validMachines []*Machine, inValidMachines []*Machine, err error) {
func List(miniHome ...string) (validMachines []*Machine, inValidMachines []*Machine, err error) {
pDirs, err := machineDirs(miniHome...)
if err != nil {
return nil, nil, err
}
for _, n := range pDirs {
p, err := LoadMachine(n)
p, err := Load(n)
if err != nil {
glog.Infof("%s not valid: %v", n, err)
inValidMachines = append(inValidMachines, p)
@ -83,14 +83,14 @@ func ListMachines(miniHome ...string) (validMachines []*Machine, inValidMachines
return validMachines, inValidMachines, nil
}
// LoadMachine loads a machine or throws an error if the machine could not be loadedG
func LoadMachine(name string) (*Machine, error) {
api, err := machine.NewAPIClient()
// Load loads a machine or throws an error if the machine could not be loadedG
func Load(name string) (*Machine, error) {
api, err := NewAPIClient()
if err != nil {
return nil, err
}
h, err := CheckIfHostExistsAndLoad(api, name)
h, err := cluster.CheckIfHostExistsAndLoad(api, name)
if err != nil {
return nil, err
}
@ -119,12 +119,3 @@ func machineDirs(miniHome ...string) (dirs []string, err error) {
}
return dirs, err
}
// MachinePath returns the Minikube machine path of a machine
func MachinePath(machine string, miniHome ...string) string {
miniPath := localpath.MiniPath()
if len(miniHome) > 0 {
miniPath = miniHome[0]
}
return filepath.Join(miniPath, "machines", machine)
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
package machine
import (
"io/ioutil"
@ -51,7 +51,7 @@ func TestListMachines(t *testing.T) {
files, _ := ioutil.ReadDir(filepath.Join(localpath.MiniPath(), "machines"))
numberOfMachineDirs := len(files)
validMachines, inValidMachines, err := ListMachines()
validMachines, inValidMachines, err := List()
if err != nil {
t.Error(err)

View File

@ -314,7 +314,7 @@ func configureAuth(p *BuildrootProvisioner) error {
return err
}
config, err := config.Load()
config, err := config.Load(p.Driver.GetMachineName())
if err != nil {
return errors.Wrap(err, "getting cluster config")
}

View File

@ -308,17 +308,51 @@ func validateDNS(ctx context.Context, t *testing.T, profile string) {
}
}
// validateCacheCmd asserts basic "ssh" command functionality
// validateCacheCmd tests functionality of cache command (cache add, delete, list)
func validateCacheCmd(ctx context.Context, t *testing.T, profile string) {
if NoneDriver() {
t.Skipf("skipping: cache unsupported by none")
}
for _, img := range []string{"busybox", "busybox:1.28.4-glibc", "mysql:5.6", "gcr.io/hello-minikube-zero-install/hello-node"} {
rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cache", "add", img))
if err != nil {
t.Errorf("%s failed: %v", rr.Args, err)
}
}
t.Run("cache", func(t *testing.T) {
t.Run("add", func(t *testing.T) {
for _, img := range []string{"busybox", "busybox:1.28.4-glibc", "k8s.gcr.io/pause:latest"} {
_, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cache", "add", img))
if err != nil {
t.Errorf("Failed to cache image %q", img)
}
}
})
t.Run("delete", func(t *testing.T) {
_, err := Run(t, exec.CommandContext(ctx, Target(), "cache", "delete", "busybox:1.28.4-glibc"))
if err != nil {
t.Errorf("failed to delete image busybox:1.28.4-glibc from cache: %v", err)
}
})
t.Run("list", func(t *testing.T) {
rr, err := Run(t, exec.CommandContext(ctx, Target(), "cache", "list"))
if err != nil {
t.Errorf("cache list failed: %v", err)
}
if !strings.Contains(rr.Output(), "k8s.gcr.io/pause") {
t.Errorf("cache list did not include k8s.gcr.io/pause")
}
if strings.Contains(rr.Output(), "busybox:1.28.4-glibc") {
t.Errorf("cache list should not include busybox:1.28.4-glibc")
}
})
t.Run("verify cache inside node", func(t *testing.T) {
rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "sudo", "crictl", "images"))
if err != nil {
t.Errorf("failed to get docker images through ssh %v", err)
}
if !strings.Contains(rr.Output(), "1.28.4-glibc") {
t.Errorf("expected '1.28.4-glibc' to be in the output: %s", rr.Output())
}
})
})
}
// validateConfigCmd asserts basic "config" command functionality