зеркало из https://github.com/microsoft/docker.git
Fix post config verification without flags.
- Set the daemon log level to what's set in the configuration. - Enable TLS when TLSVerify is enabled. Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
Родитель
30e42a2799
Коммит
cd3446972e
|
@ -84,6 +84,7 @@ type CommonConfig struct {
|
||||||
TLSOptions CommonTLSOptions `json:"tls-opts,omitempty"`
|
TLSOptions CommonTLSOptions `json:"tls-opts,omitempty"`
|
||||||
|
|
||||||
reloadLock sync.Mutex
|
reloadLock sync.Mutex
|
||||||
|
valuesSet map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallCommonFlags adds command-line options to the top-level flag parser for
|
// InstallCommonFlags adds command-line options to the top-level flag parser for
|
||||||
|
@ -112,6 +113,16 @@ func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string)
|
||||||
cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options"))
|
cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsValueSet returns true if a configuration value
|
||||||
|
// was explicitly set in the configuration file.
|
||||||
|
func (config *Config) IsValueSet(name string) bool {
|
||||||
|
if config.valuesSet == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok := config.valuesSet[name]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
|
func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
|
||||||
if clusterAdvertise == "" {
|
if clusterAdvertise == "" {
|
||||||
return "", errDiscoveryDisabled
|
return "", errDiscoveryDisabled
|
||||||
|
@ -165,6 +176,7 @@ func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Conf
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var config Config
|
||||||
var reader io.Reader
|
var reader io.Reader
|
||||||
if flags != nil {
|
if flags != nil {
|
||||||
var jsonConfig map[string]interface{}
|
var jsonConfig map[string]interface{}
|
||||||
|
@ -173,22 +185,22 @@ func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Conf
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := findConfigurationConflicts(jsonConfig, flags); err != nil {
|
configSet := configValuesSet(jsonConfig)
|
||||||
|
|
||||||
|
if err := findConfigurationConflicts(configSet, flags); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.valuesSet = configSet
|
||||||
}
|
}
|
||||||
|
|
||||||
var config Config
|
|
||||||
reader = bytes.NewReader(b)
|
reader = bytes.NewReader(b)
|
||||||
err = json.NewDecoder(reader).Decode(&config)
|
err = json.NewDecoder(reader).Decode(&config)
|
||||||
return &config, err
|
return &config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// findConfigurationConflicts iterates over the provided flags searching for
|
// configValuesSet returns the configuration values explicitly set in the file.
|
||||||
// duplicated configurations. It returns an error with all the conflicts if
|
func configValuesSet(config map[string]interface{}) map[string]interface{} {
|
||||||
// it finds any.
|
|
||||||
func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagSet) error {
|
|
||||||
var conflicts []string
|
|
||||||
flatten := make(map[string]interface{})
|
flatten := make(map[string]interface{})
|
||||||
for k, v := range config {
|
for k, v := range config {
|
||||||
if m, ok := v.(map[string]interface{}); ok {
|
if m, ok := v.(map[string]interface{}); ok {
|
||||||
|
@ -199,6 +211,14 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
||||||
flatten[k] = v
|
flatten[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return flatten
|
||||||
|
}
|
||||||
|
|
||||||
|
// findConfigurationConflicts iterates over the provided flags searching for
|
||||||
|
// duplicated configurations. It returns an error with all the conflicts if
|
||||||
|
// it finds any.
|
||||||
|
func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagSet) error {
|
||||||
|
var conflicts []string
|
||||||
|
|
||||||
printConflict := func(name string, flagValue, fileValue interface{}) string {
|
printConflict := func(name string, flagValue, fileValue interface{}) string {
|
||||||
return fmt.Sprintf("%s: (from flag: %v, from file: %v)", name, flagValue, fileValue)
|
return fmt.Sprintf("%s: (from flag: %v, from file: %v)", name, flagValue, fileValue)
|
||||||
|
@ -207,7 +227,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
||||||
collectConflicts := func(f *flag.Flag) {
|
collectConflicts := func(f *flag.Flag) {
|
||||||
// search option name in the json configuration payload if the value is a named option
|
// search option name in the json configuration payload if the value is a named option
|
||||||
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
||||||
if optsValue, ok := flatten[namedOption.Name()]; ok {
|
if optsValue, ok := config[namedOption.Name()]; ok {
|
||||||
conflicts = append(conflicts, printConflict(namedOption.Name(), f.Value.String(), optsValue))
|
conflicts = append(conflicts, printConflict(namedOption.Name(), f.Value.String(), optsValue))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,7 +235,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
||||||
for _, name := range f.Names {
|
for _, name := range f.Names {
|
||||||
name = strings.TrimLeft(name, "-")
|
name = strings.TrimLeft(name, "-")
|
||||||
|
|
||||||
if value, ok := flatten[name]; ok {
|
if value, ok := config[name]; ok {
|
||||||
conflicts = append(conflicts, printConflict(name, f.Value.String(), value))
|
conflicts = append(conflicts, printConflict(name, f.Value.String(), value))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,16 +55,7 @@ func init() {
|
||||||
func postParseCommon() {
|
func postParseCommon() {
|
||||||
cmd := commonFlags.FlagSet
|
cmd := commonFlags.FlagSet
|
||||||
|
|
||||||
if commonFlags.LogLevel != "" {
|
setDaemonLogLevel(commonFlags.LogLevel)
|
||||||
lvl, err := logrus.ParseLevel(commonFlags.LogLevel)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", commonFlags.LogLevel)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
logrus.SetLevel(lvl)
|
|
||||||
} else {
|
|
||||||
logrus.SetLevel(logrus.InfoLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regardless of whether the user sets it to true or false, if they
|
// Regardless of whether the user sets it to true or false, if they
|
||||||
// specify --tlsverify at all then we need to turn on tls
|
// specify --tlsverify at all then we need to turn on tls
|
||||||
|
@ -93,3 +84,16 @@ func postParseCommon() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setDaemonLogLevel(logLevel string) {
|
||||||
|
if logLevel != "" {
|
||||||
|
lvl, err := logrus.ParseLevel(logLevel)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
logrus.SetLevel(lvl)
|
||||||
|
} else {
|
||||||
|
logrus.SetLevel(logrus.InfoLevel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -360,5 +360,14 @@ func loadDaemonCliConfig(config *daemon.Config, daemonFlags *flag.FlagSet, commo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regardless of whether the user sets it to true or false, if they
|
||||||
|
// specify TLSVerify at all then we need to turn on TLS
|
||||||
|
if config.IsValueSet("tls-verify") {
|
||||||
|
config.TLS = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the log level is the one set after merging configurations
|
||||||
|
setDaemonLogLevel(config.LogLevel)
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/cli"
|
"github.com/docker/docker/cli"
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
|
@ -89,3 +90,126 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
|
||||||
t.Fatalf("expected labels conflict, got %v", err)
|
t.Fatalf("expected labels conflict, got %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
|
||||||
|
c := &daemon.Config{}
|
||||||
|
common := &cli.CommonFlags{
|
||||||
|
TLSOptions: &tlsconfig.Options{
|
||||||
|
CAFile: "/tmp/ca.pem",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := ioutil.TempFile("", "docker-config-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile := f.Name()
|
||||||
|
f.Write([]byte(`{"tls-verify": true}`))
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||||
|
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if loadedConfig == nil {
|
||||||
|
t.Fatalf("expected configuration %v, got nil", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !loadedConfig.TLS {
|
||||||
|
t.Fatalf("expected TLS enabled, got %q", loadedConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
|
||||||
|
c := &daemon.Config{}
|
||||||
|
common := &cli.CommonFlags{
|
||||||
|
TLSOptions: &tlsconfig.Options{
|
||||||
|
CAFile: "/tmp/ca.pem",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := ioutil.TempFile("", "docker-config-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile := f.Name()
|
||||||
|
f.Write([]byte(`{"tls-verify": false}`))
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||||
|
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if loadedConfig == nil {
|
||||||
|
t.Fatalf("expected configuration %v, got nil", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !loadedConfig.TLS {
|
||||||
|
t.Fatalf("expected TLS enabled, got %q", loadedConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
|
||||||
|
c := &daemon.Config{}
|
||||||
|
common := &cli.CommonFlags{
|
||||||
|
TLSOptions: &tlsconfig.Options{
|
||||||
|
CAFile: "/tmp/ca.pem",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := ioutil.TempFile("", "docker-config-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile := f.Name()
|
||||||
|
f.Write([]byte(`{}`))
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||||
|
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if loadedConfig == nil {
|
||||||
|
t.Fatalf("expected configuration %v, got nil", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if loadedConfig.TLS {
|
||||||
|
t.Fatalf("expected TLS disabled, got %q", loadedConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
|
||||||
|
c := &daemon.Config{}
|
||||||
|
common := &cli.CommonFlags{}
|
||||||
|
|
||||||
|
f, err := ioutil.TempFile("", "docker-config-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile := f.Name()
|
||||||
|
f.Write([]byte(`{"log-level": "warn"}`))
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||||
|
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if loadedConfig == nil {
|
||||||
|
t.Fatalf("expected configuration %v, got nil", c)
|
||||||
|
}
|
||||||
|
if loadedConfig.LogLevel != "warn" {
|
||||||
|
t.Fatalf("expected warn log level, got %v", loadedConfig.LogLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if logrus.GetLevel() != logrus.WarnLevel {
|
||||||
|
t.Fatalf("expected warn log level, got %v", logrus.GetLevel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче