提交 d1b0d047 编写于 作者: T Thomas Stromberg

Initial console implementation

上级 854d77ac
......@@ -17,12 +17,12 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
)
......@@ -42,12 +42,12 @@ var addCacheCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
// Cache and load images into docker daemon
if err := machine.CacheAndLoadImages(args); err != nil {
fmt.Fprintf(os.Stderr, "Error caching and loading images: %v\n", err)
console.Fatal("Failed to cache and load images: %v", err)
os.Exit(1)
}
// Add images to config file
if err := cmdConfig.AddToConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error adding cached images to config file: %v\n", err)
console.Fatal("Failed to update config: %v", err)
os.Exit(1)
}
},
......@@ -61,12 +61,12 @@ var deleteCacheCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
// Delete images from config file
if err := cmdConfig.DeleteFromConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images from config file: %v\n", err)
console.Fatal("Failed to delete images from config: %v", err)
os.Exit(1)
}
// Delete images from cache/images directory
if err := machine.DeleteFromImageCacheDir(args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images: %v\n", err)
console.Fatal("Failed to delete images: %v", err)
os.Exit(1)
}
},
......
......@@ -17,12 +17,12 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"text/template"
"github.com/spf13/cobra"
cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
)
......@@ -38,14 +38,13 @@ var listCacheCmd = &cobra.Command{
Short: "List all available images from the local cache.",
Long: "List all available images from the local cache.",
Run: func(cmd *cobra.Command, args []string) {
// list images from config file
images, err := cmdConfig.ListConfigMap(constants.Cache)
if err != nil {
fmt.Fprintf(os.Stderr, "Error listing image entries from config: %v\n", err)
console.Fatal("Failed to get image map: %v", err)
os.Exit(1)
}
if err := cacheList(images); err != nil {
fmt.Fprintf(os.Stderr, "Error listing images: %v\n", err)
console.Fatal("Failed to list cached images: %v", err)
os.Exit(1)
}
},
......@@ -62,13 +61,13 @@ func cacheList(images []string) error {
for _, image := range images {
tmpl, err := template.New("list").Parse(cacheListFormat)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating list template: %v\n", err)
console.Fatal("Unable to parse template: %v", err)
os.Exit(1)
}
listTmplt := CacheListTemplate{image}
err = tmpl.Execute(os.Stdout, listTmplt)
if err != nil {
fmt.Fprintf(os.Stderr, "Error executing list template: %v\n", err)
console.Fatal("Unable to process template: %v", err)
os.Exit(1)
}
}
......
......@@ -18,13 +18,13 @@ package cmd
import (
"bytes"
"fmt"
"io"
"os"
"github.com/pkg/errors"
"github.com/spf13/cobra"
cmdutil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/console"
)
const longDescription = `
......@@ -70,11 +70,11 @@ var completionCmd = &cobra.Command{
Long: longDescription,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Println("Usage: minikube completion SHELL")
console.ErrStyle("usage", "Usage: minikube completion SHELL")
os.Exit(1)
}
if args[0] != "bash" && args[0] != "zsh" {
fmt.Println("Only bash and zsh are supported for minikube completion")
console.Fatal("Sorry, completion support is not yet implemented for %q", args[0])
os.Exit(1)
} else if args[0] == "bash" {
err := GenerateBashCompletion(os.Stdout, cmd.Parent())
......
......@@ -17,7 +17,6 @@ limitations under the License.
package config
import (
"fmt"
"os"
"sort"
"text/template"
......@@ -25,6 +24,7 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
)
......@@ -41,12 +41,12 @@ 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 {
fmt.Fprintln(os.Stderr, "usage: minikube addons list")
console.ErrStyle("usage", "usage: minikube addons list")
os.Exit(1)
}
err := addonList()
if err != nil {
fmt.Fprintln(os.Stderr, err)
console.Fatal("addon list failed: %v", err)
os.Exit(1)
}
},
......
......@@ -17,13 +17,13 @@ limitations under the License.
package config
import (
"fmt"
"os"
"text/template"
"github.com/golang/glog"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
)
......@@ -41,7 +41,7 @@ var configViewCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
err := configView()
if err != nil {
fmt.Fprintln(os.Stderr, err)
console.Fatal("config view failed: %v", err)
os.Exit(1)
}
},
......
......@@ -17,11 +17,11 @@ limitations under the License.
package config
import (
"fmt"
"io/ioutil"
"os"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"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 {
fmt.Fprintln(os.Stderr, "usage: minikube addons configure ADDON_NAME")
console.ErrStyle("usage", "usage: minikube addons configure ADDON_NAME")
os.Exit(1)
}
......@@ -78,7 +78,7 @@ var addonsConfigureCmd = &cobra.Command{
dat, err := ioutil.ReadFile(gcrPath)
if err != nil {
fmt.Println("Could not read file for application_default_credentials.json")
console.Failure("Error reading %s: %v", gcrPath, err)
} else {
gcrApplicationDefaultCredentials = string(dat)
}
......@@ -110,7 +110,7 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
fmt.Println("ERROR creating `registry-creds-ecr` secret")
console.Failure("ERROR creating `registry-creds-ecr` secret: %v", err)
}
// Create GCR Secret
......@@ -128,7 +128,7 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
fmt.Println("ERROR creating `registry-creds-gcr` secret")
console.Failure("ERROR creating `registry-creds-gcr` secret: %v", err)
}
// Create Docker Secret
......@@ -147,16 +147,16 @@ var addonsConfigureCmd = &cobra.Command{
})
if err != nil {
fmt.Println("ERROR creating `registry-creds-dpr` secret")
console.Warning("ERROR creating `registry-creds-dpr` secret")
}
break
default:
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s has no available configuration options", addon))
console.Failure("%s has no available configuration options", addon)
return
}
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s was successfully configured", addon))
console.Success("%s was successfully configured", addon)
},
}
......
......@@ -17,10 +17,10 @@ limitations under the License.
package config
import (
"fmt"
"os"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
)
var addonsDisableCmd = &cobra.Command{
......@@ -29,17 +29,17 @@ 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 {
fmt.Fprintln(os.Stderr, "usage: minikube addons disable ADDON_NAME")
console.ErrStyle("usage", "usage: minikube addons disable ADDON_NAME")
os.Exit(1)
}
addon := args[0]
err := Set(addon, "false")
if err != nil {
fmt.Fprintln(os.Stdout, err)
console.Fatal("disable failed: %v", err)
os.Exit(1)
}
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s was successfully disabled", addon))
console.Success("%s was successfully disabled", addon)
},
}
......
......@@ -17,10 +17,10 @@ limitations under the License.
package config
import (
"fmt"
"os"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
)
var addonsEnableCmd = &cobra.Command{
......@@ -29,16 +29,16 @@ 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 {
fmt.Fprintln(os.Stderr, "usage: minikube addons enable ADDON_NAME")
console.ErrStyle("usage", "usage: minikube addons enable ADDON_NAME")
os.Exit(1)
}
addon := args[0]
err := Set(addon, "true")
if err != nil {
fmt.Fprintln(os.Stdout, err)
console.Fatal("enable failed: %v", err)
} else {
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s was successfully enabled", addon))
console.Success("%s was successfully enabled", addon)
}
},
}
......
......@@ -19,10 +19,10 @@ package config
import (
"errors"
"fmt"
"os"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
)
var configGetCmd = &cobra.Command{
......@@ -44,7 +44,7 @@ var configGetCmd = &cobra.Command{
return fmt.Errorf("no value for key '%s'", args[0])
}
fmt.Fprintln(os.Stdout, val)
console.OutLn(val)
return nil
},
}
......
......@@ -17,13 +17,13 @@ limitations under the License.
package config
import (
"fmt"
"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/machine"
"k8s.io/minikube/pkg/minikube/service"
......@@ -47,21 +47,21 @@ var addonsOpenCmd = &cobra.Command{
PreRun: func(cmd *cobra.Command, args []string) {
t, err := template.New("addonsURL").Parse(addonsURLFormat)
if err != nil {
fmt.Fprintln(os.Stderr, "The value passed to --format is invalid:\n\n", err)
console.Fatal("The value passed to --format is invalid: %s", err)
os.Exit(1)
}
addonsURLTemplate = t
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Fprintln(os.Stderr, "usage: minikube addons open ADDON_NAME")
console.ErrStyle("usage", "usage: minikube addons open ADDON_NAME")
os.Exit(1)
}
addonName := args[0]
//TODO(r2d4): config should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......@@ -69,20 +69,20 @@ var addonsOpenCmd = &cobra.Command{
cluster.EnsureMinikubeRunningOrExit(api, 1)
addon, ok := assets.Addons[addonName] // validate addon input
if !ok {
fmt.Fprintln(os.Stderr, fmt.Sprintf(`addon '%s' is not a valid addon packaged with minikube.
console.Fatal(`addon '%s' is not a valid addon packaged with minikube.
To see the list of available addons run:
minikube addons list`, addonName))
minikube addons list`, addonName)
os.Exit(1)
}
ok, err = addon.IsEnabled()
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
console.Fatal("IsEnabled error: %v", err)
os.Exit(1)
}
if !ok {
fmt.Fprintln(os.Stderr, fmt.Sprintf(`addon '%s' is currently not enabled.
console.ErrStyle("conflict", `addon '%s' is currently not enabled.
To enable this addon run:
minikube addons enable %s`, addonName, addonName))
minikube addons enable %s`, addonName, addonName)
os.Exit(1)
}
......@@ -91,15 +91,15 @@ minikube addons enable %s`, addonName, addonName))
serviceList, err := service.GetServiceListByLabel(namespace, key, addonName)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting service with namespace: %s and labels %s:%s: %v\n", namespace, key, addonName, err)
console.Fatal("Error getting service with namespace: %s and labels %s:%s: %v", namespace, key, addonName, err)
os.Exit(1)
}
if len(serviceList.Items) == 0 {
fmt.Fprintf(os.Stdout, `
console.Fatal(`
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)
os.Exit(0)
os.Exit(1)
}
for i := range serviceList.Items {
svc := serviceList.Items[i].ObjectMeta.Name
......
......@@ -17,11 +17,11 @@ limitations under the License.
package config
import (
"fmt"
"os"
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
)
var ProfileCmd = &cobra.Command{
......@@ -30,7 +30,7 @@ var ProfileCmd = &cobra.Command{
Long: "profile sets the current minikube profile. This is used to run and manage multiple minikube instance. You can return to the default minikube profile by running `minikube profile default`",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Fprintln(os.Stderr, "usage: minikube profile MINIKUBE_PROFILE_NAME")
console.ErrStyle("usage", "usage: minikube profile MINIKUBE_PROFILE_NAME")
os.Exit(1)
}
......@@ -40,9 +40,10 @@ var ProfileCmd = &cobra.Command{
}
err := Set(pkgConfig.MachineProfile, profile)
if err != nil {
fmt.Fprintln(os.Stdout, err)
console.Fatal("set failed: %v", err)
os.Exit(1)
} else {
fmt.Fprintln(os.Stdout, fmt.Sprintf("minikube profile was successfully set to %s", profile))
console.Success("minikube profile was successfully set to %s", profile)
}
},
}
......@@ -18,13 +18,13 @@ package config
import (
"bufio"
"fmt"
"io"
"log"
"os"
"strings"
"golang.org/x/crypto/ssh/terminal"
"k8s.io/minikube/pkg/minikube/console"
)
// AskForYesNoConfirmation asks the user for confirmation. A user must type in "yes" or "no" and
......@@ -35,7 +35,7 @@ func AskForYesNoConfirmation(s string, posResponses, negResponses []string) bool
reader := bufio.NewReader(os.Stdin)
for {
fmt.Printf("%s [y/n]: ", s)
console.Out("%s [y/n]: ", s)
response, err := reader.ReadString('\n')
if err != nil {
......@@ -49,7 +49,7 @@ func AskForYesNoConfirmation(s string, posResponses, negResponses []string) bool
} else if containsString(negResponses, response) {
return false
} else {
fmt.Println("Please type yes or no:")
console.Err("Please type yes or no:")
return AskForYesNoConfirmation(s, posResponses, negResponses)
}
}
......@@ -64,7 +64,7 @@ func AskForStaticValue(s string) string {
// Can't have zero length
if len(response) == 0 {
fmt.Println("--Error, please enter a value:")
console.Err("--Error, please enter a value:")
continue
}
return response
......@@ -79,7 +79,7 @@ func AskForStaticValueOptional(s string) string {
}
func getStaticValue(reader *bufio.Reader, s string) string {
fmt.Printf("%s", s)
console.Out("%s", s)
response, err := reader.ReadString('\n')
if err != nil {
......@@ -111,7 +111,7 @@ func concealableAskForStaticValue(readWriter io.ReadWriter, promptString string,
}
response = strings.TrimSpace(response)
if len(response) == 0 {
fmt.Println("--Error, please enter a value:")
console.Warning("Please enter a value:")
return concealableAskForStaticValue(readWriter, promptString, hidden)
}
return response, nil
......
......@@ -17,12 +17,11 @@ limitations under the License.
package config
import (
"fmt"
"os"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
)
var configSetCmd = &cobra.Command{
......@@ -32,12 +31,12 @@ 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 {
fmt.Fprintln(os.Stderr, "usage: minikube config set PROPERTY_NAME PROPERTY_VALUE")
console.ErrStyle("usage", "usage: minikube config set PROPERTY_NAME PROPERTY_VALUE")
os.Exit(1)
}
err := Set(args[0], args[1])
if err != nil {
fmt.Fprintln(os.Stderr, err)
console.Fatal("Set failed: %v", err)
os.Exit(1)
}
},
......
......@@ -17,12 +17,11 @@ limitations under the License.
package config
import (
"fmt"
"os"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"github.com/spf13/cobra"
pkgConfig "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
)
var configUnsetCmd = &cobra.Command{
......@@ -31,12 +30,12 @@ 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 {
fmt.Fprintln(os.Stdout, "usage: minikube config unset PROPERTY_NAME")
console.ErrStyle("usage", "usage: minikube config unset PROPERTY_NAME")
os.Exit(1)
}
err := unset(args[0])
if err != nil {
fmt.Fprintln(os.Stdout, err)
console.Fatal("unset failed: %v", err)
}
},
}
......
......@@ -26,6 +26,7 @@ import (
"k8s.io/minikube/pkg/minikube/assets"
"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/machine"
"k8s.io/minikube/pkg/minikube/storageclass"
......@@ -105,7 +106,7 @@ func EnableOrDisableAddon(name string, val string) error {
//TODO(r2d4): config package should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -28,6 +28,7 @@ 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"
)
......@@ -41,7 +42,7 @@ func IsValidDriver(string, driver string) error {
}
func RequiresRestartMsg(string, string) error {
fmt.Fprintln(os.Stdout, "These changes will take effect upon a minikube delete and then a minikube start")
console.OutStyle("warning", "These changes will take effect upon a minikube delete and then a minikube start")
return nil
}
......
......@@ -33,6 +33,7 @@ import (
configcmd "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/util"
......@@ -60,46 +61,47 @@ var dashboardCmd = &cobra.Command{
}()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
cluster.EnsureMinikubeRunningOrExit(api, 1)
fmt.Fprintln(os.Stderr, "Enabling dashboard ...")
// Send status messages to stderr for folks re-using this output.
console.ErrStyle("enabling", "Enabling dashboard ...")
// Enable the dashboard add-on
err = configcmd.Set("dashboard", "true")
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to enable dashboard: %v\n", err)
console.Fatal("Unable to enable dashboard: %v", err)
os.Exit(1)
}
ns := "kube-system"
svc := "kubernetes-dashboard"
fmt.Fprintln(os.Stderr, "Verifying dashboard health ...")
console.ErrStyle("verifying", "Verifying dashboard health ...")
if err = util.RetryAfter(180, func() error { return service.CheckService(ns, svc) }, 1*time.Second); err != nil {
fmt.Fprintf(os.Stderr, "%s:%s is not running: %v\n", ns, svc, err)
console.Fatal("%s:%s is not running: %v", ns, svc, err)
os.Exit(1)
}
fmt.Fprintln(os.Stderr, "Launching proxy ...")
console.ErrStyle("launch", "Launching proxy ...")
p, hostPort, err := kubectlProxy()
if err != nil {
glog.Fatalf("kubectl proxy: %v", err)
}
url := dashboardURL(hostPort, ns, svc)
fmt.Fprintln(os.Stderr, "Verifying proxy health ...")
console.ErrStyle("verifying", "Verifying proxy health ...")
if err = util.RetryAfter(60, func() error { return checkURL(url) }, 1*time.Second); err != nil {
fmt.Fprintf(os.Stderr, "%s is not responding properly: %v\n", url, err)
console.Fatal("%s is not responding properly: %v", url, err)
os.Exit(1)
}
if dashboardURLMode {
fmt.Fprintln(os.Stdout, url)
console.OutLn(url)
} else {
fmt.Fprintln(os.Stdout, fmt.Sprintf("Opening %s in your default browser...", url))
console.ErrStyle("celebrate", "Opening %s in your default browser...", url)
if err = browser.OpenURL(url); err != nil {
fmt.Fprintf(os.Stderr, fmt.Sprintf("failed to open browser: %v", err))
console.Failure("failed to open browser: %v", err)
}
}
......
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
......@@ -25,6 +24,7 @@ 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/machine"
)
......@@ -37,30 +37,30 @@ var deleteCmd = &cobra.Command{
associated files.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
fmt.Fprintln(os.Stderr, "usage: minikube delete")
console.ErrStyle("usage", "usage: minikube delete")
os.Exit(1)
}
fmt.Println("Deleting local Kubernetes cluster...")
console.OutStyle("stopping", "Deleting local Kubernetes cluster ...")
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
if err = cluster.DeleteHost(api); err != nil {
fmt.Println("Errors occurred deleting machine: ", err)
console.Fatal("Errors occurred deleting machine: %v", err)
os.Exit(1)
}
fmt.Println("Machine deleted.")
console.Success("Machine deleted.")
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
console.Fatal("Errors occurred deleting mount process: %v", err)
}
if err := os.Remove(constants.GetProfileFile(viper.GetString(pkg_config.MachineProfile))); err != nil {
fmt.Println("Error deleting machine profile config")
console.Fatal("Error deleting machine profile config: %v", err)
os.Exit(1)
}
},
......
......@@ -34,6 +34,7 @@ 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/machine"
)
......@@ -308,25 +309,24 @@ var dockerEnvCmd = &cobra.Command{
Short: "Sets up docker env variables; similar to '$(docker-machine env)'",
Long: `Sets up docker env variables; similar to '$(docker-machine env)'.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfHostExistsAndLoad(api, config.GetMachineName())
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %v\n", err)
console.Fatal("Error getting host: %v", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube docker-env' command`)
os.Exit(0)
console.Fatal(`'none' driver does not support 'minikube docker-env' command`)
os.Exit(1)
}
docker, err := GetDockerActive(host)
if !docker {
fmt.Println(`# The docker service is currently not active`)
console.OutLn(`# The docker service is currently not active`)
os.Exit(1)
}
......
......@@ -17,12 +17,11 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/golang/glog"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/machine"
)
......@@ -34,21 +33,21 @@ var ipCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
host, err := api.Load(config.GetMachineName())
if err != nil {
glog.Errorln("Error getting IP: ", err)
console.Fatal("Error getting host: %v", err)
os.Exit(1)
}
ip, err := host.Driver.GetIP()
if err != nil {
glog.Errorln("Error getting IP: ", err)
console.Fatal("Error getting IP: %v", err)
os.Exit(1)
}
fmt.Println(ip)
console.OutLn(ip)
},
}
......
......@@ -17,8 +17,6 @@ limitations under the License.
package cmd
import (
"fmt"
"log"
"os"
"github.com/golang/glog"
......@@ -26,6 +24,7 @@ import (
"github.com/spf13/viper"
cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/machine"
)
......@@ -41,7 +40,7 @@ var logsCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......@@ -52,7 +51,7 @@ var logsCmd = &cobra.Command{
err = clusterBootstrapper.GetClusterLogsTo(follow, os.Stdout)
if err != nil {
log.Println("Error getting machine logs:", err)
console.Fatal("Error getting machine logs:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
},
......
......@@ -17,18 +17,17 @@ limitations under the License.
package cmd
import (
"fmt"
"net"
"os"
"sync"
"strings"
"sync"
"github.com/golang/glog"
"github.com/spf13/cobra"
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/machine"
"k8s.io/minikube/third_party/go9p/ufs"
......@@ -49,42 +48,36 @@ var mountCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
if isKill {
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
console.Fatal("Error killing mount process: ", err)
os.Exit(1)
}
os.Exit(0)
}
if len(args) != 1 {
errText := `Please specify the directory to be mounted:
minikube mount HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY(ex:"/host-home:/vm-home")
`
fmt.Fprintln(os.Stderr, errText)
console.ErrStyle("usage", `Please specify the directory to be mounted:
minikube mount HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY(ex:"/host-home:/vm-home")`)
os.Exit(1)
}
mountString := args[0]
idx := strings.LastIndex(mountString, ":")
if idx == -1 { // no ":" was present
errText := `Mount directory must be in the form:
HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY`
fmt.Fprintln(os.Stderr, errText)
console.ErrStyle("usage", `Mount directory must be in the form:
HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY`)
os.Exit(1)
}
hostPath := mountString[:idx]
vmPath := mountString[idx+1:]
if _, err := os.Stat(hostPath); err != nil {
if os.IsNotExist(err) {
errText := fmt.Sprintf("Cannot find directory %s for mount", hostPath)
fmt.Fprintln(os.Stderr, errText)
console.Fatal("Cannot find directory %s for mount", hostPath)
} else {
errText := fmt.Sprintf("Error accessing directory %s for mount", hostPath)
fmt.Fprintln(os.Stderr, errText)
console.Fatal("Error accessing directory %s for mount", hostPath)
}
os.Exit(1)
}
if len(vmPath) == 0 || !strings.HasPrefix(vmPath, "/") {
errText := fmt.Sprintf("The :VM_MOUNT_DIRECTORY must be an absolute path")
fmt.Fprintln(os.Stderr, errText)
console.ErrStyle("usage", "The :VM_MOUNT_DIRECTORY must be an absolute path")
os.Exit(1)
}
var debugVal int
......@@ -93,17 +86,17 @@ var mountCmd = &cobra.Command{
}
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
host, err := api.Load(config.GetMachineName())
if err != nil {
glog.Errorln("Error loading api: ", err)
console.Fatal("Error loading api: %v", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube mount' command`)
console.Fatal(`'none' driver does not support 'minikube mount' command`)
os.Exit(0)
}
var ip net.IP
......@@ -120,11 +113,11 @@ var mountCmd = &cobra.Command{
os.Exit(1)
}
}
fmt.Printf("Mounting %s into %s on the minikube VM\n", hostPath, vmPath)
fmt.Println("This daemon process needs to stay alive for the mount to still be accessible...")
console.OutStyle("mounting", "Mounting %s into %s on the minikube VM", hostPath, vmPath)
console.OutStyle("notice", "This daemon process needs to stay alive for the mount to be accessible ...")
port, err := cmdUtil.GetPort()
if err != nil {
glog.Errorln("Error finding port for mount: ", err)
console.Fatal("Error finding port for mount: %v", err)
os.Exit(1)
}
var wg sync.WaitGroup
......@@ -135,7 +128,7 @@ var mountCmd = &cobra.Command{
}()
err = cluster.MountHost(api, ip, vmPath, port, mountVersion, uid, gid, msize)
if err != nil {
fmt.Println(err.Error())
console.Fatal(err.Error())
os.Exit(1)
}
wg.Wait()
......
......@@ -17,12 +17,12 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"text/template"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/service"
......@@ -48,7 +48,7 @@ var serviceCmd = &cobra.Command{
PersistentPreRun: func(cmd *cobra.Command, args []string) {
t, err := template.New("serviceURL").Parse(serviceURLFormat)
if err != nil {
fmt.Fprintln(os.Stderr, "The value passed to --format is invalid:\n\n", err)
console.Fatal("The value passed to --format is invalid: %v", err)
os.Exit(1)
}
serviceURLTemplate = t
......@@ -57,15 +57,14 @@ var serviceCmd = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 || len(args) > 1 {
errText := "Please specify a service name."
fmt.Fprintln(os.Stderr, errText)
console.Fatal("No service name was specified.")
os.Exit(1)
}
svc := args[0]
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......@@ -74,7 +73,7 @@ var serviceCmd = &cobra.Command{
err = service.WaitAndMaybeOpenService(api, namespace, svc,
serviceURLTemplate, serviceURLMode, https, wait, interval)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening service: %v\n", err)
console.Fatal("Error opening service: %v", err)
os.Exit(1)
}
},
......
......@@ -17,14 +17,13 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"strings"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/service"
)
......@@ -39,14 +38,14 @@ var serviceListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
serviceURLs, err := service.GetServiceURLs(api, serviceListNamespace, serviceURLTemplate)
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, "Check that minikube is running and that you have specified the correct namespace (-n flag) if required.")
console.Fatal("Failed to get service URL: %v", err)
console.ErrStyle("notice", "Check that minikube is running and that you have specified the correct namespace (-n flag) if required.")
os.Exit(1)
}
......
......@@ -17,12 +17,11 @@ limitations under the License.
package cmd
import (
"fmt"
"path/filepath"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
)
......@@ -32,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) {
fmt.Println(filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), "id_rsa"))
console.OutLn(filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), "id_rsa"))
},
}
......
......@@ -17,14 +17,12 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/golang/glog"
"github.com/pkg/errors"
"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/machine"
)
......@@ -36,22 +34,22 @@ var sshCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfHostExistsAndLoad(api, config.GetMachineName())
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %v\n", err)
console.Fatal("Error getting host: %v", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
fmt.Println(`'none' driver does not support 'minikube ssh' command`)
console.Fatal(`'none' driver does not support 'minikube ssh' command`)
os.Exit(0)
}
err = cluster.CreateSSHShell(api, args)
if err != nil {
glog.Errorln(errors.Wrap(err, "Error attempting to ssh/run-ssh-command"))
console.Fatal("Error creating SSH shell: %v", err)
os.Exit(1)
}
},
......
......@@ -24,6 +24,7 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
......@@ -39,6 +40,7 @@ import (
cmdutil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
pkgutil "k8s.io/minikube/pkg/util"
......@@ -116,16 +118,20 @@ func SetContainerRuntime(cfg map[string]string, runtime string) map[string]strin
}
func runStart(cmd *cobra.Command, args []string) {
if glog.V(8) {
glog.Infoln("Viper configuration:")
viper.Debug()
}
console.OutStyle("happy", "minikube %s on %s (%s)", version.GetVersion(), runtime.GOOS, runtime.GOARCH)
shouldCacheImages := viper.GetBool(cacheImages)
k8sVersion := viper.GetString(kubernetesVersion)
clusterBootstrapper := viper.GetString(cmdcfg.Bootstrapper)
var groupCacheImages errgroup.Group
if shouldCacheImages {
console.OutStyle("caching", "Caching images in the background ...")
groupCacheImages.Go(func() error {
return machine.CacheImagesForBootstrapper(k8sVersion, clusterBootstrapper)
})
......@@ -133,27 +139,24 @@ func runStart(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
fatalExit("Error getting client: %v", err)
}
defer api.Close()
exists, err := api.Exists(cfg.GetMachineName())
if err != nil {
glog.Exitf("checking if machine exists: %v", err)
fatalExit("Failed existence check: %v", err)
}
diskSize := viper.GetString(humanReadableDiskSize)
diskSizeMB := pkgutil.CalculateDiskSizeInMB(diskSize)
if diskSizeMB < constants.MinimumDiskSizeMB {
err := fmt.Errorf("Disk Size %dMB (%s) is too small, the minimum disk size is %dMB", diskSizeMB, diskSize, constants.MinimumDiskSizeMB)
glog.Errorln("Error parsing disk size:", err)
os.Exit(1)
fatalExit("Requested disk size (%dMB) is less than minimum of %dMB", diskSizeMB, constants.MinimumDiskSizeMB)
}
if viper.GetBool(gpu) && viper.GetString(vmDriver) != "kvm2" {
glog.Exitf("--gpu is only supported with --vm-driver=kvm2")
fatalExit("Sorry, the --gpu feature is currently only supported with --vm-driver=kvm2")
}
config := cfg.MachineConfig{
......@@ -184,7 +187,7 @@ func runStart(cmd *cobra.Command, args []string) {
// Load current profile cluster config from file, before overwriting it with the new state
oldConfig, err := cfg.Load()
if err != nil && !os.IsNotExist(err) {
glog.Errorln("Error loading profile config: ", err)
fatalExit("Error loading profile config: %v", err)
}
// Write profile cluster configuration to file
......@@ -193,30 +196,28 @@ func runStart(cmd *cobra.Command, args []string) {
}
if err := saveConfig(clusterConfig); err != nil {
glog.Errorln("Error saving profile cluster configuration: ", err)
fatalExit("Error saving profile cluster configuration: %v", err)
}
fmt.Printf("Starting local Kubernetes %s cluster...\n", viper.GetString(kubernetesVersion))
fmt.Println("Starting VM...")
console.OutStyle("starting-vm", "Starting local Kubernetes %s cluster ...", viper.GetString(kubernetesVersion))
var host *host.Host
start := func() (err error) {
host, err = cluster.StartHost(api, config)
if err != nil {
glog.Errorf("Error starting host: %v.\n\n Retrying.\n", err)
glog.Errorf("StartHost: %v", err)
}
return err
}
err = pkgutil.RetryAfter(5, start, 2*time.Second)
if err != nil {
glog.Errorln("Error starting host: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Error starting host: ", err)
}
fmt.Println("Getting VM IP address...")
console.OutStyle("connectivity", "Verifying connectivity ...")
ip, err := host.Driver.GetIP()
if err != nil {
glog.Errorln("Error getting VM IP address: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Unable to get VM IP address", err)
}
// common config (currently none)
......@@ -224,12 +225,11 @@ func runStart(cmd *cobra.Command, args []string) {
selectedContainerRuntime := viper.GetString(containerRuntime)
if cricfg := SetContainerRuntime(cricfg, selectedContainerRuntime); cricfg != nil {
var command string
fmt.Println("Writing crictl config...")
if command, err = cmdutil.GetCrictlConfigCommand(cricfg); err == nil {
_, err = host.RunSSHCommand(command)
}
if err != nil {
glog.Errorln("Error writing crictl config: ", err)
reportAndExit("Error writing crictl config", err)
}
}
......@@ -238,20 +238,24 @@ func runStart(cmd *cobra.Command, args []string) {
selectedKubernetesVersion = constants.DefaultKubernetesVersion
}
if oldConfig != nil {
oldKubernetesVersion, err := semver.Make(strings.TrimPrefix(oldConfig.KubernetesConfig.KubernetesVersion, version.VersionPrefix))
if err != nil {
glog.Errorln("Error parsing version semver: ", err)
}
newKubernetesVersion, err := semver.Make(strings.TrimPrefix(viper.GetString(kubernetesVersion), version.VersionPrefix))
if err != nil {
glog.Errorln("Error parsing version semver: ", err)
}
// Check if it's an attempt to downgrade version. Avoid version downgrad.
if newKubernetesVersion.LT(oldKubernetesVersion) {
selectedKubernetesVersion = version.VersionPrefix + oldKubernetesVersion.String()
fmt.Println("Kubernetes version downgrade is not supported. Using version:", selectedKubernetesVersion)
ov := strings.TrimPrefix(oldConfig.KubernetesConfig.KubernetesVersion, version.VersionPrefix)
// Don't complain about empty version strings in our old config.
if ov != "" {
oldKubernetesVersion, err := semver.Make(ov)
if err != nil {
glog.Errorf("Error parsing old version %q: %v", ov, err)
}
nv := strings.TrimPrefix(viper.GetString(kubernetesVersion), version.VersionPrefix)
newKubernetesVersion, err := semver.Make(nv)
if err != nil {
fatalExit("Error parsing new version %q: %v", nv, err)
}
// Check if it's an attempt to downgrade version. Avoid version downgrad.
if newKubernetesVersion.LT(oldKubernetesVersion) {
selectedKubernetesVersion = version.VersionPrefix + oldKubernetesVersion.String()
console.ErrStyle("conflict", "Kubernetes downgrade is not supported, will continue to use %v", selectedKubernetesVersion)
}
}
}
......@@ -276,7 +280,7 @@ func runStart(cmd *cobra.Command, args []string) {
k8sBootstrapper, err := GetClusterBootstrapper(api, clusterBootstrapper)
if err != nil {
glog.Exitf("Error getting cluster bootstrapper: %v", err)
reportAndExit("Error getting cluster bootstrapper", err)
}
// Write profile cluster configuration to file
......@@ -286,42 +290,33 @@ func runStart(cmd *cobra.Command, args []string) {
}
if err := saveConfig(clusterConfig); err != nil {
glog.Errorln("Error saving profile cluster configuration: ", err)
reportAndExit("Error saving profile cluster configuration", err)
}
if shouldCacheImages {
fmt.Println("Waiting for image caching to complete...")
console.OutStyle("waiting", "Waiting for image caching to complete ...")
if err := groupCacheImages.Wait(); err != nil {
glog.Errorln("Error caching images: ", err)
}
}
fmt.Println("Moving files into cluster...")
console.OutStyle("copying", "Copying files into VM ...")
if err := k8sBootstrapper.UpdateCluster(kubernetesConfig); err != nil {
glog.Errorln("Error updating cluster: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Failed to update cluster", err)
}
fmt.Println("Setting up certs...")
if err := k8sBootstrapper.SetupCerts(kubernetesConfig); err != nil {
glog.Errorln("Error configuring authentication: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Failed to setup certs", err)
}
fmt.Println("Connecting to cluster...")
kubeHost, err := host.Driver.GetURL()
if err != nil {
glog.Errorln("Error connecting to cluster: ", err)
reportAndExit("Failed to get driver URL", err)
}
kubeHost = strings.Replace(kubeHost, "tcp://", "https://", -1)
kubeHost = strings.Replace(kubeHost, ":2376", ":"+strconv.Itoa(kubernetesConfig.NodePort), -1)
fmt.Println("Setting up kubeconfig...")
// setup kubeconfig
kubeConfigFile := cmdutil.GetKubeConfigPath()
kubeCfgSetup := &kubeconfig.KubeConfigSetup{
ClusterName: cfg.GetMachineName(),
ClusterServerAddress: kubeHost,
......@@ -334,23 +329,24 @@ func runStart(cmd *cobra.Command, args []string) {
kubeCfgSetup.SetKubeConfigFile(kubeConfigFile)
if err := kubeconfig.SetupKubeConfig(kubeCfgSetup); err != nil {
glog.Errorln("Error setting up kubeconfig: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Failed to setup kubeconfig", err)
}
fmt.Println("Stopping extra container runtimes...")
// TODO(tstromberg): use cruntime.Manager.Name() once PR is merged
rname := viper.GetString(containerRuntime)
console.OutStyle("container-runtime", "Configuring %s within VM ...", rname)
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != "" {
if _, err := host.RunSSHCommand("sudo systemctl stop docker"); err == nil {
_, err = host.RunSSHCommand("sudo systemctl stop docker.socket")
}
if err != nil {
glog.Errorf("Error stopping docker: %v", err)
reportAndExit("Failed to stop docker", err)
}
}
if config.VMDriver != constants.DriverNone && (selectedContainerRuntime != constants.CrioRuntime && selectedContainerRuntime != constants.Cri_oRuntime) {
if _, err := host.RunSSHCommand("sudo systemctl stop crio"); err != nil {
glog.Errorf("Error stopping crio: %v", err)
reportAndExit("Failed to stop CRIO", err)
}
}
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != constants.RktRuntime {
......@@ -358,40 +354,39 @@ func runStart(cmd *cobra.Command, args []string) {
_, err = host.RunSSHCommand("sudo systemctl stop rkt-metadata")
}
if err != nil {
glog.Errorf("Error stopping rkt: %v", err)
reportAndExit("Failed to stop rkt", err)
}
}
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != constants.ContainerdRuntime {
if _, err = host.RunSSHCommand("sudo systemctl stop containerd"); err != nil {
glog.Errorf("Error stopping containerd: %v", err)
reportAndExit("Failed to stop containerd", err)
}
}
if config.VMDriver != constants.DriverNone && (selectedContainerRuntime == constants.CrioRuntime || selectedContainerRuntime == constants.Cri_oRuntime) {
fmt.Println("Restarting crio runtime...")
// restart crio so that it can monitor all hook dirs
if _, err := host.RunSSHCommand("sudo systemctl restart crio"); err != nil {
glog.Errorf("Error restarting crio: %v", err)
reportAndExit("Failed to restart crio", err)
}
}
if config.VMDriver != constants.DriverNone && selectedContainerRuntime == constants.ContainerdRuntime {
fmt.Println("Restarting containerd runtime...")
console.Fatal("Restarting containerd runtime...")
// restart containerd so that it can install all plugins
if _, err := host.RunSSHCommand("sudo systemctl restart containerd"); err != nil {
glog.Errorf("Error restarting containerd: %v", err)
reportAndExit("Failed to restart containerd", err)
}
}
if config.VMDriver == constants.DriverNone {
if viper.GetBool(cfg.WantNoneDriverWarning) {
fmt.Println(`===================
console.ErrLn(`===================
WARNING: IT IS RECOMMENDED NOT TO RUN THE NONE DRIVER ON PERSONAL WORKSTATIONS
The 'none' driver will run an insecure kubernetes apiserver as root that may leave the host vulnerable to CSRF attacks` + "\n")
}
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") == "" {
fmt.Println(`When using the none driver, the kubectl config and credentials generated will be root owned and will appear in the root home directory.
console.Fatal(`When using the none driver, the kubectl config and credentials generated will be root owned and will appear in the root home directory.
You will need to move the files to the appropriate location and then set the correct permissions. An example of this is below:
sudo mv /root/.kube $HOME/.kube # this will write over any previous configuration
......@@ -405,61 +400,55 @@ You will need to move the files to the appropriate location and then set the cor
This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true`)
}
if err := pkgutil.MaybeChownDirRecursiveToMinikubeUser(constants.GetMinipath()); err != nil {
glog.Errorf("Error recursively changing ownership of directory %s: %s",
constants.GetMinipath(), err)
cmdutil.MaybeReportErrorAndExit(err)
fatalExit("Failed to chown %s: %v", constants.GetMinipath(), err)
}
}
if !exists || config.VMDriver == constants.DriverNone {
fmt.Println("Starting cluster components...")
console.OutStyle("launch", "Launching Kubernetes %s with %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
if err := k8sBootstrapper.StartCluster(kubernetesConfig); err != nil {
glog.Errorf("Error starting cluster: %v", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Error starting cluster", err)
}
} else {
fmt.Println("Machine exists, restarting cluster components...")
console.OutStyle("restarting", "Relaunching Kubernetes %s with %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
if err := k8sBootstrapper.RestartCluster(kubernetesConfig); err != nil {
glog.Errorln("Error restarting cluster: ", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("Error restarting cluster", err)
}
}
// Block until the cluster is healthy.
fmt.Print("Verifying kubelet health ...")
console.OutStyle("verifying", "Verifying component health ...")
kStat := func() (err error) {
st, err := k8sBootstrapper.GetKubeletStatus()
if err != nil || st != state.Running.String() {
fmt.Printf(".")
console.Out(".")
return &pkgutil.RetriableError{Err: fmt.Errorf("kubelet unhealthy: %v: %s", err, st)}
}
return nil
}
err = pkgutil.RetryAfter(20, kStat, 3*time.Second)
if err != nil {
fmt.Printf("error: %v", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("kubelet checks failed", err)
}
fmt.Print("\nVerifying apiserver health ...")
aStat := func() (err error) {
st, err := k8sBootstrapper.GetApiServerStatus(net.ParseIP(ip))
if err != nil || st != state.Running.String() {
fmt.Print(".")
console.Out(".")
return &pkgutil.RetriableError{Err: fmt.Errorf("apiserver status=%s err=%v", st, err)}
}
return nil
}
err = pkgutil.RetryAfter(30, aStat, 10*time.Second)
// End the dots.
console.OutLn("")
if err != nil {
fmt.Printf("error: %v", err)
cmdutil.MaybeReportErrorAndExit(err)
reportAndExit("apiserver checks failed", err)
}
fmt.Println()
// start 9p server mount
if viper.GetBool(createMount) {
fmt.Printf("Setting up hostmount on %s...\n", viper.GetString(mountString))
console.OutStyle("mount", "Setting up mount on %s ...", viper.GetString(mountString))
path := os.Args[0]
mountDebugVal := 0
......@@ -485,18 +474,17 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
}
if kubeCfgSetup.KeepContext {
fmt.Printf("The local Kubernetes cluster has started. The kubectl context has not been altered, kubectl will require \"--context=%s\" to use the local Kubernetes cluster.\n",
console.OutStyle("kubectl", "The kubectl context has not been altered, kubectl will require \"--context=%s\" to use the local cluster.",
kubeCfgSetup.ClusterName)
} else {
fmt.Println("Kubectl is now configured to use the cluster.")
console.OutStyle("kubectl", "kubectl is now configured to use %q", cfg.GetMachineName())
}
fmt.Println("Loading cached images from config file.")
err = LoadCachedImagesInConfigFile()
if err != nil {
fmt.Println("Unable to load cached images from config file.")
console.Failure("Unable to load cached images from config file.")
}
fmt.Println("\n\nEverything looks great. Please enjoy minikube!")
console.OutStyle("ready", "Your local Kubernetes cluster is ready! Thank you for using minikube!")
return
}
......@@ -594,3 +582,18 @@ func saveConfigToFile(data []byte, file string) error {
}
return nil
}
// fatalExit is a shortcut for outputting a failure message and exiting.
func fatalExit(format string, a ...interface{}) {
glog.Errorf(format, a...)
console.Fatal(format, a...)
os.Exit(1)
}
// reportFatalExit is a shortcut for outputting an error, reporting it, and exiting.
func reportAndExit(msg string, err error) {
console.Fatal(msg+": %v", err)
glog.Errorf("%s: %v", msg, err)
cmdutil.MaybeReportErrorAndExit(err)
os.Exit(1)
}
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"text/template"
......@@ -29,6 +28,7 @@ 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/machine"
"k8s.io/minikube/pkg/util/kubeconfig"
......@@ -62,7 +62,7 @@ var statusCmd = &cobra.Command{
var returnCode = 0
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(internalErrorCode)
}
defer api.Close()
......
......@@ -17,13 +17,13 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"time"
"github.com/spf13/cobra"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/machine"
pkgutil "k8s.io/minikube/pkg/util"
)
......@@ -35,10 +35,10 @@ var stopCmd = &cobra.Command{
Long: `Stops a local kubernetes cluster running in Virtualbox. This command stops the VM
itself, leaving all files intact. The cluster can be started again with the "start" command.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Stopping local Kubernetes cluster...")
console.OutStyle("stopping", "Stopping local Kubernetes cluster...")
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......@@ -47,13 +47,13 @@ itself, leaving all files intact. The cluster can be started again with the "sta
return cluster.StopHost(api)
}
if err := pkgutil.RetryAfter(5, stop, 1*time.Second); err != nil {
fmt.Println("Error stopping machine: ", err)
console.Fatal("Error stopping machine: %v", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
fmt.Println("Machine stopped.")
console.OutStyle("stopped", "Machine stopped.")
if err := cmdUtil.KillMountProcess(); err != nil {
fmt.Println("Errors occurred deleting mount process: ", err)
console.Fatal("Errors occurred deleting mount process: %v", err)
}
},
}
......
......@@ -17,11 +17,10 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/notify"
"k8s.io/minikube/pkg/version"
......@@ -39,17 +38,17 @@ var updateCheckCmd = &cobra.Command{
url := constants.GithubMinikubeReleasesURL
r, err := notify.GetAllVersionsFromURL(url)
if err != nil {
fmt.Fprintf(os.Stderr, "Error fetching latest version from internet")
console.Fatal("Unable to fetch latest version info: %v", err)
os.Exit(1)
}
if len(r) < 1 {
fmt.Fprintf(os.Stderr, "Got empty version list from server")
console.Fatal("Update server returned an empty list")
os.Exit(2)
}
fmt.Println("CurrentVersion:", version.GetVersion())
fmt.Println("LatestVersion:", r[0].Name)
console.OutLn("CurrentVersion: %s", version.GetVersion())
console.OutLn("LatestVersion: %s", r[0].Name)
},
}
......
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"github.com/golang/glog"
......@@ -25,6 +24,7 @@ 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/machine"
kcfg "k8s.io/minikube/pkg/util/kubeconfig"
......@@ -39,7 +39,7 @@ var updateContextCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
console.Fatal("Error getting client: %v", err)
os.Exit(1)
}
defer api.Close()
......@@ -55,9 +55,9 @@ var updateContextCmd = &cobra.Command{
cmdUtil.MaybeReportErrorAndExit(err)
}
if ok {
fmt.Println("Reconfigured kubeconfig IP, now pointing at " + ip.String())
console.Fatal("Reconfigured kubeconfig IP, now pointing at %s", ip)
} else {
fmt.Println("Kubeconfig IP correctly configured, pointing at " + ip.String())
console.OutStyle("celebrate", "Kubeconfig IP has been updated to point at %s", ip)
}
},
......
......@@ -17,10 +17,8 @@ limitations under the License.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/version"
)
......@@ -33,8 +31,7 @@ var versionCmd = &cobra.Command{
enableUpdateNotification = false
},
Run: func(command *cobra.Command, args []string) {
fmt.Println("minikube version:", version.GetVersion())
console.OutLn("minikube version: %v", version.GetVersion())
},
}
......
......@@ -22,6 +22,7 @@ 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/provision"
......@@ -31,12 +32,17 @@ const minikubeEnableProfile = "MINIKUBE_ENABLE_PROFILING"
func main() {
defer glog.Flush()
if os.Getenv(minikubeEnableProfile) == "1" {
defer profile.Start(profile.TraceProfile).Stop()
}
if os.Getenv(constants.IsMinikubeChildProcess) == "" {
machine.StartDriver()
}
console.SetOutFile(os.Stdout)
console.SetErrFile(os.Stderr)
err := console.SetLanguage(os.Getenv("LANG"))
if err != nil {
glog.Warningf("unable to detect language: %v", err)
}
cmd.Execute()
}
......@@ -28,7 +28,7 @@ import (
func main() {
// Glog requires that /tmp exists.
if err := os.MkdirAll("/tmp", 0755); err != nil {
fmt.Printf("Error creating tmpdir: %v\n", err)
fmt.Fprintf(os.Stderr, "Error creating tmpdir: %v\n", err)
os.Exit(1)
}
flag.Parse()
......
......@@ -30,18 +30,18 @@ import (
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
"text/template"
"time"
"strconv"
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/viper"
"golang.org/x/crypto/ssh/terminal"
minikubeConfig "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/version"
)
......@@ -138,7 +138,7 @@ func MaybeReportErrorAndExitWithCode(errToReport error, returnCode int) {
if viper.GetBool(config.WantReportError) {
err = ReportError(errToReport, constants.ReportingURL)
} else if viper.GetBool(config.WantReportErrorPrompt) {
fmt.Println(
console.Err(
`================================================================================
An error has occurred. Would you like to opt in to sending anonymized crash
information to minikube to help prevent future errors?
......@@ -151,7 +151,7 @@ To disable this prompt, run: 'minikube config set WantReportErrorPrompt false'
err = ReportError(errToReport, constants.ReportingURL)
}
} else {
fmt.Println("Bummer, perhaps next time!")
console.ErrStyle("meh", "Bummer, perhaps next time!")
}
}
......@@ -159,13 +159,13 @@ To disable this prompt, run: 'minikube config set WantReportErrorPrompt false'
if err != nil {
glog.Infof("report error failed: %v", err)
}
fmt.Printf("\n\nminikube failed :( exiting with error code %d\n", returnCode)
console.ErrStyle("embarassed", "minikube failed, exiting with error code %d", returnCode)
os.Exit(returnCode)
}
func getInput(input chan string, r io.Reader) {
reader := bufio.NewReader(r)
fmt.Print("Please enter your response [Y/n]: ")
console.OutLn("Please enter your response [Y/n]: ")
response, err := reader.ReadString('\n')
if err != nil {
glog.Errorf(err.Error())
......@@ -187,11 +187,11 @@ func PromptUserForAccept(r io.Reader) bool {
} else if response == "n" || response == "no" {
return false
} else {
fmt.Println("Invalid response, error reporting remains disabled. Must be in form [Y/n]")
console.Warning("Invalid response, error reporting remains disabled. Must be in form [Y/n]")
return false
}
case <-time.After(30 * time.Second):
fmt.Println("Prompt timed out.")
console.Warning("Prompt timed out.")
return false
}
}
......
......@@ -34,7 +34,7 @@ type CommandRunner interface {
//
// var b bytes.Buffer
// CombinedOutput(cmd, &b)
// fmt.Println(b.Bytes())
// console.Fatal(b.Bytes())
//
// Or, you can set out to os.Stdout, the command output and
// error would show on your terminal immediately before you
......
......@@ -39,6 +39,7 @@ import (
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/console"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/sshutil"
......@@ -513,11 +514,9 @@ func maybeDownloadAndCache(binary, version string) (string, error) {
options.Checksum = constants.GetKubernetesReleaseURLSha1(binary, version)
options.ChecksumHash = crypto.SHA1
fmt.Printf("Downloading %s %s\n", binary, version)
console.OutStyle("download", "Downloading %s %s", binary, version)
if err := download.ToFile(url, targetFilepath, options); err != nil {
return "", errors.Wrapf(err, "Error downloading %s %s", binary, version)
}
fmt.Printf("Finished Downloading %s %s\n", binary, version)
return targetFilepath, nil
}
......@@ -38,8 +38,8 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"
"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/registry"
"k8s.io/minikube/pkg/util"
......@@ -80,7 +80,7 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
}
if h.Driver.DriverName() != config.VMDriver {
fmt.Printf("Skipping %s driver, existing host has %s driver.\n", config.VMDriver, h.Driver.DriverName())
console.Warning("Ignoring configuration which specifies %s driver, as the existing host is using the %s driver.", config.VMDriver, h.Driver.DriverName())
}
s, err := h.Driver.GetState()
......@@ -200,21 +200,21 @@ func preCreateHost(config *cfg.MachineConfig) error {
switch config.VMDriver {
case "kvm":
if viper.GetBool(cfg.ShowDriverDeprecationNotification) {
fmt.Fprintln(os.Stderr, `WARNING: The kvm driver is now deprecated and support for it will be removed in a future release.
console.Warning(`The kvm driver is deprecated and support for it will be removed in a future release.
Please consider switching to the kvm2 driver, which is intended to replace the kvm driver.
See https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#kvm2-driver for more information.
To disable this message, run [minikube config set WantShowDriverDeprecationNotification false]`)
}
case "xhyve":
if viper.GetBool(cfg.ShowDriverDeprecationNotification) {
fmt.Fprintln(os.Stderr, `WARNING: The xhyve driver is now deprecated and support for it will be removed in a future release.
console.Warning(`The xhyve driver is deprecated and support for it will be removed in a future release.
Please consider switching to the hyperkit driver, which is intended to replace the xhyve driver.
See https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperkit-driver for more information.
To disable this message, run [minikube config set WantShowDriverDeprecationNotification false]`)
}
case "vmwarefusion":
if viper.GetBool(cfg.ShowDriverDeprecationNotification) {
fmt.Fprintln(os.Stderr, `WARNING: The vmwarefusion driver is now deprecated and support for it will be removed in a future release.
console.Warning(`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 WantShowDriverDeprecationNotification false]`)
......@@ -412,11 +412,11 @@ func CreateSSHShell(api libmachine.API, args []string) error {
func EnsureMinikubeRunningOrExit(api libmachine.API, exitStatus int) {
s, err := GetHostStatus(api)
if err != nil {
glog.Errorln("Error getting machine status:", err)
console.Fatal("Error getting machine status:", err)
os.Exit(1)
}
if s != state.Running.String() {
fmt.Fprintln(os.Stderr, "minikube is not currently running so the service cannot be accessed")
console.ErrStyle("conflict", "minikube is not running, so the service cannot be accessed")
os.Exit(exitStatus)
}
}
......
// Package console provides a mechanism for sending localized, stylized output to the console.
package console
import (
"fmt"
"io"
"os"
"strings"
"github.com/golang/glog"
isatty "github.com/mattn/go-isatty"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
// 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("status-change", "Configuring things")
// console.SetErrFile(os.Stderr)
// console.Fatal("Oh no, everything failed.")
var (
// outFile is where Out* functions send output to. Set using SetOutFile()
outFile fdWriter
// errFile is where Err* functions send output to. Set using SetErrFile()
errFile fdWriter
// preferredLanguage is the default language messages will be output in
preferredLanguage = language.AmericanEnglish
// our default language
defaultLanguage = language.AmericanEnglish
// ignoreTTYCheck ignores the result of the TTY check (for testing!)
ignoreTTYCheck = false
// useColor is whether or not color output should be used, updated by Set*Writer.
useColor = false
)
// fdWriter is the subset of file.File that implements io.Writer and Fd()
type fdWriter interface {
io.Writer
Fd() uintptr
}
// OutStyle writes a stylized and formatted message to stdout
func OutStyle(style, format string, a ...interface{}) error {
OutStyle, err := applyStyle(style, useColor, fmt.Sprintf(format, a...))
if err != nil {
// Try anyways
if err := Out(OutStyle); err != nil {
glog.Errorf("Out failed: %v", err)
}
return err
}
return Out(OutStyle)
}
// Out writes a basic formatted string to stdout
func Out(format string, a ...interface{}) error {
p := message.NewPrinter(preferredLanguage)
if outFile == nil {
return fmt.Errorf("No output file has been set")
}
_, err := p.Fprintf(outFile, format, a...)
return err
}
// OutLn writes a basic formatted string with a newline to stdout
func OutLn(format string, a ...interface{}) error {
return Out(format+"\n", a...)
}
// ErrStyle writes a stylized and formatted error message to stderr
func ErrStyle(style, format string, a ...interface{}) error {
format, err := applyStyle(style, useColor, fmt.Sprintf(format, a...))
if err != nil {
// Try anyways.
if err := Err(format); err != nil {
glog.Errorf("Err failed: %v", err)
}
return err
}
return Err(format)
}
// Err writes a basic formatted string to stderr
func Err(format string, a ...interface{}) error {
p := message.NewPrinter(preferredLanguage)
if errFile == nil {
return fmt.Errorf("No error output file has been set")
}
_, err := p.Fprintf(errFile, format, a...)
return err
}
// ErrLn writes a basic formatted string with a newline to stderr
func ErrLn(format string, a ...interface{}) error {
return Err(format+"\n", a...)
}
// Success is a shortcut for writing a styled success message to stdout
func Success(format string, a ...interface{}) error {
return OutStyle("success", format, a...)
}
// Fatal is a shortcut for writing a styled fatal message to stderr
func Fatal(format string, a ...interface{}) error {
return ErrStyle("fatal", format, a...)
}
// Warning is a shortcut for writing a styled warning message to stderr
func Warning(format string, a ...interface{}) error {
return ErrStyle("warning", format, a...)
}
// Failure is a shortcut for writing a styled failure message to stderr
func Failure(format string, a ...interface{}) error {
return ErrStyle("failure", format, a...)
}
// SetLanguageTag configures which language future messages should use.
func SetLanguageTag(l language.Tag) {
glog.Infof("Setting Language to %s ...", l)
preferredLanguage = l
}
// SetLanguage configures which language future messages should use, based on a LANG string.
func SetLanguage(s string) error {
if s == "" || s == "C" {
SetLanguageTag(defaultLanguage)
return nil
}
// Ignore encoding preferences: we always output utf8. Handles "de_DE.utf8"
parts := strings.Split(s, ".")
l, err := language.Parse(parts[0])
if err != nil {
return err
}
SetLanguageTag(l)
return nil
}
// SetOutFile configures which writer standard output goes to.
func SetOutFile(w fdWriter) {
glog.Infof("Setting OutFile to %v (fd=%d) ...", w, w.Fd())
outFile = w
useColor = wantsColor(w.Fd())
}
// SetErrFile configures which writer error output goes to.
func SetErrFile(w fdWriter) {
glog.Infof("Setting ErrFile to %v (fd=%d)...", w, w.Fd())
errFile = w
useColor = wantsColor(w.Fd())
}
// wantsColor determines if the user might want colorized output.
func wantsColor(fd uintptr) bool {
// As in: term-256color
if !strings.Contains(os.Getenv("TERM"), "color") {
glog.Infof("TERM does not appear to support color")
return false
}
// Allow boring people to continue to be boring people.
if os.Getenv("MINIKUBE_IS_BORING") == "1" {
glog.Infof("minikube is boring.")
return false
}
if ignoreTTYCheck {
return true
}
isT := isatty.IsTerminal(fd)
glog.Infof("IsTerminal(%d) = %v", fd, isT)
return isT
}
package console
import (
"bytes"
"testing"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
// fakeFile satisfies fdWriter
type fakeFile struct {
b bytes.Buffer
}
func newFakeFile() *fakeFile {
// So that we don't have to fully emulate being a terminal
ignoreTTYCheck = true
return &fakeFile{}
}
func (f *fakeFile) Fd() uintptr {
return uintptr(0)
}
func (f *fakeFile) Write(p []byte) (int, error) {
return f.b.Write(p)
}
func (f *fakeFile) String() string {
return f.b.String()
}
func TestOutStyle(t *testing.T) {
f := newFakeFile()
SetOutFile(f)
if err := OutStyle("happy", "This is a happy message."); err != nil {
t.Errorf("unexpected error: %q", err)
}
got := f.String()
want := "😄 This is a happy message.\n"
if got != want {
t.Errorf("OutStyle() = %q, want %q", got, want)
}
}
func TestOut(t *testing.T) {
// An example translation just to assert that this code path is executed.
message.SetString(language.Arabic, "Installing Kubernetes version %s ...", "... %s تثبيت Kubernetes الإصدار")
SetLanguageTag(language.Arabic)
var tests = []struct {
format string
arg string
want string
}{
{format: "xyz123", want: "xyz123"},
{format: "Installing Kubernetes version %s ...", arg: "v1.13", want: "... v1.13 تثبيت Kubernetes الإصدار"},
}
for _, tc := range tests {
t.Run(tc.format, func(t *testing.T) {
f := newFakeFile()
SetOutFile(f)
Err("unrelated message")
if err := Out(tc.format, tc.arg); err != nil {
t.Errorf("unexpected error: %q", err)
}
got := f.String()
if got != tc.want {
t.Errorf("Out(%s, %s) = %q, want %q", tc.format, tc.arg, got, tc.want)
}
})
}
}
func TestErr(t *testing.T) {
f := newFakeFile()
SetErrFile(f)
if err := Err("xyz123\n"); err != nil {
t.Errorf("unexpected error: %q", err)
}
Out("unrelated message")
got := f.String()
want := "xyz123\n"
if got != want {
t.Errorf("Err() = %q, want %q", got, want)
}
}
func TestErrStyle(t *testing.T) {
f := newFakeFile()
SetErrFile(f)
if err := ErrStyle("fatal", "It broke"); err != nil {
t.Errorf("unexpected error: %q", err)
}
got := f.String()
want := "💣 It broke\n"
if got != want {
t.Errorf("ErrStyle() = %q, want %q", got, want)
}
}
func TestSetLanguage(t *testing.T) {
var tests = []struct {
input string
want language.Tag
}{
{"", language.AmericanEnglish},
{"C", language.AmericanEnglish},
{"zh", language.Chinese},
{"fr_FR.utf8", language.French},
}
for _, tc := range tests {
t.Run(tc.input, func(t *testing.T) {
// Set something so that we can assert change.
SetLanguageTag(language.Icelandic)
if err := SetLanguage(tc.input); err != nil {
t.Errorf("unexpected error: %q", err)
}
// Just compare the bases ("en", "fr"), since I can't seem to refer directly to them
want, _ := tc.want.Base()
got, _ := preferredLanguage.Base()
if got != want {
t.Errorf("SetLanguage(%s) = %q, want %q", tc.input, got, want)
}
})
}
}
package console
import (
"fmt"
"golang.org/x/text/message"
)
// style describes how to stylize a message.
type style struct {
// Prefix is a string to place in the beginning of a message
Prefix string
// OmitNewline omits a newline at the end of a message.
OmitNewline bool
}
// styles is a map of style name to style struct
var styles = map[string]style{
// General purpose
"happy": style{Prefix: "😄"},
"success": style{Prefix: "✅ "},
"failure": style{Prefix: "❌"},
"conflict": style{Prefix: "💥"},
"fatal": style{Prefix: "💣"},
"notice": style{Prefix: "📌"},
"ready": style{Prefix: "🏄"},
"restarting": style{Prefix: "🔁"},
"stopping": style{Prefix: "🚦"},
"stopped": style{Prefix: "🛑"},
"warning": style{Prefix: "⚠️"},
"waiting": style{Prefix: "⌛"},
"usage": style{Prefix: "💡"},
"launch": style{Prefix: "🚀"},
// Specialized purpose
"iso-download": style{Prefix: "💿"},
"file-download": style{Prefix: "💾"},
"caching": style{Prefix: "🤹"},
"starting-vm": style{Prefix: "🔥"},
"copying": style{Prefix: "✨"},
"connectivity": style{Prefix: "📡"},
"mounting": style{Prefix: "📁"},
"celebrate": style{Prefix: "🎉"},
"container-runtime": style{Prefix: "🎁"},
"enabling": style{Prefix: "🔌"},
"pulling": style{Prefix: "🚜"},
"verifying": style{Prefix: "🤔"},
"kubectl": style{Prefix: "❤️"},
"meh": style{Prefix: "🙄"},
"embarassed": style{Prefix: "🤦"},
}
// Add a prefix to a string
func applyPrefix(prefix, format string) string {
if prefix == "" {
return format
}
// TODO(tstromberg): Ensure compatibility with RTL languages.
return prefix + " " + format
}
// Apply styling to a format string
func applyStyle(style string, useColor bool, format string, a ...interface{}) (string, error) {
p := message.NewPrinter(preferredLanguage)
s, ok := styles[style]
if !s.OmitNewline {
format = format + "\n"
}
// Similar to CSS styles, if no style matches, output an unformatted string.
if !ok {
return p.Sprintf(format, a...), fmt.Errorf("unknown style: %q", style)
}
prefix := s.Prefix
if useColor && prefix != "" {
prefix = "-"
}
format = applyPrefix(prefix, format)
return p.Sprintf(format, a...), nil
}
......@@ -158,7 +158,7 @@ func TestRunDriver(t *testing.T) {
}
os.Stdout = old
fmt.Println(string(addr))
fmt.Prinln(string(addr))
// Now that we got the port, make sure we can connect.
if _, err := net.Dial("tcp", string(addr)); err != nil {
......
......@@ -74,7 +74,8 @@ type URLHandlerCorrect struct {
func (h *URLHandlerCorrect) ServeHTTP(w http.ResponseWriter, r *http.Request) {
b, err := json.Marshal(h.releases)
if err != nil {
fmt.Println(err)
// TODO(tstrombxerg): Do something else with this?
fmt.ErrLn(err)
return
}
w.Header().Set("Content-Type", "application/javascript")
......
......@@ -20,28 +20,25 @@ import (
"bytes"
"fmt"
"net/url"
"os"
"strings"
"text/template"
"time"
"github.com/docker/machine/libmachine"
"github.com/golang/glog"
"github.com/pkg/browser"
"github.com/pkg/errors"
"github.com/spf13/viper"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/clientcmd"
"text/template"
"github.com/spf13/viper"
"k8s.io/apimachinery/pkg/labels"
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/util"
)
......@@ -242,9 +239,9 @@ func WaitAndMaybeOpenService(api libmachine.API, namespace string, service strin
urlString, isHTTPSchemedURL := OptionallyHTTPSFormattedURLString(bareURLString, https)
if urlMode || !isHTTPSchemedURL {
fmt.Fprintln(os.Stdout, urlString)
console.OutLn(urlString)
} else {
fmt.Fprintln(os.Stderr, "Opening kubernetes service "+namespace+"/"+service+" in default browser...")
console.OutStyle("celebrate", "Opening kubernetes service %s/%s in default browser...", namespace, service)
browser.OpenURL(urlString)
}
}
......@@ -312,7 +309,6 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m
_, err = secrets.Create(secretObj)
if err != nil {
fmt.Println("err: ", err)
return &util.RetriableError{Err: err}
}
......
......@@ -18,7 +18,6 @@ package util
import (
"crypto"
"fmt"
"net/url"
"os"
"path/filepath"
......@@ -26,6 +25,7 @@ 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"
)
......@@ -72,7 +72,7 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
options.ChecksumHash = crypto.SHA256
}
fmt.Println("Downloading Minikube ISO")
console.OutStyle("iso-download", "Downloading Minikube ISO ...")
if err := download.ToFile(isoURL, f.GetISOCacheFilepath(isoURL), options); err != nil {
return errors.Wrap(err, isoURL)
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册