diff --git a/cmd/minikube/cmd/config/config.go b/cmd/minikube/cmd/config/config.go index 9d80c2112b09..46a9b4fe6b36 100644 --- a/cmd/minikube/cmd/config/config.go +++ b/cmd/minikube/cmd/config/config.go @@ -22,6 +22,7 @@ import ( "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/localpath" ) @@ -32,21 +33,23 @@ type setFn func(string, string) error // Setting represents a setting type Setting struct { - name string - set func(config.MinikubeConfig, string, string) error - setMap func(config.MinikubeConfig, string, map[string]interface{}) error - validations []setFn - callbacks []setFn + name string + set func(config.MinikubeConfig, string, string) error + setMap func(config.MinikubeConfig, string, map[string]interface{}) error + validDefaults func() []string + validations []setFn + callbacks []setFn } // These are all the settings that are configurable // and their validation and callback fn run on Set var settings = []Setting{ { - name: "driver", - set: SetString, - validations: []setFn{IsValidDriver}, - callbacks: []setFn{RequiresRestartMsg}, + name: "driver", + set: SetString, + validDefaults: driver.SupportedDrivers, + validations: []setFn{IsValidDriver}, + callbacks: []setFn{RequiresRestartMsg}, }, { name: "vm-driver", diff --git a/cmd/minikube/cmd/config/defaults.go b/cmd/minikube/cmd/config/defaults.go new file mode 100644 index 000000000000..180747088007 --- /dev/null +++ b/cmd/minikube/cmd/config/defaults.go @@ -0,0 +1,92 @@ +/* +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 config + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + "k8s.io/minikube/pkg/minikube/out" +) + +var configDefaultsCommand = &cobra.Command{ + Use: "defaults PROPERTY_NAME", + Short: "Lists all valid default values for PROPERTY_NAME", + Long: `list displays all valid default settings for PROPERTY_NAME +Acceptable fields: ` + "\n\n" + fieldsWithDefaults(), + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + cmd.SilenceErrors = true + return errors.New("not enough arguments.\nusage: minikube config list PROPERTY_NAME") + } + if len(args) > 1 { + cmd.SilenceErrors = true + return fmt.Errorf("too many arguments (%d)\nusage: minikube config list PROPERTY_NAME", len(args)) + } + + property := args[0] + defaults, err := getDefaults(property) + if err != nil { + return err + } + return printDefaults(defaults) + }, +} + +func getDefaults(property string) ([]string, error) { + setting, err := findSetting(property) + if err != nil { + return nil, err + } + if setting.validDefaults == nil { + return nil, fmt.Errorf("%s is not a valid option for the `defaults` command; to see valid options run `minikube config defaults -h`", property) + } + return setting.validDefaults(), nil +} + +func printDefaults(defaults []string) error { + if output == "json" { + encoding, err := json.Marshal(defaults) + if err != nil { + return errors.Wrap(err, "encoding json") + } + out.Ln(string(encoding)) + return nil + } + for _, d := range defaults { + out.Ln("* %s", d) + } + return nil +} + +func fieldsWithDefaults() string { + fields := []string{} + for _, s := range settings { + if s.validDefaults != nil { + fields = append(fields, " * "+s.name) + } + } + return strings.Join(fields, "\n") +} + +func init() { + configDefaultsCommand.Flags().StringVar(&output, "output", "", "Output format. Accepted values: [json]") + ConfigCmd.AddCommand(configDefaultsCommand) +} diff --git a/cmd/minikube/cmd/config/defaults_test.go b/cmd/minikube/cmd/config/defaults_test.go new file mode 100644 index 000000000000..e87b214e2738 --- /dev/null +++ b/cmd/minikube/cmd/config/defaults_test.go @@ -0,0 +1,91 @@ +/* +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 config + +import ( + "testing" + + "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/tests" +) + +func TestGetDefaults(t *testing.T) { + tcs := []struct { + property string + expectedContents string + shouldErr bool + }{ + { + property: "driver", + expectedContents: "docker", + }, { + property: "invalid", + shouldErr: true, + }, + } + for _, tc := range tcs { + t.Run(tc.property, func(t *testing.T) { + defaults, err := getDefaults(tc.property) + if err != nil && !tc.shouldErr { + t.Fatalf("test shouldn't have failed, error listing defaults: %v", err) + } + if err == nil && tc.shouldErr { + t.Fatal("test should have failed but did not") + } + if tc.shouldErr { + return + } + for _, d := range defaults { + if d == tc.expectedContents { + return + } + } + t.Fatalf("defaults didn't contain expected default. Actual: %v\nExpected: %v\n", defaults, tc.expectedContents) + }) + } +} + +func TestPrintDefaults(t *testing.T) { + defaults := []string{"a", "b", "c"} + tcs := []struct { + description string + format string + expected string + }{ + { + description: "print to stdout", + expected: "* a\n* b\n* c\n", + }, { + description: "print in json", + format: "json", + expected: "[\"a\",\"b\",\"c\"]\n", + }, + } + for _, tc := range tcs { + t.Run(tc.description, func(t *testing.T) { + output = tc.format + f := tests.NewFakeFile() + out.SetOutFile(f) + if err := printDefaults(defaults); err != nil { + t.Fatalf("error printing defaults: %v", err) + } + if f.String() != tc.expected { + t.Fatalf("Expected: %v\n Actual: %v\n", tc.expected, f.String()) + } + }) + } +} diff --git a/go.sum b/go.sum index e515f17ba511..d25b4f2065f4 100644 --- a/go.sum +++ b/go.sum @@ -405,6 +405,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= diff --git a/site/content/en/docs/commands/config.md b/site/content/en/docs/commands/config.md index be16831f3dbf..a77338047e92 100644 --- a/site/content/en/docs/commands/config.md +++ b/site/content/en/docs/commands/config.md @@ -68,6 +68,42 @@ minikube config SUBCOMMAND [flags] --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging ``` +## minikube config defaults + +Lists all valid default values for PROPERTY_NAME + +### Synopsis + +list displays all valid default settings for PROPERTY_NAME +Acceptable fields: + + * driver + +``` +minikube config defaults PROPERTY_NAME [flags] +``` + +### Options + +``` + -h, --help help for defaults + --output string Output format. Accepted values: [json] +``` + +### Options inherited from parent commands + +``` + --alsologtostderr log to standard error as well as files + -b, --bootstrapper string The name of the cluster bootstrapper that will set up the Kubernetes cluster. (default "kubeadm") + --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_dir string If non-empty, write log files in this directory + --logtostderr log to standard error instead of files + -p, --profile string The name of the minikube VM being used. This can be set to allow having multiple instances of minikube independently. (default "minikube") + --stderrthreshold severity logs at or above this threshold go to stderr (default 2) + -v, --v Level log level for V logs + --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging +``` + ## minikube config get Gets the value of PROPERTY_NAME from the minikube config file