未验证 提交 c92e65ec 编写于 作者: S Sharif Elgamal 提交者: GitHub

Add templating for proper localization (#4677)

* Add templating for proper localization

* Fixing tests for new translation style

* checking errors is important

* fixing more console tests

* good function names make for happy developers

* add test for OutTemplateStyle

* short function names make for happy developers

* better formatting

* more better variable names
上级 57f6d877
......@@ -181,7 +181,7 @@ assumes you have already installed one of the VM drivers: virtualbox/parallels/v
// runStart handles the executes the flow of "minikube start"
func runStart(cmd *cobra.Command, args []string) {
console.OutStyle(console.Happy, "minikube %s on %s (%s)", version.GetVersion(), runtime.GOOS, runtime.GOARCH)
console.OutT(console.Happy, "minikube {{.version}} on {{.os}} ({{.arch}})", console.Arg{"version": version.GetVersion(), "os": runtime.GOOS, "arch": runtime.GOARCH})
validateConfig()
validateUser()
......@@ -239,7 +239,7 @@ func runStart(cmd *cobra.Command, args []string) {
// Bypass proxy for minikube's vm ip
err = proxy.ExcludeIP(ip)
if err != nil {
console.ErrStyle(console.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.", ip)
console.ErrT(console.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.", console.Arg{"ip": ip})
}
// Save IP to configuration file for subsequent use
......@@ -297,7 +297,7 @@ func skipCache(config cfg.Config) {
func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
version, _ := cr.Version()
console.OutStyle(cr.Style(), "Configuring environment for Kubernetes %s on %s %s", k8sVersion, cr.Name(), version)
console.OutT(cr.Style(), "Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}", console.Arg{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
for _, v := range dockerOpt {
console.OutStyle(console.Option, "opt %s", v)
}
......@@ -308,9 +308,9 @@ func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
func showKubectlConnectInfo(kubeconfig *pkgutil.KubeConfigSetup) {
if kubeconfig.KeepContext {
console.OutStyle(console.Kubectl, "To connect to this cluster, use: kubectl --context=%s", kubeconfig.ClusterName)
console.OutT(console.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", console.Arg{"name": kubeconfig.ClusterName})
} else {
console.OutStyle(console.Ready, "Done! kubectl is now configured to use %q", cfg.GetMachineName())
console.OutT(console.Ready, "Done! kubectl is now configured to use {{.name}}", console.Arg{"name": cfg.GetMachineName()})
}
_, err := exec.LookPath("kubectl")
if err != nil {
......@@ -380,7 +380,7 @@ func validateUser() {
exit.Usage("Please run with sudo. the vm-driver %q requires sudo.", constants.DriverNone)
} else if u.Name == "root" && !(d == constants.DriverHyperv || d == constants.DriverNone) {
console.OutStyle(console.WarningType, "Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with %s driver.", d)
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})
}
} else {
......@@ -406,7 +406,7 @@ func validateConfig() {
exit.Usage("Requested memory allocation (%dMB) is less than the minimum allowed of %dMB", memorySizeMB, pkgutil.CalculateSizeInMB(constants.MinimumMemorySize))
}
if memorySizeMB < pkgutil.CalculateSizeInMB(constants.DefaultMemorySize) {
console.OutStyle(console.Notice, "Requested memory allocation (%dMB) is less than the default memory allocation of (%dMB). Beware that Minikube might not work correctly or crash unexpectedly.", 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)})
}
// check that kubeadm extra args contain only whitelisted parameters
......@@ -515,7 +515,7 @@ func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) {
}
if repository != "" {
console.OutStyle(console.SuccessType, "using image repository %s", repository)
console.OutT(console.SuccessType, "Using image repository {{.name}}", console.Arg{"name": repository})
}
cfg := cfg.Config{
......@@ -686,11 +686,11 @@ func validateKubernetesVersions(old *cfg.Config) (string, bool) {
if nvs.LT(ovs) {
nv = version.VersionPrefix + ovs.String()
console.ErrStyle(console.Conflict, "Kubernetes downgrade is not supported, will continue to use %v", nv)
console.ErrT(console.Conflict, "Kubernetes downgrade is not supported, will continue to use {{.version}}", console.Arg{"version": nv})
return nv, isUpgrade
}
if nvs.GT(ovs) {
console.OutStyle(console.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes %s to %s", ovs, nvs)
console.OutT(console.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}", console.Arg{"old": ovs, "new": nvs})
isUpgrade = true
}
return nv, isUpgrade
......@@ -767,12 +767,12 @@ func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner c
if isUpgrade || !preexisting {
console.OutStyle(console.Pulling, "Pulling images ...")
if err := bs.PullImages(kc); err != nil {
console.OutStyle(console.FailureType, "Unable to pull images, which may be OK: %v", err)
console.OutT(console.FailureType, "Unable to pull images, which may be OK: {{.error}}", console.Arg{"error": err})
}
}
if preexisting {
console.OutStyle(console.Restarting, "Relaunching Kubernetes %s using %s ... ", kc.KubernetesVersion, bsName)
console.OutT(console.Restarting, "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ", console.Arg{"version": kc.KubernetesVersion, "bootstrapper": bsName})
if err := bs.RestartCluster(kc); err != nil {
exit.WithLogEntries("Error restarting cluster", err, logs.FindProblems(r, bs, runner))
}
......@@ -791,7 +791,7 @@ func configureMounts() {
return
}
console.OutStyle(console.Mounting, "Creating mount %s ...", viper.GetString(mountString))
console.OutT(console.Mounting, "Creating mount {{.name}} ...", console.Arg{"name": viper.GetString(mountString)})
path := os.Args[0]
mountDebugVal := 0
if glog.V(8) {
......
......@@ -26,8 +26,6 @@ import (
"github.com/golang/glog"
isatty "github.com/mattn/go-isatty"
"golang.org/x/text/message"
"k8s.io/minikube/pkg/minikube/translate"
)
// By design, this package uses global references to language and output objects, in preference
......@@ -59,24 +57,27 @@ type fdWriter interface {
Fd() uintptr
}
// Arg is a convenience wrapper for templating
type Arg 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, a...)
outStyled := applyStyle(style, useColor, format)
Out(outStyled, a...)
}
// escape any outstanding '%' signs so that they don't get interpreted
// as a formatting directive down the line
outStyled = strings.Replace(outStyled, "%", "%%", -1)
func OutT(style StyleEnum, format string, a map[string]interface{}) {
outStyled := applyTemplateFormatting(style, useColor, format, a)
Out(outStyled)
}
// Out writes a basic formatted string to stdout
func Out(format string, a ...interface{}) {
p := message.NewPrinter(translate.GetPreferredLanguage())
if outFile == nil {
glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...))
return
}
_, err := p.Fprintf(outFile, format, a...)
_, err := fmt.Fprintf(outFile, format, a...)
if err != nil {
glog.Errorf("Fprintf failed: %v", err)
}
......@@ -89,22 +90,22 @@ func OutLn(format string, a ...interface{}) {
// ErrStyle writes a stylized and formatted error message to stderr
func ErrStyle(style StyleEnum, format string, a ...interface{}) {
format = applyStyle(style, useColor, format, a...)
errStyled := applyStyle(style, useColor, format)
Err(errStyled, a...)
}
// escape any outstanding '%' signs so that they don't get interpreted
// as a formatting directive down the line
format = strings.Replace(format, "%", "%%", -1)
Err(format)
func ErrT(style StyleEnum, format string, a map[string]interface{}) {
errStyled := applyTemplateFormatting(style, useColor, format, a)
Err(errStyled)
}
// Err writes a basic formatted string to stderr
func Err(format string, a ...interface{}) {
p := message.NewPrinter(translate.GetPreferredLanguage())
if errFile == nil {
glog.Errorf("[unset errFile]: %s", fmt.Sprintf(format, a...))
return
}
_, err := p.Fprintf(errFile, format, a...)
_, err := fmt.Fprintf(errFile, format, a...)
if err != nil {
glog.Errorf("Fprint failed: %v", err)
}
......
......@@ -22,13 +22,18 @@ import (
"strconv"
"testing"
"golang.org/x/text/language"
"golang.org/x/text/message"
"k8s.io/minikube/pkg/minikube/tests"
"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
......@@ -44,6 +49,7 @@ func TestOutStyle(t *testing.T) {
{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} {
......@@ -66,34 +72,74 @@ func TestOutStyle(t *testing.T) {
}
}
func TestOutT(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 {{.version}} ...": "... {{.version}} تثبيت Kubernetes الإصدار",
}
var testCases = []struct {
style StyleEnum
message string
params Arg
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"},
{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"},
}
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)
OutT(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 TestOut(t *testing.T) {
os.Setenv(OverrideEnv, "")
// An example translation just to assert that this code path is executed.
err := message.SetString(language.Arabic, "Installing Kubernetes version %s ...", "... %s تثبيت Kubernetes الإصدار")
if err != nil {
t.Fatalf("setstring: %v", err)
}
var testCases = []struct {
format string
lang string
arg interface{}
want string
}{
{format: "xyz123", want: "xyz123"},
{format: "Installing Kubernetes version %s ...", lang: "ar", arg: "v1.13", want: "... v1.13 تثبيت Kubernetes الإصدار"},
{format: "Installing Kubernetes version %s ...", lang: "en-us", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
{format: "Installing Kubernetes version %s ...", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
{format: "Parameter encoding: %s", arg: "%s%%%d", want: "Parameter encoding: %s%%%d"},
}
for _, tc := range testCases {
t.Run(tc.format, func(t *testing.T) {
if err := translate.SetPreferredLanguage(tc.lang); err != nil {
t.Errorf("unexpected error: %q", err)
}
f := tests.NewFakeFile()
SetOutFile(f)
ErrLn("unrelated message")
Out(tc.format, tc.arg)
if tc.arg == nil {
Out(tc.format)
} else {
Out(tc.format, tc.arg)
}
got := f.String()
if got != tc.want {
t.Errorf("Out(%s, %s) = %q, want %q", tc.format, tc.arg, got, tc.want)
......@@ -127,34 +173,3 @@ func TestErrStyle(t *testing.T) {
t.Errorf("ErrStyle() = %q, want %q", got, want)
}
}
func TestSetPreferredLanguage(t *testing.T) {
os.Setenv(OverrideEnv, "0")
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.
if err := translate.SetPreferredLanguage("is"); err != nil {
t.Errorf("unexpected error: %q", err)
}
if err := translate.SetPreferredLanguage(tc.input); err != nil {
t.Errorf("unexpected error: %q", err)
}
want, _ := tc.want.Base()
got, _ := translate.GetPreferredLanguage().Base()
if got != want {
t.Errorf("SetPreferredLanguage(%s) = %q, want %q", tc.input, got, want)
}
})
}
}
......@@ -17,10 +17,11 @@ limitations under the License.
package console
import (
"bytes"
"strings"
"text/template"
"golang.org/x/text/message"
"golang.org/x/text/number"
"github.com/golang/glog"
"k8s.io/minikube/pkg/minikube/translate"
)
......@@ -130,29 +131,46 @@ func lowPrefix(s style) string {
return lowBullet
}
// Apply styling to a format string
func applyStyle(style StyleEnum, useColor bool, format string, a ...interface{}) string {
p := message.NewPrinter(translate.GetPreferredLanguage())
for i, x := range a {
if _, ok := x.(int); ok {
a[i] = number.Decimal(x, number.NoSeparator())
}
}
// applyStyle translates the given string if necessary then adds any appropriate style prefix.
func applyStyle(style StyleEnum, useColor bool, format string) string {
format = translate.T(format)
out := p.Sprintf(format, a...)
s, ok := styles[style]
if !s.OmitNewline {
out += "\n"
format += "\n"
}
// Similar to CSS styles, if no style matches, output an unformatted string.
if !ok {
return p.Sprintf(format, a...)
return format
}
if !useColor {
return applyPrefix(lowPrefix(s), out)
return applyPrefix(lowPrefix(s), format)
}
return applyPrefix(s.Prefix, format)
}
func applyTemplateFormatting(style StyleEnum, useColor bool, format string, a map[string]interface{}) string {
format = applyStyle(style, useColor, format)
var buf bytes.Buffer
t, err := template.New(format).Parse(format)
if err != nil {
glog.Infof("Initializing template failed. Returning raw string.")
return format
}
err = t.Execute(&buf, a)
if err != nil {
glog.Infof("Executing template failed. Returning raw string.")
return format
}
return applyPrefix(s.Prefix, out)
outStyled := buf.String()
// escape any outstanding '%' signs so that they don't get interpreted
// as a formatting directive down the line
outStyled = strings.Replace(outStyled, "%", "%%", -1)
return outStyled
}
......@@ -40,6 +40,11 @@ var blacklist = []string{
"%s/%d",
"%s=%s",
"%v",
"GID: %s",
"MSize: %d",
"UID: %s",
"env %s",
"opt %s",
}
// state is a struct that represent the current state of the extraction process
......
/*
Copyright 2016 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 translate
import (
"testing"
"golang.org/x/text/language"
)
func TestSetPreferredLanguage(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.
if err := SetPreferredLanguage("is"); err != nil {
t.Errorf("unexpected error: %q", err)
}
if err := SetPreferredLanguage(tc.input); err != nil {
t.Errorf("unexpected error: %q", err)
}
want, _ := tc.want.Base()
got, _ := GetPreferredLanguage().Base()
if got != want {
t.Errorf("SetPreferredLanguage(%s) = %q, want %q", tc.input, got, want)
}
})
}
}
......@@ -20,13 +20,13 @@
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Cannot find directory %s for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
"Configuring environment for Kubernetes %s on %s %s": "Configurant l'environment pour Kubernetes %s sur %s %s",
"Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}": "Configurant l'environment pour Kubernetes {{.k8sVersion}} sur {{.runtime}} {{.runtimeVersion}}",
"Configuring local host environment ...": "",
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "Créant un VM %s (CPUs=%d, Mémoire=%dMB, Disque=%dMB)",
"Creating mount %s ...": "",
"Creating mount {{.name}} ...": "",
"Deleting %q from %s ...": "",
"Documentation: %s": "",
"Done! kubectl is now configured to use %q": "Fini! kubectl est maintenant configuré pour utiliser %s.",
"Done! kubectl is now configured to use {{.name}}": "Fini! kubectl est maintenant configuré pour utiliser {{.name}}.",
"Download complete!": "",
"Downloading %s %s": "",
"Downloading Minikube ISO ...": "",
......@@ -93,7 +93,7 @@
"Failed to list cached images": "",
"Failed to remove profile": "",
"Failed to save config": "",
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.": "",
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.": "",
"Failed to setup certs": "",
"Failed to setup kubeconfig": "",
"Failed to update cluster": "",
......@@ -103,14 +103,13 @@
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"For more information, see:": "",
"Found network options:": "",
"GID: %s": "",
"If the above advice does not help, please let us know: ": "",
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Invalid size passed in argument: %v": "",
"IsEnabled failed": "",
"Kubernetes downgrade is not supported, will continue to use %v": "",
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
"Launching Kubernetes ... ": "Lançant Kubernetes ...",
"Launching proxy ...": "",
"MSize: %d": "",
"Mode: %o (%s)": "",
"Mount options:": "",
"Mounting host path %s into VM as %s ...": "",
......@@ -120,25 +119,27 @@
"Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "",
"Options: %s": "",
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary.": "",
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.": "",
"Please enter a value:": "",
"Please run with sudo. the vm-driver %q requires sudo.": "",
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
"Powering off %q via SSH ...": "",
"Problems detected in %q:": "",
"Pulling images ...": "Extrayant les images ... ",
"Re-using the currently running %s VM for %q ...": "",
"Related issues:": "",
"Relaunching Kubernetes %s using %s ... ": "",
"Requested disk size (%dMB) is less than minimum of %dMB": "",
"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 ...": "",
"Set failed": "",
"Setting profile failed": "",
"Skipped switching kubectl context for %s , 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 %q": "",
"Sorry, the --gpu feature is currently only supported with --vm-driver=kvm2": "",
"Sorry, the --hidden feature is currently only supported with --vm-driver=kvm2": "",
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
"Stopping %q in %s ...": "",
"Successfully mounted %s to %s": "",
"Target directory %q must be an absolute path": "",
......@@ -157,10 +158,10 @@
"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 switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
"To use kubectl or minikube commands as your own user, you may": "",
"Type: %s": "",
"UID: %s": "",
"Unable to bind flags": "",
"Unable to enable dashboard": "",
"Unable to fetch latest version info": "",
......@@ -171,7 +172,7 @@
"Unable to load cached images: %v": "",
"Unable to load config: %v": "",
"Unable to parse %q: %v": "",
"Unable to pull images, which may be OK: %v": "",
"Unable to pull images, which may be OK: {{.error}}": "",
"Unable to start VM": "",
"Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "",
......@@ -180,6 +181,7 @@
"Usage: minikube completion SHELL": "",
"Userspace file server is shutdown": "",
"Userspace file server: ": "",
"Using image repository {{.name}}": "",
"Verifying dashboard health ...": "",
"Verifying proxy health ...": "",
"Verifying:": "Vérifiant:",
......@@ -198,7 +200,6 @@
"config view failed": "",
"disable failed": "",
"enable failed: %v": "",
"env %s": "",
"error creating clientset": "",
"error creating machine client": "",
"error getting driver": "",
......@@ -209,14 +210,13 @@
"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 %s on %s (%s)": "minikube %s sur %s (%s)",
"minikube is not running, so the service cannot be accessed": "",
"minikube profile was successfully set to %s": "",
"minikube will upgrade the local cluster from Kubernetes %s to %s": "",
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
"minikube {{.version}} on {{.os}} ({{.arch}})": "minikube {{.version}} sur {{.os}} ({{.arch}})",
"mount argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "",
"opt %s": "",
"stat failed": "",
"unable to bind flags": "",
"unable to set logtostderr": "",
......@@ -232,6 +232,5 @@
"usage: minikube config unset PROPERTY_NAME": "",
"usage: minikube delete": "",
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
"using image repository %s": "",
"zsh completion failed": ""
}
\ No newline at end of file
......@@ -20,13 +20,13 @@
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Cannot find directory %s for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
"Configuring environment for Kubernetes %s on %s %s": "开始为Kubernetes %s,%s %s 配置环境变量",
"Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}": "开始为Kubernetes {{.k8sVersion}},{{.runtime}} {{.runtimeVersion}} 配置环境变量",
"Configuring local host environment ...": "",
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "正在创建%s虚拟机(CPU=%d,内存=%dMB,磁盘=%dMB)...",
"Creating mount %s ...": "",
"Creating mount {{.name}} ...": "",
"Deleting %q from %s ...": "",
"Documentation: %s": "",
"Done! kubectl is now configured to use %q": "完成!kubectl已经配置至%q",
"Done! kubectl is now configured to use {{.name}}": "完成!kubectl已经配置至{{.name}}",
"Download complete!": "",
"Downloading %s %s": "",
"Downloading Minikube ISO ...": "",
......@@ -93,7 +93,7 @@
"Failed to list cached images": "",
"Failed to remove profile": "",
"Failed to save config": "",
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.": "",
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.": "",
"Failed to setup certs": "",
"Failed to setup kubeconfig": "",
"Failed to update cluster": "",
......@@ -103,14 +103,13 @@
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"For more information, see:": "",
"Found network options:": "",
"GID: %s": "",
"If the above advice does not help, please let us know: ": "",
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Invalid size passed in argument: %v": "",
"IsEnabled failed": "",
"Kubernetes downgrade is not supported, will continue to use %v": "",
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
"Launching Kubernetes ... ": "正在启动 Kubernetes ... ",
"Launching proxy ...": "",
"MSize: %d": "",
"Mode: %o (%s)": "",
"Mount options:": "",
"Mounting host path %s into VM as %s ...": "",
......@@ -120,25 +119,27 @@
"Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "",
"Options: %s": "",
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary.": "",
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.": "",
"Please enter a value:": "",
"Please run with sudo. the vm-driver %q requires sudo.": "",
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
"Powering off %q via SSH ...": "",
"Problems detected in %q:": "",
"Pulling images ...": "拉取镜像 ...",
"Re-using the currently running %s VM for %q ...": "",
"Related issues:": "",
"Relaunching Kubernetes %s using %s ... ": "",
"Requested disk size (%dMB) is less than minimum of %dMB": "",
"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 ...": "",
"Set failed": "",
"Setting profile failed": "",
"Skipped switching kubectl context for %s , 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 %q": "",
"Sorry, the --gpu feature is currently only supported with --vm-driver=kvm2": "",
"Sorry, the --hidden feature is currently only supported with --vm-driver=kvm2": "",
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
"Stopping %q in %s ...": "",
"Successfully mounted %s to %s": "",
"Target directory %q must be an absolute path": "",
......@@ -157,10 +158,10 @@
"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 switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
"To use kubectl or minikube commands as your own user, you may": "",
"Type: %s": "",
"UID: %s": "",
"Unable to bind flags": "",
"Unable to enable dashboard": "",
"Unable to fetch latest version info": "",
......@@ -171,7 +172,7 @@
"Unable to load cached images: %v": "",
"Unable to load config: %v": "",
"Unable to parse %q: %v": "",
"Unable to pull images, which may be OK: %v": "",
"Unable to pull images, which may be OK: {{.error}}": "",
"Unable to start VM": "",
"Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "",
......@@ -180,6 +181,7 @@
"Usage: minikube completion SHELL": "",
"Userspace file server is shutdown": "",
"Userspace file server: ": "",
"Using image repository {{.name}}": "",
"Verifying dashboard health ...": "",
"Verifying proxy health ...": "",
"Verifying:": "正在验证:",
......@@ -198,7 +200,6 @@
"config view failed": "",
"disable failed": "",
"enable failed: %v": "",
"env %s": "",
"error creating clientset": "",
"error creating machine client": "",
"error getting driver": "",
......@@ -209,14 +210,13 @@
"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 %s on %s (%s)": "您正在使用minikube %s, 运行平台:%s (%s)",
"minikube is not running, so the service cannot be accessed": "",
"minikube profile was successfully set to %s": "",
"minikube will upgrade the local cluster from Kubernetes %s to %s": "",
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
"minikube {{.version}} on {{.os}} ({{.arch}})": "您正在使用minikube {{.version}}, 运行平台:{{.os}} ({{.arch}})",
"mount argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "",
"opt %s": "",
"stat failed": "",
"unable to bind flags": "",
"unable to set logtostderr": "",
......@@ -232,6 +232,5 @@
"usage: minikube config unset PROPERTY_NAME": "",
"usage: minikube delete": "",
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
"using image repository %s": "",
"zsh completion failed": ""
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册