未验证 提交 1a19f8f0 编写于 作者: M Medya Ghazizadeh 提交者: GitHub

Merge pull request #7176 from tstromberg/down-detect

Update commands to consistently detect down & paused clusters
......@@ -26,7 +26,6 @@ import (
"github.com/golang/glog"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
......@@ -98,7 +97,7 @@ var printAddonsList = func() {
table.SetAutoFormatHeaders(true)
table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
table.SetCenterSeparator("|")
pName := viper.GetString(config.ProfileName)
pName := ClusterFlagValue()
for _, addonName := range addonNames {
addonBundle := assets.Addons[addonName]
......@@ -123,7 +122,7 @@ var printAddonsList = func() {
var printAddonsJSON = func() {
addonNames := make([]string, 0, len(assets.Addons))
pName := viper.GetString(config.ProfileName)
pName := ClusterFlagValue()
for addonName := range assets.Addons {
addonNames = append(addonNames, addonName)
}
......
......@@ -18,9 +18,7 @@ package config
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/addons"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -35,7 +33,7 @@ var addonsDisableCmd = &cobra.Command{
}
addon := args[0]
err := addons.Set(addon, "false", viper.GetString(config.ProfileName))
err := addons.Set(addon, "false", ClusterFlagValue())
if err != nil {
exit.WithError("disable failed", err)
}
......
......@@ -18,9 +18,7 @@ package config
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/addons"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -34,7 +32,7 @@ var addonsEnableCmd = &cobra.Command{
exit.UsageT("usage: minikube addons enable ADDON_NAME")
}
addon := args[0]
err := addons.Set(addon, "true", viper.GetString(config.ProfileName))
err := addons.Set(addon, "true", ClusterFlagValue())
if err != nil {
exit.WithError("enable failed", err)
}
......
/*
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 config
import (
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
)
// ClusterFlagValue returns the current cluster name based on flags
func ClusterFlagValue() string {
return viper.GetString(config.ProfileName)
}
......@@ -21,7 +21,7 @@ import (
"fmt"
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -59,5 +59,5 @@ func init() {
// Get gets a property
func Get(name string) (string, error) {
return pkgConfig.Get(name)
return config.Get(name)
}
......@@ -18,18 +18,13 @@ package config
import (
"fmt"
"os"
"text/template"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/browser"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
)
......@@ -61,32 +56,17 @@ var addonsOpenCmd = &cobra.Command{
exit.UsageT("usage: minikube addons open ADDON_NAME")
}
addonName := args[0]
// TODO(r2d4): config should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
profileName := viper.GetString(pkg_config.ProfileName)
cc, err := config.Load(profileName)
if err != nil {
exit.WithError("Error getting cluster", err)
}
cp, err := config.PrimaryControlPlane(cc)
if err != nil {
exit.WithError("Error getting control plane", err)
}
if !machine.IsRunning(api, driver.MachineName(*cc, cp)) {
os.Exit(1)
}
cname := ClusterFlagValue()
co := mustload.Healthy(cname)
addon, ok := assets.Addons[addonName] // validate addon input
if !ok {
exit.WithCodeT(exit.Data, `addon '{{.name}}' is not a valid addon packaged with minikube.
To see the list of available addons run:
minikube addons list`, out.V{"name": addonName})
}
ok, err = addon.IsEnabled(profileName)
ok, err := addon.IsEnabled(cname)
if err != nil {
exit.WithError("IsEnabled failed", err)
}
......@@ -111,7 +91,7 @@ You can add one by annotating a service with the label {{.labelName}}:{{.addonNa
svc := serviceList.Items[i].ObjectMeta.Name
var urlString []string
if urlString, err = service.WaitForService(api, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
if urlString, err = service.WaitForService(co.API, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
exit.WithCodeT(exit.Unavailable, "Wait failed: {{.error}}", out.V{"error": err})
}
......
......@@ -20,9 +20,7 @@ import (
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/out"
......@@ -35,7 +33,7 @@ var ProfileCmd = &cobra.Command{
Long: "profile sets the current minikube profile, or gets the current profile if no arguments are provided. This is used to run and manage multiple minikube instance. You can return to the default minikube profile by running `minikube profile default`",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
profile := viper.GetString(pkgConfig.ProfileName)
profile := ClusterFlagValue()
out.T(out.Empty, profile)
os.Exit(0)
}
......@@ -49,7 +47,7 @@ var ProfileCmd = &cobra.Command{
we need to add code over here to check whether the profile
name is in the list of reserved keywords
*/
if pkgConfig.ProfileNameInReservedKeywords(profile) {
if config.ProfileNameInReservedKeywords(profile) {
out.ErrT(out.FailureType, `Profile name "{{.profilename}}" is minikube keyword. To delete profile use command minikube delete -p <profile name> `, out.V{"profilename": profile})
os.Exit(0)
}
......@@ -64,18 +62,18 @@ var ProfileCmd = &cobra.Command{
}
}
if !pkgConfig.ProfileExists(profile) {
if !config.ProfileExists(profile) {
out.ErrT(out.Tip, `if you want to create a profile you can by this command: minikube start -p {{.profile_name}}`, out.V{"profile_name": profile})
os.Exit(0)
}
err := Set(pkgConfig.ProfileName, profile)
err := Set(config.ProfileName, profile)
if err != nil {
exit.WithError("Setting profile failed", err)
}
cc, err := pkgConfig.Load(profile)
cc, err := config.Load(profile)
// might err when loading older version of cfg file that doesn't have KeepContext field
if err != nil && !pkg_config.IsNotExist(err) {
if err != nil && !config.IsNotExist(err) {
out.ErrT(out.Sad, `Error loading profile config: {{.error}}`, out.V{"error": err})
}
if err == nil {
......
......@@ -19,7 +19,7 @@ package config
import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/out"
......@@ -61,11 +61,11 @@ func Set(name string, value string) error {
}
// Set the value
config, err := pkgConfig.ReadConfig(localpath.ConfigFile())
cc, err := config.ReadConfig(localpath.ConfigFile())
if err != nil {
return errors.Wrapf(err, "read config file %q", localpath.ConfigFile())
}
err = s.set(config, name, value)
err = s.set(cc, name, value)
if err != nil {
return errors.Wrapf(err, "set")
}
......@@ -77,5 +77,5 @@ func Set(name string, value string) error {
}
// Write the value
return pkgConfig.WriteConfig(localpath.ConfigFile(), config)
return config.WriteConfig(localpath.ConfigFile(), cc)
}
......@@ -18,7 +18,7 @@ package config
import (
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
)
......@@ -44,10 +44,10 @@ func init() {
// Unset unsets a property
func Unset(name string) error {
m, err := pkgConfig.ReadConfig(localpath.ConfigFile())
m, err := config.ReadConfig(localpath.ConfigFile())
if err != nil {
return err
}
delete(m, name)
return pkgConfig.WriteConfig(localpath.ConfigFile(), m)
return config.WriteConfig(localpath.ConfigFile(), m)
}
......@@ -20,11 +20,11 @@ import (
"fmt"
"testing"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
)
var minikubeConfig = pkgConfig.MinikubeConfig{
var minikubeConfig = config.MinikubeConfig{
"driver": driver.KVM2,
"cpus": 12,
"show-libmachine-logs": true,
......@@ -83,21 +83,10 @@ func TestSetBool(t *testing.T) {
}
func TestValidateProfile(t *testing.T) {
testCases := []struct {
profileName string
}{
{
profileName: "82374328742_2974224498",
},
{
profileName: "validate_test",
},
}
for _, test := range testCases {
profileNam := test.profileName
expected := fmt.Sprintf("profile %q not found", test.profileName)
err, ok := ValidateProfile(profileNam)
testCases := []string{"82374328742_2974224498", "validate_test"}
for _, name := range testCases {
expected := fmt.Sprintf("profile %q not found", name)
err, ok := ValidateProfile(name)
if !ok && err.Error() != expected {
t.Errorf("got error %q, expected %q", err, expected)
}
......
......@@ -21,25 +21,20 @@ import (
"fmt"
"io"
"net/http"
"os"
"os/exec"
"os/user"
"regexp"
"time"
"github.com/docker/machine/libmachine/mcnerror"
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
pkgaddons "k8s.io/minikube/pkg/addons"
"k8s.io/minikube/pkg/addons"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/browser"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/proxy"
"k8s.io/minikube/pkg/minikube/service"
......@@ -59,47 +54,11 @@ 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) {
profileName := viper.GetString(pkg_config.ProfileName)
cc, err := pkg_config.Load(profileName)
if err != nil && !pkg_config.IsNotExist(err) {
exit.WithError("Error loading profile config", err)
}
if err != nil {
out.ErrT(out.Meh, `"{{.name}}" profile does not exist`, out.V{"name": profileName})
os.Exit(1)
}
api, err := machine.NewAPIClient()
defer func() {
err := api.Close()
if err != nil {
glog.Warningf("Failed to close API: %v", err)
}
}()
if err != nil {
exit.WithError("Error getting client", err)
}
cp, err := config.PrimaryControlPlane(cc)
if err != nil {
exit.WithError("Error getting primary control plane", err)
}
machineName := driver.MachineName(*cc, cp)
if _, err = api.Load(machineName); err != nil {
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
exit.WithCodeT(exit.Unavailable, "{{.name}} cluster does not exist", out.V{"name": cc.Name})
default:
exit.WithError("Error getting cluster", err)
}
}
cname := ClusterFlagValue()
co := mustload.Healthy(cname)
for _, n := range cc.Nodes {
err = proxy.ExcludeIP(n.IP) // to be used for http get calls
if err != nil {
for _, n := range co.Config.Nodes {
if err := proxy.ExcludeIP(n.IP); err != nil {
glog.Errorf("Error excluding IP from proxy: %s", err)
}
}
......@@ -109,18 +68,14 @@ 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.IsRunning(api, machineName) {
os.Exit(1)
}
// Check dashboard status before enabling it
dashboardAddon := assets.Addons["dashboard"]
dashboardStatus, _ := dashboardAddon.IsEnabled(profileName)
dashboardStatus, _ := dashboardAddon.IsEnabled(cname)
if !dashboardStatus {
// Send status messages to stderr for folks re-using this output.
out.ErrT(out.Enabling, "Enabling dashboard ...")
// Enable the dashboard add-on
err = pkgaddons.Set("dashboard", "true", profileName)
err = addons.Set("dashboard", "true", cname)
if err != nil {
exit.WithError("Unable to enable dashboard", err)
}
......@@ -135,7 +90,7 @@ var dashboardCmd = &cobra.Command{
}
out.ErrT(out.Launch, "Launching proxy ...")
p, hostPort, err := kubectlProxy(kubectl, machineName)
p, hostPort, err := kubectlProxy(kubectl, cname)
if err != nil {
exit.WithError("kubectl proxy", err)
}
......@@ -169,10 +124,10 @@ var dashboardCmd = &cobra.Command{
}
// kubectlProxy runs "kubectl proxy", returning host:port
func kubectlProxy(path string, machineName string) (*exec.Cmd, string, error) {
func kubectlProxy(path string, contextName string) (*exec.Cmd, string, error) {
// port=0 picks a random system port
cmd := exec.Command(path, "--context", machineName, "proxy", "--port=0")
cmd := exec.Command(path, "--context", contextName, "proxy", "--port=0")
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
......
......@@ -141,10 +141,10 @@ func runDelete(cmd *cobra.Command, args []string) {
exit.UsageT("usage: minikube delete")
}
profileName := viper.GetString(config.ProfileName)
profile, err := config.LoadProfile(profileName)
cname := ClusterFlagValue()
profile, err := config.LoadProfile(cname)
if err != nil {
out.ErrT(out.Meh, `"{{.name}}" profile does not exist, trying anyways.`, out.V{"name": profileName})
out.ErrT(out.Meh, `"{{.name}}" profile does not exist, trying anyways.`, out.V{"name": cname})
}
errs := DeleteProfiles([]*config.Profile{profile})
......@@ -272,13 +272,13 @@ func deleteHosts(api libmachine.API, cc *config.ClusterConfig) {
}
}
func deleteConfig(profileName string) error {
if err := config.DeleteProfile(profileName); err != nil {
func deleteConfig(cname string) error {
if err := config.DeleteProfile(cname); err != nil {
if config.IsNotExist(err) {
delErr := profileDeletionErr(profileName, fmt.Sprintf("\"%s\" profile does not exist", profileName))
delErr := profileDeletionErr(cname, fmt.Sprintf("\"%s\" profile does not exist", cname))
return DeletionError{Err: delErr, Errtype: MissingProfile}
}
delErr := profileDeletionErr(profileName, fmt.Sprintf("failed to remove profile %v", err))
delErr := profileDeletionErr(cname, fmt.Sprintf("failed to remove profile %v", err))
return DeletionError{Err: delErr, Errtype: Fatal}
}
return nil
......@@ -317,8 +317,8 @@ func deleteInvalidProfile(profile *config.Profile) []error {
return errs
}
func profileDeletionErr(profileName string, additionalInfo string) error {
return fmt.Errorf("error deleting profile \"%s\": %s", profileName, additionalInfo)
func profileDeletionErr(cname string, additionalInfo string) error {
return fmt.Errorf("error deleting profile \"%s\": %s", cname, additionalInfo)
}
func uninstallKubernetes(api libmachine.API, cc config.ClusterConfig, n config.Node, bsName string) error {
......
......@@ -24,20 +24,18 @@ import (
"io"
"net"
"os"
"os/exec"
"strconv"
"strings"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/state"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/shell"
)
......@@ -117,23 +115,10 @@ func (EnvNoProxyGetter) GetNoProxyVar() (string, string) {
}
// isDockerActive checks if Docker is active
func isDockerActive(d drivers.Driver) (bool, error) {
client, err := drivers.GetSSHClientFromDriver(d)
if err != nil {
return false, err
}
cmd := "sudo systemctl is-active docker"
output, err := client.Output(cmd)
s := strings.TrimSpace(output)
if err != nil {
return false, fmt.Errorf("%s failed: %v\noutput: %q", cmd, err, s)
}
if s != "active" {
return false, fmt.Errorf("%s returned %q", cmd, s)
}
return true, nil
func isDockerActive(r command.Runner) bool {
c := exec.Command("sudo", "systemctl", "is-active", "--quiet", "service", "docker")
_, err := r.RunCmd(c)
return err == nil
}
// dockerEnvCmd represents the docker-env command
......@@ -142,94 +127,62 @@ var dockerEnvCmd = &cobra.Command{
Short: "Sets up docker env variables; similar to '$(docker-machine env)'",
Long: `Sets up docker env variables; similar to '$(docker-machine env)'.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
cname := ClusterFlagValue()
co := mustload.Running(cname)
driverName := co.CPHost.DriverName
if driverName == driver.None {
exit.UsageT(`'none' driver does not support 'minikube docker-env' command`)
}
defer api.Close()
profile := viper.GetString(config.ProfileName)
cc, err := config.Load(profile)
if err != nil {
exit.WithError("Error getting config", err)
if co.Config.KubernetesConfig.ContainerRuntime != "docker" {
exit.WithCodeT(exit.BadUsage, `The docker-env command is only compatible with the "docker" runtime, but this cluster was configured to use the "{{.runtime}}" runtime.`,
out.V{"runtime": co.Config.KubernetesConfig.ContainerRuntime})
}
for _, n := range cc.Nodes {
machineName := driver.MachineName(*cc, n)
host, err := machine.LoadHost(api, machineName)
if err != nil {
exit.WithError("Error getting host", err)
}
if host.Driver.DriverName() == driver.None {
exit.UsageT(`'none' driver does not support 'minikube docker-env' command`)
}
hostSt, err := machine.Status(api, machineName)
if err != nil {
exit.WithError("Error getting host status", err)
}
if hostSt != state.Running.String() {
exit.WithCodeT(exit.Unavailable, `'{{.profile}}' is not running`, out.V{"profile": profile})
}
if ok := isDockerActive(co.CPRunner); !ok {
exit.WithCodeT(exit.Unavailable, `The docker service within '{{.name}}' is not active`, out.V{"name": cname})
}
if cc.KubernetesConfig.ContainerRuntime != "docker" {
exit.WithCodeT(exit.BadUsage, `The docker-env command is only compatible with the "docker" runtime, but this cluster was configured to use the "{{.runtime}}" runtime.`,
out.V{"runtime": cc.KubernetesConfig.ContainerRuntime})
}
sh := shell.EnvConfig{
Shell: shell.ForceShell,
}
ok, err := isDockerActive(host.Driver)
var err error
port := constants.DockerDaemonPort
if driver.IsKIC(driverName) {
port, err = oci.ForwardedPort(driverName, cname, port)
if err != nil {
exit.WithError("Docker runtime check failed", err)
exit.WithCodeT(exit.Failure, "Error getting port binding for '{{.driver_name}} driver: {{.error}}", out.V{"driver_name": driverName, "error": err})
}
}
if !ok {
exit.WithCodeT(exit.Unavailable, `The docker service within '{{.profile}}' is not active`, out.V{"profile": profile})
}
ec := DockerEnvConfig{
EnvConfig: sh,
profile: cname,
driver: driverName,
hostIP: co.DriverIP.String(),
port: port,
certsDir: localpath.MakeMiniPath("certs"),
noProxy: noProxy,
}
hostIP, err := host.Driver.GetIP()
if ec.Shell == "" {
ec.Shell, err = shell.Detect()
if err != nil {
exit.WithError("Error getting host IP", err)
}
sh := shell.EnvConfig{
Shell: shell.ForceShell,
}
port := constants.DockerDaemonPort
if driver.IsKIC(host.DriverName) { // for kic we need to find what port docker/podman chose for us
hostIP = oci.DefaultBindIPV4
port, err = oci.ForwardedPort(host.DriverName, profile, port)
if err != nil {
exit.WithCodeT(exit.Failure, "Error getting port binding for '{{.driver_name}} driver: {{.error}}", out.V{"driver_name": host.DriverName, "error": err})
}
}
ec := DockerEnvConfig{
EnvConfig: sh,
profile: profile,
driver: host.DriverName,
hostIP: hostIP,
port: port,
certsDir: localpath.MakeMiniPath("certs"),
noProxy: noProxy,
}
if ec.Shell == "" {
ec.Shell, err = shell.Detect()
if err != nil {
exit.WithError("Error detecting shell", err)
}
exit.WithError("Error detecting shell", err)
}
}
if dockerUnset {
if err := dockerUnsetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating unset output", err)
}
return
if dockerUnset {
if err := dockerUnsetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating unset output", err)
}
return
}
if err := dockerSetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating set output", err)
}
if err := dockerSetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating set output", err)
}
},
}
......
/*
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 cmd
import (
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
)
// ClusterFlagValue returns the current cluster name based on flags
func ClusterFlagValue() string {
return viper.GetString(config.ProfileName)
}
......@@ -17,14 +17,8 @@ limitations under the License.
package cmd
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/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -34,32 +28,7 @@ var ipCmd = &cobra.Command{
Short: "Retrieves the IP address of the running cluster",
Long: `Retrieves the IP address of the running cluster, and writes it to STDOUT.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Error getting config", err)
}
for _, n := range cc.Nodes {
machineName := driver.MachineName(*cc, n)
host, err := api.Load(machineName)
if err != nil {
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
exit.WithCodeT(exit.NoInput, `"{{.profile_name}}" host does not exist, unable to show an IP`, out.V{"profile_name": cc.Name})
default:
exit.WithError("Error getting host", err)
}
}
ip, err := host.Driver.GetIP()
if err != nil {
exit.WithError("Error getting IP", err)
}
out.Ln(ip)
}
co := mustload.Running(ClusterFlagValue())
out.Ln(co.DriverIP.String())
},
}
......@@ -24,10 +24,8 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -42,21 +40,11 @@ Examples:
minikube kubectl -- --help
minikube kubectl -- get pods --namespace kube-system`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil && !config.IsNotExist(err) {
out.ErrLn("Error loading profile config: %v", err)
}
co := mustload.Healthy(ClusterFlagValue())
version := constants.DefaultKubernetesVersion
if cc != nil {
version = cc.KubernetesConfig.KubernetesVersion
version := co.Config.KubernetesConfig.KubernetesVersion
if version == "" {
version = constants.DefaultKubernetesVersion
}
path, err := node.CacheKubectlBinary(version)
......
......@@ -17,17 +17,17 @@ limitations under the License.
package cmd
import (
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/logs"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
const (
......@@ -51,64 +51,35 @@ 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(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Error getting config", err)
}
if nodeName == "" {
cp, err := config.PrimaryControlPlane(cfg)
if err != nil {
exit.WithError("Error getting primary control plane", err)
}
nodeName = cp.Name
}
n, _, err := node.Retrieve(cfg, nodeName)
if err != nil {
exit.WithError("Error retrieving node", err)
}
machineName := driver.MachineName(*cfg, *n)
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
co := mustload.Running(ClusterFlagValue())
h, err := api.Load(machineName)
if err != nil {
exit.WithError("api load", err)
}
runner, err := machine.CommandRunner(h)
if err != nil {
exit.WithError("command runner", err)
}
bs, err := cluster.Bootstrapper(api, viper.GetString(cmdcfg.Bootstrapper), *cfg, *n)
bs, err := cluster.Bootstrapper(co.API, viper.GetString(cmdcfg.Bootstrapper), *co.Config, *co.CPNode)
if err != nil {
exit.WithError("Error getting cluster bootstrapper", err)
}
cr, err := cruntime.New(cruntime.Config{Type: cfg.KubernetesConfig.ContainerRuntime, Runner: runner})
cr, err := cruntime.New(cruntime.Config{Type: co.Config.KubernetesConfig.ContainerRuntime, Runner: co.CPRunner})
if err != nil {
exit.WithError("Unable to get runtime", err)
}
if followLogs {
err := logs.Follow(cr, bs, *cfg, runner)
err := logs.Follow(cr, bs, *co.Config, co.CPRunner)
if err != nil {
exit.WithError("Follow", err)
}
return
}
if showProblems {
problems := logs.FindProblems(cr, bs, *cfg, runner)
problems := logs.FindProblems(cr, bs, *co.Config, co.CPRunner)
logs.OutputProblems(problems, numberOfProblems)
return
}
err = logs.Output(cr, bs, *cfg, runner, numberOfLines)
err = logs.Output(cr, bs, *co.Config, co.CPRunner, numberOfLines)
if err != nil {
exit.WithError("Error getting machine logs", err)
out.Ln("")
// Avoid exit.WithError, since it outputs the issue URL
out.T(out.Warning, "{{.error}}", out.V{"error": err})
os.Exit(exit.Unavailable)
}
},
}
......
......@@ -30,12 +30,10 @@ 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"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/third_party/go9p/ufs"
)
......@@ -99,30 +97,16 @@ var mountCmd = &cobra.Command{
if glog.V(1) {
debugVal = 1 // ufs.StartServer takes int debug param
}
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Error getting config", err)
}
cp, err := config.PrimaryControlPlane(cc)
if err != nil {
exit.WithError("Error getting primary cp", err)
}
host, err := api.Load(driver.MachineName(*cc, cp))
if err != nil {
exit.WithError("Error loading api", err)
}
if host.Driver.DriverName() == driver.None {
co := mustload.Running(ClusterFlagValue())
if co.CPHost.Driver.DriverName() == driver.None {
exit.UsageT(`'none' driver does not support 'minikube mount' command`)
}
var ip net.IP
var err error
if mountIP == "" {
ip, err = cluster.GetVMHostIP(host)
ip, err = cluster.GetVMHostIP(co.CPHost)
if err != nil {
exit.WithError("Error getting the host IP address to use from within the VM", err)
}
......@@ -163,7 +147,7 @@ var mountCmd = &cobra.Command{
}
bindIP := ip.String() // the ip to listen on the user's host machine
if driver.IsKIC(host.Driver.DriverName()) && runtime.GOOS != "linux" {
if driver.IsKIC(co.CPHost.Driver.DriverName()) && runtime.GOOS != "linux" {
bindIP = "127.0.0.1"
}
out.T(out.Mounting, "Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...", out.V{"sourcePath": hostPath, "destinationPath": vmPath})
......@@ -187,19 +171,13 @@ var mountCmd = &cobra.Command{
}()
}
// Use CommandRunner, as the native docker ssh service dies when Ctrl-C is received.
runner, err := machine.CommandRunner(host)
if err != nil {
exit.WithError("Failed to get command runner", err)
}
// Unmount if Ctrl-C or kill request is received.
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
for sig := range c {
out.T(out.Unmount, "Unmounting {{.path}} ...", out.V{"path": vmPath})
err := cluster.Unmount(runner, vmPath)
err := cluster.Unmount(co.CPRunner, vmPath)
if err != nil {
out.ErrT(out.FailureType, "Failed unmount: {{.error}}", out.V{"error": err})
}
......@@ -207,7 +185,7 @@ var mountCmd = &cobra.Command{
}
}()
err = cluster.Mount(runner, ip.String(), vmPath, cfg)
err = cluster.Mount(co.CPRunner, ip.String(), vmPath, cfg)
if err != nil {
exit.WithError("mount failed", err)
}
......
......@@ -19,10 +19,10 @@ package cmd
import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -36,11 +36,8 @@ var nodeAddCmd = &cobra.Command{
Short: "Adds a node to the given cluster.",
Long: "Adds a node to the given cluster config, and starts it.",
Run: func(cmd *cobra.Command, args []string) {
profile := viper.GetString(config.ProfileName)
cc, err := config.Load(profile)
if err != nil {
exit.WithError("Error getting config", err)
}
co := mustload.Healthy(ClusterFlagValue())
cc := co.Config
if driver.BareMetal(cc.Driver) {
out.ErrT(out.FailureType, "none driver does not support multi-node clusters")
......@@ -48,7 +45,7 @@ var nodeAddCmd = &cobra.Command{
name := node.Name(len(cc.Nodes) + 1)
out.T(out.Happy, "Adding node {{.name}} to cluster {{.cluster}}", out.V{"name": name, "cluster": profile})
out.T(out.Happy, "Adding node {{.name}} to cluster {{.cluster}}", out.V{"name": name, "cluster": cc.Name})
// TODO: Deal with parameters better. Ideally we should be able to acceot any node-specific minikube start params here.
n := config.Node{
......@@ -58,12 +55,11 @@ var nodeAddCmd = &cobra.Command{
KubernetesVersion: cc.KubernetesConfig.KubernetesVersion,
}
err = node.Add(cc, n)
if err != nil {
if err := node.Add(cc, n); err != nil {
exit.WithError("Error adding node to cluster", err)
}
out.T(out.Ready, "Successfully added {{.name}} to {{.cluster}}!", out.V{"name": name, "cluster": profile})
out.T(out.Ready, "Successfully added {{.name}} to {{.cluster}}!", out.V{"name": name, "cluster": cc.Name})
},
}
......
......@@ -18,9 +18,8 @@ package cmd
import (
"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/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -36,16 +35,10 @@ var nodeDeleteCmd = &cobra.Command{
}
name := args[0]
profile := viper.GetString(config.ProfileName)
out.T(out.DeletingHost, "Deleting node {{.name}} from cluster {{.cluster}}", out.V{"name": name, "cluster": profile})
co := mustload.Healthy(ClusterFlagValue())
out.T(out.DeletingHost, "Deleting node {{.name}} from cluster {{.cluster}}", out.V{"name": name, "cluster": co.Config.Name})
cc, err := config.Load(profile)
if err != nil {
exit.WithError("loading config", err)
}
err = node.Delete(*cc, name)
if err != nil {
if err := node.Delete(*co.Config, name); err != nil {
exit.WithError("deleting node", err)
}
......
......@@ -20,10 +20,9 @@ import (
"os"
"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"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -37,24 +36,14 @@ var nodeStartCmd = &cobra.Command{
exit.UsageT("Usage: minikube node start [name]")
}
api, cc := mustload.Partial(ClusterFlagValue())
name := args[0]
// Make sure it's not running
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("creating api client", err)
}
if machine.IsRunning(api, name) {
out.T(out.Check, "{{.name}} is already running", out.V{"name": name})
os.Exit(0)
}
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("loading config", err)
}
n, _, err := node.Retrieve(cc, name)
if err != nil {
exit.WithError("retrieving node", err)
......
......@@ -18,11 +18,10 @@ package cmd
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -37,16 +36,7 @@ var nodeStopCmd = &cobra.Command{
}
name := args[0]
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("creating api client", err)
}
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("getting config", err)
}
api, cc := mustload.Partial(ClusterFlagValue())
n, _, err := node.Retrieve(cc, name)
if err != nil {
......
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"os"
"strings"
"github.com/golang/glog"
......@@ -25,11 +24,11 @@ import (
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -46,27 +45,10 @@ var pauseCmd = &cobra.Command{
}
func runPause(cmd *cobra.Command, args []string) {
cname := viper.GetString(config.ProfileName)
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load(cname)
if err != nil && !config.IsNotExist(err) {
exit.WithError("Error loading profile config", err)
}
if err != nil {
out.ErrT(out.Meh, `"{{.name}}" profile does not exist`, out.V{"name": cname})
os.Exit(1)
}
glog.Infof("config: %+v", cc)
co := mustload.Running(ClusterFlagValue())
for _, n := range cc.Nodes {
host, err := machine.LoadHost(api, driver.MachineName(*cc, n))
for _, n := range co.Config.Nodes {
host, err := machine.LoadHost(co.API, driver.MachineName(*co.Config, n))
if err != nil {
exit.WithError("Error getting host", err)
}
......@@ -76,7 +58,7 @@ func runPause(cmd *cobra.Command, args []string) {
exit.WithError("Failed to get command runner", err)
}
cr, err := cruntime.New(cruntime.Config{Type: cc.KubernetesConfig.ContainerRuntime, Runner: r})
cr, err := cruntime.New(cruntime.Config{Type: co.Config.KubernetesConfig.ContainerRuntime, Runner: r})
if err != nil {
exit.WithError("Failed runtime", err)
}
......
......@@ -27,16 +27,13 @@ import (
"strings"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/ssh"
"github.com/docker/machine/libmachine/state"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/shell"
)
......@@ -67,15 +64,16 @@ func podmanShellCfgSet(ec PodmanEnvConfig, envMap map[string]string) *PodmanShel
}
// isPodmanAvailable checks if Podman is available
func isPodmanAvailable(host *host.Host) (bool, error) {
// we need both "varlink bridge" and "podman varlink"
if _, err := host.RunSSHCommand("which varlink"); err != nil {
return false, err
func isPodmanAvailable(r command.Runner) bool {
if _, err := r.RunCmd(exec.Command("which", "varlink")); err != nil {
return false
}
if _, err := host.RunSSHCommand("which podman"); err != nil {
return false, err
if _, err := r.RunCmd(exec.Command("which", "podman")); err != nil {
return false
}
return true, nil
return true
}
func createExternalSSHClient(d drivers.Driver) (*ssh.ExternalClient, error) {
......@@ -108,75 +106,49 @@ var podmanEnvCmd = &cobra.Command{
Short: "Sets up podman env variables; similar to '$(podman-machine env)'",
Long: `Sets up podman env variables; similar to '$(podman-machine env)'.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
cname := ClusterFlagValue()
co := mustload.Running(cname)
driverName := co.CPHost.DriverName
if driverName == driver.None {
exit.UsageT(`'none' driver does not support 'minikube podman-env' command`)
}
defer api.Close()
profile := viper.GetString(config.ProfileName)
cc, err := config.Load(profile)
if err != nil {
exit.WithError("Error getting config", err)
if ok := isPodmanAvailable(co.CPRunner); !ok {
exit.WithCodeT(exit.Unavailable, `The podman service within '{{.cluster}}' is not active`, out.V{"cluster": cname})
}
for _, n := range cc.Nodes {
machineName := driver.MachineName(*cc, n)
host, err := machine.LoadHost(api, machineName)
if err != nil {
exit.WithError("Error getting host", err)
}
if host.Driver.DriverName() == driver.None {
exit.UsageT(`'none' driver does not support 'minikube podman-env' command`)
}
hostSt, err := machine.Status(api, machineName)
if err != nil {
exit.WithError("Error getting host status", err)
}
if hostSt != state.Running.String() {
exit.WithCodeT(exit.Unavailable, `'{{.profile}}' is not running`, out.V{"profile": profile})
}
ok, err := isPodmanAvailable(host)
if err != nil {
exit.WithError("Error getting service status", err)
}
client, err := createExternalSSHClient(co.CPHost.Driver)
if err != nil {
exit.WithError("Error getting ssh client", err)
}
if !ok {
exit.WithCodeT(exit.Unavailable, `The podman service within '{{.profile}}' is not active`, out.V{"profile": profile})
}
sh := shell.EnvConfig{
Shell: shell.ForceShell,
}
ec := PodmanEnvConfig{
EnvConfig: sh,
profile: cname,
driver: driverName,
client: client,
}
client, err := createExternalSSHClient(host.Driver)
if ec.Shell == "" {
ec.Shell, err = shell.Detect()
if err != nil {
exit.WithError("Error getting ssh client", err)
}
sh := shell.EnvConfig{
Shell: shell.ForceShell,
}
ec := PodmanEnvConfig{
EnvConfig: sh,
profile: profile,
driver: host.DriverName,
client: client,
}
if ec.Shell == "" {
ec.Shell, err = shell.Detect()
if err != nil {
exit.WithError("Error detecting shell", err)
}
exit.WithError("Error detecting shell", err)
}
}
if podmanUnset {
if err := podmanUnsetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating unset output", err)
}
return
if podmanUnset {
if err := podmanUnsetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating unset output", err)
}
return
}
if err := podmanSetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating set output", err)
}
if err := podmanSetScript(ec, os.Stdout); err != nil {
exit.WithError("Error generating set output", err)
}
},
}
......
......@@ -31,16 +31,12 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/browser"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/minikube/tunnel/kic"
......@@ -78,32 +74,16 @@ var serviceCmd = &cobra.Command{
}
svc := args[0]
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
profileName := viper.GetString(pkg_config.ProfileName)
cfg, err := config.Load(profileName)
if err != nil {
exit.WithError("Error getting config", err)
}
cp, err := config.PrimaryControlPlane(cfg)
if err != nil {
exit.WithError("Error getting control plane", err)
}
machineName := driver.MachineName(*cfg, cp)
if !machine.IsRunning(api, machineName) {
os.Exit(1)
}
cname := ClusterFlagValue()
co := mustload.Healthy(cname)
if runtime.GOOS == "darwin" && cfg.Driver == oci.Docker {
startKicServiceTunnel(svc, cfg.Name)
if runtime.GOOS == "darwin" && co.Config.Driver == oci.Docker {
startKicServiceTunnel(svc, cname)
return
}
urls, err := service.WaitForService(api, namespace, svc, serviceURLTemplate, serviceURLMode, https, wait, interval)
urls, err := service.WaitForService(co.API, namespace, svc, serviceURLTemplate, serviceURLMode, https, wait, interval)
if err != nil {
var s *service.SVCNotFoundError
if errors.As(err, &s) {
......
......@@ -22,14 +22,10 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
core "k8s.io/api/core/v1"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/config"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
)
......@@ -42,24 +38,9 @@ var serviceListCmd = &cobra.Command{
Short: "Lists the URLs for the services in your local cluster",
Long: `Lists the URLs for the services in your local cluster`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
profileName := viper.GetString(pkg_config.ProfileName)
cfg, err := config.Load(profileName)
if err != nil {
exit.WithError("Error getting config", err)
}
cp, err := config.PrimaryControlPlane(cfg)
if err != nil {
exit.WithError("Error getting primary control plane", err)
}
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)
co := mustload.Healthy(ClusterFlagValue())
serviceURLs, err := service.GetServiceURLs(co.API, serviceListNamespace, serviceURLTemplate)
if err != nil {
out.FatalT("Failed to get service URL: {{.error}}", out.V{"error": err})
out.ErrT(out.Notice, "Check that minikube is running and that you have specified the correct namespace (-n flag) if required.")
......@@ -74,7 +55,7 @@ var serviceListCmd = &cobra.Command{
serviceURLs := strings.Join(serviceURL.URLs, "\n")
// if we are running Docker on OSX we empty the internal service URLs
if runtime.GOOS == "darwin" && cfg.Driver == oci.Docker {
if runtime.GOOS == "darwin" && co.Config.Driver == oci.Docker {
serviceURLs = ""
}
......
......@@ -20,10 +20,8 @@ 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"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -33,10 +31,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(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Getting machine config failed", err)
}
_, cc := mustload.Partial(ClusterFlagValue())
out.Ln(filepath.Join(localpath.MiniPath(), "machines", cc.Name, "id_rsa"))
},
}
......@@ -21,12 +21,12 @@ import (
"github.com/docker/machine/libmachine/ssh"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -41,42 +41,30 @@ var sshCmd = &cobra.Command{
Short: "Log into or run a command on a machine with SSH; similar to 'docker-machine ssh'",
Long: "Log into or run a command on a machine with SSH; similar to 'docker-machine ssh'.",
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Error getting config", err)
cname := ClusterFlagValue()
co := mustload.Running(cname)
if co.CPHost.DriverName == driver.None {
exit.UsageT("'none' driver does not support 'minikube ssh' command")
}
var err error
var n *config.Node
if nodeName == "" {
cp, err := config.PrimaryControlPlane(cc)
if err != nil {
exit.WithError("Getting primary control plane", err)
}
n = &cp
n = co.CPNode
} else {
n, _, err = node.Retrieve(cc, nodeName)
n, _, err = node.Retrieve(co.Config, nodeName)
if err != nil {
exit.WithCodeT(exit.Unavailable, "Node {{.nodeName}} does not exist.", out.V{"nodeName": nodeName})
}
}
host, err := machine.LoadHost(api, driver.MachineName(*cc, *n))
if err != nil {
exit.WithError("Error getting host", err)
}
if host.Driver.DriverName() == driver.None {
exit.UsageT("'none' driver does not support 'minikube ssh' command")
}
if nativeSSHClient {
ssh.SetDefaultClient(ssh.Native)
} else {
ssh.SetDefaultClient(ssh.External)
}
err = machine.CreateSSHShell(api, *cc, *n, args)
err = machine.CreateSSHShell(co.API, *co.Config, *n, args)
if err != nil {
// This is typically due to a non-zero exit code, so no need for flourish.
out.ErrLn("ssh: %v", err)
......
......@@ -54,6 +54,7 @@ import (
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/node"
"k8s.io/minikube/pkg/minikube/notify"
"k8s.io/minikube/pkg/minikube/out"
......@@ -291,7 +292,7 @@ func runStart(cmd *cobra.Command, args []string) {
registryMirror = viper.GetStringSlice("registry_mirror")
}
existing, err := config.Load(viper.GetString(config.ProfileName))
existing, err := config.Load(ClusterFlagValue())
if err != nil && !config.IsNotExist(err) {
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err})
}
......@@ -390,8 +391,8 @@ func updateDriver(driverName string) {
func displayVersion(version string) {
prefix := ""
if viper.GetString(config.ProfileName) != constants.DefaultClusterName {
prefix = fmt.Sprintf("[%s] ", viper.GetString(config.ProfileName))
if ClusterFlagValue() != constants.DefaultClusterName {
prefix = fmt.Sprintf("[%s] ", ClusterFlagValue())
}
versionState := out.Happy
......@@ -570,17 +571,17 @@ func validateSpecifiedDriver(existing *config.ClusterConfig) {
return
}
out.ErrT(out.Conflict, `The existing "{{.profile_name}}" VM was created using the "{{.old_driver}}" driver, and is incompatible with the "{{.driver}}" driver.`,
out.V{"profile_name": existing.Name, "driver": requested, "old_driver": old})
out.ErrT(out.Conflict, `The existing "{{.name}}" VM was created using the "{{.old}}" driver, and is incompatible with the "{{.new}}" driver.`,
out.V{"name": existing.Name, "new": requested, "old": old})
out.ErrT(out.Workaround, `To proceed, either:
1) Delete the existing "{{.profile_name}}" cluster using: '{{.command}} delete'
1) Delete the existing "{{.name}}" cluster using: '{{.command}} delete'
* or *
2) Start the existing "{{.profile_name}}" cluster using: '{{.command}} start --driver={{.old_driver}}'
`, out.V{"command": minikubeCmd(), "old_driver": old, "profile_name": existing.Name})
2) Start the existing "{{.name}}" cluster using: '{{.command}} --driver={{.old}}'
`, out.V{"command": mustload.ExampleCmd(existing.Name, "start"), "old": old, "name": existing.Name})
exit.WithCodeT(exit.Config, "Exiting.")
}
......@@ -668,14 +669,6 @@ func selectImageRepository(mirrorCountry string, v semver.Version) (bool, string
return false, fallback, nil
}
// Return a minikube command containing the current profile name
func minikubeCmd() string {
if viper.GetString(config.ProfileName) != constants.DefaultClusterName {
return fmt.Sprintf("minikube -p %s", config.ProfileName)
}
return "minikube"
}
// validateUser validates minikube is run by the recommended user (privileged or regular)
func validateUser(drvName string) {
u, err := user.Current()
......@@ -701,9 +694,10 @@ func validateUser(drvName string) {
if !useForce {
os.Exit(exit.Permissions)
}
_, err = config.Load(viper.GetString(config.ProfileName))
cname := ClusterFlagValue()
_, err = config.Load(cname)
if err == nil || !config.IsNotExist(err) {
out.T(out.Tip, "Tip: To remove this root owned cluster, run: sudo {{.cmd}} delete", out.V{"cmd": minikubeCmd()})
out.T(out.Tip, "Tip: To remove this root owned cluster, run: sudo {{.cmd}}", out.V{"cmd": mustload.ExampleCmd(cname, "delete")})
}
if !useForce {
exit.WithCodeT(exit.Permissions, "Exiting")
......@@ -826,7 +820,7 @@ func validateFlags(cmd *cobra.Command, drvName string) {
}
if driver.BareMetal(drvName) {
if viper.GetString(config.ProfileName) != constants.DefaultClusterName {
if ClusterFlagValue() != constants.DefaultClusterName {
exit.WithCodeT(exit.Config, "The '{{.name}} driver does not support multiple profiles: https://minikube.sigs.k8s.io/docs/reference/drivers/none/", out.V{"name": drvName})
}
......@@ -953,7 +947,7 @@ func createNode(cmd *cobra.Command, k8sVersion, kubeNodeName, drvName, repositor
}
cfg := config.ClusterConfig{
Name: viper.GetString(config.ProfileName),
Name: ClusterFlagValue(),
KeepContext: viper.GetBool(keepContext),
EmbedCerts: viper.GetBool(embedCerts),
MinikubeISO: viper.GetString(isoURL),
......@@ -986,7 +980,7 @@ func createNode(cmd *cobra.Command, k8sVersion, kubeNodeName, drvName, repositor
NatNicType: viper.GetString(natNicType),
KubernetesConfig: config.KubernetesConfig{
KubernetesVersion: k8sVersion,
ClusterName: viper.GetString(config.ProfileName),
ClusterName: ClusterFlagValue(),
APIServerName: viper.GetString(apiServerName),
APIServerNames: apiServerNames,
APIServerIPs: apiServerIPs,
......
......@@ -29,16 +29,14 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil/kverify"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/mustload"
)
var statusFormat string
......@@ -101,24 +99,17 @@ var statusCmd = &cobra.Command{
exit.UsageT("Cannot use both --output and --format options")
}
api, err := machine.NewAPIClient()
if err != nil {
exit.WithCodeT(exit.Unavailable, "Error getting client: {{.error}}", out.V{"error": err})
}
defer api.Close()
cc, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
if config.IsNotExist(err) {
exit.WithCodeT(exitCode(&Status{}), `The "{{.name}}" cluster does not exist!`, out.V{"name": viper.GetString(config.ProfileName)})
}
exit.WithError("getting config", err)
}
cname := ClusterFlagValue()
api, cc := mustload.Partial(cname)
var st *Status
var err error
for _, n := range cc.Nodes {
glog.Infof("checking status of %s ...", n.Name)
machineName := driver.MachineName(*cc, n)
st, err = status(api, machineName, n.ControlPlane)
glog.Infof("%s status: %+v", machineName, st)
if err != nil {
glog.Errorf("status error: %v", err)
}
......@@ -140,6 +131,7 @@ var statusCmd = &cobra.Command{
}
}
// TODO: Update for multi-node
os.Exit(exitCode(st))
},
}
......
......@@ -24,13 +24,12 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"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/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/util/retry"
)
......@@ -46,17 +45,10 @@ itself, leaving all files intact. The cluster can be started again with the "sta
// runStop handles the executes the flow of "minikube stop"
func runStop(cmd *cobra.Command, args []string) {
profile := viper.GetString(pkg_config.ProfileName)
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cname := ClusterFlagValue()
cc, err := config.Load(profile)
if err != nil {
exit.WithError("Error getting cluster config", err)
}
api, cc := mustload.Partial(cname)
defer api.Close()
for _, n := range cc.Nodes {
nonexistent := stop(api, *cc, n)
......@@ -70,8 +62,7 @@ func runStop(cmd *cobra.Command, args []string) {
out.T(out.Warning, "Unable to kill mount process: {{.error}}", out.V{"error": err})
}
err = kubeconfig.UnsetCurrentContext(profile, kubeconfig.PathFromEnv())
if err != nil {
if err := kubeconfig.UnsetCurrentContext(cname, kubeconfig.PathFromEnv()); err != nil {
exit.WithError("update config", err)
}
}
......
......@@ -27,13 +27,12 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/minikube/tunnel"
"k8s.io/minikube/pkg/minikube/tunnel/kic"
......@@ -51,6 +50,8 @@ var tunnelCmd = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
manager := tunnel.NewManager()
cname := ClusterFlagValue()
co := mustload.Healthy(cname)
if cleanup {
glog.Info("Checking for tunnels to cleanup...")
......@@ -60,13 +61,6 @@ var tunnelCmd = &cobra.Command{
return
}
glog.Infof("Creating docker machine client...")
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("error creating machine client", err)
}
glog.Infof("Creating k8s client...")
// Tunnel uses the k8s clientset to query the API server for services in the LoadBalancerEmulator.
// We define the tunnel and minikube error free if the API server responds within a second.
// This also contributes to better UX, the tunnel status check can happen every second and
......@@ -76,11 +70,6 @@ var tunnelCmd = &cobra.Command{
exit.WithError("error creating clientset", err)
}
cfg, err := config.Load(viper.GetString(config.ProfileName))
if err != nil {
exit.WithError("Error getting config", err)
}
ctrlC := make(chan os.Signal, 1)
signal.Notify(ctrlC, os.Interrupt)
ctx, cancel := context.WithCancel(context.Background())
......@@ -89,13 +78,13 @@ var tunnelCmd = &cobra.Command{
cancel()
}()
if runtime.GOOS == "darwin" && cfg.Driver == oci.Docker {
port, err := oci.ForwardedPort(oci.Docker, cfg.Name, 22)
if runtime.GOOS == "darwin" && co.Config.Driver == oci.Docker {
port, err := oci.ForwardedPort(oci.Docker, cname, 22)
if err != nil {
exit.WithError("error getting ssh port", err)
}
sshPort := strconv.Itoa(port)
sshKey := filepath.Join(localpath.MiniPath(), "machines", cfg.Name, "id_rsa")
sshKey := filepath.Join(localpath.MiniPath(), "machines", cname, "id_rsa")
kicSSHTunnel := kic.NewSSHTunnel(ctx, sshPort, sshKey, clientset.CoreV1())
err = kicSSHTunnel.Start()
......@@ -106,7 +95,7 @@ var tunnelCmd = &cobra.Command{
return
}
done, err := manager.StartTunnel(ctx, cfg.Name, api, config.DefaultLoader, clientset.CoreV1())
done, err := manager.StartTunnel(ctx, cname, co.API, config.DefaultLoader, clientset.CoreV1())
if err != nil {
exit.WithError("error starting tunnel", err)
}
......
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"os"
"strings"
"github.com/golang/glog"
......@@ -25,11 +24,11 @@ import (
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -38,27 +37,12 @@ var unpauseCmd = &cobra.Command{
Use: "unpause",
Short: "unpause Kubernetes",
Run: func(cmd *cobra.Command, args []string) {
cname := viper.GetString(config.ProfileName)
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
cc, err := config.Load(cname)
if err != nil && !config.IsNotExist(err) {
exit.WithError("Error loading profile config", err)
}
if err != nil {
out.ErrT(out.Meh, `"{{.name}}" profile does not exist`, out.V{"name": cname})
os.Exit(1)
}
glog.Infof("config: %+v", cc)
cname := ClusterFlagValue()
co := mustload.Running(cname)
for _, n := range cc.Nodes {
machineName := driver.MachineName(*cc, n)
host, err := machine.LoadHost(api, machineName)
for _, n := range co.Config.Nodes {
machineName := driver.MachineName(*co.Config, n)
host, err := machine.LoadHost(co.API, machineName)
if err != nil {
exit.WithError("Error getting host", err)
}
......@@ -68,7 +52,7 @@ var unpauseCmd = &cobra.Command{
exit.WithError("Failed to get command runner", err)
}
cr, err := cruntime.New(cruntime.Config{Type: cc.KubernetesConfig.ContainerRuntime, Runner: r})
cr, err := cruntime.New(cruntime.Config{Type: co.Config.KubernetesConfig.ContainerRuntime, Runner: r})
if err != nil {
exit.WithError("Failed runtime", err)
}
......
......@@ -18,12 +18,9 @@ package cmd
import (
"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/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
)
......@@ -34,24 +31,16 @@ var updateContextCmd = &cobra.Command{
Long: `Retrieves the IP address of the running cluster, checks it
with IP in kubeconfig, and corrects kubeconfig if incorrect.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("Error getting client", err)
}
defer api.Close()
machineName := viper.GetString(config.ProfileName)
ip, err := cluster.GetHostDriverIP(api, machineName)
if err != nil {
exit.WithError("Error host driver ip status", err)
}
updated, err := kubeconfig.UpdateIP(ip, machineName, kubeconfig.PathFromEnv())
cname := ClusterFlagValue()
co := mustload.Running(cname)
updated, err := kubeconfig.UpdateIP(co.DriverIP, cname, kubeconfig.PathFromEnv())
if err != nil {
exit.WithError("update config", err)
}
if updated {
out.T(out.Celebrate, "{{.machine}} IP has been updated to point at {{.ip}}", out.V{"machine": machineName, "ip": ip})
out.T(out.Celebrate, "{{.cluster}} IP has been updated to point at {{.ip}}", out.V{"cluster": cname, "ip": co.DriverIP})
} else {
out.T(out.Meh, "{{.machine}} IP was already correctly configured for {{.ip}}", out.V{"machine": machineName, "ip": ip})
out.T(out.Meh, "{{.cluster}} IP was already correctly configured for {{.ip}}", out.V{"cluster": cname, "ip": co.DriverIP})
}
},
......
/*
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.
*/
// mustload loads minikube clusters, exiting with user-friendly messages
package mustload
import (
"fmt"
"net"
"os"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/state"
"github.com/golang/glog"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil/kverify"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
)
type ClusterController struct {
Config *config.ClusterConfig
API libmachine.API
CPHost *host.Host
CPNode *config.Node
CPRunner command.Runner
DriverIP net.IP
}
// Partial is a cmd-friendly way to load a cluster which may or may not be running
func Partial(name string) (libmachine.API, *config.ClusterConfig) {
glog.Infof("Loading cluster: %s", name)
api, err := machine.NewAPIClient()
if err != nil {
exit.WithError("libmachine failed", err)
}
cc, err := config.Load(name)
if err != nil {
if config.IsNotExist(err) {
out.T(out.Shrug, `There is no local cluster named "{{.cluster}}"`, out.V{"cluster": name})
exitTip("start", name, exit.Data)
}
exit.WithError("Error getting cluster config", err)
}
return api, cc
}
// Running is a cmd-friendly way to load a running cluster
func Running(name string) ClusterController {
api, cc := Partial(name)
cp, err := config.PrimaryControlPlane(cc)
if err != nil {
exit.WithError("Unable to find control plane", err)
}
machineName := driver.MachineName(*cc, cp)
hs, err := machine.Status(api, machineName)
if err != nil {
exit.WithError("Unable to get machine status", err)
}
if hs == state.None.String() {
out.T(out.Shrug, `The control plane node "{{.name}}" does not exist.`, out.V{"name": cp.Name})
exitTip("start", name, exit.Unavailable)
}
if hs == state.Stopped.String() {
out.T(out.Shrug, `The control plane node must be running for this command`)
exitTip("start", name, exit.Unavailable)
}
if hs != state.Running.String() {
out.T(out.Shrug, `The control plane node is not running (state={{.state}})`, out.V{"name": cp.Name, "state": hs})
exitTip("start", name, exit.Unavailable)
}
host, err := machine.LoadHost(api, name)
if err != nil {
exit.WithError("Unable to load host", err)
}
cr, err := machine.CommandRunner(host)
if err != nil {
exit.WithError("Unable to get command runner", err)
}
ips, err := host.Driver.GetIP()
if err != nil {
exit.WithError("Unable to get driver IP", err)
}
if driver.IsKIC(host.DriverName) {
ips = oci.DefaultBindIPV4
}
ip := net.ParseIP(ips)
if ip == nil {
exit.WithCodeT(exit.Software, fmt.Sprintf("Unable to parse driver IP: %q", ips))
}
return ClusterController{
API: api,
Config: cc,
CPRunner: cr,
CPHost: host,
CPNode: &cp,
DriverIP: ip,
}
}
// Healthy is a cmd-friendly way to load a healthy cluster
func Healthy(name string) ClusterController {
co := Running(name)
as, err := kverify.APIServerStatus(co.CPRunner, net.ParseIP(co.CPNode.IP), co.CPNode.Port)
if err != nil {
out.T(out.FailureType, `Unable to get control plane status: {{.error}}`, out.V{"error": err})
exitTip("delete", name, exit.Unavailable)
}
if as == state.Paused {
out.T(out.Shrug, `The control plane for "{{.name}}" is paused!`, out.V{"name": name})
exitTip("unpause", name, exit.Unavailable)
}
if as != state.Running {
out.T(out.Shrug, `This control plane is not running! (state={{.state}})`, out.V{"state": as.String()})
out.T(out.Warning, `This is unusual - you may want to investigate using "{{.command}}"`, out.V{"command": ExampleCmd(name, "logs")})
exitTip("start", name, exit.Unavailable)
}
return co
}
// ExampleCmd Return a minikube command containing the current profile name
func ExampleCmd(cname string, action string) string {
if cname != constants.DefaultClusterName {
return fmt.Sprintf("minikube %s -p %s", action, cname)
}
return fmt.Sprintf("minikube %s", action)
}
// exitTip returns an action tip and exits
func exitTip(action string, profile string, code int) {
command := ExampleCmd(profile, action)
out.T(out.Workaround, "To fix this, run: {{.command}}", out.V{"command": command})
os.Exit(code)
}
......@@ -83,6 +83,8 @@ var styles = map[StyleEnum]style{
Sparkle: {Prefix: "✨ "},
Pause: {Prefix: "⏸️ "},
Unpause: {Prefix: "⏯️ "},
Confused: {Prefix: "😕 "},
Shrug: {Prefix: "🤷 "},
// Specialized purpose styles
ISODownload: {Prefix: "💿 "},
......
......@@ -61,6 +61,7 @@ const (
DeletingHost
Copying
Connectivity
Confused
Internet
Mounting
Celebrate
......@@ -89,4 +90,5 @@ const (
DryRun
AddonEnable
AddonDisable
Shrug
)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册