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
pull/4732/head
Sharif Elgamal 2019-07-10 10:17:28 -07:00 committed by GitHub
parent 57f6d877ed
commit c92e65ec28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 217 additions and 127 deletions

View File

@ -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" // runStart handles the executes the flow of "minikube start"
func runStart(cmd *cobra.Command, args []string) { 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() validateConfig()
validateUser() validateUser()
@ -239,7 +239,7 @@ func runStart(cmd *cobra.Command, args []string) {
// Bypass proxy for minikube's vm ip // Bypass proxy for minikube's vm ip
err = proxy.ExcludeIP(ip) err = proxy.ExcludeIP(ip)
if err != nil { 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 // Save IP to configuration file for subsequent use
@ -297,7 +297,7 @@ func skipCache(config cfg.Config) {
func showVersionInfo(k8sVersion string, cr cruntime.Manager) { func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
version, _ := cr.Version() 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 { for _, v := range dockerOpt {
console.OutStyle(console.Option, "opt %s", v) console.OutStyle(console.Option, "opt %s", v)
} }
@ -308,9 +308,9 @@ func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
func showKubectlConnectInfo(kubeconfig *pkgutil.KubeConfigSetup) { func showKubectlConnectInfo(kubeconfig *pkgutil.KubeConfigSetup) {
if kubeconfig.KeepContext { 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 { } 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") _, err := exec.LookPath("kubectl")
if err != nil { if err != nil {
@ -380,7 +380,7 @@ func validateUser() {
exit.Usage("Please run with sudo. the vm-driver %q requires sudo.", constants.DriverNone) 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) { } 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 { } 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)) 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) { 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 // 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 != "" { 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{ cfg := cfg.Config{
@ -686,11 +686,11 @@ func validateKubernetesVersions(old *cfg.Config) (string, bool) {
if nvs.LT(ovs) { if nvs.LT(ovs) {
nv = version.VersionPrefix + ovs.String() 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 return nv, isUpgrade
} }
if nvs.GT(ovs) { 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 isUpgrade = true
} }
return nv, isUpgrade return nv, isUpgrade
@ -767,12 +767,12 @@ func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner c
if isUpgrade || !preexisting { if isUpgrade || !preexisting {
console.OutStyle(console.Pulling, "Pulling images ...") console.OutStyle(console.Pulling, "Pulling images ...")
if err := bs.PullImages(kc); err != nil { 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 { 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 { if err := bs.RestartCluster(kc); err != nil {
exit.WithLogEntries("Error restarting cluster", err, logs.FindProblems(r, bs, runner)) exit.WithLogEntries("Error restarting cluster", err, logs.FindProblems(r, bs, runner))
} }
@ -791,7 +791,7 @@ func configureMounts() {
return 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] path := os.Args[0]
mountDebugVal := 0 mountDebugVal := 0
if glog.V(8) { if glog.V(8) {

View File

@ -26,8 +26,6 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
isatty "github.com/mattn/go-isatty" 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 // By design, this package uses global references to language and output objects, in preference
@ -59,24 +57,27 @@ type fdWriter interface {
Fd() uintptr Fd() uintptr
} }
// Arg is a convenience wrapper for templating
type Arg map[string]interface{}
// OutStyle writes a stylized and formatted message to stdout // OutStyle writes a stylized and formatted message to stdout
func OutStyle(style StyleEnum, format string, a ...interface{}) { 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 func OutT(style StyleEnum, format string, a map[string]interface{}) {
// as a formatting directive down the line outStyled := applyTemplateFormatting(style, useColor, format, a)
outStyled = strings.Replace(outStyled, "%", "%%", -1)
Out(outStyled) Out(outStyled)
} }
// Out writes a basic formatted string to stdout // Out writes a basic formatted string to stdout
func Out(format string, a ...interface{}) { func Out(format string, a ...interface{}) {
p := message.NewPrinter(translate.GetPreferredLanguage())
if outFile == nil { if outFile == nil {
glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...)) glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...))
return return
} }
_, err := p.Fprintf(outFile, format, a...) _, err := fmt.Fprintf(outFile, format, a...)
if err != nil { if err != nil {
glog.Errorf("Fprintf failed: %v", err) 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 // ErrStyle writes a stylized and formatted error message to stderr
func ErrStyle(style StyleEnum, format string, a ...interface{}) { 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 func ErrT(style StyleEnum, format string, a map[string]interface{}) {
// as a formatting directive down the line errStyled := applyTemplateFormatting(style, useColor, format, a)
format = strings.Replace(format, "%", "%%", -1) Err(errStyled)
Err(format)
} }
// Err writes a basic formatted string to stderr // Err writes a basic formatted string to stderr
func Err(format string, a ...interface{}) { func Err(format string, a ...interface{}) {
p := message.NewPrinter(translate.GetPreferredLanguage())
if errFile == nil { if errFile == nil {
glog.Errorf("[unset errFile]: %s", fmt.Sprintf(format, a...)) glog.Errorf("[unset errFile]: %s", fmt.Sprintf(format, a...))
return return
} }
_, err := p.Fprintf(errFile, format, a...) _, err := fmt.Fprintf(errFile, format, a...)
if err != nil { if err != nil {
glog.Errorf("Fprint failed: %v", err) glog.Errorf("Fprint failed: %v", err)
} }

View File

@ -22,13 +22,18 @@ import (
"strconv" "strconv"
"testing" "testing"
"golang.org/x/text/language"
"golang.org/x/text/message"
"k8s.io/minikube/pkg/minikube/tests" "k8s.io/minikube/pkg/minikube/tests"
"k8s.io/minikube/pkg/minikube/translate" "k8s.io/minikube/pkg/minikube/translate"
) )
func TestOutStyle(t *testing.T) { 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 { var testCases = []struct {
style StyleEnum style StyleEnum
@ -44,6 +49,7 @@ func TestOutStyle(t *testing.T) {
{WaitingPods, "wait", nil, "⌛ wait", "* wait"}, {WaitingPods, "wait", nil, "⌛ wait", "* wait"},
{Issue, "http://i/%d", []interface{}{10000}, " ▪ http://i/10000\n", " - http://i/10000\n"}, {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"}, {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 _, tc := range testCases {
for _, override := range []bool{true, false} { for _, override := range []bool{true, false} {
@ -66,34 +72,74 @@ func TestOutStyle(t *testing.T) {
} }
} }
func TestOut(t *testing.T) { func TestOutT(t *testing.T) {
os.Setenv(OverrideEnv, "") // Set the system locale to Arabic and define a dummy translation file.
// An example translation just to assert that this code path is executed. if err := translate.SetPreferredLanguage("ar"); err != nil {
err := message.SetString(language.Arabic, "Installing Kubernetes version %s ...", "... %s تثبيت Kubernetes الإصدار") t.Fatalf("SetPreferredLanguage: %v", err)
if err != nil { }
t.Fatalf("setstring: %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, "")
var testCases = []struct { var testCases = []struct {
format string format string
lang string
arg interface{} arg interface{}
want string want string
}{ }{
{format: "xyz123", want: "xyz123"}, {format: "xyz123", want: "xyz123"},
{format: "Installing Kubernetes version %s ...", lang: "ar", arg: "v1.13", want: "... v1.13 تثبيت Kubernetes الإصدار"}, {format: "Installing Kubernetes version %s ...", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
{format: "Installing Kubernetes version %s ...", lang: "en-us", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
{format: "Parameter encoding: %s", arg: "%s%%%d", want: "Parameter encoding: %s%%%d"}, {format: "Parameter encoding: %s", arg: "%s%%%d", want: "Parameter encoding: %s%%%d"},
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.format, func(t *testing.T) { 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() f := tests.NewFakeFile()
SetOutFile(f) SetOutFile(f)
ErrLn("unrelated message") ErrLn("unrelated message")
Out(tc.format, tc.arg) if tc.arg == nil {
Out(tc.format)
} else {
Out(tc.format, tc.arg)
}
got := f.String() got := f.String()
if got != tc.want { if got != tc.want {
t.Errorf("Out(%s, %s) = %q, want %q", tc.format, tc.arg, 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) 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)
}
})
}
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package console package console
import ( import (
"bytes"
"strings" "strings"
"text/template"
"golang.org/x/text/message" "github.com/golang/glog"
"golang.org/x/text/number"
"k8s.io/minikube/pkg/minikube/translate" "k8s.io/minikube/pkg/minikube/translate"
) )
@ -130,29 +131,46 @@ func lowPrefix(s style) string {
return lowBullet return lowBullet
} }
// Apply styling to a format string // applyStyle translates the given string if necessary then adds any appropriate style prefix.
func applyStyle(style StyleEnum, useColor bool, format string, a ...interface{}) string { func applyStyle(style StyleEnum, useColor bool, format string) string {
p := message.NewPrinter(translate.GetPreferredLanguage())
for i, x := range a {
if _, ok := x.(int); ok {
a[i] = number.Decimal(x, number.NoSeparator())
}
}
format = translate.T(format) format = translate.T(format)
out := p.Sprintf(format, a...)
s, ok := styles[style] s, ok := styles[style]
if !s.OmitNewline { if !s.OmitNewline {
out += "\n" format += "\n"
} }
// Similar to CSS styles, if no style matches, output an unformatted string. // Similar to CSS styles, if no style matches, output an unformatted string.
if !ok { if !ok {
return p.Sprintf(format, a...) return format
} }
if !useColor { if !useColor {
return applyPrefix(lowPrefix(s), out) return applyPrefix(lowPrefix(s), format)
} }
return applyPrefix(s.Prefix, out) 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
}
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
} }

View File

@ -40,6 +40,11 @@ var blacklist = []string{
"%s/%d", "%s/%d",
"%s=%s", "%s=%s",
"%v", "%v",
"GID: %s",
"MSize: %d",
"UID: %s",
"env %s",
"opt %s",
} }
// state is a struct that represent the current state of the extraction process // state is a struct that represent the current state of the extraction process

View File

@ -0,0 +1,53 @@
/*
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)
}
})
}
}

View File

@ -20,13 +20,13 @@
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "", "Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Cannot find directory %s for mount": "", "Cannot find directory %s for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "", "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 ...": "", "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 %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 ...": "", "Deleting %q from %s ...": "",
"Documentation: %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!": "", "Download complete!": "",
"Downloading %s %s": "", "Downloading %s %s": "",
"Downloading Minikube ISO ...": "", "Downloading Minikube ISO ...": "",
@ -93,7 +93,7 @@
"Failed to list cached images": "", "Failed to list cached images": "",
"Failed to remove profile": "", "Failed to remove profile": "",
"Failed to save config": "", "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 certs": "",
"Failed to setup kubeconfig": "", "Failed to setup kubeconfig": "",
"Failed to update cluster": "", "Failed to update cluster": "",
@ -103,14 +103,13 @@
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "", "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"For more information, see:": "", "For more information, see:": "",
"Found network options:": "", "Found network options:": "",
"GID: %s": "",
"If the above advice does not help, please let us know: ": "", "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.": "", "Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Invalid size passed in argument: %v": "",
"IsEnabled failed": "", "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 Kubernetes ... ": "Lançant Kubernetes ...",
"Launching proxy ...": "", "Launching proxy ...": "",
"MSize: %d": "",
"Mode: %o (%s)": "", "Mode: %o (%s)": "",
"Mount options:": "", "Mount options:": "",
"Mounting host path %s into VM as %s ...": "", "Mounting host path %s into VM as %s ...": "",
@ -120,25 +119,27 @@
"Opening %s in your default browser...": "", "Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "", "Opening kubernetes service %s/%s in default browser...": "",
"Options: %s": "", "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 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\")": "", "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 ...": "", "Powering off %q via SSH ...": "",
"Problems detected in %q:": "", "Problems detected in %q:": "",
"Pulling images ...": "Extrayant les images ... ", "Pulling images ...": "Extrayant les images ... ",
"Re-using the currently running %s VM for %q ...": "", "Re-using the currently running %s VM for %q ...": "",
"Related issues:": "", "Related issues:": "",
"Relaunching Kubernetes %s using %s ... ": "", "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
"Requested disk size (%dMB) is less than minimum of %dMB": "", "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 ...": "", "Restarting existing %s VM for %q ...": "",
"Set failed": "", "Set failed": "",
"Setting profile failed": "", "Setting profile failed": "",
"Skipped switching kubectl context for %s , because --keep-context": "", "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 that minikube crashed. If this was unexpected, we would love to hear from you:": "",
"Sorry, completion support is not yet implemented for %q": "", "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, 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 ...": "", "Stopping %q in %s ...": "",
"Successfully mounted %s to %s": "", "Successfully mounted %s to %s": "",
"Target directory %q must be an absolute path": "", "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": "", "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.": "", "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=%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 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": "", "To use kubectl or minikube commands as your own user, you may": "",
"Type: %s": "", "Type: %s": "",
"UID: %s": "",
"Unable to bind flags": "", "Unable to bind flags": "",
"Unable to enable dashboard": "", "Unable to enable dashboard": "",
"Unable to fetch latest version info": "", "Unable to fetch latest version info": "",
@ -171,7 +172,7 @@
"Unable to load cached images: %v": "", "Unable to load cached images: %v": "",
"Unable to load config: %v": "", "Unable to load config: %v": "",
"Unable to parse %q: %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 start VM": "",
"Unable to stop VM": "", "Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "", "Uninstalling Kubernetes %s using %s ...": "",
@ -180,6 +181,7 @@
"Usage: minikube completion SHELL": "", "Usage: minikube completion SHELL": "",
"Userspace file server is shutdown": "", "Userspace file server is shutdown": "",
"Userspace file server: ": "", "Userspace file server: ": "",
"Using image repository {{.name}}": "",
"Verifying dashboard health ...": "", "Verifying dashboard health ...": "",
"Verifying proxy health ...": "", "Verifying proxy health ...": "",
"Verifying:": "Vérifiant:", "Verifying:": "Vérifiant:",
@ -198,7 +200,6 @@
"config view failed": "", "config view failed": "",
"disable failed": "", "disable failed": "",
"enable failed: %v": "", "enable failed: %v": "",
"env %s": "",
"error creating clientset": "", "error creating clientset": "",
"error creating machine client": "", "error creating machine client": "",
"error getting driver": "", "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 not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"kubectl proxy": "", "kubectl proxy": "",
"logdir set failed": "", "logdir set failed": "",
"minikube %s on %s (%s)": "minikube %s sur %s (%s)",
"minikube is not running, so the service cannot be accessed": "", "minikube is not running, so the service cannot be accessed": "",
"minikube profile was successfully set to %s": "", "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 argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "", "mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "", "need to relocate them. For example, to overwrite your own settings:": "",
"opt %s": "",
"stat failed": "", "stat failed": "",
"unable to bind flags": "", "unable to bind flags": "",
"unable to set logtostderr": "", "unable to set logtostderr": "",
@ -232,6 +232,5 @@
"usage: minikube config unset PROPERTY_NAME": "", "usage: minikube config unset PROPERTY_NAME": "",
"usage: minikube delete": "", "usage: minikube delete": "",
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "", "usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
"using image repository %s": "",
"zsh completion failed": "" "zsh completion failed": ""
} }

View File

@ -20,13 +20,13 @@
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "", "Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
"Cannot find directory %s for mount": "", "Cannot find directory %s for mount": "",
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "", "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 ...": "", "Configuring local host environment ...": "",
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "正在创建%s虚拟机CPU=%d内存=%dMB磁盘=%dMB...", "Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "正在创建%s虚拟机CPU=%d内存=%dMB磁盘=%dMB...",
"Creating mount %s ...": "", "Creating mount {{.name}} ...": "",
"Deleting %q from %s ...": "", "Deleting %q from %s ...": "",
"Documentation: %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!": "", "Download complete!": "",
"Downloading %s %s": "", "Downloading %s %s": "",
"Downloading Minikube ISO ...": "", "Downloading Minikube ISO ...": "",
@ -93,7 +93,7 @@
"Failed to list cached images": "", "Failed to list cached images": "",
"Failed to remove profile": "", "Failed to remove profile": "",
"Failed to save config": "", "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 certs": "",
"Failed to setup kubeconfig": "", "Failed to setup kubeconfig": "",
"Failed to update cluster": "", "Failed to update cluster": "",
@ -103,14 +103,13 @@
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "", "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"For more information, see:": "", "For more information, see:": "",
"Found network options:": "", "Found network options:": "",
"GID: %s": "",
"If the above advice does not help, please let us know: ": "", "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.": "", "Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
"Invalid size passed in argument: %v": "",
"IsEnabled failed": "", "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 Kubernetes ... ": "正在启动 Kubernetes ... ",
"Launching proxy ...": "", "Launching proxy ...": "",
"MSize: %d": "",
"Mode: %o (%s)": "", "Mode: %o (%s)": "",
"Mount options:": "", "Mount options:": "",
"Mounting host path %s into VM as %s ...": "", "Mounting host path %s into VM as %s ...": "",
@ -120,25 +119,27 @@
"Opening %s in your default browser...": "", "Opening %s in your default browser...": "",
"Opening kubernetes service %s/%s in default browser...": "", "Opening kubernetes service %s/%s in default browser...": "",
"Options: %s": "", "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 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\")": "", "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 ...": "", "Powering off %q via SSH ...": "",
"Problems detected in %q:": "", "Problems detected in %q:": "",
"Pulling images ...": "拉取镜像 ...", "Pulling images ...": "拉取镜像 ...",
"Re-using the currently running %s VM for %q ...": "", "Re-using the currently running %s VM for %q ...": "",
"Related issues:": "", "Related issues:": "",
"Relaunching Kubernetes %s using %s ... ": "", "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
"Requested disk size (%dMB) is less than minimum of %dMB": "", "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 ...": "", "Restarting existing %s VM for %q ...": "",
"Set failed": "", "Set failed": "",
"Setting profile failed": "", "Setting profile failed": "",
"Skipped switching kubectl context for %s , because --keep-context": "", "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 that minikube crashed. If this was unexpected, we would love to hear from you:": "",
"Sorry, completion support is not yet implemented for %q": "", "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, 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 ...": "", "Stopping %q in %s ...": "",
"Successfully mounted %s to %s": "", "Successfully mounted %s to %s": "",
"Target directory %q must be an absolute path": "", "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": "", "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.": "", "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=%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 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": "", "To use kubectl or minikube commands as your own user, you may": "",
"Type: %s": "", "Type: %s": "",
"UID: %s": "",
"Unable to bind flags": "", "Unable to bind flags": "",
"Unable to enable dashboard": "", "Unable to enable dashboard": "",
"Unable to fetch latest version info": "", "Unable to fetch latest version info": "",
@ -171,7 +172,7 @@
"Unable to load cached images: %v": "", "Unable to load cached images: %v": "",
"Unable to load config: %v": "", "Unable to load config: %v": "",
"Unable to parse %q: %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 start VM": "",
"Unable to stop VM": "", "Unable to stop VM": "",
"Uninstalling Kubernetes %s using %s ...": "", "Uninstalling Kubernetes %s using %s ...": "",
@ -180,6 +181,7 @@
"Usage: minikube completion SHELL": "", "Usage: minikube completion SHELL": "",
"Userspace file server is shutdown": "", "Userspace file server is shutdown": "",
"Userspace file server: ": "", "Userspace file server: ": "",
"Using image repository {{.name}}": "",
"Verifying dashboard health ...": "", "Verifying dashboard health ...": "",
"Verifying proxy health ...": "", "Verifying proxy health ...": "",
"Verifying:": "正在验证:", "Verifying:": "正在验证:",
@ -198,7 +200,6 @@
"config view failed": "", "config view failed": "",
"disable failed": "", "disable failed": "",
"enable failed: %v": "", "enable failed: %v": "",
"env %s": "",
"error creating clientset": "", "error creating clientset": "",
"error creating machine client": "", "error creating machine client": "",
"error getting driver": "", "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 not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
"kubectl proxy": "", "kubectl proxy": "",
"logdir set failed": "", "logdir set failed": "",
"minikube %s on %s (%s)": "您正在使用minikube %s 运行平台:%s (%s)",
"minikube is not running, so the service cannot be accessed": "", "minikube is not running, so the service cannot be accessed": "",
"minikube profile was successfully set to %s": "", "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 argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
"mount failed": "", "mount failed": "",
"need to relocate them. For example, to overwrite your own settings:": "", "need to relocate them. For example, to overwrite your own settings:": "",
"opt %s": "",
"stat failed": "", "stat failed": "",
"unable to bind flags": "", "unable to bind flags": "",
"unable to set logtostderr": "", "unable to set logtostderr": "",
@ -232,6 +232,5 @@
"usage: minikube config unset PROPERTY_NAME": "", "usage: minikube config unset PROPERTY_NAME": "",
"usage: minikube delete": "", "usage: minikube delete": "",
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "", "usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
"using image repository %s": "",
"zsh completion failed": "" "zsh completion failed": ""
} }