Browse code

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 authored on 2018/04/24 04:24:01
Showing 3 changed files
... ...
@@ -284,29 +284,41 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
284 284
 }
285 285
 
286 286
 func (cli *DaemonCli) reloadConfig() {
287
-	reload := func(config *config.Config) {
287
+	reload := func(c *config.Config) {
288 288
 
289 289
 		// Revalidate and reload the authorization plugins
290
-		if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
290
+		if err := validateAuthzPlugins(c.AuthorizationPlugins, cli.d.PluginStore); err != nil {
291 291
 			logrus.Fatalf("Error validating authorization plugin: %v", err)
292 292
 			return
293 293
 		}
294
-		cli.authzMiddleware.SetPlugins(config.AuthorizationPlugins)
294
+		cli.authzMiddleware.SetPlugins(c.AuthorizationPlugins)
295
+
296
+		// The namespaces com.docker.*, io.docker.*, org.dockerproject.* have been documented
297
+		// to be reserved for Docker's internal use, but this was never enforced.  Allowing
298
+		// configured labels to use these namespaces are deprecated for 18.05.
299
+		//
300
+		// The following will check the usage of such labels, and report a warning for deprecation.
301
+		//
302
+		// TODO: At the next stable release, the validation should be folded into the other
303
+		// configuration validation functions and an error will be returned instead, and this
304
+		// block should be deleted.
305
+		if err := config.ValidateReservedNamespaceLabels(c.Labels); err != nil {
306
+			logrus.Warnf("Configured labels using reserved namespaces is deprecated: %s", err)
307
+		}
295 308
 
296
-		if err := cli.d.Reload(config); err != nil {
309
+		if err := cli.d.Reload(c); err != nil {
297 310
 			logrus.Errorf("Error reconfiguring the daemon: %v", err)
298 311
 			return
299 312
 		}
300 313
 
301
-		if config.IsValueSet("debug") {
314
+		if c.IsValueSet("debug") {
302 315
 			debugEnabled := debug.IsEnabled()
303 316
 			switch {
304
-			case debugEnabled && !config.Debug: // disable debug
317
+			case debugEnabled && !c.Debug: // disable debug
305 318
 				debug.Disable()
306
-			case config.Debug && !debugEnabled: // enable debug
319
+			case c.Debug && !debugEnabled: // enable debug
307 320
 				debug.Enable()
308 321
 			}
309
-
310 322
 		}
311 323
 	}
312 324
 
... ...
@@ -406,6 +418,18 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
406 406
 	if err != nil {
407 407
 		return nil, err
408 408
 	}
409
+	// The namespaces com.docker.*, io.docker.*, org.dockerproject.* have been documented
410
+	// to be reserved for Docker's internal use, but this was never enforced.  Allowing
411
+	// configured labels to use these namespaces are deprecated for 18.05.
412
+	//
413
+	// The following will check the usage of such labels, and report a warning for deprecation.
414
+	//
415
+	// TODO: At the next stable release, the validation should be folded into the other
416
+	// configuration validation functions and an error will be returned instead, and this
417
+	// block should be deleted.
418
+	if err := config.ValidateReservedNamespaceLabels(newLabels); err != nil {
419
+		logrus.Warnf("Configured labels using reserved namespaces is deprecated: %s", err)
420
+	}
409 421
 	conf.Labels = newLabels
410 422
 
411 423
 	// Regardless of whether the user sets it to true or false, if they
... ...
@@ -255,6 +255,25 @@ func GetConflictFreeLabels(labels []string) ([]string, error) {
255 255
 	return newLabels, nil
256 256
 }
257 257
 
258
+// ValidateReservedNamespaceLabels errors if the reserved namespaces com.docker.*,
259
+// io.docker.*, org.dockerproject.* are used in a configured engine label.
260
+//
261
+// TODO: This is a separate function because we need to warn users first of the
262
+// deprecation.  When we return an error, this logic can be added to Validate
263
+// or GetConflictFreeLabels instead of being here.
264
+func ValidateReservedNamespaceLabels(labels []string) error {
265
+	for _, label := range labels {
266
+		lowered := strings.ToLower(label)
267
+		if strings.HasPrefix(lowered, "com.docker.") || strings.HasPrefix(lowered, "io.docker.") ||
268
+			strings.HasPrefix(lowered, "org.dockerproject.") {
269
+			return fmt.Errorf(
270
+				"label %s not allowed: the namespaces com.docker.*, io.docker.*, and org.dockerproject.* are reserved for Docker's internal use",
271
+				label)
272
+		}
273
+	}
274
+	return nil
275
+}
276
+
258 277
 // Reload reads the configuration in the host and reloads the daemon and server.
259 278
 func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
260 279
 	logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
... ...
@@ -192,6 +192,40 @@ func TestFindConfigurationConflictsWithMergedValues(t *testing.T) {
192 192
 	}
193 193
 }
194 194
 
195
+func TestValidateReservedNamespaceLabels(t *testing.T) {
196
+	for _, validLabels := range [][]string{
197
+		nil, // no error if there are no labels
198
+		{ // no error if there aren't any reserved namespace labels
199
+			"hello=world",
200
+			"label=me",
201
+		},
202
+		{ // only reserved namespaces that end with a dot are invalid
203
+			"com.dockerpsychnotreserved.label=value",
204
+			"io.dockerproject.not=reserved",
205
+			"org.docker.not=reserved",
206
+		},
207
+	} {
208
+		assert.Check(t, ValidateReservedNamespaceLabels(validLabels))
209
+	}
210
+
211
+	for _, invalidLabel := range []string{
212
+		"com.docker.feature=enabled",
213
+		"io.docker.configuration=0",
214
+		"org.dockerproject.setting=on",
215
+		// casing doesn't matter
216
+		"COM.docker.feature=enabled",
217
+		"io.DOCKER.CONFIGURATION=0",
218
+		"Org.Dockerproject.Setting=on",
219
+	} {
220
+		err := ValidateReservedNamespaceLabels([]string{
221
+			"valid=label",
222
+			invalidLabel,
223
+			"another=valid",
224
+		})
225
+		assert.Check(t, is.ErrorContains(err, invalidLabel))
226
+	}
227
+}
228
+
195 229
 func TestValidateConfigurationErrors(t *testing.T) {
196 230
 	minusNumber := -10
197 231
 	testCases := []struct {