소스 검색

Filter engine labels to exclude com.docker.*, io.docker.*, and org.dockerproject.*
labels as per https://docs.docker.com/config/labels-custom-metadata/.

Signed-off-by: Ying Li <ying.li@docker.com>

cyli 7 년 전
부모
커밋
d1d7bcd6d7
3개의 변경된 파일85개의 추가작업 그리고 8개의 파일을 삭제
  1. 32 8
      cmd/dockerd/daemon.go
  2. 19 0
      daemon/config/config.go
  3. 34 0
      daemon/config/config_test.go

+ 32 - 8
cmd/dockerd/daemon.go

@@ -284,29 +284,41 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
 }
 }
 
 
 func (cli *DaemonCli) reloadConfig() {
 func (cli *DaemonCli) reloadConfig() {
-	reload := func(config *config.Config) {
+	reload := func(c *config.Config) {
 
 
 		// Revalidate and reload the authorization plugins
 		// Revalidate and reload the authorization plugins
-		if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
+		if err := validateAuthzPlugins(c.AuthorizationPlugins, cli.d.PluginStore); err != nil {
 			logrus.Fatalf("Error validating authorization plugin: %v", err)
 			logrus.Fatalf("Error validating authorization plugin: %v", err)
 			return
 			return
 		}
 		}
-		cli.authzMiddleware.SetPlugins(config.AuthorizationPlugins)
+		cli.authzMiddleware.SetPlugins(c.AuthorizationPlugins)
+
+		// The namespaces com.docker.*, io.docker.*, org.dockerproject.* have been documented
+		// to be reserved for Docker's internal use, but this was never enforced.  Allowing
+		// configured labels to use these namespaces are deprecated for 18.05.
+		//
+		// The following will check the usage of such labels, and report a warning for deprecation.
+		//
+		// TODO: At the next stable release, the validation should be folded into the other
+		// configuration validation functions and an error will be returned instead, and this
+		// block should be deleted.
+		if err := config.ValidateReservedNamespaceLabels(c.Labels); err != nil {
+			logrus.Warnf("Configured labels using reserved namespaces is deprecated: %s", err)
+		}
 
 
-		if err := cli.d.Reload(config); err != nil {
+		if err := cli.d.Reload(c); err != nil {
 			logrus.Errorf("Error reconfiguring the daemon: %v", err)
 			logrus.Errorf("Error reconfiguring the daemon: %v", err)
 			return
 			return
 		}
 		}
 
 
-		if config.IsValueSet("debug") {
+		if c.IsValueSet("debug") {
 			debugEnabled := debug.IsEnabled()
 			debugEnabled := debug.IsEnabled()
 			switch {
 			switch {
-			case debugEnabled && !config.Debug: // disable debug
+			case debugEnabled && !c.Debug: // disable debug
 				debug.Disable()
 				debug.Disable()
-			case config.Debug && !debugEnabled: // enable debug
+			case c.Debug && !debugEnabled: // enable debug
 				debug.Enable()
 				debug.Enable()
 			}
 			}
-
 		}
 		}
 	}
 	}
 
 
@@ -406,6 +418,18 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+	// The namespaces com.docker.*, io.docker.*, org.dockerproject.* have been documented
+	// to be reserved for Docker's internal use, but this was never enforced.  Allowing
+	// configured labels to use these namespaces are deprecated for 18.05.
+	//
+	// The following will check the usage of such labels, and report a warning for deprecation.
+	//
+	// TODO: At the next stable release, the validation should be folded into the other
+	// configuration validation functions and an error will be returned instead, and this
+	// block should be deleted.
+	if err := config.ValidateReservedNamespaceLabels(newLabels); err != nil {
+		logrus.Warnf("Configured labels using reserved namespaces is deprecated: %s", err)
+	}
 	conf.Labels = newLabels
 	conf.Labels = newLabels
 
 
 	// 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

+ 19 - 0
daemon/config/config.go

@@ -255,6 +255,25 @@ func GetConflictFreeLabels(labels []string) ([]string, error) {
 	return newLabels, nil
 	return newLabels, nil
 }
 }
 
 
+// ValidateReservedNamespaceLabels errors if the reserved namespaces com.docker.*,
+// io.docker.*, org.dockerproject.* are used in a configured engine label.
+//
+// TODO: This is a separate function because we need to warn users first of the
+// deprecation.  When we return an error, this logic can be added to Validate
+// or GetConflictFreeLabels instead of being here.
+func ValidateReservedNamespaceLabels(labels []string) error {
+	for _, label := range labels {
+		lowered := strings.ToLower(label)
+		if strings.HasPrefix(lowered, "com.docker.") || strings.HasPrefix(lowered, "io.docker.") ||
+			strings.HasPrefix(lowered, "org.dockerproject.") {
+			return fmt.Errorf(
+				"label %s not allowed: the namespaces com.docker.*, io.docker.*, and org.dockerproject.* are reserved for Docker's internal use",
+				label)
+		}
+	}
+	return nil
+}
+
 // Reload reads the configuration in the host and reloads the daemon and server.
 // Reload reads the configuration in the host and reloads the daemon and server.
 func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
 func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
 	logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
 	logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)

+ 34 - 0
daemon/config/config_test.go

@@ -192,6 +192,40 @@ func TestFindConfigurationConflictsWithMergedValues(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestValidateReservedNamespaceLabels(t *testing.T) {
+	for _, validLabels := range [][]string{
+		nil, // no error if there are no labels
+		{ // no error if there aren't any reserved namespace labels
+			"hello=world",
+			"label=me",
+		},
+		{ // only reserved namespaces that end with a dot are invalid
+			"com.dockerpsychnotreserved.label=value",
+			"io.dockerproject.not=reserved",
+			"org.docker.not=reserved",
+		},
+	} {
+		assert.Check(t, ValidateReservedNamespaceLabels(validLabels))
+	}
+
+	for _, invalidLabel := range []string{
+		"com.docker.feature=enabled",
+		"io.docker.configuration=0",
+		"org.dockerproject.setting=on",
+		// casing doesn't matter
+		"COM.docker.feature=enabled",
+		"io.DOCKER.CONFIGURATION=0",
+		"Org.Dockerproject.Setting=on",
+	} {
+		err := ValidateReservedNamespaceLabels([]string{
+			"valid=label",
+			invalidLabel,
+			"another=valid",
+		})
+		assert.Check(t, is.ErrorContains(err, invalidLabel))
+	}
+}
+
 func TestValidateConfigurationErrors(t *testing.T) {
 func TestValidateConfigurationErrors(t *testing.T) {
 	minusNumber := -10
 	minusNumber := -10
 	testCases := []struct {
 	testCases := []struct {