Merge branch 'master' into DELETE_ALL_PROFILES

# Conflicts:
#	cmd/minikube/cmd/delete.go
pull/4780/head
Marek Schwarz 2019-07-20 18:18:30 +02:00
commit 70f4cb99ce
93 changed files with 1303 additions and 934 deletions

View File

@ -23,8 +23,8 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
const longDescription = `
@ -73,7 +73,7 @@ var completionCmd = &cobra.Command{
exit.UsageT("Usage: minikube completion SHELL")
}
if args[0] != "bash" && args[0] != "zsh" {
exit.UsageT("Sorry, completion support is not yet implemented for {{.name}}", console.Arg{"name": args[0]})
exit.UsageT("Sorry, completion support is not yet implemented for {{.name}}", out.V{"name": args[0]})
} else if args[0] == "bash" {
err := GenerateBashCompletion(os.Stdout, cmd.Parent())
if err != nil {

View File

@ -41,7 +41,7 @@ var addonsListCmd = &cobra.Command{
Long: "Lists all available minikube addons as well as their current statuses (enabled/disabled)",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 0 {
exit.Usage("usage: minikube addons list")
exit.UsageT("usage: minikube addons list")
}
err := addonList()
if err != nil {

View File

@ -20,8 +20,8 @@ import (
"io/ioutil"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
)
@ -31,7 +31,7 @@ var addonsConfigureCmd = &cobra.Command{
Long: "Configures the addon w/ADDON_NAME within minikube (example: minikube addons configure registry-creds). For a list of available addons use: minikube addons list ",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
exit.Usage("usage: minikube addons configure ADDON_NAME")
exit.UsageT("usage: minikube addons configure ADDON_NAME")
}
addon := args[0]
@ -77,7 +77,7 @@ var addonsConfigureCmd = &cobra.Command{
dat, err := ioutil.ReadFile(gcrPath)
if err != nil {
console.Failure("Error reading %s: %v", gcrPath, err)
out.FailureT("Error reading {{.path}}: {{.error}}", out.V{"path": gcrPath, "error": err})
} else {
gcrApplicationDefaultCredentials = string(dat)
}
@ -109,7 +109,7 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
console.Failure("ERROR creating `registry-creds-ecr` secret: %v", err)
out.FailureT("ERROR creating `registry-creds-ecr` secret: {{.error}}", out.V{"error": err})
}
// Create GCR Secret
@ -127,7 +127,7 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
console.Failure("ERROR creating `registry-creds-gcr` secret: %v", err)
out.FailureT("ERROR creating `registry-creds-gcr` secret: {{.error}}", out.V{"error": err})
}
// Create Docker Secret
@ -146,14 +146,14 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
console.Warning("ERROR creating `registry-creds-dpr` secret")
out.WarningT("ERROR creating `registry-creds-dpr` secret")
}
default:
console.Failure("%s has no available configuration options", addon)
out.FailureT("{{.name}} has no available configuration options", out.V{"name": addon})
return
}
console.Success("%s was successfully configured", addon)
out.SuccessT("{{.name}} was successfully configured", out.V{"name": addon})
},
}

View File

@ -18,8 +18,8 @@ package config
import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
var addonsDisableCmd = &cobra.Command{
@ -28,7 +28,7 @@ var addonsDisableCmd = &cobra.Command{
Long: "Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list ",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
exit.Usage("usage: minikube addons disable ADDON_NAME")
exit.UsageT("usage: minikube addons disable ADDON_NAME")
}
addon := args[0]
@ -36,7 +36,7 @@ var addonsDisableCmd = &cobra.Command{
if err != nil {
exit.WithError("disable failed", err)
}
console.Success("%s was successfully disabled", addon)
out.SuccessT(`"{{.minikube_addon}}" was successfully disabled`, out.V{"minikube_addon": addon})
},
}

View File

@ -18,8 +18,8 @@ package config
import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
var addonsEnableCmd = &cobra.Command{
@ -28,7 +28,7 @@ var addonsEnableCmd = &cobra.Command{
Long: "Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list ",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
exit.Usage("usage: minikube addons enable ADDON_NAME")
exit.UsageT("usage: minikube addons enable ADDON_NAME")
}
addon := args[0]
@ -36,7 +36,7 @@ var addonsEnableCmd = &cobra.Command{
if err != nil {
exit.WithError("enable failed", err)
}
console.SuccessT("{{.addonName}} was successfully enabled", console.Arg{"addonName": addon})
out.SuccessT("{{.addonName}} was successfully enabled", out.V{"addonName": addon})
},
}

View File

@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
var configGetCmd = &cobra.Command{
@ -44,7 +44,7 @@ var configGetCmd = &cobra.Command{
return fmt.Errorf("no value for key '%s'", args[0])
}
console.OutLn(val)
out.Ln(val)
return nil
},
}

View File

@ -17,16 +17,15 @@ limitations under the License.
package config
import (
"os"
"text/template"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
)
@ -48,13 +47,13 @@ var addonsOpenCmd = &cobra.Command{
PreRun: func(cmd *cobra.Command, args []string) {
t, err := template.New("addonsURL").Parse(addonsURLFormat)
if err != nil {
exit.Usage("The value passed to --format is invalid: %s", err)
exit.UsageT("The value passed to --format is invalid: {{.error}}", out.V{"error": err})
}
addonsURLTemplate = t
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
exit.Usage("usage: minikube addons open ADDON_NAME")
exit.UsageT("usage: minikube addons open ADDON_NAME")
}
addonName := args[0]
// TODO(r2d4): config should not reference API, pull this out
@ -67,19 +66,18 @@ var addonsOpenCmd = &cobra.Command{
cluster.EnsureMinikubeRunningOrExit(api, 1)
addon, ok := assets.Addons[addonName] // validate addon input
if !ok {
exit.WithCode(exit.Data, `addon '%s' is not a valid addon packaged with minikube.
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`, addonName)
minikube addons list`, out.V{"name": addonName})
}
ok, err = addon.IsEnabled()
if err != nil {
exit.WithError("IsEnabled failed", err)
}
if !ok {
console.ErrStyle(console.Conflict, `addon '%s' is currently not enabled.
exit.WithCodeT(exit.Unavailable, `addon '{{.name}}' is currently not enabled.
To enable this addon run:
minikube addons enable %s`, addonName, addonName)
os.Exit(exit.Unavailable)
minikube addons enable {{.name}}`, out.V{"name": addonName})
}
namespace := "kube-system"
@ -87,16 +85,16 @@ minikube addons enable %s`, addonName, addonName)
serviceList, err := service.GetServiceListByLabel(namespace, key, addonName)
if err != nil {
exit.WithCode(exit.Unavailable, "Error getting service with namespace: %s and labels %s:%s: %v", namespace, key, addonName, err)
exit.WithCodeT(exit.Unavailable, "Error getting service with namespace: {{.namespace}} and labels {{.labelName}}:{{.addonName}}: {{.error}}", out.V{"namespace": namespace, "labelName": key, "addonName": addonName, "error": err})
}
if len(serviceList.Items) == 0 {
exit.WithCode(exit.Config, `This addon does not have an endpoint defined for the 'addons open' command.
You can add one by annotating a service with the label %s:%s`, key, addonName)
exit.WithCodeT(exit.Config, `This addon does not have an endpoint defined for the 'addons open' command.
You can add one by annotating a service with the label {{.labelName}}:{{.addonName}}`, out.V{"labelName": key, "addonName": addonName})
}
for i := range serviceList.Items {
svc := serviceList.Items[i].ObjectMeta.Name
if err := service.WaitAndMaybeOpenService(api, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
exit.WithCode(exit.Unavailable, "Wait failed: %v", err)
exit.WithCodeT(exit.Unavailable, "Wait failed: {{.error}}", out.V{"error": err})
}
}
},

View File

@ -27,9 +27,9 @@ import (
"github.com/spf13/viper"
mkConfig "k8s.io/minikube/pkg/minikube/config"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
pkgutil "k8s.io/minikube/pkg/util"
)
@ -41,12 +41,12 @@ var ProfileCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
profile := viper.GetString(pkgConfig.MachineProfile)
console.OutLn("%s", profile)
out.T(out.Empty, profile)
os.Exit(0)
}
if len(args) > 1 {
exit.Usage("usage: minikube profile [MINIKUBE_PROFILE_NAME]")
exit.UsageT("usage: minikube profile [MINIKUBE_PROFILE_NAME]")
}
profile := args[0]
@ -60,20 +60,20 @@ var ProfileCmd = &cobra.Command{
cc, err := pkgConfig.Load()
// might err when loading older version of cfg file that doesn't have KeepContext field
if err != nil && !os.IsNotExist(err) {
console.ErrLn("Error loading profile config: %v", err)
out.ErrT(out.Sad, `Error loading profile config: {{.error}}`, out.V{"error": err})
}
if err == nil {
if cc.MachineConfig.KeepContext {
console.Success("Skipped switching kubectl context for %s , because --keep-context", profile)
console.Success("To connect to this cluster, use: kubectl --context=%s", profile)
out.SuccessT("Skipped switching kubectl context for {{.profile_name}} , because --keep-context", out.V{"profile_name": profile})
out.SuccessT("To connect to this cluster, use: kubectl --context={{.profile_name}}", out.V{"profile_name": profile})
} else {
err := pkgutil.SetCurrentContext(constants.KubeconfigPath, profile)
if err != nil {
console.ErrLn("Error while setting kubectl current context : %v", err)
out.ErrT(out.Sad, `Error while setting kubectl current context : {{.error}}`, out.V{"error": err})
}
}
}
console.Success("minikube profile was successfully set to %s", profile)
out.SuccessT("minikube profile was successfully set to {{.profile_name}}", out.V{"profile_name": profile})
},
}

View File

@ -0,0 +1,76 @@
/*
Copyright 2019 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 (
"fmt"
"os"
"strconv"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
)
var profileListCmd = &cobra.Command{
Use: "list",
Short: "Lists all minikube profiles.",
Long: "Lists all valid minikube profiles and detects all possible invalid profiles.",
Run: func(cmd *cobra.Command, args []string) {
var validData [][]string
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Profile", "VM Driver", "NodeIP", "Node Port", "Kubernetes Version"})
table.SetAutoFormatHeaders(false)
table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
table.SetCenterSeparator("|")
validProfiles, invalidProfiles, err := config.ListProfiles()
if len(validProfiles) == 0 || err != nil {
exit.UsageT("No minikube profile was found. you could create one using: `minikube start`")
}
for _, p := range validProfiles {
validData = append(validData, []string{p.Name, p.Config.MachineConfig.VMDriver, p.Config.KubernetesConfig.NodeIP, strconv.Itoa(p.Config.KubernetesConfig.NodePort), p.Config.KubernetesConfig.KubernetesVersion})
}
table.AppendBulk(validData)
table.Render()
if invalidProfiles != nil {
out.T(out.WarningType, "Found {{.number}} invalid profile(s) ! ", out.V{"number": len(invalidProfiles)})
for _, p := range invalidProfiles {
out.T(out.Empty, "\t "+p.Name)
}
out.T(out.Tip, "You can delete them using the following command(s): ")
for _, p := range invalidProfiles {
out.String(fmt.Sprintf("\t $ minikube delete -p %s \n", p.Name))
}
}
if err != nil {
exit.WithCodeT(exit.Config, fmt.Sprintf("error loading profiles: %v", err))
}
},
}
func init() {
ProfileCmd.AddCommand(profileListCmd)
}

View File

@ -25,7 +25,7 @@ import (
"github.com/golang/glog"
"golang.org/x/crypto/ssh/terminal"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
// AskForYesNoConfirmation asks the user for confirmation. A user must type in "yes" or "no" and
@ -36,7 +36,7 @@ func AskForYesNoConfirmation(s string, posResponses, negResponses []string) bool
reader := bufio.NewReader(os.Stdin)
for {
console.Out("%s [y/n]: ", s)
out.String("%s [y/n]: ", s)
response, err := reader.ReadString('\n')
if err != nil {
@ -49,7 +49,7 @@ func AskForYesNoConfirmation(s string, posResponses, negResponses []string) bool
case containsString(negResponses, r):
return false
default:
console.Err("Please type yes or no:")
out.Err("Please type yes or no:")
}
}
}
@ -63,7 +63,7 @@ func AskForStaticValue(s string) string {
// Can't have zero length
if len(response) == 0 {
console.Err("--Error, please enter a value:")
out.Err("--Error, please enter a value:")
continue
}
return response
@ -78,7 +78,7 @@ func AskForStaticValueOptional(s string) string {
}
func getStaticValue(reader *bufio.Reader, s string) string {
console.Out("%s", s)
out.String("%s", s)
response, err := reader.ReadString('\n')
if err != nil {
@ -110,7 +110,7 @@ func concealableAskForStaticValue(readWriter io.ReadWriter, promptString string,
}
response = strings.TrimSpace(response)
if len(response) == 0 {
console.Warning("Please enter a value:")
out.WarningT("Please enter a value:")
continue
}
return response, nil

View File

@ -29,7 +29,7 @@ var configSetCmd = &cobra.Command{
These values can be overwritten by flags or environment variables at runtime.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
exit.Usage("usage: minikube config set PROPERTY_NAME PROPERTY_VALUE")
exit.UsageT("usage: minikube config set PROPERTY_NAME PROPERTY_VALUE")
}
err := Set(args[0], args[1])
if err != nil {

View File

@ -28,7 +28,7 @@ var configUnsetCmd = &cobra.Command{
Long: "unsets PROPERTY_NAME from the minikube config file. Can be overwritten by flags or environmental variables",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
exit.Usage("usage: minikube config unset PROPERTY_NAME")
exit.UsageT("usage: minikube config unset PROPERTY_NAME")
}
err := unset(args[0])
if err != nil {

View File

@ -27,10 +27,10 @@ import (
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/storageclass"
)
@ -130,7 +130,7 @@ func EnableOrDisableAddon(name string, val string) error {
cfg, err := config.Load()
if err != nil && !os.IsNotExist(err) {
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", console.Arg{"error": err})
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err})
}
data := assets.GenerateTemplateData(cfg.KubernetesConfig)
@ -158,7 +158,7 @@ func enableOrDisableAddonInternal(addon *assets.Addon, cmd command.Runner, data
var err error
// check addon status before enabling/disabling it
if err := isAddonAlreadySet(addon, enable); err != nil {
console.ErrT(console.Conflict, "{{.error}}", console.Arg{"error": err})
out.ErrT(out.Conflict, "{{.error}}", out.V{"error": err})
os.Exit(0)
}

View File

@ -28,9 +28,9 @@ import (
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/out"
)
// containerdOnlyMsg is the message shown when a containerd-only addon is enabled
@ -55,7 +55,7 @@ func IsValidDriver(string, driver string) error {
// RequiresRestartMsg returns the "requires restart" message
func RequiresRestartMsg(string, string) error {
console.OutStyle(console.WarningType, "These changes will take effect upon a minikube delete and then a minikube start")
out.T(out.WarningType, "These changes will take effect upon a minikube delete and then a minikube start")
return nil
}

View File

@ -35,9 +35,9 @@ import (
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/cluster"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/proxy"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/util"
@ -76,7 +76,7 @@ var dashboardCmd = &cobra.Command{
if _, err = api.Load(pkg_config.GetMachineName()); err != nil {
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
exit.WithCodeT(exit.Unavailable, "{{.name}} cluster does not exist", console.Arg{"name": pkg_config.GetMachineName()})
exit.WithCodeT(exit.Unavailable, "{{.name}} cluster does not exist", out.V{"name": pkg_config.GetMachineName()})
default:
exit.WithError("Error getting cluster", err)
}
@ -89,7 +89,7 @@ var dashboardCmd = &cobra.Command{
kubectl, err := exec.LookPath("kubectl")
if err != nil {
exit.WithCode(exit.NoInput, "kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
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/")
}
cluster.EnsureMinikubeRunningOrExit(api, 1)
@ -99,7 +99,7 @@ var dashboardCmd = &cobra.Command{
dashboardStatus, _ := dashboardAddon.IsEnabled()
if !dashboardStatus {
// Send status messages to stderr for folks re-using this output.
console.ErrT(console.Enabling, "Enabling dashboard ...")
out.ErrT(out.Enabling, "Enabling dashboard ...")
// Enable the dashboard add-on
err = configcmd.Set("dashboard", "true")
if err != nil {
@ -109,29 +109,29 @@ var dashboardCmd = &cobra.Command{
ns := "kube-system"
svc := "kubernetes-dashboard"
console.ErrT(console.Verifying, "Verifying dashboard health ...")
out.ErrT(out.Verifying, "Verifying dashboard health ...")
if err = util.RetryAfter(180, func() error { return service.CheckService(ns, svc) }, 1*time.Second); err != nil {
exit.WithCodeT(exit.Unavailable, "dashboard service is not running: {{.error}}", console.Arg{"error": err})
exit.WithCodeT(exit.Unavailable, "dashboard service is not running: {{.error}}", out.V{"error": err})
}
console.ErrT(console.Launch, "Launching proxy ...")
out.ErrT(out.Launch, "Launching proxy ...")
p, hostPort, err := kubectlProxy(kubectl)
if err != nil {
exit.WithError("kubectl proxy", err)
}
url := dashboardURL(hostPort, ns, svc)
console.ErrT(console.Verifying, "Verifying proxy health ...")
out.ErrT(out.Verifying, "Verifying proxy health ...")
if err = util.RetryAfter(60, func() error { return checkURL(url) }, 1*time.Second); err != nil {
exit.WithCodeT(exit.Unavailable, "{{.url}} is not accessible: {{.error}}", console.Arg{"url": url, "error": err})
exit.WithCodeT(exit.Unavailable, "{{.url}} is not accessible: {{.error}}", out.V{"url": url, "error": err})
}
if dashboardURLMode {
console.OutLn(url)
out.Ln(url)
} else {
console.ErrT(console.Celebrate, "Opening %s in your default browser...", console.Arg{"url": url})
out.ErrT(out.Celebrate, "Opening %s in your default browser...", out.V{"url": url})
if err = browser.OpenURL(url); err != nil {
exit.WithCodeT(exit.Software, "failed to open browser: {{.error}}", console.Arg{"error": err})
exit.WithCodeT(exit.Software, "failed to open browser: {{.error}}", out.V{"error": err})
}
}

View File

@ -28,10 +28,10 @@ import (
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
pkgutil "k8s.io/minikube/pkg/util"
)
@ -48,29 +48,32 @@ associated files.`,
// runDelete handles the executes the flow of "minikube delete"
func runDelete(cmd *cobra.Command, args []string) {
profileFlag, err := cmd.Flags().GetString("profile")
if err != nil {
exit.WithError("Could not get profile flag", err)
}
if deleteAll {
if profileFlag != constants.DefaultMachineName {
exit.Usage("usage: minikube delete --all")
}
profiles, err := cmdcfg.GetAllProfiles()
if len(args) > 0 {
exit.UsageT("usage: minikube delete")
profileFlag, err := cmd.Flags().GetString("profile")
if err != nil {
exit.WithError("Error getting profiles to delete", err)
exit.WithError("Could not get profile flag", err)
}
deleteAllProfiles(profiles)
} else {
if len(args) > 0 {
exit.Usage("usage: minikube delete")
}
if deleteAll {
if profileFlag != constants.DefaultMachineName {
exit.UsageT("usage: minikube delete --all")
}
profileName := viper.GetString(pkg_config.MachineProfile)
deleteProfile(profileName)
profiles, err := cmdcfg.GetAllProfiles()
if err != nil {
exit.WithError("Error getting profiles to delete", err)
}
deleteAllProfiles(profiles)
} else {
if len(args) > 0 {
exit.UsageT("usage: minikube delete")
}
profileName := viper.GetString(pkg_config.MachineProfile)
deleteProfile(profileName)
}
}
}
@ -86,7 +89,7 @@ func deleteProfile(profileName string) {
cc, err := pkg_config.Load()
if err != nil && !os.IsNotExist(err) {
console.ErrLn("Error loading profile config: %v", err)
out.ErrT(out.Sad, "Error loading profile config: {{.error}}", out.V{"name": profileName})
}
// In the case of "none", we want to uninstall Kubernetes as there is no VM to delete
@ -97,24 +100,24 @@ func deleteProfile(profileName string) {
if err = cluster.DeleteHost(api); err != nil {
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
console.OutT(console.Meh, `"{{.name}}" cluster does not exist`, console.Arg{"name": profileName})
out.T(out.Meh, `"{{.name}}" cluster does not exist`, out.V{"name": profileName})
default:
exit.WithError("Failed to delete cluster", err)
}
}
if err := cmdUtil.KillMountProcess(); err != nil {
console.Fatal("Failed to kill mount process: %v", err)
out.FatalT("Failed to kill mount process: {{.error}}", out.V{"error": err})
}
if err := os.RemoveAll(constants.GetProfilePath(viper.GetString(pkg_config.MachineProfile))); err != nil {
if os.IsNotExist(err) {
console.OutStyle(console.Meh, "%q profile does not exist", profileName)
out.T(out.Meh, `"{{.profile_name}}" profile does not exist`, out.V{"profile_name": profileName})
os.Exit(0)
}
exit.WithError("Failed to remove profile", err)
}
console.OutStyle(console.Crushed, "The %q cluster has been deleted.", profileName)
out.T(out.Crushed, `The "{{.cluster_name}}" cluster has been deleted.`, out.V{"cluster_name": profileName})
machineName := pkg_config.GetMachineName()
if err := pkgutil.DeleteKubeConfigContext(constants.KubeconfigPath, machineName); err != nil {
@ -130,12 +133,12 @@ func deleteAllProfiles(profiles []string) {
// TODO: Return errors?
func uninstallKubernetes(api libmachine.API, kc pkg_config.KubernetesConfig, bsName string) {
console.OutStyle(console.Resetting, "Uninstalling Kubernetes %s using %s ...", kc.KubernetesVersion, bsName)
out.T(out.Resetting, "Uninstalling Kubernetes {{.kubernetes_version}} using {{.bootstrapper_name}} ...", out.V{"kubernetes_version": kc.KubernetesVersion, "bootstrapper_name": bsName})
clusterBootstrapper, err := getClusterBootstrapper(api, bsName)
if err != nil {
console.ErrLn("Unable to get bootstrapper: %v", err)
out.ErrT(out.Empty, "Unable to get bootstrapper: {{.error}}", out.V{"error": err})
} else if err = clusterBootstrapper.DeleteCluster(kc); err != nil {
console.ErrLn("Failed to delete cluster: %v", err)
out.ErrT(out.Empty, "Failed to delete cluster: {{.error}}", out.V{"error": err})
}
}

View File

@ -344,21 +344,21 @@ var dockerEnvCmd = &cobra.Command{
exit.WithError("Error getting host", err)
}
if host.Driver.DriverName() == constants.DriverNone {
exit.Usage(`'none' driver does not support 'minikube docker-env' command`)
exit.UsageT(`'none' driver does not support 'minikube docker-env' command`)
}
hostSt, err := cluster.GetHostStatus(api)
if err != nil {
exit.WithError("Error getting host status", err)
}
if hostSt != state.Running.String() {
exit.WithCode(exit.Unavailable, `The docker host is currently not running`)
exit.WithCodeT(exit.Unavailable, `The docker host is currently not running`)
}
docker, err := GetDockerActive(host)
if err != nil {
exit.WithError("Error getting service status", err)
}
if !docker {
exit.WithCode(exit.Unavailable, `The docker service is currently not active`)
exit.WithCodeT(exit.Unavailable, `The docker service is currently not active`)
}
var shellCfg *ShellConfig

View File

@ -20,7 +20,6 @@ import (
"reflect"
"testing"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/host"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
@ -71,7 +70,7 @@ func newShellCfg(shell, prefix, suffix, delim string) *ShellConfig {
func TestShellCfgSet(t *testing.T) {
var tests = []struct {
description string
api libmachine.API
api *tests.MockAPI
shell string
noProxyVar string
noProxyValue string
@ -236,7 +235,7 @@ func TestShellCfgSet(t *testing.T) {
defaultShellDetector = &FakeShellDetector{test.shell}
defaultNoProxyGetter = &FakeNoProxyGetter{test.noProxyVar, test.noProxyValue}
noProxy = test.noProxyFlag
test.api.T = t
shellCfg, err := shellCfgSet(test.api)
if !reflect.DeepEqual(shellCfg, test.expectedShellCfg) {
t.Errorf("Shell cfgs differ: expected %+v, \n\n got %+v", test.expectedShellCfg, shellCfg)

View File

@ -21,9 +21,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
)
// ipCmd represents the ip command
@ -42,7 +42,7 @@ var ipCmd = &cobra.Command{
if err != nil {
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
exit.WithCode(exit.NoInput, "%q host does not exist, unable to show an IP", config.GetMachineName())
exit.WithCodeT(exit.NoInput, `"{{.profile_name}}" host does not exist, unable to show an IP`, out.V{"profile_name": config.GetMachineName()})
default:
exit.WithError("Error getting host", err)
}
@ -51,7 +51,7 @@ var ipCmd = &cobra.Command{
if err != nil {
exit.WithError("Error getting IP", err)
}
console.OutLn(ip)
out.Ln(ip)
},
}

View File

@ -26,10 +26,10 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
)
// kubectlCmd represents the kubectl command
@ -50,7 +50,7 @@ kubectl get pods --namespace kube-system`,
cc, err := pkg_config.Load()
if err != nil && !os.IsNotExist(err) {
console.ErrLn("Error loading profile config: %v", err)
out.ErrLn("Error loading profile config: %v", err)
}
binary := "kubectl"

View File

@ -31,10 +31,10 @@ import (
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/third_party/go9p/ufs"
)
@ -69,25 +69,25 @@ var mountCmd = &cobra.Command{
}
if len(args) != 1 {
exit.Usage(`Please specify the directory to be mounted:
exit.UsageT(`Please specify the directory to be mounted:
minikube mount <source directory>:<target directory> (example: "/host-home:/vm-home")`)
}
mountString := args[0]
idx := strings.LastIndex(mountString, ":")
if idx == -1 { // no ":" was present
exit.UsageT(`mount argument "{{.value}}" must be in form: <source directory>:<target directory>`, console.Arg{"value": mountString})
exit.UsageT(`mount argument "{{.value}}" must be in form: <source directory>:<target directory>`, out.V{"value": mountString})
}
hostPath := mountString[:idx]
vmPath := mountString[idx+1:]
if _, err := os.Stat(hostPath); err != nil {
if os.IsNotExist(err) {
exit.WithCodeT(exit.NoInput, "Cannot find directory {{.path}} for mount", console.Arg{"path": hostPath})
exit.WithCodeT(exit.NoInput, "Cannot find directory {{.path}} for mount", out.V{"path": hostPath})
} else {
exit.WithError("stat failed", err)
}
}
if len(vmPath) == 0 || !strings.HasPrefix(vmPath, "/") {
exit.UsageT("Target directory {{.path}} must be an absolute path", console.Arg{"path": vmPath})
exit.UsageT("Target directory {{.path}} must be an absolute path", out.V{"path": vmPath})
}
var debugVal int
if glog.V(1) {
@ -104,7 +104,7 @@ var mountCmd = &cobra.Command{
exit.WithError("Error loading api", err)
}
if host.Driver.DriverName() == constants.DriverNone {
exit.Usage(`'none' driver does not support 'minikube mount' command`)
exit.UsageT(`'none' driver does not support 'minikube mount' command`)
}
var ip net.IP
if mountIP == "" {
@ -115,7 +115,7 @@ var mountCmd = &cobra.Command{
} else {
ip = net.ParseIP(mountIP)
if ip == nil {
exit.WithCode(exit.Data, "error parsing the input ip address for mount")
exit.WithCodeT(exit.Data, "error parsing the input ip address for mount")
}
}
port, err := cmdUtil.GetPort()
@ -143,27 +143,27 @@ var mountCmd = &cobra.Command{
cfg.Options[parts[0]] = parts[1]
}
console.OutT(console.Mounting, "Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...", console.Arg{"sourcePath": hostPath, "destinationPath": vmPath})
console.OutT(console.Option, "Mount type: {{.name}}", console.Arg{"type": cfg.Type})
console.OutT(console.Option, "User ID: {{.userID}}", console.Arg{"userID": cfg.UID})
console.OutT(console.Option, "Group ID: {{.groupID}}", console.Arg{"groupID": cfg.GID})
console.OutT(console.Option, "Version: {{.version}}", console.Arg{"version": cfg.Version})
console.OutT(console.Option, "Message Size: {{.size}}", console.Arg{"size": cfg.MSize})
console.OutT(console.Option, "Permissions: {{.octalMode}} ({{.writtenMode}})", console.Arg{"octalMode": fmt.Sprintf("%o", cfg.Mode), "writtenMode": cfg.Mode})
console.OutT(console.Option, "Options: {{.options}}", console.Arg{"options": cfg.Options})
out.T(out.Mounting, "Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...", out.V{"sourcePath": hostPath, "destinationPath": vmPath})
out.T(out.Option, "Mount type: {{.name}}", out.V{"type": cfg.Type})
out.T(out.Option, "User ID: {{.userID}}", out.V{"userID": cfg.UID})
out.T(out.Option, "Group ID: {{.groupID}}", out.V{"groupID": cfg.GID})
out.T(out.Option, "Version: {{.version}}", out.V{"version": cfg.Version})
out.T(out.Option, "Message Size: {{.size}}", out.V{"size": cfg.MSize})
out.T(out.Option, "Permissions: {{.octalMode}} ({{.writtenMode}})", out.V{"octalMode": fmt.Sprintf("%o", cfg.Mode), "writtenMode": cfg.Mode})
out.T(out.Option, "Options: {{.options}}", out.V{"options": cfg.Options})
// An escape valve to allow future hackers to try NFS, VirtFS, or other FS types.
if !supportedFilesystems[cfg.Type] {
console.OutT(console.WarningType, "{{.type}} is not yet a supported filesystem. We will try anyways!", console.Arg{"type": cfg.Type})
out.T(out.WarningType, "{{.type}} is not yet a supported filesystem. We will try anyways!", out.V{"type": cfg.Type})
}
var wg sync.WaitGroup
if cfg.Type == nineP {
wg.Add(1)
go func() {
console.OutT(console.Fileserver, "Userspace file server: ")
out.T(out.Fileserver, "Userspace file server: ")
ufs.StartServer(net.JoinHostPort(ip.String(), strconv.Itoa(port)), debugVal, hostPath)
console.OutT(console.Stopped, "Userspace file server is shutdown")
out.T(out.Stopped, "Userspace file server is shutdown")
wg.Done()
}()
}
@ -179,12 +179,12 @@ var mountCmd = &cobra.Command{
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
for sig := range c {
console.OutT(console.Unmount, "Unmounting {{.path}} ...", console.Arg{"path": vmPath})
out.T(out.Unmount, "Unmounting {{.path}} ...", out.V{"path": vmPath})
err := cluster.Unmount(runner, vmPath)
if err != nil {
console.ErrT(console.FailureType, "Failed unmount: {{.error}}", console.Arg{"error": err})
out.ErrT(out.FailureType, "Failed unmount: {{.error}}", out.V{"error": err})
}
exit.WithCodeT(exit.Interrupted, "Received {{.name}} signal", console.Arg{"name": sig})
exit.WithCodeT(exit.Interrupted, "Received {{.name}} signal", out.V{"name": sig})
}
}()
@ -192,9 +192,9 @@ var mountCmd = &cobra.Command{
if err != nil {
exit.WithError("mount failed", err)
}
console.OutT(console.SuccessType, "Successfully mounted {{.sourcePath}} to {{.destinationPath}}", console.Arg{"sourcePath": hostPath, "destinationPath": vmPath})
console.OutLn("")
console.OutT(console.Notice, "NOTE: This process must stay alive for the mount to be accessible ...")
out.T(out.SuccessType, "Successfully mounted {{.sourcePath}} to {{.destinationPath}}", out.V{"sourcePath": hostPath, "destinationPath": vmPath})
out.Ln("")
out.T(out.Notice, "NOTE: This process must stay alive for the mount to be accessible ...")
wg.Wait()
},
}

View File

@ -55,7 +55,7 @@ var serviceCmd = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 || len(args) > 1 {
exit.Usage("You must specify a service name")
exit.UsageT("You must specify a service name")
}
svc := args[0]

View File

@ -22,9 +22,9 @@ import (
"github.com/spf13/cobra"
core "k8s.io/api/core/v1"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/service"
)
@ -43,8 +43,8 @@ var serviceListCmd = &cobra.Command{
defer api.Close()
serviceURLs, err := service.GetServiceURLs(api, serviceListNamespace, serviceURLTemplate)
if err != nil {
console.FatalT("Failed to get service URL: {{.error}}", console.Arg{"error": err})
console.ErrT(console.Notice, "Check that minikube is running and that you have specified the correct namespace (-n flag) if required.")
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.")
os.Exit(exit.Unavailable)
}

View File

@ -21,8 +21,8 @@ import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
)
// sshKeyCmd represents the sshKey command
@ -31,7 +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) {
console.OutLn(filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), "id_rsa"))
out.Ln(filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), "id_rsa"))
},
}

View File

@ -22,10 +22,10 @@ import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
)
// sshCmd represents the docker-ssh command
@ -44,12 +44,12 @@ var sshCmd = &cobra.Command{
exit.WithError("Error getting host", err)
}
if host.Driver.DriverName() == constants.DriverNone {
exit.Usage("'none' driver does not support 'minikube ssh' command")
exit.UsageT("'none' driver does not support 'minikube ssh' command")
}
err = cluster.CreateSSHShell(api, args)
if err != nil {
// This is typically due to a non-zero exit code, so no need for flourish.
console.ErrLn("ssh: %v", err)
out.ErrLn("ssh: %v", err)
// It'd be nice if we could pass up the correct error code here :(
os.Exit(exit.Failure)
}

View File

@ -51,12 +51,12 @@ import (
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/command"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/logs"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/proxy"
pkgutil "k8s.io/minikube/pkg/util"
"k8s.io/minikube/pkg/version"
@ -101,6 +101,7 @@ const (
downloadOnly = "download-only"
dnsProxy = "dns-proxy"
hostDNSResolver = "host-dns-resolver"
waitUntilHealthy = "wait"
)
var (
@ -140,6 +141,7 @@ func initMinikubeFlags() {
startCmd.Flags().String(criSocket, "", "The cri socket path to be used")
startCmd.Flags().String(networkPlugin, "", "The name of the network plugin")
startCmd.Flags().Bool(enableDefaultCNI, false, "Enable the default CNI plugin (/etc/cni/net.d/k8s.conf). Used in conjunction with \"--network-plugin=cni\"")
startCmd.Flags().Bool(waitUntilHealthy, true, "Wait until Kubernetes core services are healthy before exiting")
}
// initKubernetesFlags inits the commandline flags for kubernetes related options
@ -207,7 +209,7 @@ var startCmd = &cobra.Command{
// runStart handles the executes the flow of "minikube start"
func runStart(cmd *cobra.Command, args []string) {
console.OutT(console.Happy, "minikube {{.version}} on {{.os}} ({{.arch}})", console.Arg{"version": version.GetVersion(), "os": runtime.GOOS, "arch": runtime.GOARCH})
out.T(out.Happy, "minikube {{.version}} on {{.os}} ({{.arch}})", out.V{"version": version.GetVersion(), "os": runtime.GOOS, "arch": runtime.GOARCH})
validateConfig()
validateUser()
@ -251,13 +253,14 @@ func runStart(cmd *cobra.Command, args []string) {
bootstrapCluster(bs, cr, mRunner, config.KubernetesConfig, preExists, isUpgrade)
configureMounts()
if err = loadCachedImagesInConfigFile(); err != nil {
console.Failure("Unable to load cached images from config file.")
out.T(out.FailureType, "Unable to load cached images from config file.")
}
// special ops for none driver, like change minikube directory.
prepareNone(viper.GetString(vmDriver))
if err := bs.WaitCluster(config.KubernetesConfig); err != nil {
exit.WithError("Wait failed", err)
if viper.GetBool(waitUntilHealthy) {
if err := bs.WaitCluster(config.KubernetesConfig); err != nil {
exit.WithError("Wait failed", err)
}
}
showKubectlConnectInfo(kubeconfig)
@ -275,7 +278,7 @@ func handleDownloadOnly(cacheGroup *errgroup.Group, k8sVersion string) {
if err := CacheImagesInConfigFile(); err != nil {
exit.WithError("Failed to cache images", err)
}
console.OutStyle(console.Check, "Download complete!")
out.T(out.Check, "Download complete!")
os.Exit(0)
}
@ -291,7 +294,7 @@ func startMachine(config *cfg.Config) (runner command.Runner, preExists bool, ma
// Bypass proxy for minikube's vm host ip
err = proxy.ExcludeIP(ip)
if err != nil {
console.ErrT(console.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.", console.Arg{"ip": ip})
out.ErrT(out.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.", out.V{"ip": ip})
}
// Save IP to configuration file for subsequent use
config.KubernetesConfig.NodeIP = ip
@ -309,7 +312,7 @@ func startMachine(config *cfg.Config) (runner command.Runner, preExists bool, ma
func getKubernetesVersion() (k8sVersion string, isUpgrade bool) {
oldConfig, err := cfg.Load()
if err != nil && !os.IsNotExist(err) {
exit.WithCode(exit.Data, "Unable to load config: %v", err)
exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err})
}
return validateKubernetesVersions(oldConfig)
}
@ -331,24 +334,28 @@ func skipCache(config *cfg.Config) {
func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
version, _ := cr.Version()
console.OutT(cr.Style(), "Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}", console.Arg{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
out.T(cr.Style(), "Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
for _, v := range dockerOpt {
console.OutStyle(console.Option, "opt %s", v)
out.T(out.Option, "opt {{.docker_option}}", out.V{"docker_option": v})
}
for _, v := range dockerEnv {
console.OutStyle(console.Option, "env %s", v)
out.T(out.Option, "env {{.docker_env}}", out.V{"docker_env": v})
}
}
func showKubectlConnectInfo(kubeconfig *pkgutil.KubeConfigSetup) {
if kubeconfig.KeepContext {
console.OutT(console.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", console.Arg{"name": kubeconfig.ClusterName})
out.T(out.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", out.V{"name": kubeconfig.ClusterName})
} else {
console.OutT(console.Ready, "Done! kubectl is now configured to use {{.name}}", console.Arg{"name": cfg.GetMachineName()})
if !viper.GetBool(waitUntilHealthy) {
out.T(out.Ready, "kubectl has been configured configured to use {{.name}}", out.V{"name": cfg.GetMachineName()})
} else {
out.T(out.Ready, "Done! kubectl is now configured to use {{.name}}", out.V{"name": cfg.GetMachineName()})
}
}
_, err := exec.LookPath("kubectl")
if err != nil {
console.OutStyle(console.Tip, "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
out.T(out.Tip, "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
}
}
@ -411,10 +418,9 @@ func validateUser() {
// Check if minikube needs to run with sudo or not.
if err == nil {
if d == constants.DriverNone && u.Name != "root" {
exit.Usage("Please run with sudo. the vm-driver %q requires sudo.", constants.DriverNone)
exit.UsageT(`Please run with sudo. the vm-driver "{{.driver_name}}" requires sudo.`, out.V{"driver_name": constants.DriverNone})
} else if u.Name == "root" && !(d == constants.DriverHyperv || d == constants.DriverNone) {
console.OutT(console.WarningType, "Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.", console.Arg{"driver": d})
out.T(out.WarningType, "Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.", out.V{"driver": d})
}
} else {
@ -427,7 +433,7 @@ func validateUser() {
func validateConfig() {
diskSizeMB := pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize))
if diskSizeMB < pkgutil.CalculateSizeInMB(constants.MinimumDiskSize) {
exit.WithCode(exit.Config, "Requested disk size (%dMB) is less than minimum of (%dMB)", diskSizeMB, pkgutil.CalculateSizeInMB(constants.MinimumDiskSize))
exit.WithCodeT(exit.Config, "Requested disk size {{.size_in_mb}} is less than minimum of {{.size_in_mb2}}", out.V{"size_in_mb": diskSizeMB, "size_in_mb2": pkgutil.CalculateSizeInMB(constants.MinimumDiskSize)})
}
err := autoSetOptions(viper.GetString(vmDriver))
@ -437,17 +443,18 @@ func validateConfig() {
memorySizeMB := pkgutil.CalculateSizeInMB(viper.GetString(memory))
if memorySizeMB < pkgutil.CalculateSizeInMB(constants.MinimumMemorySize) {
exit.Usage("Requested memory allocation (%dMB) is less than the minimum allowed of %dMB", memorySizeMB, pkgutil.CalculateSizeInMB(constants.MinimumMemorySize))
exit.UsageT("Requested memory allocation {{.size_in_mb}} is less than the minimum allowed of {{.size_in_mb2}}", out.V{"size_in_mb": memorySizeMB, "size_in_mb2": pkgutil.CalculateSizeInMB(constants.MinimumMemorySize)})
}
if memorySizeMB < pkgutil.CalculateSizeInMB(constants.DefaultMemorySize) {
console.OutT(console.Notice, "Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.", console.Arg{"memory": memorySizeMB, "default": pkgutil.CalculateSizeInMB(constants.DefaultMemorySize)})
out.T(out.Notice, "Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default_memorysize}}MB. Beware that minikube might not work correctly or crash unexpectedly.",
out.V{"memory": memorySizeMB, "default_memorysize": pkgutil.CalculateSizeInMB(constants.DefaultMemorySize)})
}
// check that kubeadm extra args contain only whitelisted parameters
for param := range extraOptions.AsMap().Get(kubeadm.Kubeadm) {
if !pkgutil.ContainsString(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmCmdParam], param) &&
!pkgutil.ContainsString(kubeadm.KubeadmExtraArgsWhitelist[kubeadm.KubeadmConfigParam], param) {
exit.Usage("Sorry, the kubeadm.%s parameter is currently not supported by --extra-config", param)
exit.UsageT("Sorry, the kubeadm.{{.parameter_name}} parameter is currently not supported by --extra-config", out.V{"parameter_name": param})
}
}
@ -465,7 +472,7 @@ func validateRegistryMirror() {
glog.Errorln("Error Parsing URL: ", err)
}
if (URL.Scheme != "http" && URL.Scheme != "https") || URL.Path != "" {
exit.Usage("Sorry, url provided with --registry-mirror flag is invalid %q", loc)
exit.UsageT("Sorry, url provided with --registry-mirror flag is invalid {{.url}}", out.V{"url": loc})
}
}
@ -539,9 +546,9 @@ func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) {
if !found {
if autoSelectedRepository == "" {
exit.WithCode(exit.Failure, "None of known repositories is accessible. Consider specifying an alternative image repository with --image-repository flag")
exit.WithCodeT(exit.Failure, "None of known repositories is accessible. Consider specifying an alternative image repository with --image-repository flag")
} else {
console.Warning("None of known repositories in your location is accessible. Use %s as fallback.", autoSelectedRepository)
out.WarningT("None of known repositories in your location is accessible. Use {{.image_repository_name}} as fallback.", out.V{"image_repository_name": autoSelectedRepository})
}
}
@ -549,7 +556,7 @@ func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) {
}
if repository != "" {
console.OutT(console.SuccessType, "Using image repository {{.name}}", console.Arg{"name": repository})
out.T(out.SuccessType, "Using image repository {{.name}}", out.V{"name": repository})
}
cfg := cfg.Config{
@ -620,31 +627,31 @@ func prepareNone(vmDriver string) {
if vmDriver != constants.DriverNone {
return
}
console.OutStyle(console.StartingNone, "Configuring local host environment ...")
out.T(out.StartingNone, "Configuring local host environment ...")
if viper.GetBool(cfg.WantNoneDriverWarning) {
console.OutLn("")
console.Warning("The 'none' driver provides limited isolation and may reduce system security and reliability.")
console.Warning("For more information, see:")
console.OutStyle(console.URL, "https://github.com/kubernetes/minikube/blob/master/docs/vmdriver-none.md")
console.OutLn("")
out.T(out.Empty, "")
out.WarningT("The 'none' driver provides limited isolation and may reduce system security and reliability.")
out.WarningT("For more information, see:")
out.T(out.URL, "https://github.com/kubernetes/minikube/blob/master/docs/vmdriver-none.md")
out.T(out.Empty, "")
}
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") == "" {
home := os.Getenv("HOME")
console.Warning("kubectl and minikube configuration will be stored in %s", home)
console.Warning("To use kubectl or minikube commands as your own user, you may")
console.Warning("need to relocate them. For example, to overwrite your own settings:")
out.WarningT("kubectl and minikube configuration will be stored in {{.home_folder}}", out.V{"home_folder": home})
out.WarningT("To use kubectl or minikube commands as your own user, you may")
out.WarningT("need to relocate them. For example, to overwrite your own settings:")
console.OutLn("")
console.OutStyle(console.Command, "sudo mv %s/.kube %s/.minikube $HOME", home, home)
console.OutStyle(console.Command, "sudo chown -R $USER $HOME/.kube $HOME/.minikube")
console.OutLn("")
out.T(out.Empty, "")
out.T(out.Command, "sudo mv {{.home_folder}}/.kube {{.home_folder}}/.minikube $HOME", out.V{"home_folder": home})
out.T(out.Command, "sudo chown -R $USER $HOME/.kube $HOME/.minikube")
out.T(out.Empty, "")
console.OutStyle(console.Tip, "This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true")
out.T(out.Tip, "This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true")
}
if err := pkgutil.MaybeChownDirRecursiveToMinikubeUser(constants.GetMinipath()); err != nil {
exit.WithCode(exit.Permissions, "Failed to chown %s: %v", constants.GetMinipath(), err)
exit.WithCodeT(exit.Permissions, "Failed to chown {{.minikube_dir_path}}: {{.error}}", out.V{"minikube_dir_path": constants.GetMinipath(), "error": err})
}
}
@ -681,14 +688,14 @@ func validateNetwork(h *host.Host) string {
for _, k := range proxy.EnvVars {
if v := os.Getenv(k); v != "" {
if !optSeen {
console.OutStyle(console.Internet, "Found network options:")
out.T(out.Internet, "Found network options:")
optSeen = true
}
console.OutStyle(console.Option, "%s=%s", k, v)
out.T(out.Option, "{{.key}}={{.value}}", out.V{"key": k, "value": v})
ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY
k = strings.ToUpper(k) // for http_proxy & https_proxy
if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !ipExcluded && !warnedOnce {
console.Warning("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP (%s). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details", ip)
out.WarningT("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details", out.V{"ip_address": ip})
warnedOnce = true
}
}
@ -708,7 +715,7 @@ func validateKubernetesVersions(old *cfg.Config) (string, bool) {
nvs, err := semver.Make(strings.TrimPrefix(rawVersion, version.VersionPrefix))
if err != nil {
exit.WithCode(exit.Data, "Unable to parse %q: %v", rawVersion, err)
exit.WithCodeT(exit.Data, `Unable to parse "{{.kubenretes_version}}": {{.error}}`, out.V{"kubenretes_version": rawVersion, "error": err})
}
nv := version.VersionPrefix + nvs.String()
@ -723,11 +730,11 @@ func validateKubernetesVersions(old *cfg.Config) (string, bool) {
if nvs.LT(ovs) {
nv = version.VersionPrefix + ovs.String()
console.ErrT(console.Conflict, "Kubernetes downgrade is not supported, will continue to use {{.version}}", console.Arg{"version": nv})
out.ErrT(out.Conflict, "Kubernetes downgrade is not supported, will continue to use {{.version}}", out.V{"version": nv})
return nv, isUpgrade
}
if nvs.GT(ovs) {
console.OutT(console.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}", console.Arg{"old": ovs, "new": nvs})
out.T(out.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}", out.V{"old": ovs, "new": nvs})
isUpgrade = true
}
return nv, isUpgrade
@ -740,7 +747,7 @@ func setupKubeAdm(mAPI libmachine.API, kc cfg.KubernetesConfig) bootstrapper.Boo
exit.WithError("Failed to get bootstrapper", err)
}
for _, eo := range extraOptions {
console.OutStyle(console.Option, "%s.%s=%s", eo.Component, eo.Key, eo.Value)
out.T(out.Option, "{{.extra_option_component_name}}.{{.key}}={{.value}}", out.V{"extra_option_component_name": eo.Component, "key": eo.Key, "value": eo.Value})
}
// Loads cached images, generates config files, download binaries
if err := bs.UpdateCluster(kc); err != nil {
@ -785,7 +792,7 @@ func configureRuntimes(runner cruntime.CommandRunner) cruntime.Manager {
config := cruntime.Config{Type: viper.GetString(containerRuntime), Runner: runner}
cr, err := cruntime.New(config)
if err != nil {
exit.WithError(fmt.Sprintf("Failed runtime for %+v", config), err)
exit.WithError("Failed runtime", err)
}
disableOthers := true
@ -806,21 +813,21 @@ func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner c
bsName := viper.GetString(cmdcfg.Bootstrapper)
if isUpgrade || !preexisting {
console.OutStyle(console.Pulling, "Pulling images ...")
out.T(out.Pulling, "Pulling images ...")
if err := bs.PullImages(kc); err != nil {
console.OutT(console.FailureType, "Unable to pull images, which may be OK: {{.error}}", console.Arg{"error": err})
out.T(out.FailureType, "Unable to pull images, which may be OK: {{.error}}", out.V{"error": err})
}
}
if preexisting {
console.OutT(console.Restarting, "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ", console.Arg{"version": kc.KubernetesVersion, "bootstrapper": bsName})
out.T(out.Restarting, "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ", out.V{"version": kc.KubernetesVersion, "bootstrapper": bsName})
if err := bs.RestartCluster(kc); err != nil {
exit.WithLogEntries("Error restarting cluster", err, logs.FindProblems(r, bs, runner))
}
return
}
console.OutStyle(console.Launch, "Launching Kubernetes ... ")
out.T(out.Launch, "Launching Kubernetes ... ")
if err := bs.StartCluster(kc); err != nil {
exit.WithLogEntries("Error starting cluster", err, logs.FindProblems(r, bs, runner))
}
@ -832,7 +839,7 @@ func configureMounts() {
return
}
console.OutT(console.Mounting, "Creating mount {{.name}} ...", console.Arg{"name": viper.GetString(mountString)})
out.T(out.Mounting, "Creating mount {{.name}} ...", out.V{"name": viper.GetString(mountString)})
path := os.Args[0]
mountDebugVal := 0
if glog.V(8) {
@ -904,7 +911,7 @@ func validateDriverVersion(vmDriver string) {
// we don't want to fail if an error was returned,
// libmachine has a nice message for the user if the driver isn't present
if err != nil {
console.Warning("Error checking driver version: %v", err)
out.WarningT("Error checking driver version: {{.error}}", out.V{"error": err})
return
}
@ -912,23 +919,23 @@ func validateDriverVersion(vmDriver string) {
// if the driver doesn't have return any version, it is really old, we force a upgrade.
if len(v) == 0 {
exit.WithCode(exit.Failure, "Please upgrade the 'docker-machine-driver-kvm2'. %s", constants.KVMDocumentation)
exit.WithCodeT(exit.Failure, "Please upgrade the 'docker-machine-driver-kvm2'. {{.documentation_url}}", out.V{"documentation_url": constants.KVMDocumentation})
}
vmDriverVersion, err := semver.Make(v)
if err != nil {
console.Warning("Error parsing vmDriver version: %v", err)
out.WarningT("Error parsing vmDriver version: {{.error}}", out.V{"error": err})
return
}
minikubeVersion, err := version.GetSemverVersion()
if err != nil {
console.Warning("Error parsing minukube version: %v", err)
out.WarningT("Error parsing minukube version: {{.error}}", out.V{"error": err})
return
}
if vmDriverVersion.LT(minikubeVersion) {
console.Warning("The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. %s", constants.KVMDocumentation)
out.WarningT("The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. {{.documentation_url}}", out.V{"documentation_url": constants.KVMDocumentation})
}
}
}

View File

@ -31,6 +31,7 @@ import (
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
pkgutil "k8s.io/minikube/pkg/util"
)
@ -61,7 +62,7 @@ var statusCmd = &cobra.Command{
var returnCode = 0
api, err := machine.NewAPIClient()
if err != nil {
exit.WithCode(exit.Unavailable, "Error getting client: %v", err)
exit.WithCodeT(exit.Unavailable, "Error getting client: {{.error}}", out.V{"error": err})
}
defer api.Close()

View File

@ -26,10 +26,10 @@ import (
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
pkg_config "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
pkgutil "k8s.io/minikube/pkg/util"
)
@ -57,7 +57,7 @@ func runStop(cmd *cobra.Command, args []string) {
err = cluster.StopHost(api)
switch err := errors.Cause(err).(type) {
case mcnerror.ErrHostDoesNotExist:
console.OutStyle(console.Meh, "%q VM does not exist, nothing to stop", profile)
out.T(out.Meh, `"{{.profile_name}}" VM does not exist, nothing to stop`, out.V{"profile_name": profile})
nonexistent = true
return nil
default:
@ -68,11 +68,11 @@ func runStop(cmd *cobra.Command, args []string) {
exit.WithError("Unable to stop VM", err)
}
if !nonexistent {
console.OutStyle(console.Stopped, "%q stopped.", profile)
out.T(out.Stopped, `"{{.profile_name}}" stopped.`, out.V{"profile_name": profile})
}
if err := cmdUtil.KillMountProcess(); err != nil {
console.OutStyle(console.WarningType, "Unable to kill mount process: %s", err)
out.T(out.WarningType, "Unable to kill mount process: {{.error}}", out.V{"error": err})
}
machineName := pkg_config.GetMachineName()

View File

@ -18,10 +18,10 @@ package cmd
import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/notify"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/version"
)
@ -41,11 +41,11 @@ var updateCheckCmd = &cobra.Command{
}
if len(r) < 1 {
exit.WithCode(exit.Data, "Update server returned an empty list")
exit.WithCodeT(exit.Data, "Update server returned an empty list")
}
console.OutLn("CurrentVersion: %s", version.GetVersion())
console.OutLn("LatestVersion: %s", r[0].Name)
out.Ln("CurrentVersion: %s", version.GetVersion())
out.Ln("LatestVersion: %s", r[0].Name)
},
}

View File

@ -20,10 +20,10 @@ import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/util"
)
@ -49,9 +49,9 @@ var updateContextCmd = &cobra.Command{
exit.WithError("update config", err)
}
if updated {
console.OutStyle(console.Celebrate, "%s IP has been updated to point at %s", machineName, ip)
out.T(out.Celebrate, "{{.machine}} IP has been updated to point at {{.ip}}", out.V{"machine": machineName, "ip": ip})
} else {
console.OutStyle(console.Meh, "%s IP was already correctly configured for %s", machineName, ip)
out.T(out.Meh, "{{.machine}} IP was already correctly configured for {{.ip}}", out.V{"machine": machineName, "ip": ip})
}
},

View File

@ -18,7 +18,7 @@ package cmd
import (
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/version"
)
@ -31,10 +31,10 @@ var versionCmd = &cobra.Command{
enableUpdateNotification = false
},
Run: func(command *cobra.Command, args []string) {
console.OutLn("minikube version: %v", version.GetVersion())
out.Ln("minikube version: %v", version.GetVersion())
gitCommitID := version.GetGitCommitID()
if gitCommitID != "" {
console.OutLn("commit: %v", gitCommitID)
out.Ln("commit: %v", gitCommitID)
}
},
}

View File

@ -26,9 +26,9 @@ import (
"github.com/golang/glog"
"github.com/pkg/profile"
"k8s.io/minikube/cmd/minikube/cmd"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/translate"
_ "k8s.io/minikube/pkg/provision"
)
@ -45,8 +45,8 @@ func main() {
if os.Getenv(constants.IsMinikubeChildProcess) == "" {
machine.StartDriver()
}
console.SetOutFile(os.Stdout)
console.SetErrFile(os.Stderr)
out.SetOutFile(os.Stdout)
out.SetErrFile(os.Stderr)
translate.DetermineLocale()
cmd.Execute()
}

View File

@ -2,7 +2,7 @@ apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
kubernetes.io/minikube-addons: registry-proxy
kubernetes.io/minikube-addons: registry
addonmanager.kubernetes.io/mode: Reconcile
name: registry-proxy
namespace: kube-system
@ -10,7 +10,7 @@ spec:
template:
metadata:
labels:
kubernetes.io/minikube-addons: registry-proxy
kubernetes.io/minikube-addons: registry
addonmanager.kubernetes.io/mode: Reconcile
spec:
containers:

View File

@ -13,6 +13,7 @@ spec:
template:
metadata:
labels:
actual-registry: "true"
kubernetes.io/minikube-addons: registry
addonmanager.kubernetes.io/mode: Reconcile
spec:

View File

@ -12,4 +12,5 @@ spec:
- port: 80
targetPort: 5000
selector:
actual-registry: "true"
kubernetes.io/minikube-addons: registry

View File

@ -11,3 +11,4 @@ sha256 346f9394393ee8db5f8bd1e229ee9d90e5b36931bdd754308b2ae68884dd6822 docker-
sha256 99ca9395e9c7ffbf75537de71aa828761f492491d02bc6e29db2920fa582c6c5 docker-18.09.5.tgz
sha256 1f3f6774117765279fce64ee7f76abbb5f260264548cf80631d68fb2d795bb09 docker-18.09.6.tgz
sha256 e106ccfa2b1f60794faaa6bae57a2dac9dc4cb33e5541fad6a826ea525d01cc4 docker-18.09.7.tgz
sha256 12277eff64363f51ba2f20dd258bdc2c3248022996c0251921193ec6fd179e52 docker-18.09.8.tgz

View File

@ -4,7 +4,7 @@
#
################################################################################
DOCKER_BIN_VERSION = 18.09.7
DOCKER_BIN_VERSION = 18.09.8
DOCKER_BIN_SITE = https://download.docker.com/linux/static/stable/x86_64
DOCKER_BIN_SOURCE = docker-$(DOCKER_BIN_VERSION).tgz

View File

@ -38,10 +38,10 @@ import (
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/util"
)
@ -305,7 +305,7 @@ func (k *Bootstrapper) WaitCluster(k8s config.KubernetesConfig) error {
// by a CNI plugin which is usually started after minikube has been brought
// up. Otherwise, minikube won't start, as "k8s-app" pods are not ready.
componentsOnly := k8s.NetworkPlugin == "cni"
console.OutT(console.WaitingPods, "Verifying:")
out.T(out.WaitingPods, "Verifying:")
client, err := util.GetClient()
if err != nil {
return errors.Wrap(err, "k8s client")
@ -313,7 +313,7 @@ func (k *Bootstrapper) WaitCluster(k8s config.KubernetesConfig) error {
// Wait until the apiserver can answer queries properly. We don't care if the apiserver
// pod shows up as registered, but need the webserver for all subsequent queries.
console.Out(" apiserver")
out.String(" apiserver")
if err := k.waitForAPIServer(k8s); err != nil {
return errors.Wrap(err, "waiting for apiserver")
}
@ -323,13 +323,13 @@ func (k *Bootstrapper) WaitCluster(k8s config.KubernetesConfig) error {
continue
}
console.Out(" %s", p.name)
out.String(" %s", p.name)
selector := labels.SelectorFromSet(labels.Set(map[string]string{p.key: p.value}))
if err := util.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil {
return errors.Wrap(err, fmt.Sprintf("waiting for %s=%s", p.key, p.value))
}
}
console.OutLn("")
out.Ln("")
return nil
}
@ -483,7 +483,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
_, images := constants.GetKubeadmCachedImages(cfg.ImageRepository, cfg.KubernetesVersion)
if cfg.ShouldLoadCachedImages {
if err := machine.LoadImages(k.c, images, constants.ImageCacheDir); err != nil {
console.FailureT("Unable to load cached images: {{.error}}", console.Arg{"error": err})
out.FailureT("Unable to load cached images: {{.error}}", out.V{"error": err})
}
}
r, err := cruntime.New(cruntime.Config{Type: cfg.ContainerRuntime, Socket: cfg.CRISocket})

View File

@ -42,9 +42,9 @@ import (
"github.com/shirou/gopsutil/mem"
"github.com/spf13/viper"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/registry"
"k8s.io/minikube/pkg/util"
pkgutil "k8s.io/minikube/pkg/util"
@ -75,12 +75,10 @@ func init() {
// CacheISO downloads and caches ISO.
func CacheISO(config cfg.MachineConfig) error {
if config.VMDriver != constants.DriverNone {
if err := config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO); err != nil {
return err
}
if localDriver(config.VMDriver) {
return nil
}
return nil
return config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO)
}
// StartHost starts a host VM.
@ -103,14 +101,14 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
}
if h.Driver.DriverName() != config.VMDriver {
console.Out("\n")
console.Warning("Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.",
config.VMDriver, cfg.GetMachineName(), h.Driver.DriverName())
console.Warning("To switch drivers, you may create a new VM using `minikube start -p <name> --vm-driver=%s`", config.VMDriver)
console.Warning("Alternatively, you may delete the existing VM using `minikube delete -p %s`", cfg.GetMachineName())
console.Out("\n")
out.T(out.Empty, "\n")
out.WarningT(`Ignoring --vm-driver={{.driver_name}}, as the existing "{{.profile_name}}" VM was created using the {{.driver_name2}} driver.`,
out.V{"driver_name": config.VMDriver, "profile_name": cfg.GetMachineName(), "driver_name2": h.Driver.DriverName()})
out.WarningT("To switch drivers, you may create a new VM using `minikube start -p <name> --vm-driver={{.driver_name}}`", out.V{"driver_name": config.VMDriver})
out.WarningT("Alternatively, you may delete the existing VM using `minikube delete -p {{.profile_name}}`", out.V{"profile_name": cfg.GetMachineName()})
out.T(out.Empty, "\n")
} else if exists && cfg.GetMachineName() == constants.DefaultMachineName {
console.OutStyle(console.Tip, "Tip: Use 'minikube start -p <name>' to create a new cluster, or 'minikube delete' to delete this one.")
out.T(out.Tip, "Tip: Use 'minikube start -p <name>' to create a new cluster, or 'minikube delete' to delete this one.")
}
s, err := h.Driver.GetState()
@ -120,9 +118,9 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
}
if s == state.Running {
console.OutStyle(console.Running, "Re-using the currently running %s VM for %q ...", h.Driver.DriverName(), cfg.GetMachineName())
out.T(out.Running, `Re-using the currently running {{.driver_name}} VM for "{{.profile_name}}" ...`, out.V{"driver_name": h.Driver.DriverName(), "profile_name": cfg.GetMachineName()})
} else {
console.OutStyle(console.Restarting, "Restarting existing %s VM for %q ...", h.Driver.DriverName(), cfg.GetMachineName())
out.T(out.Restarting, `Restarting existing {{.driver_name}} VM for "{{.profile_name}}" ...`, out.V{"driver_name": h.Driver.DriverName(), "profile_name": cfg.GetMachineName()})
if err := h.Driver.Start(); err != nil {
return nil, errors.Wrap(err, "start")
}
@ -141,23 +139,35 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
return h, nil
}
// localDriver returns whether or not the driver should be considered local
func localDriver(name string) bool {
if name == constants.DriverNone || name == constants.DriverMock {
return true
}
return false
}
// configureHost handles any post-powerup configuration required
func configureHost(h *host.Host, e *engine.Options) error {
glog.Infof("configureHost: %T %+v", h, h)
// Slightly counter-intuitive, but this is what DetectProvisioner & ConfigureAuth block on.
console.OutStyle(console.Waiting, "Waiting for SSH access ...")
out.T(out.Waiting, "Waiting for SSH access ...", out.V{})
if len(e.Env) > 0 {
h.HostOptions.EngineOptions.Env = e.Env
glog.Infof("Detecting provisioner ...")
provisioner, err := provision.DetectProvisioner(h.Driver)
if err != nil {
return errors.Wrap(err, "detecting provisioner")
}
glog.Infof("Provisioning: %+v", *h.HostOptions)
if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil {
return errors.Wrap(err, "provision")
}
}
if h.Driver.DriverName() != constants.DriverNone {
if !localDriver(h.Driver.DriverName()) {
glog.Infof("Configuring auth for driver %s ...", h.Driver.DriverName())
if err := h.ConfigureAuth(); err != nil {
return &util.RetriableError{Err: errors.Wrap(err, "Error configuring auth on host")}
}
@ -227,7 +237,7 @@ func trySSHPowerOff(h *host.Host) {
return
}
console.OutStyle(console.Shutdown, "Powering off %q via SSH ...", cfg.GetMachineName())
out.T(out.Shutdown, `Powering off "{{.profile_name}}" via SSH ...`, out.V{"profile_name": cfg.GetMachineName()})
out, err := h.RunSSHCommand("sudo poweroff")
// poweroff always results in an error, since the host disconnects.
glog.Infof("poweroff result: out=%s, err=%v", out, err)
@ -239,7 +249,7 @@ func StopHost(api libmachine.API) error {
if err != nil {
return errors.Wrapf(err, "load")
}
console.OutStyle(console.Stopping, "Stopping %q in %s ...", cfg.GetMachineName(), host.DriverName)
out.T(out.Stopping, `Stopping "{{.profile_name}}" in {{.driver_name}} ...`, out.V{"profile_name": cfg.GetMachineName(), "driver_name": host.DriverName})
if err := host.Stop(); err != nil {
alreadyInStateError, ok := err.(mcnerror.ErrHostAlreadyInState)
if ok && alreadyInStateError.State == state.Stopped {
@ -261,7 +271,7 @@ func DeleteHost(api libmachine.API) error {
trySSHPowerOff(host)
}
console.OutStyle(console.DeletingHost, "Deleting %q from %s ...", cfg.GetMachineName(), host.DriverName)
out.T(out.DeletingHost, `Deleting "{{.profile_name}}" in {{.driver_name}} ...`, out.V{"profile_name": cfg.GetMachineName(), "driver_name": host.DriverName})
if err := host.Driver.Remove(); err != nil {
return errors.Wrap(err, "host remove")
}
@ -357,26 +367,26 @@ func getHostInfo() (*hostInfo, error) {
func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error) {
if config.VMDriver == constants.DriverVmwareFusion && viper.GetBool(cfg.ShowDriverDeprecationNotification) {
console.Warning(`The vmwarefusion driver is deprecated and support for it will be removed in a future release.
out.WarningT(`The vmwarefusion driver is deprecated and support for it will be removed in a future release.
Please consider switching to the new vmware unified driver, which is intended to replace the vmwarefusion driver.
See https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#vmware-unified-driver for more information.
To disable this message, run [minikube config set ShowDriverDeprecationNotification false]`)
}
if config.VMDriver != constants.DriverNone {
console.OutStyle(console.StartingVM, "Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...", config.VMDriver, config.CPUs, config.Memory, config.DiskSize)
if !localDriver(config.VMDriver) {
out.T(out.StartingVM, "Creating {{.driver_name}} VM (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...", out.V{"driver_name": config.VMDriver, "number_of_cpus": config.CPUs, "memory_size": config.Memory, "disk_size": config.DiskSize})
} else {
info, err := getHostInfo()
if err == nil {
console.OutStyle(console.StartingNone, "Running on localhost (CPUs=%d, Memory=%dMB, Disk=%dMB) ...", info.CPUs, info.Memory, info.DiskSize)
out.T(out.StartingNone, "Running on localhost (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...", out.V{"number_of_cpus": info.CPUs, "memory_size": info.Memory, "disk_size": info.DiskSize})
}
}
def, err := registry.Driver(config.VMDriver)
if err != nil {
if err == registry.ErrDriverNotFound {
exit.Usage("unsupported driver: %s", config.VMDriver)
return nil, fmt.Errorf("unsupported driver: %s", config.VMDriver)
}
exit.WithError("error getting driver", err)
return nil, errors.Wrap(err, "error getting driver")
}
driver := def.ConfigCreator(config)
@ -534,6 +544,6 @@ func EnsureMinikubeRunningOrExit(api libmachine.API, exitStatus int) {
exit.WithError("Error getting machine status", err)
}
if s != state.Running.String() {
exit.WithCode(exit.Unavailable, "minikube is not running, so the service cannot be accessed")
exit.WithCodeT(exit.Unavailable, "minikube is not running, so the service cannot be accessed")
}
}

View File

@ -37,14 +37,40 @@ type MockDownloader struct{}
func (d MockDownloader) GetISOFileURI(isoURL string) string { return "" }
func (d MockDownloader) CacheMinikubeISOFromURL(isoURL string) error { return nil }
func createMockDriverHost(c config.MachineConfig) interface{} {
return nil
}
func RegisterMockDriver(t *testing.T) {
t.Helper()
_, err := registry.Driver(constants.DriverMock)
// Already registered
if err == nil {
return
}
err = registry.Register(registry.DriverDef{
Name: constants.DriverMock,
Builtin: true,
ConfigCreator: createMockDriverHost,
DriverCreator: func() drivers.Driver {
return &tests.MockDriver{T: t}
},
})
if err != nil {
t.Fatalf("register failed: %v", err)
}
}
var defaultMachineConfig = config.MachineConfig{
VMDriver: constants.DefaultVMDriver,
VMDriver: constants.DriverMock,
MinikubeISO: constants.DefaultISOURL,
Downloader: MockDownloader{},
DockerEnv: []string{"MOCK_MAKE_IT_PROVISION=true"},
}
func TestCreateHost(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
exists, _ := api.Exists(config.GetMachineName())
if exists {
@ -54,9 +80,12 @@ func TestCreateHost(t *testing.T) {
if err != nil {
t.Fatalf("Error creating host: %v", err)
}
exists, _ = api.Exists(config.GetMachineName())
exists, err = api.Exists(config.GetMachineName())
if err != nil {
t.Fatalf("exists failed for %q: %v", config.GetMachineName(), err)
}
if !exists {
t.Fatal("Machine does not exist, but should.")
t.Fatalf("%q does not exist, but should.", config.GetMachineName())
}
h, err := api.Load(config.GetMachineName())
@ -82,7 +111,8 @@ func TestCreateHost(t *testing.T) {
}
func TestStartHostExists(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
// Create an initial host.
_, err := createHost(api, defaultMachineConfig)
if err != nil {
@ -101,10 +131,10 @@ func TestStartHostExists(t *testing.T) {
// This should pass without calling Create because the host exists already.
h, err := StartHost(api, defaultMachineConfig)
if err != nil {
t.Fatal("Error starting host.")
t.Fatalf("Error starting host: %v", err)
}
if h.Name != config.GetMachineName() {
t.Fatalf("Machine created with incorrect name: %s", h.Name)
t.Fatalf("GetMachineName()=%q, want %q", config.GetMachineName(), h.Name)
}
if s, _ := h.Driver.GetState(); s != state.Running {
t.Fatalf("Machine not started.")
@ -115,13 +145,14 @@ func TestStartHostExists(t *testing.T) {
}
func TestStartStoppedHost(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
// Create an initial host.
h, err := createHost(api, defaultMachineConfig)
if err != nil {
t.Fatalf("Error creating host: %v", err)
}
d := tests.MockDriver{}
d := tests.MockDriver{T: t}
h.Driver = &d
d.CurrentState = state.Stopped
@ -149,7 +180,8 @@ func TestStartStoppedHost(t *testing.T) {
}
func TestStartHost(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
md := &tests.MockDetector{Provisioner: &tests.MockProvisioner{}}
provision.SetDetector(md)
@ -159,7 +191,7 @@ func TestStartHost(t *testing.T) {
t.Fatal("Error starting host.")
}
if h.Name != config.GetMachineName() {
t.Fatalf("Machine created with incorrect name: %s", h.Name)
t.Fatalf("GetMachineName()=%q, want %q", config.GetMachineName(), h.Name)
}
if exists, _ := api.Exists(h.Name); !exists {
t.Fatal("Machine not saved.")
@ -176,7 +208,8 @@ func TestStartHost(t *testing.T) {
}
func TestStartHostConfig(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
md := &tests.MockDetector{Provisioner: &tests.MockProvisioner{}}
provision.SetDetector(md)
@ -208,14 +241,16 @@ func TestStartHostConfig(t *testing.T) {
}
func TestStopHostError(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
if err := StopHost(api); err == nil {
t.Fatal("An error should be thrown when stopping non-existing machine.")
}
}
func TestStopHost(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
h, err := createHost(api, defaultMachineConfig)
if err != nil {
t.Errorf("createHost failed: %v", err)
@ -230,7 +265,8 @@ func TestStopHost(t *testing.T) {
}
func TestDeleteHost(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
if _, err := createHost(api, defaultMachineConfig); err != nil {
t.Errorf("createHost failed: %v", err)
}
@ -241,14 +277,14 @@ func TestDeleteHost(t *testing.T) {
}
func TestDeleteHostErrorDeletingVM(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
h, err := createHost(api, defaultMachineConfig)
if err != nil {
t.Errorf("createHost failed: %v", err)
}
d := &tests.MockDriver{RemoveError: true}
d := &tests.MockDriver{RemoveError: true, T: t}
h.Driver = d
if err := DeleteHost(api); err == nil {
@ -257,7 +293,8 @@ func TestDeleteHostErrorDeletingVM(t *testing.T) {
}
func TestDeleteHostErrorDeletingFiles(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
api.RemoveError = true
if _, err := createHost(api, defaultMachineConfig); err != nil {
t.Errorf("createHost failed: %v", err)
@ -269,7 +306,8 @@ func TestDeleteHostErrorDeletingFiles(t *testing.T) {
}
func TestGetHostStatus(t *testing.T) {
api := tests.NewMockAPI()
RegisterMockDriver(t)
api := tests.NewMockAPI(t)
checkState := func(expected string) {
s, err := GetHostStatus(api)
@ -296,10 +334,11 @@ func TestGetHostStatus(t *testing.T) {
}
func TestGetHostDockerEnv(t *testing.T) {
RegisterMockDriver(t)
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
api := tests.NewMockAPI()
api := tests.NewMockAPI(t)
h, err := createHost(api, defaultMachineConfig)
if err != nil {
t.Fatalf("Error creating host: %v", err)
@ -308,6 +347,7 @@ func TestGetHostDockerEnv(t *testing.T) {
BaseDriver: drivers.BaseDriver{
IPAddress: "127.0.0.1",
},
T: t,
}
h.Driver = d
@ -332,7 +372,7 @@ func TestGetHostDockerEnvIPv6(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
api := tests.NewMockAPI()
api := tests.NewMockAPI(t)
h, err := createHost(api, defaultMachineConfig)
if err != nil {
t.Fatalf("Error creating host: %v", err)
@ -341,6 +381,7 @@ func TestGetHostDockerEnvIPv6(t *testing.T) {
BaseDriver: drivers.BaseDriver{
IPAddress: "fe80::215:5dff:fe00:a903",
},
T: t,
}
h.Driver = d
@ -357,9 +398,9 @@ func TestGetHostDockerEnvIPv6(t *testing.T) {
}
func TestCreateSSHShell(t *testing.T) {
api := tests.NewMockAPI()
api := tests.NewMockAPI(t)
s, _ := tests.NewSSHServer()
s, _ := tests.NewSSHServer(t)
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %v", err)
@ -372,6 +413,7 @@ func TestCreateSSHShell(t *testing.T) {
IPAddress: "127.0.0.1",
SSHKeyPath: "",
},
T: t,
}
api.Hosts[config.GetMachineName()] = &host.Host{Driver: d}

View File

@ -96,6 +96,7 @@ func decode(r io.Reader) (MinikubeConfig, error) {
// GetMachineName gets the machine name for the VM
func GetMachineName() string {
// REFACTOR NECESSARY: This function should not rely on globals.
if viper.GetString(MachineProfile) == "" {
return constants.DefaultMachineName
}
@ -109,7 +110,7 @@ func Load() (*Config, error) {
// Loader loads the kubernetes and machine config based on the machine profile name
type Loader interface {
LoadConfigFromFile(profile string) (*Config, error)
LoadConfigFromFile(profile string, miniHome ...string) (*Config, error)
}
type simpleConfigLoader struct{}
@ -117,10 +118,10 @@ type simpleConfigLoader struct{}
// DefaultLoader is the default config loader
var DefaultLoader Loader = &simpleConfigLoader{}
func (c *simpleConfigLoader) LoadConfigFromFile(profile string) (*Config, error) {
func (c *simpleConfigLoader) LoadConfigFromFile(profile string, miniHome ...string) (*Config, error) {
var cc Config
path := constants.GetProfileFile(profile)
path := constants.GetProfileFile(profile, miniHome...)
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil, err

View File

@ -0,0 +1,84 @@
/*
Copyright 2019 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 (
"io/ioutil"
"path/filepath"
"k8s.io/minikube/pkg/minikube/constants"
)
// isValid checks if the profile has the essential info needed for a profile
func (p *Profile) isValid() bool {
if p.Config.MachineConfig.VMDriver == "" {
return false
}
if p.Config.KubernetesConfig.KubernetesVersion == "" {
return false
}
return true
}
// ListProfiles returns all valid and invalid (if any) minikube profiles
// invalidPs are the profiles that have a directory or config file but not usable
// invalidPs would be suggeted to be deleted
func ListProfiles(miniHome ...string) (validPs []*Profile, inValidPs []*Profile, err error) {
pDirs, err := profileDirs(miniHome...)
if err != nil {
return nil, nil, err
}
for _, n := range pDirs {
p, err := loadProfile(n, miniHome...)
if err != nil {
inValidPs = append(inValidPs, p)
continue
}
if !p.isValid() {
inValidPs = append(inValidPs, p)
continue
}
validPs = append(validPs, p)
}
return validPs, inValidPs, nil
}
// loadProfile loads type Profile based on its name
func loadProfile(name string, miniHome ...string) (*Profile, error) {
cfg, err := DefaultLoader.LoadConfigFromFile(name, miniHome...)
p := &Profile{
Name: name,
Config: cfg,
}
return p, err
}
// profileDirs gets all the folders in the user's profiles folder regardless of valid or invalid config
func profileDirs(miniHome ...string) (dirs []string, err error) {
miniPath := constants.GetMinipath()
if len(miniHome) > 0 {
miniPath = miniHome[0]
}
pRootDir := filepath.Join(miniPath, "profiles")
items, err := ioutil.ReadDir(pRootDir)
for _, f := range items {
if f.IsDir() {
dirs = append(dirs, f.Name())
}
}
return dirs, err
}

View File

@ -0,0 +1,72 @@
/*
Copyright 2019 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 (
"path/filepath"
"testing"
)
func TestListProfiles(t *testing.T) {
miniDir, err := filepath.Abs("./testdata/.minikube")
if err != nil {
t.Errorf("error getting dir path for ./testdata/.minikube : %v", err)
}
// test cases for valid profiles
var testCasesValidProfs = []struct {
index int
expectName string
vmDriver string
}{
{0, "p1", "hyperkit"},
{1, "p2", "virtualbox"},
}
// test cases for invalid profiles
var testCasesInValidProfs = []struct {
index int
expectName string
vmDriver string
}{
{0, "p3_empty", ""},
{1, "p4_invalid_file", ""},
{2, "p5_partial_config", ""},
}
val, inv, err := ListProfiles(miniDir)
for _, tt := range testCasesValidProfs {
if val[tt.index].Name != tt.expectName {
t.Errorf("expected %s got %v", tt.expectName, val[tt.index].Name)
}
if val[tt.index].Config.MachineConfig.VMDriver != tt.vmDriver {
t.Errorf("expected %s got %v", tt.vmDriver, val[tt.index].Config.MachineConfig.VMDriver)
}
}
// making sure it returns the invalid profiles
for _, tt := range testCasesInValidProfs {
if inv[tt.index].Name != tt.expectName {
t.Errorf("expected %s got %v", tt.expectName, inv[tt.index].Name)
}
}
if err != nil {
t.Errorf("error listing profiles %v", err)
}
}

View File

@ -0,0 +1,50 @@
{
"MachineConfig": {
"KeepContext": false,
"MinikubeISO": "https://storage.googleapis.com/minikube/iso/minikube-v1.2.0.iso",
"Memory": 2000,
"CPUs": 2,
"DiskSize": 20000,
"VMDriver": "hyperkit",
"ContainerRuntime": "docker",
"HyperkitVpnKitSock": "",
"HyperkitVSockPorts": [],
"XhyveDiskDriver": "ahci-hd",
"DockerEnv": null,
"InsecureRegistry": null,
"RegistryMirror": null,
"HostOnlyCIDR": "192.168.99.1/24",
"HypervVirtualSwitch": "",
"KVMNetwork": "default",
"KVMQemuURI": "qemu:///system",
"KVMGPU": false,
"KVMHidden": false,
"DockerOpt": null,
"DisableDriverMounts": false,
"NFSShare": [],
"NFSSharesRoot": "/nfsshares",
"UUID": "",
"NoVTXCheck": false,
"DNSProxy": false,
"HostDNSResolver": true
},
"KubernetesConfig": {
"KubernetesVersion": "v1.15.0",
"NodeIP": "192.168.64.75",
"NodePort": 8443,
"NodeName": "minikube",
"APIServerName": "minikubeCA",
"APIServerNames": null,
"APIServerIPs": null,
"DNSDomain": "cluster.local",
"ContainerRuntime": "docker",
"CRISocket": "",
"NetworkPlugin": "",
"FeatureGates": "",
"ServiceCIDR": "10.96.0.0/12",
"ImageRepository": "",
"ExtraOptions": null,
"ShouldLoadCachedImages": true,
"EnableDefaultCNI": false
}
}

View File

@ -0,0 +1,49 @@
{
"MachineConfig": {
"KeepContext": false,
"MinikubeISO": "https://storage.googleapis.com/minikube/iso/minikube-v1.2.0.iso",
"Memory": 2000,
"CPUs": 2,
"DiskSize": 20000,
"VMDriver": "virtualbox",
"ContainerRuntime": "docker",
"HyperkitVpnKitSock": "",
"HyperkitVSockPorts": [],
"DockerEnv": null,
"InsecureRegistry": null,
"RegistryMirror": null,
"HostOnlyCIDR": "192.168.99.1/24",
"HypervVirtualSwitch": "",
"KVMNetwork": "default",
"KVMQemuURI": "qemu:///system",
"KVMGPU": false,
"KVMHidden": false,
"DockerOpt": null,
"DisableDriverMounts": false,
"NFSShare": [],
"NFSSharesRoot": "/nfsshares",
"UUID": "",
"NoVTXCheck": false,
"DNSProxy": false,
"HostDNSResolver": true
},
"KubernetesConfig": {
"KubernetesVersion": "v1.15.0",
"NodeIP": "192.168.99.136",
"NodePort": 8443,
"NodeName": "minikube",
"APIServerName": "minikubeCA",
"APIServerNames": null,
"APIServerIPs": null,
"DNSDomain": "cluster.local",
"ContainerRuntime": "docker",
"CRISocket": "",
"NetworkPlugin": "",
"FeatureGates": "",
"ServiceCIDR": "10.96.0.0/12",
"ImageRepository": "",
"ExtraOptions": null,
"ShouldLoadCachedImages": true,
"EnableDefaultCNI": false
}
}

View File

@ -0,0 +1 @@
invalid json file :)

View File

@ -0,0 +1,47 @@
{
"MachineConfig": {
"KeepContext": false,
"MinikubeISO": "https://storage.googleapis.com/minikube/iso/minikube-v1.2.0.iso",
"Memory": 2000,
"CPUs": 2,
"DiskSize": 20000,
"ContainerRuntime": "docker",
"HyperkitVpnKitSock": "",
"HyperkitVSockPorts": [],
"XhyveDiskDriver": "ahci-hd",
"DockerEnv": null,
"InsecureRegistry": null,
"RegistryMirror": null,
"HostOnlyCIDR": "192.168.99.1/24",
"HypervVirtualSwitch": "",
"KVMNetwork": "default",
"KVMQemuURI": "qemu:///system",
"KVMGPU": false,
"KVMHidden": false,
"DockerOpt": null,
"DisableDriverMounts": false,
"NFSShare": [],
"NFSSharesRoot": "/nfsshares",
"UUID": "",
"NoVTXCheck": false,
"DNSProxy": false,
"HostDNSResolver": true
},
"KubernetesConfig": {
"NodePort": 8443,
"NodeName": "minikube",
"APIServerName": "minikubeCA",
"APIServerNames": null,
"APIServerIPs": null,
"DNSDomain": "cluster.local",
"ContainerRuntime": "docker",
"CRISocket": "",
"NetworkPlugin": "",
"FeatureGates": "",
"ServiceCIDR": "10.96.0.0/12",
"ImageRepository": "",
"ExtraOptions": null,
"ShouldLoadCachedImages": true,
"EnableDefaultCNI": false
}
}

View File

@ -22,6 +22,12 @@ import (
"k8s.io/minikube/pkg/util"
)
// Profile represents a minikube profile
type Profile struct {
Name string
Config *Config
}
// Config contains machine and k8s config
type Config struct {
MachineConfig MachineConfig

View File

@ -59,6 +59,9 @@ func ArchTag(hasTag bool) string {
return "-" + runtime.GOARCH + ":"
}
// DriverMock is a mock driver.
const DriverMock = "mock-driver"
// DriverNone is the none driver.
const DriverNone = "none"
@ -188,13 +191,21 @@ var ConfigFilePath = MakeMiniPath("config")
var ConfigFile = MakeMiniPath("config", "config.json")
// GetProfileFile returns the Minikube profile config file
func GetProfileFile(profile string) string {
return filepath.Join(GetMinipath(), "profiles", profile, "config.json")
func GetProfileFile(profile string, miniHome ...string) string {
miniPath := GetMinipath()
if len(miniHome) > 0 {
miniPath = miniHome[0]
}
return filepath.Join(miniPath, "profiles", profile, "config.json")
}
// GetProfilePath returns the Minikube profile path of config file
func GetProfilePath(profile string) string {
return filepath.Join(GetMinipath(), "profiles", profile)
func GetProfilePath(profile string, miniHome ...string) string {
miniPath := GetMinipath()
if len(miniHome) > 0 {
miniPath = miniHome[0]
}
return filepath.Join(miniPath, "profiles", profile)
}
// AddonsPath is the default path of the addons configuration

View File

@ -21,7 +21,7 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
// Containerd contains containerd runtime state
@ -36,8 +36,8 @@ func (r *Containerd) Name() string {
}
// Style is the console style for containerd
func (r *Containerd) Style() console.StyleEnum {
return console.Containerd
func (r *Containerd) Style() out.StyleEnum {
return out.Containerd
}
// Version retrieves the current version of this runtime

View File

@ -21,7 +21,7 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
// CRIO contains CRIO runtime state
@ -36,8 +36,8 @@ func (r *CRIO) Name() string {
}
// Style is the console style for CRIO
func (r *CRIO) Style() console.StyleEnum {
return console.CRIO
func (r *CRIO) Style() out.StyleEnum {
return out.CRIO
}
// Version retrieves the current version of this runtime

View File

@ -22,7 +22,7 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
// CommandRunner is the subset of command.Runner this package consumes
@ -46,7 +46,7 @@ type Manager interface {
// Available returns an error if it is not possible to use this runtime on a host
Available() error
// Style is an associated StyleEnum for Name()
Style() console.StyleEnum
Style() out.StyleEnum
// KubeletOptions returns kubelet options for a runtime.
KubeletOptions() map[string]string

View File

@ -22,7 +22,7 @@ import (
"strings"
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
)
// KubernetesContainerPrefix is the prefix of each kubernetes container
@ -40,8 +40,8 @@ func (r *Docker) Name() string {
}
// Style is the console style for Docker
func (r *Docker) Style() console.StyleEnum {
return console.Docker
func (r *Docker) Style() out.StyleEnum {
return out.Docker
}
// Version retrieves the current version of this runtime

View File

@ -23,7 +23,7 @@ import (
"runtime"
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/problem"
"k8s.io/minikube/pkg/minikube/translate"
)
@ -45,29 +45,15 @@ const (
MaxLogEntries = 3
)
// Usage outputs a usage error and exits with error code 64
func Usage(format string, a ...interface{}) {
console.ErrStyle(console.Usage, format, a...)
os.Exit(BadUsage)
}
// UsageT outputs a templated usage error and exits with error code 64
func UsageT(format string, a ...console.Arg) {
console.ErrT(console.Usage, format, a...)
func UsageT(format string, a ...out.V) {
out.ErrT(out.Usage, format, a...)
os.Exit(BadUsage)
}
// WithCode outputs a fatal error message and exits with a supplied error code.
func WithCode(code int, format string, a ...interface{}) {
// use Warning because Error will display a duplicate message to stderr
glog.Warningf(format, a...)
console.Fatal(format, a...)
os.Exit(code)
}
// WithCodeT outputs a templated fatal error message and exits with the supplied error code.
func WithCodeT(code int, format string, a ...console.Arg) {
console.FatalT(format, a...)
func WithCodeT(code int, format string, a ...out.V) {
out.FatalT(format, a...)
os.Exit(code)
}
@ -83,12 +69,12 @@ func WithError(msg string, err error) {
// WithProblem outputs info related to a known problem and exits.
func WithProblem(msg string, p *problem.Problem) {
console.Err("\n")
console.FatalT(msg)
out.ErrT(out.Empty, "")
out.FatalT(msg)
p.Display()
console.Err("\n")
console.ErrT(console.Sad, "If the above advice does not help, please let us know: ")
console.ErrT(console.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
out.ErrT(out.Empty, "")
out.ErrT(out.Sad, "If the above advice does not help, please let us know: ")
out.ErrT(out.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
os.Exit(Config)
}
@ -97,12 +83,12 @@ func WithLogEntries(msg string, err error, entries map[string][]string) {
displayError(msg, err)
for name, lines := range entries {
console.OutT(console.FailureType, "Problems detected in {{.entry}}:", console.Arg{"entry": name})
out.T(out.FailureType, "Problems detected in {{.entry}}:", out.V{"entry": name})
if len(lines) > MaxLogEntries {
lines = lines[:MaxLogEntries]
}
for _, l := range lines {
console.OutT(console.LogEntry, l)
out.T(out.LogEntry, l)
}
}
os.Exit(Software)
@ -111,9 +97,9 @@ func WithLogEntries(msg string, err error, entries map[string][]string) {
func displayError(msg string, err error) {
// use Warning because Error will display a duplicate message to stderr
glog.Warningf(fmt.Sprintf("%s: %v", msg, err))
console.Err("\n")
console.FatalT("{{.msg}}: {{.err}}", console.Arg{"msg": translate.T(msg), "err": err})
console.Err("\n")
console.ErrT(console.Sad, "Sorry that minikube crashed. If this was unexpected, we would love to hear from you:")
console.ErrT(console.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
out.ErrT(out.Empty, "")
out.FatalT("{{.msg}}: {{.err}}", out.V{"msg": translate.T(msg), "err": err})
out.ErrT(out.Empty, "")
out.ErrT(out.Sad, "Sorry that minikube crashed. If this was unexpected, we would love to hear from you:")
out.ErrT(out.URL, "https://github.com/kubernetes/minikube/issues/new/choose")
}

View File

@ -23,8 +23,6 @@ import (
"path/filepath"
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestExtract(t *testing.T) {
@ -81,70 +79,3 @@ func TestExtract(t *testing.T) {
}
}
func TestTranslationsUpToDate(t *testing.T) {
// Move the working dir to where we would run `make extract` from
cwd, err := os.Getwd()
if err != nil {
t.Fatalf("Getting current working dir: %v", err)
}
err = os.Chdir("../../..")
if err != nil {
t.Fatalf("Chdir failed: %v", err)
}
defer func() {
if err = os.Chdir(cwd); err != nil {
t.Logf("Chdir to cwd failed: %v", err)
}
}()
// The translation file we're going to check
exampleFile := "translations/fr-FR.json"
src, err := ioutil.ReadFile(exampleFile)
if err != nil {
t.Fatalf("Reading json file: %v", err)
}
// Create a temp file to run the extractor on
tempdir, err := ioutil.TempDir("", "temptestdata")
if err != nil {
t.Fatalf("Creating temp dir: %v", err)
}
defer os.RemoveAll(tempdir)
tempfile := filepath.Join(tempdir, "tmpdata.json")
err = ioutil.WriteFile(tempfile, src, 0666)
if err != nil {
t.Fatalf("Writing temp json file: %v", err)
}
// Run the extractor exactly how `make extract` would run, but on the temp file
err = TranslatableStrings([]string{"cmd", "pkg"}, []string{"translate.T"}, tempdir)
if err != nil {
t.Fatalf("Error translating strings: %v", err)
}
dest, err := ioutil.ReadFile(tempfile)
if err != nil {
t.Fatalf("Reading resulting json file: %v", err)
}
var got map[string]interface{}
var want map[string]interface{}
err = json.Unmarshal(dest, &got)
if err != nil {
t.Fatalf("Populating resulting json: %v", err)
}
err = json.Unmarshal(src, &want)
if err != nil {
t.Fatalf("Populating original json: %v", err)
}
if diff := cmp.Diff(want, got); diff != "" {
t.Fatalf("Localized string mismatch (-want, +got):\n%s\n\nRun `make extract` to fix.", diff)
}
}

View File

@ -29,8 +29,8 @@ import (
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/cruntime"
"k8s.io/minikube/pkg/minikube/out"
)
// rootCauseRe is a regular expression that matches known failure root causes
@ -100,12 +100,12 @@ func FindProblems(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner comma
// OutputProblems outputs discovered problems.
func OutputProblems(problems map[string][]string, maxLines int) {
for name, lines := range problems {
console.OutStyle(console.FailureType, "Problems detected in %q:", name)
out.T(out.FailureType, "Problems detected in {{.name}}:", out.V{"name": name})
if len(lines) > maxLines {
lines = lines[len(lines)-maxLines:]
}
for _, l := range lines {
console.OutStyle(console.LogEntry, l)
out.T(out.LogEntry, l)
}
}
}
@ -126,9 +126,9 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run
failed := []string{}
for i, name := range names {
if i > 0 {
console.OutLn("")
out.T(out.Empty, "")
}
console.OutLn("==> %s <==", name)
out.T(out.Empty, "==> {{.name}} <==", out.V{"name": name})
var b bytes.Buffer
err := runner.CombinedOutputTo(cmds[name], &b)
if err != nil {
@ -138,7 +138,7 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run
}
scanner := bufio.NewScanner(&b)
for scanner.Scan() {
console.OutLn(scanner.Text())
out.T(out.Empty, scanner.Text())
}
}
if len(failed) > 0 {

View File

@ -29,8 +29,8 @@ import (
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
)
// CacheBinariesForBootstrapper will cache binaries for a bootstrapper
@ -78,7 +78,7 @@ func CacheBinary(binary, version, osName, archName string) (string, error) {
options.Checksum = constants.GetKubernetesReleaseURLSHA1(binary, version, osName, archName)
options.ChecksumHash = crypto.SHA1
console.OutT(console.FileDownload, "Downloading {{.name}} {{.version}}", console.Arg{"name": binary, "version": version})
out.T(out.FileDownload, "Downloading {{.name}} {{.version}}", out.V{"name": binary, "version": version})
if err := download.ToFile(url, targetFilepath, options); err != nil {
return "", errors.Wrapf(err, "Error downloading %s %s", binary, version)
}

View File

@ -41,9 +41,9 @@ import (
"github.com/docker/machine/libmachine/version"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/registry"
"k8s.io/minikube/pkg/minikube/sshutil"
"k8s.io/minikube/pkg/provision"
@ -147,6 +147,9 @@ func (api *LocalClient) Close() error {
// CommandRunner returns best available command runner for this host
func CommandRunner(h *host.Host) (command.Runner, error) {
if h.DriverName == constants.DriverMock {
return &command.FakeCommandRunner{}, nil
}
if h.DriverName == constants.DriverNone {
return &command.ExecRunner{}, nil
}
@ -270,7 +273,7 @@ func registerDriver(driverName string) {
def, err := registry.Driver(driverName)
if err != nil {
if err == registry.ErrDriverNotFound {
exit.UsageT("unsupported driver: {{.name}}", console.Arg{"name": driverName})
exit.UsageT("unsupported driver: {{.name}}", out.V{"name": driverName})
}
exit.WithError("error getting driver", err)
}

View File

@ -30,8 +30,8 @@ import (
"github.com/pkg/errors"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/version"
)
@ -67,8 +67,8 @@ func MaybePrintUpdateText(url string, lastUpdatePath string) {
glog.Errorf("write time failed: %v", err)
}
url := fmt.Sprintf("%s/%s", updateLinkPrefix, latestVersion)
console.ErrT(console.WarningType, `minikube {{.version}} is available! Download it: {{.url}}`, console.Arg{"version": latestVersion, "url": url})
console.OutT(console.Tip, "To disable this notice, run: 'minikube config set WantUpdateNotification false'")
out.ErrT(out.WarningType, `minikube {{.version}} is available! Download it: {{.url}}`, out.V{"version": latestVersion, "url": url})
out.T(out.Tip, "To disable this notice, run: 'minikube config set WantUpdateNotification false'")
}
}

View File

@ -29,7 +29,7 @@ import (
"github.com/blang/semver"
"github.com/spf13/viper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/tests"
"k8s.io/minikube/pkg/version"
)
@ -151,7 +151,7 @@ func TestMaybePrintUpdateText(t *testing.T) {
viper.Set(config.ReminderWaitPeriodInHours, 24)
outputBuffer := tests.NewFakeFile()
console.SetErrFile(outputBuffer)
out.SetErrFile(outputBuffer)
lastUpdateCheckFilePath := filepath.Join(tempDir, "last_update_check")
// test that no update text is printed if the latest version is lower/equal to the current version

View File

@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package console provides a mechanism for sending localized, stylized output to the console.
package console
// Package out provides a mechanism for sending localized, stylized output to the console.
package out
import (
"fmt"
@ -31,12 +31,12 @@ import (
// By design, this package uses global references to language and output objects, in preference
// to passing a console object throughout the code base. Typical usage is:
//
// console.SetOutFile(os.Stdout)
// console.Out("Starting up!")
// console.OutStyle(console.StatusChange, "Configuring things")
// out.SetOutFile(os.Stdout)
// out.String("Starting up!")
// out.T(out.StatusChange, "Configuring things")
// console.SetErrFile(os.Stderr)
// console.Fatal("Oh no, everything failed.")
// out.SetErrFile(os.Stderr)
// out.Fatal("Oh no, everything failed.")
// NOTE: If you do not want colorized output, set MINIKUBE_IN_STYLE=false in your environment.
@ -57,23 +57,17 @@ type fdWriter interface {
Fd() uintptr
}
// Arg is a convenience wrapper for templating
type Arg map[string]interface{}
// V is a convenience wrapper for templating, it represents the variable key/value pair.
type V map[string]interface{}
// OutStyle writes a stylized and formatted message to stdout
func OutStyle(style StyleEnum, format string, a ...interface{}) {
outStyled := applyStyle(style, useColor, format)
Out(outStyled, a...)
}
// OutT writes a stylized and templated message to stdout
func OutT(style StyleEnum, format string, a ...Arg) {
// T writes a stylized and templated message to stdout
func T(style StyleEnum, format string, a ...V) {
outStyled := applyTemplateFormatting(style, useColor, format, a...)
Out(outStyled)
String(outStyled)
}
// Out writes a basic formatted string to stdout
func Out(format string, a ...interface{}) {
// String writes a basic formatted string to stdout
func String(format string, a ...interface{}) {
if outFile == nil {
glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...))
return
@ -84,19 +78,13 @@ func Out(format string, a ...interface{}) {
}
}
// OutLn writes a basic formatted string with a newline to stdout
func OutLn(format string, a ...interface{}) {
Out(format+"\n", a...)
}
// ErrStyle writes a stylized and formatted error message to stderr
func ErrStyle(style StyleEnum, format string, a ...interface{}) {
errStyled := applyStyle(style, useColor, format)
Err(errStyled, a...)
// Ln writes a basic formatted string with a newline to stdout
func Ln(format string, a ...interface{}) {
String(format+"\n", a...)
}
// ErrT writes a stylized and templated error message to stderr
func ErrT(style StyleEnum, format string, a ...Arg) {
func ErrT(style StyleEnum, format string, a ...V) {
errStyled := applyTemplateFormatting(style, useColor, format, a...)
Err(errStyled)
}
@ -118,43 +106,23 @@ func ErrLn(format string, a ...interface{}) {
Err(format+"\n", a...)
}
// Success is a shortcut for writing a styled success message to stdout
func Success(format string, a ...interface{}) {
OutStyle(SuccessType, format, a...)
}
// Fatal is a shortcut for writing a styled fatal message to stderr
func Fatal(format string, a ...interface{}) {
ErrStyle(FatalType, format, a...)
}
// Warning is a shortcut for writing a styled warning message to stderr
func Warning(format string, a ...interface{}) {
ErrStyle(WarningType, format, a...)
}
// Failure is a shortcut for writing a styled failure message to stderr
func Failure(format string, a ...interface{}) {
ErrStyle(FailureType, format, a...)
}
// SuccessT is a shortcut for writing a templated success message to stdout
func SuccessT(format string, a ...Arg) {
OutT(SuccessType, format, a...)
func SuccessT(format string, a ...V) {
T(SuccessType, format, a...)
}
// FatalT is a shortcut for writing a templated fatal message to stderr
func FatalT(format string, a ...Arg) {
func FatalT(format string, a ...V) {
ErrT(FatalType, format, a...)
}
// WarningT is a shortcut for writing a templated warning message to stderr
func WarningT(format string, a ...Arg) {
func WarningT(format string, a ...V) {
ErrT(WarningType, format, a...)
}
// FailureT is a shortcut for writing a templated failure message to stderr
func FailureT(format string, a ...Arg) {
func FailureT(format string, a ...V) {
ErrT(FailureType, format, a...)
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package console
package out
import (
"fmt"
@ -26,52 +26,6 @@ import (
"k8s.io/minikube/pkg/minikube/translate"
)
func TestOutStyle(t *testing.T) {
// Set the system locale to Arabic and define a dummy translation file.
if err := translate.SetPreferredLanguage("ar"); err != nil {
t.Fatalf("SetPreferredLanguage: %v", err)
}
translate.Translations = map[string]interface{}{
"Installing Kubernetes version %s ...": "... %s تثبيت Kubernetes الإصدار",
}
var testCases = []struct {
style StyleEnum
message string
params []interface{}
want string
wantASCII string
}{
{Happy, "Happy", nil, "😄 Happy\n", "* Happy\n"},
{Option, "Option", nil, " ▪ Option\n", " - Option\n"},
{WarningType, "Warning", nil, "⚠️ Warning\n", "! Warning\n"},
{FatalType, "Fatal: %v", []interface{}{"ugh"}, "💣 Fatal: ugh\n", "X Fatal: ugh\n"},
{WaitingPods, "wait", nil, "⌛ wait", "* wait"},
{Issue, "http://i/%d", []interface{}{10000}, " ▪ http://i/10000\n", " - http://i/10000\n"},
{Usage, "raw: %s %s", []interface{}{"'%'", "%d"}, "💡 raw: '%' %d\n", "* raw: '%' %d\n"},
{Running, "Installing Kubernetes version %s ...", []interface{}{"v1.13"}, "🏃 ... v1.13 تثبيت Kubernetes الإصدار\n", "* ... v1.13 تثبيت Kubernetes الإصدار\n"},
}
for _, tc := range testCases {
for _, override := range []bool{true, false} {
t.Run(fmt.Sprintf("%s-override-%v", tc.message, override), func(t *testing.T) {
// Set MINIKUBE_IN_STYLE=<override>
os.Setenv(OverrideEnv, strconv.FormatBool(override))
f := tests.NewFakeFile()
SetOutFile(f)
OutStyle(tc.style, tc.message, tc.params...)
got := f.String()
want := tc.wantASCII
if override {
want = tc.want
}
if got != want {
t.Errorf("OutStyle() = %q (%d runes), want %q (%d runes)", got, len(got), want, len(want))
}
})
}
}
}
func TestOutT(t *testing.T) {
// Set the system locale to Arabic and define a dummy translation file.
if err := translate.SetPreferredLanguage("ar"); err != nil {
@ -84,18 +38,18 @@ func TestOutT(t *testing.T) {
var testCases = []struct {
style StyleEnum
message string
params Arg
params V
want string
wantASCII string
}{
{Happy, "Happy", nil, "😄 Happy\n", "* Happy\n"},
{Option, "Option", nil, " ▪ Option\n", " - Option\n"},
{WarningType, "Warning", nil, "⚠️ Warning\n", "! Warning\n"},
{FatalType, "Fatal: {{.error}}", Arg{"error": "ugh"}, "💣 Fatal: ugh\n", "X Fatal: ugh\n"},
{FatalType, "Fatal: {{.error}}", V{"error": "ugh"}, "💣 Fatal: ugh\n", "X Fatal: ugh\n"},
{WaitingPods, "wait", nil, "⌛ wait", "* wait"},
{Issue, "http://i/{{.number}}", Arg{"number": 10000}, " ▪ http://i/10000\n", " - http://i/10000\n"},
{Usage, "raw: {{.one}} {{.two}}", Arg{"one": "'%'", "two": "%d"}, "💡 raw: '%' %d\n", "* raw: '%' %d\n"},
{Running, "Installing Kubernetes version {{.version}} ...", Arg{"version": "v1.13"}, "🏃 ... v1.13 تثبيت Kubernetes الإصدار\n", "* ... v1.13 تثبيت Kubernetes الإصدار\n"},
{Issue, "http://i/{{.number}}", V{"number": 10000}, " ▪ http://i/10000\n", " - http://i/10000\n"},
{Usage, "raw: {{.one}} {{.two}}", V{"one": "'%'", "two": "%d"}, "💡 raw: '%' %d\n", "* raw: '%' %d\n"},
{Running, "Installing Kubernetes version {{.version}} ...", V{"version": "v1.13"}, "🏃 ... v1.13 تثبيت Kubernetes الإصدار\n", "* ... v1.13 تثبيت Kubernetes الإصدار\n"},
}
for _, tc := range testCases {
for _, override := range []bool{true, false} {
@ -104,7 +58,7 @@ func TestOutT(t *testing.T) {
os.Setenv(OverrideEnv, strconv.FormatBool(override))
f := tests.NewFakeFile()
SetOutFile(f)
OutT(tc.style, tc.message, tc.params)
T(tc.style, tc.message, tc.params)
got := f.String()
want := tc.wantASCII
if override {
@ -136,9 +90,9 @@ func TestOut(t *testing.T) {
SetOutFile(f)
ErrLn("unrelated message")
if tc.arg == nil {
Out(tc.format)
String(tc.format)
} else {
Out(tc.format, tc.arg)
String(tc.format, tc.arg)
}
got := f.String()
if got != tc.want {
@ -153,7 +107,7 @@ func TestErr(t *testing.T) {
f := tests.NewFakeFile()
SetErrFile(f)
Err("xyz123 %s\n", "%s%%%d")
OutLn("unrelated message")
Ln("unrelated message")
got := f.String()
want := "xyz123 %s%%%d\n"
@ -161,15 +115,3 @@ func TestErr(t *testing.T) {
t.Errorf("Err() = %q, want %q", got, want)
}
}
func TestErrStyle(t *testing.T) {
os.Setenv(OverrideEnv, "1")
f := tests.NewFakeFile()
SetErrFile(f)
ErrStyle(FatalType, "error: %s", "%s%%%d")
got := f.String()
want := "💣 error: %s%%%d\n"
if got != want {
t.Errorf("ErrStyle() = %q, want %q", got, want)
}
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package console
package out
import (
"bytes"
@ -49,6 +49,7 @@ type style struct {
// styles is a map of style name to style struct
// For consistency, ensure that emojis added render with the same width across platforms.
var styles = map[StyleEnum]style{
Empty: {Prefix: "", LowPrefix: ""},
Happy: {Prefix: "😄 "},
SuccessType: {Prefix: "✅ "},
FailureType: {Prefix: "❌ "},
@ -152,9 +153,9 @@ func applyStyle(style StyleEnum, useColor bool, format string) string {
return applyPrefix(s.Prefix, format)
}
func applyTemplateFormatting(style StyleEnum, useColor bool, format string, a ...Arg) string {
func applyTemplateFormatting(style StyleEnum, useColor bool, format string, a ...V) string {
if a == nil {
a = []Arg{Arg{}}
a = []V{V{}}
}
format = applyStyle(style, useColor, format)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package console
package out
// StyleEnum is an enumeration of Style
type StyleEnum int
@ -80,4 +80,5 @@ const (
Unmount
MountOptions
Fileserver
Empty
)

View File

@ -21,7 +21,7 @@ import (
"fmt"
"regexp"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/translate"
)
@ -53,21 +53,21 @@ type match struct {
// Display problem metadata to the console
func (p *Problem) Display() {
console.ErrT(console.FailureType, "Error: [{{.id}}] {{.error}}", console.Arg{"id": p.ID, "error": p.Err})
console.ErrT(console.Tip, "Suggestion: {{.advice}}", console.Arg{"advice": translate.T(p.Advice)})
out.ErrT(out.FailureType, "Error: [{{.id}}] {{.error}}", out.V{"id": p.ID, "error": p.Err})
out.ErrT(out.Tip, "Suggestion: {{.advice}}", out.V{"advice": translate.T(p.Advice)})
if p.URL != "" {
console.ErrT(console.Documentation, "Documentation: {{.url}}", console.Arg{"url": p.URL})
out.ErrT(out.Documentation, "Documentation: {{.url}}", out.V{"url": p.URL})
}
if len(p.Issues) == 0 {
return
}
console.ErrT(console.Issues, "Related issues:")
out.ErrT(out.Issues, "Related issues:")
issues := p.Issues
if len(issues) > 3 {
issues = issues[0:3]
}
for _, i := range issues {
console.ErrT(console.Issue, "{{.url}}", console.Arg{"url": fmt.Sprintf("%s/%d", issueBase, i)})
out.ErrT(out.Issue, "{{.url}}", out.V{"url": fmt.Sprintf("%s/%d", issueBase, i)})
}
}

View File

@ -41,8 +41,8 @@ import (
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/proxy"
"k8s.io/minikube/pkg/util"
)
@ -284,7 +284,7 @@ func WaitAndMaybeOpenService(api libmachine.API, namespace string, service strin
}
if len(urls) == 0 {
console.OutStyle(console.Sad, "service %s/%s has no node port", namespace, service)
out.T(out.Sad, "service {{.namespace_name}}/{{.service_name}} has no node port", out.V{"namespace_name": namespace, "service_name": service})
return nil
}
@ -292,11 +292,11 @@ func WaitAndMaybeOpenService(api libmachine.API, namespace string, service strin
urlString, isHTTPSchemedURL := OptionallyHTTPSFormattedURLString(bareURLString, https)
if urlMode || !isHTTPSchemedURL {
console.OutLn(urlString)
out.T(out.Empty, urlString)
} else {
console.OutStyle(console.Celebrate, "Opening kubernetes service %s/%s in default browser...", namespace, service)
out.T(out.Celebrate, "Opening kubernetes service {{.namespace_name}}/{{.service_name}} in default browser...", out.V{"namespace_name": namespace, "service_name": service})
if err := browser.OpenURL(urlString); err != nil {
console.Err("browser failed to open url: %v", err)
out.ErrT(out.Empty, "browser failed to open url: {{.error}}", out.V{"error": err})
}
}
}

View File

@ -25,37 +25,43 @@ import (
)
func TestNewSSHClient(t *testing.T) {
s, _ := tests.NewSSHServer()
s, err := tests.NewSSHServer(t)
if err != nil {
t.Fatalf("NewSSHServer: %v", err)
}
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %v", err)
}
defer s.Stop()
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
IPAddress: "127.0.0.1",
SSHKeyPath: "",
},
T: t,
}
c, err := NewSSHClient(d)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
defer c.Close()
cmd := "foo"
sess, err := c.NewSession()
if err != nil {
t.Fatal("Error creating new session for ssh client")
}
defer sess.Close()
cmd := "foo"
if err := sess.Run(cmd); err != nil {
t.Fatalf("Error running command: %s", cmd)
t.Fatalf("Error running %q: %v", cmd, err)
}
if !s.Connected {
t.Fatalf("Error!")
t.Fatalf("Server not connected")
}
if _, ok := s.Commands[cmd]; !ok {
t.Fatalf("Expected command: %s", cmd)
}

View File

@ -19,10 +19,15 @@ package tests
import (
"encoding/json"
"fmt"
"math/rand"
"testing"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/swarm"
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/viper"
)
// MockAPI is a struct used to mock out libmachine.API
@ -31,18 +36,31 @@ type MockAPI struct {
CreateError bool
RemoveError bool
SaveCalled bool
t *testing.T
}
// NewMockAPI returns a new MockAPI
func NewMockAPI() *MockAPI {
func NewMockAPI(t *testing.T) *MockAPI {
t.Helper()
m := MockAPI{
FakeStore: FakeStore{
Hosts: make(map[string]*host.Host),
T: t,
},
t: t,
}
return &m
}
// Logf logs mock interactions
func (api *MockAPI) Logf(format string, args ...interface{}) {
if api.t == nil {
glog.Infof(format, args...)
return
}
api.t.Logf(format, args...)
}
// Close closes the API.
func (api *MockAPI) Close() error {
return nil
@ -54,21 +72,44 @@ func (api *MockAPI) NewHost(driverName string, rawDriver []byte) (*host.Host, er
if err := json.Unmarshal(rawDriver, &driver); err != nil {
return nil, errors.Wrap(err, "error unmarshalling json")
}
h := &host.Host{
DriverName: driverName,
RawDriver: rawDriver,
Driver: &MockDriver{},
Name: driver.GetMachineName(),
HostOptions: &host.Options{AuthOptions: &auth.Options{}},
DriverName: driverName,
RawDriver: rawDriver,
Driver: &MockDriver{},
Name: fmt.Sprintf("mock-machine-%.8f", rand.Float64()),
HostOptions: &host.Options{
AuthOptions: &auth.Options{},
SwarmOptions: &swarm.Options{},
},
}
// HACK: Make future calls to config.GetMachineName() work properly.
api.Logf("MockAPI.NewHost: Setting profile=%q", h.Name)
viper.Set("profile", h.Name)
api.Logf("MockAPI.NewHost: %+v", h)
return h, nil
}
// Load a created mock
func (api *MockAPI) Load(name string) (*host.Host, error) {
h, err := api.FakeStore.Load(name)
api.Logf("MockAPI.Load: %+v - %v", h, err)
return h, err
}
// Create creates the actual host.
func (api *MockAPI) Create(h *host.Host) error {
api.Logf("MockAPI.Create: %+v", h)
if api.CreateError {
return errors.New("error creating host")
}
// Propagate test info messages
drv, ok := h.Driver.(*MockDriver)
if ok {
drv.T = api.t
}
return h.Driver.Create()
}
@ -79,6 +120,7 @@ func (api *MockAPI) List() ([]string, error) {
// Remove a host.
func (api *MockAPI) Remove(name string) error {
api.Logf("MockAPI.Delete: %s", name)
if api.RemoveError {
return fmt.Errorf("error removing %s", name)
}
@ -90,6 +132,7 @@ func (api *MockAPI) Remove(name string) error {
// Save saves a host to disk.
func (api *MockAPI) Save(host *host.Host) error {
api.SaveCalled = true
api.Logf("MockAPI.Save: %+v", host)
return api.FakeStore.Save(host)
}

View File

@ -17,9 +17,14 @@ limitations under the License.
package tests
import (
"testing"
"k8s.io/minikube/pkg/minikube/constants"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/state"
"github.com/golang/glog"
"github.com/pkg/errors"
)
@ -31,16 +36,28 @@ type MockDriver struct {
HostError bool
Port int
IP string
T *testing.T
}
// Logf logs mock interactions
func (driver *MockDriver) Logf(format string, args ...interface{}) {
if driver.T == nil {
glog.Infof(format, args...)
return
}
driver.T.Logf(format, args...)
}
// Create creates a MockDriver instance
func (driver *MockDriver) Create() error {
driver.Logf("MockDriver.Create")
driver.CurrentState = state.Running
return nil
}
// GetIP returns the IP address
func (driver *MockDriver) GetIP() (string, error) {
driver.Logf("MockDriver.GetIP")
if driver.IP != "" {
return driver.IP, nil
}
@ -75,6 +92,7 @@ func (driver *MockDriver) GetSSHKeyPath() string {
// GetState returns the state of the driver
func (driver *MockDriver) GetState() (state.State, error) {
driver.Logf("MockDriver.GetState: %v", driver.CurrentState)
return driver.CurrentState, nil
}
@ -85,12 +103,14 @@ func (driver *MockDriver) GetURL() (string, error) {
// Kill kills the machine
func (driver *MockDriver) Kill() error {
driver.Logf("MockDriver.Kill")
driver.CurrentState = state.Stopped
return nil
}
// Remove removes the machine
func (driver *MockDriver) Remove() error {
driver.Logf("MockDriver.Remove")
if driver.RemoveError {
return errors.New("error deleting machine")
}
@ -99,6 +119,7 @@ func (driver *MockDriver) Remove() error {
// Restart restarts the machine
func (driver *MockDriver) Restart() error {
driver.Logf("MockDriver.Restart")
driver.CurrentState = state.Running
return nil
}
@ -110,12 +131,20 @@ func (driver *MockDriver) SetConfigFromFlags(opts drivers.DriverOptions) error {
// Start starts the machine
func (driver *MockDriver) Start() error {
driver.Logf("MockDriver.Start")
driver.CurrentState = state.Running
return nil
}
// Stop stops the machine
func (driver *MockDriver) Stop() error {
driver.Logf("MockDriver.Stop")
driver.CurrentState = state.Stopped
return nil
}
// DriverName returns the name of the driver
func (driver *MockDriver) DriverName() string {
driver.Logf("MockDriver.Name")
return constants.DriverMock
}

View File

@ -17,6 +17,8 @@ limitations under the License.
package tests
import (
"testing"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/mcnerror"
)
@ -24,6 +26,7 @@ import (
// FakeStore implements persist.Store from libmachine
type FakeStore struct {
Hosts map[string]*host.Host
T *testing.T
}
// Exists determines if the host already exists.
@ -67,7 +70,7 @@ func (s *FakeStore) Remove(name string) error {
}
// Save persists a machine in the store
func (s *FakeStore) Save(host *host.Host) error {
s.Hosts[host.Name] = host
func (s *FakeStore) Save(h *host.Host) error {
s.Hosts[h.Name] = h
return nil
}

View File

@ -25,8 +25,8 @@ import (
"net"
"strconv"
"sync/atomic"
"testing"
"github.com/golang/glog"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
)
@ -43,16 +43,21 @@ type SSHServer struct {
// commandsToOutput can be used to mock what the SSHServer returns for a given command
// Only access this with atomic ops
commandToOutput atomic.Value
quit bool
listener net.Listener
t *testing.T
}
// NewSSHServer returns a NewSSHServer instance, ready for use.
func NewSSHServer() (*SSHServer, error) {
s := &SSHServer{}
s.Transfers = &bytes.Buffer{}
s.Config = &ssh.ServerConfig{
NoClientAuth: true,
func NewSSHServer(t *testing.T) (*SSHServer, error) {
t.Helper()
s := &SSHServer{
Transfers: &bytes.Buffer{},
Config: &ssh.ServerConfig{NoClientAuth: true},
Commands: map[string]int{},
t: t,
}
s.Commands = make(map[string]int)
private, err := rsa.GenerateKey(rand.Reader, 2014)
if err != nil {
@ -72,102 +77,103 @@ type execRequest struct {
Command string
}
// Main loop, listen for connections and store the commands.
func (s *SSHServer) mainLoop(listener net.Listener) {
go func() {
for {
nConn, err := listener.Accept()
go func() {
if err != nil {
return
}
_, chans, reqs, err := ssh.NewServerConn(nConn, s.Config)
if err != nil {
return
}
// The incoming Request channel must be serviced.
go ssh.DiscardRequests(reqs)
// Service the incoming Channel channel.
for newChannel := range chans {
if newChannel.ChannelType() == "session" {
s.SetSessionRequested(true)
}
channel, requests, err := newChannel.Accept()
s.Connected = true
if err != nil {
return
}
for req := range requests {
glog.Infoln("Got Req: ", req.Type)
// Store anything that comes in over stdin.
s.handleRequest(channel, req)
}
}
}()
// Serve loop, listen for connections and store the commands.
func (s *SSHServer) serve() {
for {
s.t.Logf("Accepting...")
c, err := s.listener.Accept()
if s.quit {
return
}
}()
if err != nil {
s.t.Errorf("Listener: %v", err)
return
}
go s.handleIncomingConnection(c)
}
}
// handle an incoming ssh connection
func (s *SSHServer) handleIncomingConnection(c net.Conn) {
_, chans, reqs, err := ssh.NewServerConn(c, s.Config)
if err != nil {
s.t.Logf("newserverconn error: %v", err)
return
}
// The incoming Request channel must be serviced.
go ssh.DiscardRequests(reqs)
// Service the incoming Channel channel.
for newChannel := range chans {
if newChannel.ChannelType() == "session" {
s.SetSessionRequested(true)
}
channel, requests, err := newChannel.Accept()
if err != nil {
s.t.Logf("ch accept err: %v", err)
return
}
s.Connected = true
for req := range requests {
s.handleRequest(channel, req)
}
}
}
func (s *SSHServer) handleRequest(channel ssh.Channel, req *ssh.Request) {
go func() {
if _, err := io.Copy(s.Transfers, channel); err != nil {
panic(fmt.Sprintf("copy failed: %v", err))
s.t.Errorf("copy failed: %v", err)
}
channel.Close()
}()
switch req.Type {
case "exec":
s.t.Logf("exec request received: %+v", req)
if err := req.Reply(true, nil); err != nil {
panic(fmt.Sprintf("reply failed: %v", err))
s.t.Errorf("reply failed: %v", err)
}
// Note: string(req.Payload) adds additional characters to start of input.
var cmd execRequest
if err := ssh.Unmarshal(req.Payload, &cmd); err != nil {
glog.Errorf("Unmarshall encountered error: %v with req: %v", err, req.Type)
return
s.t.Errorf("unmarshal failed: %v", err)
}
s.Commands[cmd.Command] = 1
// Write specified command output as mocked ssh output
if val, err := s.GetCommandToOutput(cmd.Command); err == nil {
if _, err := channel.Write([]byte(val)); err != nil {
glog.Errorf("Write failed: %v", err)
return
s.t.Errorf("Write failed: %v", err)
}
}
if _, err := channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0}); err != nil {
glog.Errorf("SendRequest failed: %v", err)
return
s.t.Errorf("SendRequest failed: %v", err)
}
case "pty-req":
s.t.Logf("pty request received: %+v", req)
if err := req.Reply(true, nil); err != nil {
glog.Errorf("Reply failed: %v", err)
return
s.t.Errorf("Reply failed: %v", err)
}
if _, err := channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0}); err != nil {
glog.Errorf("SendRequest failed: %v", err)
return
s.t.Errorf("SendRequest failed: %v", err)
}
}
}
// Start starts the mock SSH Server, and returns the port it's listening on.
// Start the mock SSH Server
func (s *SSHServer) Start() (int, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
return 0, errors.Wrap(err, "Error creating tcp listener for ssh server")
}
s.listener = l
s.t.Logf("Listening on %s", s.listener.Addr())
go s.serve()
s.mainLoop(listener)
// Parse and return the port.
_, p, err := net.SplitHostPort(listener.Addr().String())
_, p, err := net.SplitHostPort(s.listener.Addr().String())
if err != nil {
return 0, errors.Wrap(err, "Error splitting host port")
}
@ -178,6 +184,13 @@ func (s *SSHServer) Start() (int, error) {
return port, nil
}
// Stop the mock SSH server
func (s *SSHServer) Stop() {
s.t.Logf("Stopping")
s.quit = true
s.listener.Close()
}
// SetCommandToOutput sets command to output
func (s *SSHServer) SetCommandToOutput(cmdToOutput map[string]string) {
s.commandToOutput.Store(cmdToOutput)

View File

@ -34,7 +34,7 @@ import (
func TestAPIError(t *testing.T) {
machineName := "nonexistentmachine"
machineAPI := tests.NewMockAPI()
machineAPI := tests.NewMockAPI(t)
configLoader := &stubConfigLoader{}
inspector := &clusterInspector{
machineAPI, configLoader, machineName,

View File

@ -86,6 +86,6 @@ type stubConfigLoader struct {
e error
}
func (l *stubConfigLoader) LoadConfigFromFile(profile string) (*config.Config, error) {
func (l *stubConfigLoader) LoadConfigFromFile(profile string, miniHome ...string) (*config.Config, error) {
return l.c, l.e
}

View File

@ -25,8 +25,8 @@ import (
"github.com/golang/glog"
download "github.com/jimmidyson/go-download"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
)
const fileScheme = "file"
@ -76,7 +76,7 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
options.ChecksumHash = crypto.SHA256
}
console.OutStyle(console.ISODownload, "Downloading Minikube ISO ...")
out.T(out.ISODownload, "Downloading Minikube ISO ...")
if err := download.ToFile(isoURL, f.GetISOCacheFilepath(isoURL), options); err != nil {
return errors.Wrap(err, isoURL)
}

View File

@ -21,8 +21,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/user"
"path/filepath"
@ -32,9 +30,9 @@ import (
units "github.com/docker/go-units"
"github.com/golang/glog"
retryablehttp "github.com/hashicorp/go-retryablehttp"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/out"
)
// ErrPrefix notes an error
@ -62,7 +60,7 @@ func CalculateSizeInMB(humanReadableSize string) int {
}
size, err := units.FromHumanSize(humanReadableSize)
if err != nil {
exit.WithCode(exit.Config, "Invalid size passed in argument: %v", err)
exit.WithCodeT(exit.Config, "Invalid size passed in argument: {{.error}}", out.V{"error": err})
}
return int(size / units.MB)
@ -135,24 +133,6 @@ func RetryAfter(attempts int, callback func() error, d time.Duration) (err error
return m.ToError()
}
// ParseSHAFromURL downloads and reads a SHA checksum from an URL
func ParseSHAFromURL(url string) (string, error) {
r, err := retryablehttp.Get(url)
if err != nil {
return "", errors.Wrap(err, "Error downloading checksum.")
} else if r.StatusCode != http.StatusOK {
return "", errors.Errorf("Error downloading checksum. Got HTTP Error: %s", r.Status)
}
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return "", errors.Wrap(err, "Error reading checksum.")
}
return strings.Trim(string(body), "\n"), nil
}
// GetBinaryDownloadURL returns a suitable URL for the platform
func GetBinaryDownloadURL(version, platform string) string {
switch platform {

View File

@ -19,9 +19,6 @@ package util
import (
"bytes"
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
@ -88,45 +85,6 @@ func TestRetryNotRetriableError(t *testing.T) {
}
}
type getTestArgs struct {
input string
expected string
expectedError bool
}
var testSHAString = "test"
func TestParseSHAFromURL(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, err := io.WriteString(w, testSHAString); err != nil {
t.Fatalf("WriteString: %v", err)
}
}))
serverBadResponse := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
if _, err := w.Write([]byte("500 HTTP status code returned!")); err != nil {
t.Fatalf("Write: %v", err)
}
}))
argsList := [...]getTestArgs{
{server.URL, testSHAString, false},
{serverBadResponse.URL, "", true},
{"abc", "", true},
}
for _, args := range argsList {
url, err := ParseSHAFromURL(args.input)
wasError := err != nil
if wasError != args.expectedError {
t.Errorf("ParseSHAFromURL Expected error was: %t, Actual Error was: %s",
args.expectedError, err)
}
if url != args.expected {
t.Errorf("ParseSHAFromURL: Expected %s, Actual: %s", args.expected, url)
}
}
}
func TestMultiError(t *testing.T) {
m := MultiError{}

View File

@ -76,8 +76,8 @@ func readLineWithTimeout(b *bufio.Reader, timeout time.Duration) (string, error)
func testDashboard(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
cmd, out := minikubeRunner.RunDaemon("dashboard --url")
mk := NewMinikubeRunner(t, "--wait=false")
cmd, out := mk.RunDaemon("dashboard --url")
defer func() {
err := cmd.Process.Kill()
if err != nil {
@ -121,10 +121,10 @@ func testDashboard(t *testing.T) {
func testIngressController(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
kubectlRunner := util.NewKubectlRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
kr := util.NewKubectlRunner(t)
minikubeRunner.RunCommand("addons enable ingress", true)
mk.RunCommand("addons enable ingress", true)
if err := util.WaitForIngressControllerRunning(t); err != nil {
t.Fatalf("waiting for ingress-controller to be up: %v", err)
}
@ -138,12 +138,12 @@ func testIngressController(t *testing.T) {
t.Errorf("Error getting the file path for current directory: %s", curdir)
}
ingressPath := path.Join(curdir, "testdata", "nginx-ing.yaml")
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", ingressPath}); err != nil {
if _, err := kr.RunCommand([]string{"create", "-f", ingressPath}); err != nil {
t.Fatalf("creating nginx ingress resource: %v", err)
}
podPath := path.Join(curdir, "testdata", "nginx-pod-svc.yaml")
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", podPath}); err != nil {
if _, err := kr.RunCommand([]string{"create", "-f", podPath}); err != nil {
t.Fatalf("creating nginx ingress resource: %v", err)
}
@ -154,7 +154,7 @@ func testIngressController(t *testing.T) {
checkIngress := func() error {
expectedStr := "Welcome to nginx!"
runCmd := fmt.Sprintf("curl http://127.0.0.1:80 -H 'Host: nginx.example.com'")
sshCmdOutput, _ := minikubeRunner.SSH(runCmd)
sshCmdOutput, _ := mk.SSH(runCmd)
if !strings.Contains(sshCmdOutput, expectedStr) {
return fmt.Errorf("ExpectedStr sshCmdOutput to be: %s. Output was: %s", expectedStr, sshCmdOutput)
}
@ -167,20 +167,20 @@ func testIngressController(t *testing.T) {
defer func() {
for _, p := range []string{podPath, ingressPath} {
if out, err := kubectlRunner.RunCommand([]string{"delete", "-f", p}); err != nil {
if out, err := kr.RunCommand([]string{"delete", "-f", p}); err != nil {
t.Logf("delete -f %s failed: %v\noutput: %s\n", p, err, out)
}
}
}()
minikubeRunner.RunCommand("addons disable ingress", true)
mk.RunCommand("addons disable ingress", true)
}
func testServicesList(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t)
checkServices := func() error {
output := minikubeRunner.RunCommand("service list", false)
output := mk.RunCommand("service list", false)
if !strings.Contains(output, "kubernetes") {
return fmt.Errorf("Error, kubernetes service missing from output %s", output)
}
@ -192,51 +192,55 @@ func testServicesList(t *testing.T) {
}
func testRegistry(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
kubectlRunner := util.NewKubectlRunner(t)
minikubeRunner.RunCommand("addons enable registry", true)
t.Log("wait for registry to come up")
if err := util.WaitForDockerRegistryRunning(t); err != nil {
t.Fatalf("waiting for registry to be up: %v", err)
mk := NewMinikubeRunner(t)
mk.RunCommand("addons enable registry", true)
client, err := pkgutil.GetClient()
if err != nil {
t.Fatalf("getting kubernetes client: %v", err)
}
if err := pkgutil.WaitForRCToStabilize(client, "kube-system", "registry", time.Minute*5); err != nil {
t.Fatalf("waiting for registry replicacontroller to stabilize: %v", err)
}
rs := labels.SelectorFromSet(labels.Set(map[string]string{"actual-registry": "true"}))
if err := pkgutil.WaitForPodsWithLabelRunning(client, "kube-system", rs); err != nil {
t.Fatalf("waiting for registry pods: %v", err)
}
ps, err := labels.Parse("kubernetes.io/minikube-addons=registry,actual-registry!=true")
if err != nil {
t.Fatalf("Unable to parse selector: %v", err)
}
if err := pkgutil.WaitForPodsWithLabelRunning(client, "kube-system", ps); err != nil {
t.Fatalf("waiting for registry-proxy pods: %v", err)
}
ip := strings.TrimSpace(mk.RunCommand("ip", true))
endpoint := fmt.Sprintf("http://%s:%d", ip, 5000)
u, err := url.Parse(endpoint)
if err != nil {
t.Fatalf("failed to parse %q: %v", endpoint, err)
}
t.Log("checking registry access from outside cluster")
// Check access from outside the cluster on port 5000, validing connectivity via registry-proxy
checkExternalAccess := func() error {
t.Log("checking registry access from outside cluster")
_, out := minikubeRunner.RunDaemon("ip")
s, err := readLineWithTimeout(out, 180*time.Second)
if err != nil {
t.Fatalf("failed to read minikubeIP: %v", err)
}
registryEndpoint := "http://" + strings.TrimSpace(s) + ":5000"
u, err := url.Parse(registryEndpoint)
if err != nil {
t.Fatalf("failed to parse %q: %v", s, err)
}
resp, err := retryablehttp.Get(u.String())
if err != nil {
t.Errorf("failed get: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("%s returned status code %d, expected %d.\n", registryEndpoint, resp.StatusCode, http.StatusOK)
t.Errorf("%s returned status code %d, expected %d.\n", u, resp.StatusCode, http.StatusOK)
}
return nil
}
if err := util.Retry(t, checkExternalAccess, 2*time.Second, 5); err != nil {
t.Fatalf(err.Error())
}
// check access from inside the cluster via a busybox container running inside cluster
t.Log("checking registry access from inside cluster")
expectedStr := "200"
out, _ := kubectlRunner.RunCommand([]string{
kr := util.NewKubectlRunner(t)
out, _ := kr.RunCommand([]string{
"run",
"registry-test",
"--restart=Never",
@ -247,20 +251,21 @@ func testRegistry(t *testing.T) {
"-c",
"wget --spider -S 'http://registry.kube-system.svc.cluster.local' 2>&1 | grep 'HTTP/' | awk '{print $2}'"})
internalCheckOutput := string(out)
expectedStr := "200"
if !strings.Contains(internalCheckOutput, expectedStr) {
t.Fatalf("ExpectedStr internalCheckOutput to be: %s. Output was: %s", expectedStr, internalCheckOutput)
}
defer func() {
if _, err := kubectlRunner.RunCommand([]string{"delete", "pod", "registry-test"}); err != nil {
if _, err := kr.RunCommand([]string{"delete", "pod", "registry-test"}); err != nil {
t.Fatalf("failed to delete pod registry-test")
}
}()
minikubeRunner.RunCommand("addons disable registry", true)
mk.RunCommand("addons disable registry", true)
}
func testGvisor(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
minikubeRunner.RunCommand("addons enable gvisor", true)
mk := NewMinikubeRunner(t, "--wait=false")
mk.RunCommand("addons enable gvisor", true)
t.Log("waiting for gvisor controller to come up")
if err := util.WaitForGvisorControllerRunning(t); err != nil {
@ -275,7 +280,7 @@ func testGvisor(t *testing.T) {
}
t.Log("disabling gvisor addon")
minikubeRunner.RunCommand("addons disable gvisor", true)
mk.RunCommand("addons disable gvisor", true)
t.Log("waiting for gvisor controller pod to be deleted")
if err := util.WaitForGvisorControllerDeleted(); err != nil {
t.Fatalf("waiting for gvisor controller to be deleted: %v", err)
@ -291,9 +296,9 @@ func testGvisor(t *testing.T) {
}
func testGvisorRestart(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
minikubeRunner.EnsureRunning()
minikubeRunner.RunCommand("addons enable gvisor", true)
mk := NewMinikubeRunner(t, "--wait=false")
mk.EnsureRunning()
mk.RunCommand("addons enable gvisor", true)
t.Log("waiting for gvisor controller to come up")
if err := util.WaitForGvisorControllerRunning(t); err != nil {
@ -301,10 +306,10 @@ func testGvisorRestart(t *testing.T) {
}
// TODO: @priyawadhwa to add test for stop as well
minikubeRunner.RunCommand("delete", false)
minikubeRunner.CheckStatus(state.None.String())
minikubeRunner.Start()
minikubeRunner.CheckStatus(state.Running.String())
mk.RunCommand("delete", false)
mk.CheckStatus(state.None.String())
mk.Start()
mk.CheckStatus(state.Running.String())
t.Log("waiting for gvisor controller to come up")
if err := util.WaitForGvisorControllerRunning(t); err != nil {
@ -320,26 +325,26 @@ func testGvisorRestart(t *testing.T) {
}
func createUntrustedWorkload(t *testing.T) {
kubectlRunner := util.NewKubectlRunner(t)
kr := util.NewKubectlRunner(t)
curdir, err := filepath.Abs("")
if err != nil {
t.Errorf("Error getting the file path for current directory: %s", curdir)
}
untrustedPath := path.Join(curdir, "testdata", "nginx-untrusted.yaml")
t.Log("creating pod with untrusted workload annotation")
if _, err := kubectlRunner.RunCommand([]string{"replace", "-f", untrustedPath, "--force"}); err != nil {
if _, err := kr.RunCommand([]string{"replace", "-f", untrustedPath, "--force"}); err != nil {
t.Fatalf("creating untrusted nginx resource: %v", err)
}
}
func deleteUntrustedWorkload(t *testing.T) {
kubectlRunner := util.NewKubectlRunner(t)
kr := util.NewKubectlRunner(t)
curdir, err := filepath.Abs("")
if err != nil {
t.Errorf("Error getting the file path for current directory: %s", curdir)
}
untrustedPath := path.Join(curdir, "testdata", "nginx-untrusted.yaml")
if _, err := kubectlRunner.RunCommand([]string{"delete", "-f", untrustedPath}); err != nil {
if _, err := kr.RunCommand([]string{"delete", "-f", untrustedPath}); err != nil {
t.Logf("error deleting untrusted nginx resource: %v", err)
}
}

View File

@ -30,8 +30,7 @@ import (
// Assert that docker-env subcommand outputs usable information for "docker ps"
func testClusterEnv(t *testing.T) {
t.Parallel()
r := NewMinikubeRunner(t)
r := NewMinikubeRunner(t, "--wait=false")
// Set a specific shell syntax so that we don't have to handle every possible user shell
envOut := r.RunCommand("docker-env --shell=bash", true)

View File

@ -25,9 +25,9 @@ import (
func testClusterLogs(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
minikubeRunner.EnsureRunning()
logsCmdOutput := minikubeRunner.GetLogs()
mk := NewMinikubeRunner(t)
mk.EnsureRunning()
logsCmdOutput := mk.GetLogs()
// check for # of lines or check for strings
logWords := []string{"minikube", ".go"}

View File

@ -25,9 +25,9 @@ import (
func testClusterSSH(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
expectedStr := "hello"
sshCmdOutput := minikubeRunner.RunCommand("ssh echo "+expectedStr, true)
sshCmdOutput := mk.RunCommand("ssh echo "+expectedStr, true)
if !strings.Contains(sshCmdOutput, expectedStr) {
t.Fatalf("ExpectedStr sshCmdOutput to be: %s. Output was: %s", expectedStr, sshCmdOutput)
}

View File

@ -27,8 +27,8 @@ import (
)
func TestDocker(t *testing.T) {
mk := NewMinikubeRunner(t)
if strings.Contains(mk.StartArgs, "--vm-driver=none") {
mk := NewMinikubeRunner(t, "--wait=false")
if usingNoneDriver(mk) {
t.Skip("skipping test as none driver does not bundle docker")
}
@ -40,8 +40,8 @@ func TestDocker(t *testing.T) {
t.Logf("pre-delete failed (probably ok): %v", err)
}
startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.Args,
"--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true --alsologtostderr --v=5")
startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.GlobalArgs,
"--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true")
stdout, stderr, err := mk.RunWithContext(ctx, startCmd)
if err != nil {
t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr)

View File

@ -19,6 +19,7 @@ package integration
import (
"flag"
"os"
"strings"
"testing"
"k8s.io/minikube/test/integration/util"
@ -31,17 +32,17 @@ func TestMain(m *testing.M) {
}
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var args = flag.String("minikube-args", "", "Arguments to pass to minikube")
var globalArgs = flag.String("minikube-args", "", "Arguments to pass to minikube")
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")
var mountArgs = flag.String("minikube-mount-args", "", "Arguments to pass to minikube mount")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")
// NewMinikubeRunner creates a new MinikubeRunner
func NewMinikubeRunner(t *testing.T) util.MinikubeRunner {
func NewMinikubeRunner(t *testing.T, extraArgs ...string) util.MinikubeRunner {
return util.MinikubeRunner{
Args: *args,
BinaryPath: *binaryPath,
StartArgs: *startArgs,
StartArgs: *startArgs + strings.Join(extraArgs, " "),
GlobalArgs: *globalArgs,
MountArgs: *mountArgs,
T: t,
}

View File

@ -32,7 +32,7 @@ func TestFunctional(t *testing.T) {
// This one is not parallel, and ensures the cluster comes up
// before we run any other tests.
t.Run("Status", testClusterStatus)
t.Run("ProfileList", testProfileList)
t.Run("DNS", testClusterDNS)
t.Run("Logs", testClusterLogs)
t.Run("Addons", testAddons)

View File

@ -26,10 +26,10 @@ import (
func TestISO(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
minikubeRunner.RunCommand("delete", false)
minikubeRunner.Start()
mk.RunCommand("delete", false)
mk.Start()
t.Run("permissions", testMountPermissions)
t.Run("packages", testPackages)
@ -37,14 +37,14 @@ func TestISO(t *testing.T) {
}
func testMountPermissions(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
// test mount permissions
mountPoints := []string{"/Users", "/hosthome"}
perms := "drwxr-xr-x"
foundMount := false
for _, dir := range mountPoints {
output, err := minikubeRunner.SSH(fmt.Sprintf("ls -l %s", dir))
output, err := mk.SSH(fmt.Sprintf("ls -l %s", dir))
if err != nil {
continue
}
@ -59,7 +59,7 @@ func testMountPermissions(t *testing.T) {
}
func testPackages(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
packages := []string{
"git",
@ -73,7 +73,7 @@ func testPackages(t *testing.T) {
}
for _, pkg := range packages {
if output, err := minikubeRunner.SSH(fmt.Sprintf("which %s", pkg)); err != nil {
if output, err := mk.SSH(fmt.Sprintf("which %s", pkg)); err != nil {
t.Errorf("Error finding package: %s. Error: %v. Output: %s", pkg, err, output)
}
}
@ -81,7 +81,7 @@ func testPackages(t *testing.T) {
}
func testPersistence(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
for _, dir := range []string{
"/data",
@ -92,7 +92,7 @@ func testPersistence(t *testing.T) {
"/var/lib/toolbox",
"/var/lib/boot2docker",
} {
output, err := minikubeRunner.SSH(fmt.Sprintf("df %s | tail -n 1 | awk '{print $1}'", dir))
output, err := mk.SSH(fmt.Sprintf("df %s | tail -n 1 | awk '{print $1}'", dir))
if err != nil {
t.Errorf("Error checking device for %s. Error: %v", dir, err)
}

View File

@ -38,12 +38,12 @@ func testMounting(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("mount tests disabled in darwin due to timeout (issue#3200)")
}
if strings.Contains(*args, "--vm-driver=none") {
if strings.Contains(*globalArgs, "--vm-driver=none") {
t.Skip("skipping test for none driver as it does not need mount")
}
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
mk := NewMinikubeRunner(t, "--wait=false")
tempDir, err := ioutil.TempDir("", "mounttest")
if err != nil {
@ -51,8 +51,8 @@ func testMounting(t *testing.T) {
}
defer os.RemoveAll(tempDir)
mountCmd := getMountCmd(minikubeRunner, tempDir)
cmd, _, _ := minikubeRunner.RunDaemon2(mountCmd)
mountCmd := getMountCmd(mk, tempDir)
cmd, _, _ := mk.RunDaemon2(mountCmd)
defer func() {
err := cmd.Process.Kill()
if err != nil {
@ -99,7 +99,7 @@ func testMounting(t *testing.T) {
t.Logf("Pods appear to be running")
mountTest := func() error {
if err := verifyFiles(minikubeRunner, kubectlRunner, tempDir, podName, expected); err != nil {
if err := verifyFiles(mk, kubectlRunner, tempDir, podName, expected); err != nil {
t.Fatalf(err.Error())
}
@ -111,10 +111,10 @@ func testMounting(t *testing.T) {
}
func getMountCmd(minikubeRunner util.MinikubeRunner, mountDir string) string {
func getMountCmd(mk util.MinikubeRunner, mountDir string) string {
var mountCmd string
if len(minikubeRunner.MountArgs) > 0 {
mountCmd = fmt.Sprintf("mount %s %s:/mount-9p", minikubeRunner.MountArgs, mountDir)
if len(mk.MountArgs) > 0 {
mountCmd = fmt.Sprintf("mount %s %s:/mount-9p", mk.MountArgs, mountDir)
} else {
mountCmd = fmt.Sprintf("mount %s:/mount-9p", mountDir)
}
@ -144,7 +144,7 @@ func waitForPods(s map[string]string) error {
return nil
}
func verifyFiles(minikubeRunner util.MinikubeRunner, kubectlRunner *util.KubectlRunner, tempDir string, podName string, expected string) error {
func verifyFiles(mk util.MinikubeRunner, kubectlRunner *util.KubectlRunner, tempDir string, podName string, expected string) error {
path := filepath.Join(tempDir, "frompod")
out, err := ioutil.ReadFile(path)
if err != nil {
@ -167,7 +167,7 @@ func verifyFiles(minikubeRunner util.MinikubeRunner, kubectlRunner *util.Kubectl
files := []string{"fromhost", "frompod"}
for _, file := range files {
statCmd := fmt.Sprintf("stat /mount-9p/%s", file)
statOutput, err := minikubeRunner.SSH(statCmd)
statOutput, err := mk.SSH(statCmd)
if err != nil {
return fmt.Errorf("Unable to stat %s via SSH. error %v, %s", file, err, statOutput)
}

View File

@ -21,7 +21,6 @@ package integration
import (
"path"
"path/filepath"
"strings"
"testing"
"time"
@ -30,11 +29,11 @@ import (
)
func TestPersistence(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
if strings.Contains(minikubeRunner.StartArgs, "--vm-driver=none") {
mk := NewMinikubeRunner(t, "--wait=false")
if usingNoneDriver(mk) {
t.Skip("skipping test as none driver does not support persistence")
}
minikubeRunner.EnsureRunning()
mk.EnsureRunning()
kubectlRunner := util.NewKubectlRunner(t)
curdir, err := filepath.Abs("")
@ -59,19 +58,19 @@ func TestPersistence(t *testing.T) {
verify(t)
// Now restart minikube and make sure the pod is still there.
// minikubeRunner.RunCommand("stop", true)
// minikubeRunner.CheckStatus("Stopped")
// mk.RunCommand("stop", true)
// mk.CheckStatus("Stopped")
checkStop := func() error {
minikubeRunner.RunCommand("stop", true)
return minikubeRunner.CheckStatusNoFail(state.Stopped.String())
mk.RunCommand("stop", true)
return mk.CheckStatusNoFail(state.Stopped.String())
}
if err := util.Retry(t, checkStop, 5*time.Second, 6); err != nil {
t.Fatalf("timed out while checking stopped status: %v", err)
}
minikubeRunner.Start()
minikubeRunner.CheckStatus(state.Running.String())
mk.Start()
mk.CheckStatus(state.Running.String())
// Make sure the same things come up after we've restarted.
verify(t)

View File

@ -0,0 +1,35 @@
// +build integration
/*
Copyright 2019 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 integration
import (
"strings"
"testing"
)
// testProfileList tests the `minikube profile list` command
func testProfileList(t *testing.T) {
t.Parallel()
profile := "minikube"
mk := NewMinikubeRunner(t, "--wait=false")
out := mk.RunCommand("profile list", true)
if !strings.Contains(out, profile) {
t.Errorf("Error , failed to read profile name (%s) in `profile list` command output : \n %q ", profile, out)
}
}

View File

@ -71,7 +71,7 @@ func TestProxy(t *testing.T) {
t.Fatalf("Failed to set up the test proxy: %s", err)
}
// making sure there is no running miniukube to avoid https://github.com/kubernetes/minikube/issues/4132
// making sure there is no running minikube to avoid https://github.com/kubernetes/minikube/issues/4132
r := NewMinikubeRunner(t)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
@ -109,10 +109,10 @@ func TestProxy(t *testing.T) {
// testProxyWarning checks user is warned correctly about the proxy related env vars
func testProxyWarning(t *testing.T) {
r := NewMinikubeRunner(t)
r := NewMinikubeRunner(t, "--wait=false")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
startCmd := fmt.Sprintf("start %s %s %s", r.StartArgs, r.Args, "--alsologtostderr --v=5")
startCmd := fmt.Sprintf("start %s %s", r.StartArgs, r.GlobalArgs)
stdout, stderr, err := r.RunWithContext(ctx, startCmd)
if err != nil {
t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
@ -131,8 +131,8 @@ func testProxyWarning(t *testing.T) {
// testProxyDashboard checks if dashboard URL is accessible if proxy is set
func testProxyDashboard(t *testing.T) {
minikubeRunner := NewMinikubeRunner(t)
cmd, out := minikubeRunner.RunDaemon("dashboard --url")
mk := NewMinikubeRunner(t, "--wait=false")
cmd, out := mk.RunDaemon("dashboard --url")
defer func() {
err := cmd.Process.Kill()
if err != nil {

View File

@ -46,7 +46,7 @@ func testTunnel(t *testing.T) {
}
t.Log("starting tunnel test...")
runner := NewMinikubeRunner(t)
runner := NewMinikubeRunner(t, "--wait=false")
go func() {
output := runner.RunCommand("tunnel --alsologtostderr -v 8 --logtostderr", true)
if t.Failed() {

View File

@ -43,7 +43,7 @@ const kubectlBinary = "kubectl"
type MinikubeRunner struct {
T *testing.T
BinaryPath string
Args string
GlobalArgs string
StartArgs string
MountArgs string
Runtime string
@ -208,9 +208,9 @@ func (m *MinikubeRunner) SSH(command string) (string, error) {
return string(stdout), nil
}
// Start starts the container runtime
// Start starts the cluster
func (m *MinikubeRunner) Start(opts ...string) {
cmd := fmt.Sprintf("start %s %s %s --alsologtostderr --v=2", m.StartArgs, m.Args, strings.Join(opts, " "))
cmd := fmt.Sprintf("start %s %s %s --alsologtostderr --v=2", m.StartArgs, m.GlobalArgs, strings.Join(opts, " "))
m.RunCommand(cmd, true)
}
@ -234,12 +234,12 @@ func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
// GetStatus returns the status of a service
func (m *MinikubeRunner) GetStatus() string {
return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.Args), false)
return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.GlobalArgs), false)
}
// GetLogs returns the logs of a service
func (m *MinikubeRunner) GetLogs() string {
return m.RunCommand(fmt.Sprintf("logs %s", m.Args), true)
return m.RunCommand(fmt.Sprintf("logs %s", m.GlobalArgs), true)
}
// CheckStatus makes sure the service has the desired status, or cause fatal error
@ -359,28 +359,6 @@ func WaitForIngressControllerRunning(t *testing.T) error {
return nil
}
// WaitForDockerRegistryRunning waits until docker registry pod to be running
func WaitForDockerRegistryRunning(t *testing.T) error {
client, err := commonutil.GetClient()
if err != nil {
return errors.Wrap(err, "getting kubernetes client")
}
if err := commonutil.WaitForRCToStabilize(client, "kube-system", "registry", time.Minute*10); err != nil {
return errors.Wrap(err, "waiting for registry replicacontroller to stabilize")
}
registrySelector := labels.SelectorFromSet(labels.Set(map[string]string{"kubernetes.io/minikube-addons": "registry"}))
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", registrySelector); err != nil {
return errors.Wrap(err, "waiting for registry pods")
}
proxySelector := labels.SelectorFromSet(labels.Set(map[string]string{"kubernetes.io/minikube-addons": "registry-proxy"}))
if err := commonutil.WaitForPodsWithLabelRunning(client, "kube-system", proxySelector); err != nil {
return errors.Wrap(err, "waiting for registry-proxy pods")
}
return nil
}
// WaitForIngressDefaultBackendRunning waits until ingress default backend pod to be running
func WaitForIngressDefaultBackendRunning(t *testing.T) error {
client, err := commonutil.GetClient()

View File

@ -1,21 +1,18 @@
{
"\"{{.minikube_addon}}\" was successfully disabled": "",
"\"{{.name}}\" cluster does not exist": "",
"%q VM does not exist, nothing to stop": "",
"%q host does not exist, unable to show an IP": "",
"%q profile does not exist": "",
"%q stopped.": "",
"%s IP has been updated to point at %s": "",
"%s IP was already correctly configured for %s": "",
"%s has no available configuration options": "",
"%s was successfully configured": "",
"%s was successfully disabled": "",
"\"{{.profile_name}}\" VM does not exist, nothing to stop": "",
"\"{{.profile_name}}\" host does not exist, unable to show an IP": "",
"\"{{.profile_name}}\" profile does not exist": "",
"\"{{.profile_name}}\" stopped.": "",
"'none' driver does not support 'minikube docker-env' command": "",
"'none' driver does not support 'minikube mount' command": "",
"'none' driver does not support 'minikube ssh' command": "",
"==\u003e {{.name}} \u003c==": "",
"A firewall is blocking Docker within the minikube VM from reaching the internet. You may need to configure it to use a proxy.": "",
"A firewall is interfering with minikube's ability to make outgoing HTTPS requests. You may need to change the value of the HTTPS_PROXY environment variable.": "",
"A firewall is likely blocking minikube from reaching the internet. You may need to configure minikube to use a proxy.": "",
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Alternatively, you may delete the existing VM using `minikube delete -p {{.profile_name}}`": "",
"Cannot find directory {{.path}} for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
"Check that your --kubernetes-version has a leading 'v'. For example: 'v1.1.14'": "",
@ -25,7 +22,8 @@
"Could not get profile flag": "",
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "Créant un VM %s (CPUs=%d, Mémoire=%dMB, Disque=%dMB)",
"Creating mount {{.name}} ...": "",
"Deleting %q from %s ...": "",
"Creating {{.driver_name}} VM (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "",
"Deleting \"{{.profile_name}}\" in {{.driver_name}} ...": "",
"Disable Hyper-V when you want to run VirtualBox to boot the VM": "",
"Disable dynamic memory in your VM manager, or pass in a larger --memory value": "",
"Disable real-time anti-virus software, reboot, and reinstall VirtualBox if the problem continues.": "",
@ -36,10 +34,10 @@
"Downloading Minikube ISO ...": "",
"Downloading {{.name}} {{.version}}": "",
"ERROR creating `registry-creds-dpr` secret": "",
"ERROR creating `registry-creds-ecr` secret: %v": "",
"ERROR creating `registry-creds-gcr` secret: %v": "",
"ERROR creating `registry-creds-ecr` secret: {{.error}}": "",
"ERROR creating `registry-creds-gcr` secret: {{.error}}": "",
"Enabling dashboard ...": "",
"Error checking driver version: %v": "",
"Error checking driver version: {{.error}}": "",
"Error creating list template": "",
"Error creating minikube directory": "",
"Error creating status template": "",
@ -52,7 +50,7 @@
"Error getting IP": "",
"Error getting bootstrapper": "",
"Error getting client": "",
"Error getting client: %v": "",
"Error getting client: {{.error}}": "",
"Error getting cluster": "",
"Error getting cluster bootstrapper": "",
"Error getting config": "",
@ -62,31 +60,35 @@
"Error getting machine status": "",
"Error getting profiles to delete": "",
"Error getting service status": "",
"Error getting service with namespace: %s and labels %s:%s: %v": "",
"Error getting service with namespace: {{.namespace}} and labels {{.labelName}}:{{.addonName}}: {{.error}}": "",
"Error getting the host IP address to use from within the VM": "",
"Error host driver ip status": "",
"Error killing mount process": "",
"Error loading api": "",
"Error loading profile config": "",
"Error loading profile config: {{.error}}": "",
"Error opening service": "",
"Error parsing minukube version: %v": "",
"Error parsing vmDriver version: %v": "",
"Error reading %s: %v": "",
"Error parsing minukube version: {{.error}}": "",
"Error parsing vmDriver version: {{.error}}": "",
"Error reading {{.path}}: {{.error}}": "",
"Error restarting cluster": "",
"Error setting shell variables": "",
"Error starting cluster": "",
"Error starting mount": "",
"Error unsetting shell variables": "",
"Error while setting kubectl current context : {{.error}}": "",
"Error writing mount pid": "",
"Error: [{{.id}}] {{.error}}": "",
"Failed runtime": "",
"Failed to cache ISO": "",
"Failed to cache and load images": "",
"Failed to cache binaries": "",
"Failed to cache images": "",
"Failed to check if machine exists": "",
"Failed to check main repository and mirrors for images for images": "",
"Failed to chown %s: %v": "",
"Failed to chown {{.minikube_dir_path}}: {{.error}}": "",
"Failed to delete cluster": "",
"Failed to delete cluster: {{.error}}": "",
"Failed to delete images": "",
"Failed to delete images from config": "",
"Failed to download kubectl": "",
@ -98,7 +100,7 @@
"Failed to get image map": "",
"Failed to get machine client": "",
"Failed to get service URL: {{.error}}": "",
"Failed to kill mount process: %v": "",
"Failed to kill mount process: {{.error}}": "",
"Failed to list cached images": "",
"Failed to remove profile": "",
"Failed to save config": "",
@ -116,12 +118,12 @@
"Have you set up libvirt correctly?": "",
"If the above advice does not help, please let us know: ": "",
"If using the none driver, ensure that systemctl is installed": "",
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Ignoring --vm-driver={{.driver_name}}, as the existing \"{{.profile_name}}\" VM was created using the {{.driver_name2}} driver.": "",
"In some environments, this message is incorrect. Try 'minikube start --no-vtx-check'": "",
"Install VirtualBox, ensure that VBoxManage is executable and in path, or select an alternative value for --vm-driver": "",
"Install the latest kvm2 driver and run 'virt-host-validate'": "",
"Install the latest minikube hyperkit driver, and run 'minikube delete'": "",
"Invalid size passed in argument: %v": "",
"Invalid size passed in argument: {{.error}}": "",
"IsEnabled failed": "",
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
"Launching Kubernetes ... ": "Lançant Kubernetes ...",
@ -130,10 +132,10 @@
"Mount type: {{.name}}": "",
"Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...": "",
"NOTE: This process must stay alive for the mount to be accessible ...": "",
"None of known repositories in your location is accessible. Use %s as fallback.": "",
"None of known repositories in your location is accessible. Use {{.image_repository_name}} as fallback.": "",
"None of known repositories is accessible. Consider specifying an alternative image repository with --image-repository flag": "",
"Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "",
"Opening kubernetes service {{.namespace_name}}/{{.service_name}} in default browser...": "",
"Options: {{.options}}": "",
"Permissions: {{.octalMode}} ({{.writtenMode}})": "",
"Please check your BIOS, and ensure that you are running without HyperV or other nested virtualization that may interfere": "",
@ -142,45 +144,45 @@
"Please install the minikube hyperkit VM driver, or select an alternative --vm-driver": "",
"Please install the minikube kvm2 VM driver, or select an alternative --vm-driver": "",
"Please make sure the service you are looking for is deployed or is in the correct namespace.": "",
"Please run with sudo. the vm-driver %q requires sudo.": "",
"Please run with sudo. the vm-driver \"{{.driver_name}}\" requires sudo.": "",
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
"Please upgrade the 'docker-machine-driver-kvm2'. %s": "",
"Powering off %q via SSH ...": "",
"Problems detected in %q:": "",
"Please upgrade the 'docker-machine-driver-kvm2'. {{.documentation_url}}": "",
"Powering off \"{{.profile_name}}\" via SSH ...": "",
"Problems detected in {{.entry}}:": "",
"Problems detected in {{.name}}:": "",
"Pulling images ...": "Extrayant les images ... ",
"Re-run 'minikube start' with --alsologtostderr -v=8 to see the VM driver error message": "",
"Re-using the currently running %s VM for %q ...": "",
"Re-using the currently running {{.driver_name}} VM for \"{{.profile_name}}\" ...": "",
"Reboot to complete VirtualBox installation, and verify that VirtualBox is not blocked by your system": "",
"Rebuild libvirt with virt-network support": "",
"Received {{.name}} signal": "",
"Reinstall VirtualBox and verify that it is not blocked: System Preferences -\u003e Security \u0026 Privacy -\u003e General -\u003e Some system software was blocked from loading": "",
"Related issues:": "",
"Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
"Requested disk size (%dMB) is less than minimum of (%dMB)": "",
"Requested memory allocation (%dMB) is less than the minimum allowed of %dMB": "",
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
"Restarting existing %s VM for %q ...": "",
"Requested disk size {{.size_in_mb}} is less than minimum of {{.size_in_mb2}}": "",
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default_memorysize}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
"Requested memory allocation {{.size_in_mb}} is less than the minimum allowed of {{.size_in_mb2}}": "",
"Restarting existing {{.driver_name}} VM for \"{{.profile_name}}\" ...": "",
"Run 'minikube delete' to delete the stale VM": "",
"Run 'minikube delete'. If the problem persists, check your proxy or firewall configuration": "",
"Run 'sudo modprobe vboxdrv' and reinstall VirtualBox if it fails.": "",
"Run minikube from the C: drive.": "",
"Running on localhost (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "",
"Running on localhost (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "",
"Set failed": "",
"Setting profile failed": "",
"Skipped switching kubectl context for %s , because --keep-context": "",
"Skipped switching kubectl context for {{.profile_name}} , because --keep-context": "",
"Sorry that minikube crashed. If this was unexpected, we would love to hear from you:": "",
"Sorry, completion support is not yet implemented for {{.name}}": "",
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
"Sorry, the kubeadm.{{.parameter_name}} parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid {{.url}}": "",
"Specify --kubernetes-version in v\u003cmajor\u003e.\u003cminor.\u003cbuild\u003e form. example: 'v1.1.14'": "",
"Specify an alternate --host-only-cidr value, such as 172.16.0.1/24": "",
"Stopping %q in %s ...": "",
"Stopping \"{{.profile_name}}\" in {{.driver_name}} ...": "",
"Successfully mounted {{.sourcePath}} to {{.destinationPath}}": "",
"Suggestion: {{.advice}}": "",
"Target directory {{.path}} must be an absolute path": "",
"The %q cluster has been deleted.": "",
"The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. %s": "",
"The \"{{.cluster_name}}\" cluster has been deleted.": "",
"The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. {{.documentation_url}}": "",
"The 'none' driver provides limited isolation and may reduce system security and reliability.": "",
"The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.": "",
"The VM driver exited with an error, and may be corrupt. Run 'minikube start' with --alsologtostderr -v=8 to see the error": "",
@ -188,32 +190,32 @@
"The docker service is currently not active": "",
"The minikube VM is offline. Please run 'minikube start' to start it again.": "",
"The value passed to --format is invalid": "",
"The value passed to --format is invalid: %s": "",
"The value passed to --format is invalid: {{.error}}": "",
"The vmwarefusion driver is deprecated and support for it will be removed in a future release.\n\t\t\tPlease consider switching to the new vmware unified driver, which is intended to replace the vmwarefusion driver.\n\t\t\tSee https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#vmware-unified-driver for more information.\n\t\t\tTo disable this message, run [minikube config set ShowDriverDeprecationNotification false]": "",
"These changes will take effect upon a minikube delete and then a minikube start": "",
"This addon does not have an endpoint defined for the 'addons open' command.\nYou can add one by annotating a service with the label %s:%s": "",
"This addon does not have an endpoint defined for the 'addons open' command.\nYou can add one by annotating a service with the label {{.labelName}}:{{.addonName}}": "",
"This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true": "",
"Tip: Use 'minikube start -p \u003cname\u003e' to create a new cluster, or 'minikube delete' to delete this one.": "",
"To connect to this cluster, use: kubectl --context=%s": "",
"To connect to this cluster, use: kubectl --context={{.name}}": "",
"To connect to this cluster, use: kubectl --context={{.profile_name}}": "",
"To disable this notice, run: 'minikube config set WantUpdateNotification false'": "",
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver={{.driver_name}}`": "",
"To use kubectl or minikube commands as your own user, you may": "",
"Unable to bind flags": "",
"Unable to enable dashboard": "",
"Unable to fetch latest version info": "",
"Unable to get VM IP address": "",
"Unable to get bootstrapper: {{.error}}": "",
"Unable to get runtime": "",
"Unable to kill mount process: %s": "",
"Unable to kill mount process: {{.error}}": "",
"Unable to load cached images from config file.": "",
"Unable to load cached images: {{.error}}": "",
"Unable to load config: %v": "",
"Unable to load config: {{.error}}": "",
"Unable to parse %q: %v": "",
"Unable to parse \"{{.kubenretes_version}}\": {{.error}}": "",
"Unable to pull images, which may be OK: {{.error}}": "",
"Unable to start VM": "",
"Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "",
"Uninstalling Kubernetes {{.kubernetes_version}} using {{.bootstrapper_name}} ...": "",
"Unmounting {{.path}} ...": "",
"Update server returned an empty list": "",
"Upgrade to QEMU v3.1.0+, run 'virt-host-validate', or ensure that you are not running in a nested VM environment.": "",
@ -228,47 +230,53 @@
"Verifying:": "Vérifiant:",
"Version: {{.version}}": "",
"Wait failed": "",
"Wait failed: %v": "",
"Wait failed: {{.error}}": "",
"Waiting for SSH access ...": "Attendant l'accès SSH ...",
"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP (%s). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details": "",
"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details": "",
"You must specify a service name": "",
"Your host does not support KVM virtualization. Ensure that qemu-kvm is installed, and run 'virt-host-validate' to debug the problem": "",
"Your host is failing to route packets to the minikube VM. If you have VPN software, try turning it off or configuring it so that it does not re-route traffic to the VM IP. If not, check your VM environment routing options.": "",
"addon '%s' is currently not enabled.\nTo enable this addon run:\nminikube addons enable %s": "",
"addon '%s' is not a valid addon packaged with minikube.\nTo see the list of available addons run:\nminikube addons list": "",
"\\n": "",
"addon '{{.name}}' is currently not enabled.\nTo enable this addon run:\nminikube addons enable {{.name}}": "",
"addon '{{.name}}' is not a valid addon packaged with minikube.\nTo see the list of available addons run:\nminikube addons list": "",
"addon list failed": "",
"api load": "",
"bash completion failed": "",
"browser failed to open url: {{.error}}": "",
"command runner": "",
"config view failed": "",
"dashboard service is not running: {{.error}}": "",
"disable failed": "",
"enable failed": "",
"env {{.docker_env}}": "",
"error creating clientset": "",
"error creating machine client": "",
"error getting driver": "",
"error parsing the input ip address for mount": "",
"error starting tunnel": "",
"failed to open browser: {{.error}}": "",
"kubectl and minikube configuration will be stored in %s": "",
"kube-system": "",
"kubectl and minikube configuration will be stored in {{.home_folder}}": "",
"kubectl has been configured configured to use {{.name}}": "",
"kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"kubectl proxy": "",
"logdir set failed": "",
"minikube is not running, so the service cannot be accessed": "",
"minikube is unable to access the Google Container Registry. You may need to configure it to use a HTTP proxy.": "",
"minikube profile was successfully set to %s": "",
"minikube profile was successfully set to {{.profile_name}}": "",
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
"minikube {{.version}} is available! Download it: {{.url}}": "",
"minikube {{.version}} on {{.os}} ({{.arch}})": "minikube {{.version}} sur {{.os}} ({{.arch}})",
"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "",
"service %s/%s has no node port": "",
"opt {{.docker_option}}": "",
"service {{.namespace_name}}/{{.service_name}} has no node port": "",
"stat failed": "",
"unable to bind flags": "",
"unable to set logtostderr": "",
"unset failed": "",
"unsupported driver: %s": "",
"unsupported driver: {{.driver_name}}": "",
"unsupported driver: {{.name}}": "",
"update config": "",
"usage: minikube addons configure ADDON_NAME": "",
@ -284,8 +292,14 @@
"zsh completion failed": "",
"{{.addonName}} was successfully enabled": "",
"{{.error}}": "",
"{{.extra_option_component_name}}.{{.key}}={{.value}}": "",
"{{.key}}={{.value}}": "",
"{{.machine}} IP has been updated to point at {{.ip}}": "",
"{{.machine}} IP was already correctly configured for {{.ip}}": "",
"{{.msg}}: {{.err}}": "",
"{{.name}} cluster does not exist": "",
"{{.name}} has no available configuration options": "",
"{{.name}} was successfully configured": "",
"{{.type}} is not yet a supported filesystem. We will try anyways!": "",
"{{.url}}": "",
"{{.url}} is not accessible: {{.error}}": ""

View File

@ -1,21 +1,18 @@
{
"\"{{.minikube_addon}}\" was successfully disabled": "",
"\"{{.name}}\" cluster does not exist": "",
"%q VM does not exist, nothing to stop": "",
"%q host does not exist, unable to show an IP": "",
"%q profile does not exist": "",
"%q stopped.": "",
"%s IP has been updated to point at %s": "",
"%s IP was already correctly configured for %s": "",
"%s has no available configuration options": "",
"%s was successfully configured": "",
"%s was successfully disabled": "",
"\"{{.profile_name}}\" VM does not exist, nothing to stop": "",
"\"{{.profile_name}}\" host does not exist, unable to show an IP": "",
"\"{{.profile_name}}\" profile does not exist": "",
"\"{{.profile_name}}\" stopped.": "",
"'none' driver does not support 'minikube docker-env' command": "",
"'none' driver does not support 'minikube mount' command": "",
"'none' driver does not support 'minikube ssh' command": "",
"==\u003e {{.name}} \u003c==": "",
"A firewall is blocking Docker within the minikube VM from reaching the internet. You may need to configure it to use a proxy.": "",
"A firewall is interfering with minikube's ability to make outgoing HTTPS requests. You may need to change the value of the HTTPS_PROXY environment variable.": "",
"A firewall is likely blocking minikube from reaching the internet. You may need to configure minikube to use a proxy.": "",
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Alternatively, you may delete the existing VM using `minikube delete -p {{.profile_name}}`": "",
"Cannot find directory {{.path}} for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
"Check that your --kubernetes-version has a leading 'v'. For example: 'v1.1.14'": "",
@ -25,7 +22,8 @@
"Could not get profile flag": "",
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "正在创建%s虚拟机CPU=%d内存=%dMB磁盘=%dMB...",
"Creating mount {{.name}} ...": "",
"Deleting %q from %s ...": "",
"Creating {{.driver_name}} VM (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "",
"Deleting \"{{.profile_name}}\" in {{.driver_name}} ...": "",
"Disable Hyper-V when you want to run VirtualBox to boot the VM": "",
"Disable dynamic memory in your VM manager, or pass in a larger --memory value": "",
"Disable real-time anti-virus software, reboot, and reinstall VirtualBox if the problem continues.": "",
@ -36,10 +34,10 @@
"Downloading Minikube ISO ...": "",
"Downloading {{.name}} {{.version}}": "",
"ERROR creating `registry-creds-dpr` secret": "",
"ERROR creating `registry-creds-ecr` secret: %v": "",
"ERROR creating `registry-creds-gcr` secret: %v": "",
"ERROR creating `registry-creds-ecr` secret: {{.error}}": "",
"ERROR creating `registry-creds-gcr` secret: {{.error}}": "",
"Enabling dashboard ...": "",
"Error checking driver version: %v": "",
"Error checking driver version: {{.error}}": "",
"Error creating list template": "",
"Error creating minikube directory": "",
"Error creating status template": "",
@ -52,7 +50,7 @@
"Error getting IP": "",
"Error getting bootstrapper": "",
"Error getting client": "",
"Error getting client: %v": "",
"Error getting client: {{.error}}": "",
"Error getting cluster": "",
"Error getting cluster bootstrapper": "",
"Error getting config": "",
@ -62,31 +60,35 @@
"Error getting machine status": "",
"Error getting profiles to delete": "",
"Error getting service status": "",
"Error getting service with namespace: %s and labels %s:%s: %v": "",
"Error getting service with namespace: {{.namespace}} and labels {{.labelName}}:{{.addonName}}: {{.error}}": "",
"Error getting the host IP address to use from within the VM": "",
"Error host driver ip status": "",
"Error killing mount process": "",
"Error loading api": "",
"Error loading profile config": "",
"Error loading profile config: {{.error}}": "",
"Error opening service": "",
"Error parsing minukube version: %v": "",
"Error parsing vmDriver version: %v": "",
"Error reading %s: %v": "",
"Error parsing minukube version: {{.error}}": "",
"Error parsing vmDriver version: {{.error}}": "",
"Error reading {{.path}}: {{.error}}": "",
"Error restarting cluster": "",
"Error setting shell variables": "",
"Error starting cluster": "",
"Error starting mount": "",
"Error unsetting shell variables": "",
"Error while setting kubectl current context : {{.error}}": "",
"Error writing mount pid": "",
"Error: [{{.id}}] {{.error}}": "",
"Failed runtime": "",
"Failed to cache ISO": "",
"Failed to cache and load images": "",
"Failed to cache binaries": "",
"Failed to cache images": "",
"Failed to check if machine exists": "",
"Failed to check main repository and mirrors for images for images": "",
"Failed to chown %s: %v": "",
"Failed to chown {{.minikube_dir_path}}: {{.error}}": "",
"Failed to delete cluster": "",
"Failed to delete cluster: {{.error}}": "",
"Failed to delete images": "",
"Failed to delete images from config": "",
"Failed to download kubectl": "",
@ -98,7 +100,7 @@
"Failed to get image map": "",
"Failed to get machine client": "",
"Failed to get service URL: {{.error}}": "",
"Failed to kill mount process: %v": "",
"Failed to kill mount process: {{.error}}": "",
"Failed to list cached images": "",
"Failed to remove profile": "",
"Failed to save config": "",
@ -116,12 +118,12 @@
"Have you set up libvirt correctly?": "",
"If the above advice does not help, please let us know: ": "",
"If using the none driver, ensure that systemctl is installed": "",
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Ignoring --vm-driver={{.driver_name}}, as the existing \"{{.profile_name}}\" VM was created using the {{.driver_name2}} driver.": "",
"In some environments, this message is incorrect. Try 'minikube start --no-vtx-check'": "",
"Install VirtualBox, ensure that VBoxManage is executable and in path, or select an alternative value for --vm-driver": "",
"Install the latest kvm2 driver and run 'virt-host-validate'": "",
"Install the latest minikube hyperkit driver, and run 'minikube delete'": "",
"Invalid size passed in argument: %v": "",
"Invalid size passed in argument: {{.error}}": "",
"IsEnabled failed": "",
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
"Launching Kubernetes ... ": "正在启动 Kubernetes ... ",
@ -130,10 +132,10 @@
"Mount type: {{.name}}": "",
"Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...": "",
"NOTE: This process must stay alive for the mount to be accessible ...": "",
"None of known repositories in your location is accessible. Use %s as fallback.": "",
"None of known repositories in your location is accessible. Use {{.image_repository_name}} as fallback.": "",
"None of known repositories is accessible. Consider specifying an alternative image repository with --image-repository flag": "",
"Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "",
"Opening kubernetes service {{.namespace_name}}/{{.service_name}} in default browser...": "",
"Options: {{.options}}": "",
"Permissions: {{.octalMode}} ({{.writtenMode}})": "",
"Please check your BIOS, and ensure that you are running without HyperV or other nested virtualization that may interfere": "",
@ -142,45 +144,45 @@
"Please install the minikube hyperkit VM driver, or select an alternative --vm-driver": "",
"Please install the minikube kvm2 VM driver, or select an alternative --vm-driver": "",
"Please make sure the service you are looking for is deployed or is in the correct namespace.": "",
"Please run with sudo. the vm-driver %q requires sudo.": "",
"Please run with sudo. the vm-driver \"{{.driver_name}}\" requires sudo.": "",
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
"Please upgrade the 'docker-machine-driver-kvm2'. %s": "",
"Powering off %q via SSH ...": "",
"Problems detected in %q:": "",
"Please upgrade the 'docker-machine-driver-kvm2'. {{.documentation_url}}": "",
"Powering off \"{{.profile_name}}\" via SSH ...": "",
"Problems detected in {{.entry}}:": "",
"Problems detected in {{.name}}:": "",
"Pulling images ...": "拉取镜像 ...",
"Re-run 'minikube start' with --alsologtostderr -v=8 to see the VM driver error message": "",
"Re-using the currently running %s VM for %q ...": "",
"Re-using the currently running {{.driver_name}} VM for \"{{.profile_name}}\" ...": "",
"Reboot to complete VirtualBox installation, and verify that VirtualBox is not blocked by your system": "",
"Rebuild libvirt with virt-network support": "",
"Received {{.name}} signal": "",
"Reinstall VirtualBox and verify that it is not blocked: System Preferences -\u003e Security \u0026 Privacy -\u003e General -\u003e Some system software was blocked from loading": "",
"Related issues:": "",
"Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
"Requested disk size (%dMB) is less than minimum of (%dMB)": "",
"Requested memory allocation (%dMB) is less than the minimum allowed of %dMB": "",
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
"Restarting existing %s VM for %q ...": "",
"Requested disk size {{.size_in_mb}} is less than minimum of {{.size_in_mb2}}": "",
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default_memorysize}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
"Requested memory allocation {{.size_in_mb}} is less than the minimum allowed of {{.size_in_mb2}}": "",
"Restarting existing {{.driver_name}} VM for \"{{.profile_name}}\" ...": "",
"Run 'minikube delete' to delete the stale VM": "",
"Run 'minikube delete'. If the problem persists, check your proxy or firewall configuration": "",
"Run 'sudo modprobe vboxdrv' and reinstall VirtualBox if it fails.": "",
"Run minikube from the C: drive.": "",
"Running on localhost (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "",
"Running on localhost (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...": "",
"Set failed": "",
"Setting profile failed": "",
"Skipped switching kubectl context for %s , because --keep-context": "",
"Skipped switching kubectl context for {{.profile_name}} , because --keep-context": "",
"Sorry that minikube crashed. If this was unexpected, we would love to hear from you:": "",
"Sorry, completion support is not yet implemented for {{.name}}": "",
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
"Sorry, the kubeadm.{{.parameter_name}} parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid {{.url}}": "",
"Specify --kubernetes-version in v\u003cmajor\u003e.\u003cminor.\u003cbuild\u003e form. example: 'v1.1.14'": "",
"Specify an alternate --host-only-cidr value, such as 172.16.0.1/24": "",
"Stopping %q in %s ...": "",
"Stopping \"{{.profile_name}}\" in {{.driver_name}} ...": "",
"Successfully mounted {{.sourcePath}} to {{.destinationPath}}": "",
"Suggestion: {{.advice}}": "",
"Target directory {{.path}} must be an absolute path": "",
"The %q cluster has been deleted.": "",
"The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. %s": "",
"The \"{{.cluster_name}}\" cluster has been deleted.": "",
"The 'docker-machine-driver-kvm2' version is old. Please consider upgrading. {{.documentation_url}}": "",
"The 'none' driver provides limited isolation and may reduce system security and reliability.": "",
"The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.": "",
"The VM driver exited with an error, and may be corrupt. Run 'minikube start' with --alsologtostderr -v=8 to see the error": "",
@ -188,32 +190,32 @@
"The docker service is currently not active": "",
"The minikube VM is offline. Please run 'minikube start' to start it again.": "",
"The value passed to --format is invalid": "",
"The value passed to --format is invalid: %s": "",
"The value passed to --format is invalid: {{.error}}": "",
"The vmwarefusion driver is deprecated and support for it will be removed in a future release.\n\t\t\tPlease consider switching to the new vmware unified driver, which is intended to replace the vmwarefusion driver.\n\t\t\tSee https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#vmware-unified-driver for more information.\n\t\t\tTo disable this message, run [minikube config set ShowDriverDeprecationNotification false]": "",
"These changes will take effect upon a minikube delete and then a minikube start": "",
"This addon does not have an endpoint defined for the 'addons open' command.\nYou can add one by annotating a service with the label %s:%s": "",
"This addon does not have an endpoint defined for the 'addons open' command.\nYou can add one by annotating a service with the label {{.labelName}}:{{.addonName}}": "",
"This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true": "",
"Tip: Use 'minikube start -p \u003cname\u003e' to create a new cluster, or 'minikube delete' to delete this one.": "",
"To connect to this cluster, use: kubectl --context=%s": "",
"To connect to this cluster, use: kubectl --context={{.name}}": "",
"To connect to this cluster, use: kubectl --context={{.profile_name}}": "",
"To disable this notice, run: 'minikube config set WantUpdateNotification false'": "",
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver={{.driver_name}}`": "",
"To use kubectl or minikube commands as your own user, you may": "",
"Unable to bind flags": "",
"Unable to enable dashboard": "",
"Unable to fetch latest version info": "",
"Unable to get VM IP address": "",
"Unable to get bootstrapper: {{.error}}": "",
"Unable to get runtime": "",
"Unable to kill mount process: %s": "",
"Unable to kill mount process: {{.error}}": "",
"Unable to load cached images from config file.": "",
"Unable to load cached images: {{.error}}": "",
"Unable to load config: %v": "",
"Unable to load config: {{.error}}": "",
"Unable to parse %q: %v": "",
"Unable to parse \"{{.kubenretes_version}}\": {{.error}}": "",
"Unable to pull images, which may be OK: {{.error}}": "",
"Unable to start VM": "",
"Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "",
"Uninstalling Kubernetes {{.kubernetes_version}} using {{.bootstrapper_name}} ...": "",
"Unmounting {{.path}} ...": "",
"Update server returned an empty list": "",
"Upgrade to QEMU v3.1.0+, run 'virt-host-validate', or ensure that you are not running in a nested VM environment.": "",
@ -228,47 +230,53 @@
"Verifying:": "正在验证:",
"Version: {{.version}}": "",
"Wait failed": "",
"Wait failed: %v": "",
"Wait failed: {{.error}}": "",
"Waiting for SSH access ...": "",
"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP (%s). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details": "",
"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}). Please see https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md for more details": "",
"You must specify a service name": "",
"Your host does not support KVM virtualization. Ensure that qemu-kvm is installed, and run 'virt-host-validate' to debug the problem": "",
"Your host is failing to route packets to the minikube VM. If you have VPN software, try turning it off or configuring it so that it does not re-route traffic to the VM IP. If not, check your VM environment routing options.": "",
"addon '%s' is currently not enabled.\nTo enable this addon run:\nminikube addons enable %s": "",
"addon '%s' is not a valid addon packaged with minikube.\nTo see the list of available addons run:\nminikube addons list": "",
"\\n": "",
"addon '{{.name}}' is currently not enabled.\nTo enable this addon run:\nminikube addons enable {{.name}}": "",
"addon '{{.name}}' is not a valid addon packaged with minikube.\nTo see the list of available addons run:\nminikube addons list": "",
"addon list failed": "",
"api load": "",
"bash completion failed": "",
"browser failed to open url: {{.error}}": "",
"command runner": "",
"config view failed": "",
"dashboard service is not running: {{.error}}": "",
"disable failed": "",
"enable failed": "",
"env {{.docker_env}}": "",
"error creating clientset": "",
"error creating machine client": "",
"error getting driver": "",
"error parsing the input ip address for mount": "",
"error starting tunnel": "",
"failed to open browser: {{.error}}": "",
"kubectl and minikube configuration will be stored in %s": "",
"kube-system": "",
"kubectl and minikube configuration will be stored in {{.home_folder}}": "",
"kubectl has been configured configured to use {{.name}}": "",
"kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"kubectl proxy": "",
"logdir set failed": "",
"minikube is not running, so the service cannot be accessed": "",
"minikube is unable to access the Google Container Registry. You may need to configure it to use a HTTP proxy.": "",
"minikube profile was successfully set to %s": "",
"minikube profile was successfully set to {{.profile_name}}": "",
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
"minikube {{.version}} is available! Download it: {{.url}}": "",
"minikube {{.version}} on {{.os}} ({{.arch}})": "您正在使用minikube {{.version}} 运行平台:{{.os}} ({{.arch}})",
"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "",
"service %s/%s has no node port": "",
"opt {{.docker_option}}": "",
"service {{.namespace_name}}/{{.service_name}} has no node port": "",
"stat failed": "",
"unable to bind flags": "",
"unable to set logtostderr": "",
"unset failed": "",
"unsupported driver: %s": "",
"unsupported driver: {{.driver_name}}": "",
"unsupported driver: {{.name}}": "",
"update config": "",
"usage: minikube addons configure ADDON_NAME": "",
@ -284,8 +292,14 @@
"zsh completion failed": "",
"{{.addonName}} was successfully enabled": "",
"{{.error}}": "",
"{{.extra_option_component_name}}.{{.key}}={{.value}}": "",
"{{.key}}={{.value}}": "",
"{{.machine}} IP has been updated to point at {{.ip}}": "",
"{{.machine}} IP was already correctly configured for {{.ip}}": "",
"{{.msg}}: {{.err}}": "",
"{{.name}} cluster does not exist": "",
"{{.name}} has no available configuration options": "",
"{{.name}} was successfully configured": "",
"{{.type}} is not yet a supported filesystem. We will try anyways!": "",
"{{.url}}": "",
"{{.url}} is not accessible: {{.error}}": ""