From 196a8d7b8201e0931fce10c38b515cdeec957223 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Fri, 13 Mar 2020 15:51:03 -0700 Subject: [PATCH] Delete: output underlying status failure, refactor wordy code --- cmd/minikube/cmd/config/open.go | 2 +- cmd/minikube/cmd/config/profile_list.go | 4 +- cmd/minikube/cmd/dashboard.go | 2 +- cmd/minikube/cmd/delete.go | 6 +-- cmd/minikube/cmd/docker-env.go | 4 +- cmd/minikube/cmd/node_start.go | 2 +- cmd/minikube/cmd/pause.go | 2 +- cmd/minikube/cmd/podman-env.go | 4 +- cmd/minikube/cmd/service.go | 2 +- cmd/minikube/cmd/service_list.go | 2 +- cmd/minikube/cmd/ssh.go | 2 +- cmd/minikube/cmd/status.go | 4 +- cmd/minikube/cmd/unpause.go | 2 +- pkg/addons/addons.go | 6 +-- pkg/drivers/kic/kic.go | 2 +- pkg/minikube/cluster/ip.go | 2 +- pkg/minikube/machine/cache_images.go | 2 +- pkg/minikube/machine/cluster_test.go | 4 +- pkg/minikube/machine/delete.go | 4 +- pkg/minikube/machine/{status.go => host.go} | 18 +++---- pkg/minikube/machine/machine.go | 59 ++------------------- pkg/minikube/machine/machine_test.go | 58 -------------------- pkg/minikube/machine/runner.go | 43 +++++++++++++++ pkg/minikube/machine/ssh.go | 49 +++++++++++++++++ pkg/minikube/service/service.go | 4 +- pkg/minikube/tunnel/cluster_inspector.go | 2 +- 26 files changed, 136 insertions(+), 155 deletions(-) rename pkg/minikube/machine/{status.go => host.go} (77%) create mode 100644 pkg/minikube/machine/runner.go create mode 100644 pkg/minikube/machine/ssh.go diff --git a/cmd/minikube/cmd/config/open.go b/cmd/minikube/cmd/config/open.go index 5229385d9..c4c8b5416 100644 --- a/cmd/minikube/cmd/config/open.go +++ b/cmd/minikube/cmd/config/open.go @@ -78,7 +78,7 @@ var addonsOpenCmd = &cobra.Command{ if err != nil { exit.WithError("Error getting control plane", err) } - if !machine.IsHostRunning(api, driver.MachineName(*cc, cp)) { + if !machine.IsRunning(api, driver.MachineName(*cc, cp)) { os.Exit(1) } addon, ok := assets.Addons[addonName] // validate addon input diff --git a/cmd/minikube/cmd/config/profile_list.go b/cmd/minikube/cmd/config/profile_list.go index 7a03084ec..d3b4bf1b9 100644 --- a/cmd/minikube/cmd/config/profile_list.go +++ b/cmd/minikube/cmd/config/profile_list.go @@ -80,7 +80,7 @@ var printProfilesTable = func() { if err != nil { exit.WithError("error getting primary control plane", err) } - p.Status, err = machine.GetHostStatus(api, driver.MachineName(*p.Config, cp)) + p.Status, err = machine.Status(api, driver.MachineName(*p.Config, cp)) if err != nil { glog.Warningf("error getting host status for %s: %v", p.Name, err) } @@ -121,7 +121,7 @@ var printProfilesJSON = func() { if err != nil { exit.WithError("error getting primary control plane", err) } - status, err := machine.GetHostStatus(api, driver.MachineName(*v.Config, cp)) + status, err := machine.Status(api, driver.MachineName(*v.Config, cp)) if err != nil { glog.Warningf("error getting host status for %s: %v", v.Name, err) } diff --git a/cmd/minikube/cmd/dashboard.go b/cmd/minikube/cmd/dashboard.go index 214d7fa25..b5fd848eb 100644 --- a/cmd/minikube/cmd/dashboard.go +++ b/cmd/minikube/cmd/dashboard.go @@ -109,7 +109,7 @@ var dashboardCmd = &cobra.Command{ exit.WithCodeT(exit.NoInput, "kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/") } - if !machine.IsHostRunning(api, machineName) { + if !machine.IsRunning(api, machineName) { os.Exit(1) } diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index c9a6670b9..253f48128 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -174,7 +174,7 @@ func DeleteProfiles(profiles []*config.Profile) []error { err := deleteProfile(profile) if err != nil { - mm, loadErr := machine.Load(profile.Name) + mm, loadErr := machine.LoadMachine(profile.Name) if !profile.IsValid() || (loadErr != nil || !mm.IsValid()) { invalidProfileDeletionErrs := deleteInvalidProfile(profile) @@ -208,7 +208,6 @@ func deleteProfileContainersAndVolumes(name string) { func deleteProfile(profile *config.Profile) error { viper.Set(config.ProfileName, profile.Name) - deleteProfileContainersAndVolumes(profile.Name) api, err := machine.NewAPIClient() @@ -217,6 +216,7 @@ func deleteProfile(profile *config.Profile) error { return DeletionError{Err: delErr, Errtype: Fatal} } defer api.Close() + cc, err := config.Load(profile.Name) if err != nil && !config.IsNotExist(err) { delErr := profileDeletionErr(profile.Name, fmt.Sprintf("error loading profile config: %v", err)) @@ -328,7 +328,7 @@ func uninstallKubernetes(api libmachine.API, cc config.ClusterConfig, n config.N return DeletionError{Err: fmt.Errorf("unable to get bootstrapper: %v", err), Errtype: Fatal} } - host, err := machine.CheckIfHostExistsAndLoad(api, driver.MachineName(cc, n)) + host, err := machine.LoadHost(api, driver.MachineName(cc, n)) if err != nil { exit.WithError("Error getting host", err) } diff --git a/cmd/minikube/cmd/docker-env.go b/cmd/minikube/cmd/docker-env.go index d7d532fb2..02b857b0e 100644 --- a/cmd/minikube/cmd/docker-env.go +++ b/cmd/minikube/cmd/docker-env.go @@ -150,7 +150,7 @@ var dockerEnvCmd = &cobra.Command{ } for _, n := range cc.Nodes { machineName := driver.MachineName(*cc, n) - host, err := machine.CheckIfHostExistsAndLoad(api, machineName) + host, err := machine.LoadHost(api, machineName) if err != nil { exit.WithError("Error getting host", err) } @@ -158,7 +158,7 @@ var dockerEnvCmd = &cobra.Command{ exit.UsageT(`'none' driver does not support 'minikube docker-env' command`) } - hostSt, err := machine.GetHostStatus(api, machineName) + hostSt, err := machine.Status(api, machineName) if err != nil { exit.WithError("Error getting host status", err) } diff --git a/cmd/minikube/cmd/node_start.go b/cmd/minikube/cmd/node_start.go index 9144e8815..c0090b628 100644 --- a/cmd/minikube/cmd/node_start.go +++ b/cmd/minikube/cmd/node_start.go @@ -45,7 +45,7 @@ var nodeStartCmd = &cobra.Command{ exit.WithError("creating api client", err) } - if machine.IsHostRunning(api, name) { + if machine.IsRunning(api, name) { out.T(out.Check, "{{.name}} is already running", out.V{"name": name}) os.Exit(0) } diff --git a/cmd/minikube/cmd/pause.go b/cmd/minikube/cmd/pause.go index 7cbc3855d..4b63ed963 100644 --- a/cmd/minikube/cmd/pause.go +++ b/cmd/minikube/cmd/pause.go @@ -66,7 +66,7 @@ func runPause(cmd *cobra.Command, args []string) { glog.Infof("config: %+v", cc) for _, n := range cc.Nodes { - host, err := machine.CheckIfHostExistsAndLoad(api, driver.MachineName(*cc, n)) + host, err := machine.LoadHost(api, driver.MachineName(*cc, n)) if err != nil { exit.WithError("Error getting host", err) } diff --git a/cmd/minikube/cmd/podman-env.go b/cmd/minikube/cmd/podman-env.go index 1240d08c8..f68191f53 100644 --- a/cmd/minikube/cmd/podman-env.go +++ b/cmd/minikube/cmd/podman-env.go @@ -121,7 +121,7 @@ var podmanEnvCmd = &cobra.Command{ } for _, n := range cc.Nodes { machineName := driver.MachineName(*cc, n) - host, err := machine.CheckIfHostExistsAndLoad(api, machineName) + host, err := machine.LoadHost(api, machineName) if err != nil { exit.WithError("Error getting host", err) } @@ -129,7 +129,7 @@ var podmanEnvCmd = &cobra.Command{ exit.UsageT(`'none' driver does not support 'minikube podman-env' command`) } - hostSt, err := machine.GetHostStatus(api, machineName) + hostSt, err := machine.Status(api, machineName) if err != nil { exit.WithError("Error getting host status", err) } diff --git a/cmd/minikube/cmd/service.go b/cmd/minikube/cmd/service.go index 174e1b88c..bbb25013f 100644 --- a/cmd/minikube/cmd/service.go +++ b/cmd/minikube/cmd/service.go @@ -93,7 +93,7 @@ var serviceCmd = &cobra.Command{ exit.WithError("Error getting control plane", err) } machineName := driver.MachineName(*cfg, cp) - if !machine.IsHostRunning(api, machineName) { + if !machine.IsRunning(api, machineName) { os.Exit(1) } diff --git a/cmd/minikube/cmd/service_list.go b/cmd/minikube/cmd/service_list.go index 15aeec7a5..f22aa71d2 100644 --- a/cmd/minikube/cmd/service_list.go +++ b/cmd/minikube/cmd/service_list.go @@ -56,7 +56,7 @@ var serviceListCmd = &cobra.Command{ if err != nil { exit.WithError("Error getting primary control plane", err) } - if !machine.IsHostRunning(api, driver.MachineName(*cfg, cp)) { + if !machine.IsRunning(api, driver.MachineName(*cfg, cp)) { exit.WithCodeT(exit.Unavailable, "profile {{.name}} is not running.", out.V{"name": profileName}) } serviceURLs, err := service.GetServiceURLs(api, serviceListNamespace, serviceURLTemplate) diff --git a/cmd/minikube/cmd/ssh.go b/cmd/minikube/cmd/ssh.go index bb20321c1..8c78c87ee 100644 --- a/cmd/minikube/cmd/ssh.go +++ b/cmd/minikube/cmd/ssh.go @@ -54,7 +54,7 @@ var sshCmd = &cobra.Command{ if err != nil { exit.WithError("Error getting primary control plane", err) } - host, err := machine.CheckIfHostExistsAndLoad(api, driver.MachineName(*cc, cp)) + host, err := machine.LoadHost(api, driver.MachineName(*cc, cp)) if err != nil { exit.WithError("Error getting host", err) } diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index b8ad90838..5d1452e46 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -154,7 +154,7 @@ func status(api libmachine.API, name string) (*Status, error) { Kubeconfig: Nonexistent, } - hs, err := machine.GetHostStatus(api, name) + hs, err := machine.Status(api, name) glog.Infof("%s host status = %q (err=%v)", name, hs, err) if err != nil { return st, errors.Wrap(err, "host") @@ -196,7 +196,7 @@ func status(api libmachine.API, name string) (*Status, error) { st.Kubeconfig = Configured } - host, err := machine.CheckIfHostExistsAndLoad(api, name) + host, err := machine.LoadHost(api, name) if err != nil { return st, err } diff --git a/cmd/minikube/cmd/unpause.go b/cmd/minikube/cmd/unpause.go index 8b77f10d5..7549f1b00 100644 --- a/cmd/minikube/cmd/unpause.go +++ b/cmd/minikube/cmd/unpause.go @@ -58,7 +58,7 @@ var unpauseCmd = &cobra.Command{ for _, n := range cc.Nodes { machineName := driver.MachineName(*cc, n) - host, err := machine.CheckIfHostExistsAndLoad(api, machineName) + host, err := machine.LoadHost(api, machineName) if err != nil { exit.WithError("Error getting host", err) } diff --git a/pkg/addons/addons.go b/pkg/addons/addons.go index 09e62ef3e..d644aafc8 100644 --- a/pkg/addons/addons.go +++ b/pkg/addons/addons.go @@ -145,8 +145,8 @@ func enableOrDisableAddon(cc *config.ClusterConfig, name string, val string) err } mName := driver.MachineName(*cc, cp) - host, err := machine.CheckIfHostExistsAndLoad(api, mName) - if err != nil || !machine.IsHostRunning(api, mName) { + host, err := machine.LoadHost(api, mName) + if err != nil || !machine.IsRunning(api, mName) { glog.Warningf("%q is not running, writing %s=%v to disk and skipping enablement (err=%v)", mName, addon.Name(), enable, err) return nil } @@ -247,7 +247,7 @@ func enableOrDisableStorageClasses(cc *config.ClusterConfig, name string, val st if err != nil { return errors.Wrap(err, "getting control plane") } - if !machine.IsHostRunning(api, driver.MachineName(*cc, cp)) { + if !machine.IsRunning(api, driver.MachineName(*cc, cp)) { glog.Warningf("%q is not running, writing %s=%v to disk and skipping enablement", driver.MachineName(*cc, cp), name, val) return enableOrDisableAddon(cc, name, val) } diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index dc9d2a530..2689490e1 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -226,7 +226,7 @@ func (d *Driver) GetState() (state.State, error) { } o := strings.TrimSpace(string(out)) if err != nil { - return state.Error, errors.Wrapf(err, "get container %s status", d.MachineName) + return state.Error, errors.Wrapf(err, "%s: %s", cmd.Args, out) } switch o { case "running": diff --git a/pkg/minikube/cluster/ip.go b/pkg/minikube/cluster/ip.go index 7bd76c8c6..7ec11064c 100644 --- a/pkg/minikube/cluster/ip.go +++ b/pkg/minikube/cluster/ip.go @@ -79,7 +79,7 @@ func GetVMHostIP(host *host.Host) (net.IP, error) { // GetHostDriverIP gets the ip address of the current minikube cluster func GetHostDriverIP(api libmachine.API, machineName string) (net.IP, error) { - host, err := machine.CheckIfHostExistsAndLoad(api, machineName) + host, err := machine.LoadHost(api, machineName) if err != nil { return nil, err } diff --git a/pkg/minikube/machine/cache_images.go b/pkg/minikube/machine/cache_images.go index 65505e0e6..34b437931 100644 --- a/pkg/minikube/machine/cache_images.go +++ b/pkg/minikube/machine/cache_images.go @@ -152,7 +152,7 @@ func CacheAndLoadImages(images []string) error { } for _, n := range c.Nodes { m := driver.MachineName(*c, n) - status, err := GetHostStatus(api, m) + status, err := Status(api, m) if err != nil { glog.Warningf("skipping loading cache for profile %s", pName) glog.Errorf("error getting status for %s: %v", pName, err) diff --git a/pkg/minikube/machine/cluster_test.go b/pkg/minikube/machine/cluster_test.go index 98a22cd92..0c32c8642 100644 --- a/pkg/minikube/machine/cluster_test.go +++ b/pkg/minikube/machine/cluster_test.go @@ -374,7 +374,7 @@ func TestDeleteHostErrMachineNotExist(t *testing.T) { } } -func TestGetHostStatus(t *testing.T) { +func TestStatus(t *testing.T) { RegisterMockDriver(t) api := tests.NewMockAPI(t) @@ -384,7 +384,7 @@ func TestGetHostStatus(t *testing.T) { m := driver.MachineName(cc, config.Node{Name: "minikube"}) checkState := func(expected string, machineName string) { - s, err := GetHostStatus(api, machineName) + s, err := Status(api, machineName) if err != nil { t.Fatalf("Unexpected error getting status: %v", err) } diff --git a/pkg/minikube/machine/delete.go b/pkg/minikube/machine/delete.go index e3a8ead7d..518f7b3fc 100644 --- a/pkg/minikube/machine/delete.go +++ b/pkg/minikube/machine/delete.go @@ -64,10 +64,10 @@ func DeleteHost(api libmachine.API, machineName string) error { } // Get the status of the host. Ensure that it exists before proceeding ahead. - status, err := GetHostStatus(api, machineName) + status, err := Status(api, machineName) if err != nil { // Warn, but proceed - out.WarningT("Unable to get the status of the {{.name}} cluster.", out.V{"name": machineName}) + out.WarningT(`Unable to get host status for "{{.name}}": {{.error}}`, out.V{"name": machineName, "error": err}) } if status == state.None.String() { diff --git a/pkg/minikube/machine/status.go b/pkg/minikube/machine/host.go similarity index 77% rename from pkg/minikube/machine/status.go rename to pkg/minikube/machine/host.go index 141d6a9bd..38fc02a33 100644 --- a/pkg/minikube/machine/status.go +++ b/pkg/minikube/machine/host.go @@ -24,8 +24,8 @@ import ( "github.com/pkg/errors" ) -// GetHostStatus gets the status of the host VM. -func GetHostStatus(api libmachine.API, machineName string) (string, error) { +// Status returns the status of a libmachine host +func Status(api libmachine.API, machineName string) (string, error) { exists, err := api.Exists(machineName) if err != nil { return "", errors.Wrapf(err, "%s exists", machineName) @@ -46,9 +46,9 @@ func GetHostStatus(api libmachine.API, machineName string) (string, error) { return s.String(), nil } -// IsHostRunning asserts that this profile's primary host is in state "Running" -func IsHostRunning(api libmachine.API, name string) bool { - s, err := GetHostStatus(api, name) +// IsRunning asserts that a libmachine host is in state "Running" +func IsRunning(api libmachine.API, name string) bool { + s, err := Status(api, name) if err != nil { glog.Warningf("host status for %q returned error: %v", name, err) return false @@ -60,8 +60,8 @@ func IsHostRunning(api libmachine.API, name string) bool { return true } -// CheckIfHostExistsAndLoad checks if a host exists, and loads it if it does -func CheckIfHostExistsAndLoad(api libmachine.API, machineName string) (*host.Host, error) { +// LoadHost returns a libmachine host by name +func LoadHost(api libmachine.API, machineName string) (*host.Host, error) { glog.Infof("Checking if %q exists ...", machineName) exists, err := api.Exists(machineName) if err != nil { @@ -71,9 +71,9 @@ func CheckIfHostExistsAndLoad(api libmachine.API, machineName string) (*host.Hos return nil, errors.Errorf("machine %q does not exist", machineName) } - host, err := api.Load(machineName) + h, err := api.Load(machineName) if err != nil { return nil, errors.Wrapf(err, "loading machine %q", machineName) } - return host, nil + return h, nil } diff --git a/pkg/minikube/machine/machine.go b/pkg/minikube/machine/machine.go index fd3804ecb..f508c9847 100644 --- a/pkg/minikube/machine/machine.go +++ b/pkg/minikube/machine/machine.go @@ -20,13 +20,8 @@ import ( "io/ioutil" "path/filepath" - "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/host" - "github.com/docker/machine/libmachine/state" - "github.com/golang/glog" "github.com/pkg/errors" - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" ) @@ -63,37 +58,14 @@ func (h *Machine) IsValid() bool { return true } -// List return all valid and invalid machines -// If a machine is valid or invalid is determined by the cluster.IsValid function -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 := Load(n) - if err != nil { - glog.Infof("%s not valid: %v", n, err) - inValidMachines = append(inValidMachines, p) - continue - } - if !p.IsValid() { - inValidMachines = append(inValidMachines, p) - continue - } - validMachines = append(validMachines, p) - } - return validMachines, inValidMachines, nil -} - -// Load loads a machine or throws an error if the machine could not be loaded. -func Load(name string) (*Machine, error) { +// LoadMachine returns a Machine abstracting a libmachine.Host +func LoadMachine(name string) (*Machine, error) { api, err := NewAPIClient() if err != nil { return nil, err } - h, err := CheckIfHostExistsAndLoad(api, name) + h, err := LoadHost(api, name) if err != nil { return nil, err } @@ -104,7 +76,6 @@ func Load(name string) (*Machine, error) { } else { return nil, errors.New("host is nil") } - return &mm, nil } @@ -122,27 +93,3 @@ func machineDirs(miniHome ...string) (dirs []string, err error) { } return dirs, err } - -// CreateSSHShell creates a new SSH shell / client -func CreateSSHShell(api libmachine.API, cc config.ClusterConfig, n config.Node, args []string) error { - machineName := driver.MachineName(cc, n) - host, err := CheckIfHostExistsAndLoad(api, machineName) - if err != nil { - return errors.Wrap(err, "host exists and load") - } - - currentState, err := host.Driver.GetState() - if err != nil { - return errors.Wrap(err, "state") - } - - if currentState != state.Running { - return errors.Errorf("%q is not running", machineName) - } - - client, err := host.CreateSSHClient() - if err != nil { - return errors.Wrap(err, "Creating ssh client") - } - return client.Shell(args...) -} diff --git a/pkg/minikube/machine/machine_test.go b/pkg/minikube/machine/machine_test.go index c08465085..451feca66 100644 --- a/pkg/minikube/machine/machine_test.go +++ b/pkg/minikube/machine/machine_test.go @@ -15,61 +15,3 @@ limitations under the License. */ package machine - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/spf13/viper" - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/localpath" -) - -func TestListMachines(t *testing.T) { - const ( - numberOfValidMachines = 2 - numberOfInValidMachines = 3 - totalNumberOfMachines = numberOfValidMachines + numberOfInValidMachines - ) - - viper.Set(config.ProfileName, "") - - testMinikubeDir := "./testdata/list-machines/.minikube" - miniDir, err := filepath.Abs(testMinikubeDir) - - if err != nil { - t.Errorf("error getting dir path for %s : %v", testMinikubeDir, err) - } - - err = os.Setenv(localpath.MinikubeHome, miniDir) - if err != nil { - t.Errorf("error setting up test environment. could not set %s", localpath.MinikubeHome) - } - - files, _ := ioutil.ReadDir(filepath.Join(localpath.MiniPath(), "machines")) - numberOfMachineDirs := len(files) - - validMachines, inValidMachines, err := List() - - if err != nil { - t.Error(err) - } - - if numberOfValidMachines != len(validMachines) { - t.Errorf("expected %d valid machines, got %d", numberOfValidMachines, len(validMachines)) - } - - if numberOfInValidMachines != len(inValidMachines) { - t.Errorf("expected %d invalid machines, got %d", numberOfInValidMachines, len(inValidMachines)) - } - - if totalNumberOfMachines != len(validMachines)+len(inValidMachines) { - t.Errorf("expected %d total machines, got %d", totalNumberOfMachines, len(validMachines)+len(inValidMachines)) - } - - if numberOfMachineDirs != len(validMachines)+len(inValidMachines) { - t.Error("expected number of machine directories to be equal to the number of total machines") - } -} diff --git a/pkg/minikube/machine/runner.go b/pkg/minikube/machine/runner.go new file mode 100644 index 000000000..957741c5e --- /dev/null +++ b/pkg/minikube/machine/runner.go @@ -0,0 +1,43 @@ +/* +Copyright 2020 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 machine + +import ( + "sync" + + "github.com/docker/machine/libmachine/host" + "github.com/golang/glog" + "k8s.io/minikube/pkg/minikube/command" + "k8s.io/minikube/pkg/minikube/drvcmd" +) + +var cachedRunner sync.Map + +// Runner returns best available command runner for this host +func Runner(h *host.Host) (command.Runner, error) { + result, ok := cachedRunner.Load(h.Name) + if ok { + glog.Errorf("NOTE: returning cached runner for %q", h.Name) + return result.(command.Runner), nil + } + cr, err := drvcmd.Runner(h.Driver) + if err != nil { + return nil, err + } + cachedRunner.Store(h.Name, cr) + return cr, nil +} diff --git a/pkg/minikube/machine/ssh.go b/pkg/minikube/machine/ssh.go new file mode 100644 index 000000000..955b2e1a2 --- /dev/null +++ b/pkg/minikube/machine/ssh.go @@ -0,0 +1,49 @@ +/* +Copyright 2020 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 machine + +import ( + "github.com/docker/machine/libmachine" + "github.com/docker/machine/libmachine/state" + "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/driver" +) + +// CreateSSHShell creates a new SSH shell / client +func CreateSSHShell(api libmachine.API, cc config.ClusterConfig, n config.Node, args []string) error { + machineName := driver.MachineName(cc, n) + host, err := LoadHost(api, machineName) + if err != nil { + return errors.Wrap(err, "host exists and load") + } + + currentState, err := host.Driver.GetState() + if err != nil { + return errors.Wrap(err, "state") + } + + if currentState != state.Running { + return errors.Errorf("%q is not running", machineName) + } + + client, err := host.CreateSSHClient() + if err != nil { + return errors.Wrap(err, "Creating ssh client") + } + return client.Shell(args...) +} diff --git a/pkg/minikube/service/service.go b/pkg/minikube/service/service.go index 2d349d7a3..eddb45dcf 100644 --- a/pkg/minikube/service/service.go +++ b/pkg/minikube/service/service.go @@ -119,7 +119,7 @@ type URLs []SvcURL // GetServiceURLs returns a SvcURL object for every service in a particular namespace. // Accepts a template for formatting func GetServiceURLs(api libmachine.API, namespace string, t *template.Template) (URLs, error) { - host, err := machine.CheckIfHostExistsAndLoad(api, viper.GetString(config.ProfileName)) + host, err := machine.LoadHost(api, viper.GetString(config.ProfileName)) if err != nil { return nil, err } @@ -155,7 +155,7 @@ func GetServiceURLs(api libmachine.API, namespace string, t *template.Template) // GetServiceURLsForService returns a SvcUrl object for a service in a namespace. Supports optional formatting. func GetServiceURLsForService(api libmachine.API, namespace, service string, t *template.Template) (SvcURL, error) { - host, err := machine.CheckIfHostExistsAndLoad(api, viper.GetString(config.ProfileName)) + host, err := machine.LoadHost(api, viper.GetString(config.ProfileName)) if err != nil { return SvcURL{}, errors.Wrap(err, "Error checking if api exist and loading it") } diff --git a/pkg/minikube/tunnel/cluster_inspector.go b/pkg/minikube/tunnel/cluster_inspector.go index 8f9001e3d..84315a62c 100644 --- a/pkg/minikube/tunnel/cluster_inspector.go +++ b/pkg/minikube/tunnel/cluster_inspector.go @@ -37,7 +37,7 @@ type clusterInspector struct { func (m *clusterInspector) getStateAndHost() (HostState, *host.Host, error) { - h, err := machine.CheckIfHostExistsAndLoad(m.machineAPI, m.machineName) + h, err := machine.LoadHost(m.machineAPI, m.machineName) if err != nil { err = errors.Wrapf(err, "error loading docker-machine host for: %s", m.machineName) -- GitLab