Browse code

Remove hostname validation as it seems to break users

Validation is still done by swarmkit on the service side.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/12/01 03:22:07
Showing 12 changed files
... ...
@@ -32,17 +32,17 @@ type copyBackend interface {
32 32
 
33 33
 // stateBackend includes functions to implement to provide container state lifecycle functionality.
34 34
 type stateBackend interface {
35
-	ContainerCreate(config types.ContainerCreateConfig, validateHostname bool) (container.ContainerCreateCreatedBody, error)
35
+	ContainerCreate(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
36 36
 	ContainerKill(name string, sig uint64) error
37 37
 	ContainerPause(name string) error
38 38
 	ContainerRename(oldName, newName string) error
39 39
 	ContainerResize(name string, height, width int) error
40 40
 	ContainerRestart(name string, seconds *int) error
41 41
 	ContainerRm(name string, config *types.ContainerRmConfig) error
42
-	ContainerStart(name string, hostConfig *container.HostConfig, validateHostname bool, checkpoint string, checkpointDir string) error
42
+	ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
43 43
 	ContainerStop(name string, seconds *int) error
44 44
 	ContainerUnpause(name string) error
45
-	ContainerUpdate(name string, hostConfig *container.HostConfig, validateHostname bool) (container.ContainerUpdateOKBody, error)
45
+	ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error)
46 46
 	ContainerWait(name string, timeout time.Duration) (int, error)
47 47
 }
48 48
 
... ...
@@ -156,8 +156,7 @@ func (s *containerRouter) postContainersStart(ctx context.Context, w http.Respon
156 156
 
157 157
 	checkpoint := r.Form.Get("checkpoint")
158 158
 	checkpointDir := r.Form.Get("checkpoint-dir")
159
-	validateHostname := versions.GreaterThanOrEqualTo(version, "1.24")
160
-	if err := s.backend.ContainerStart(vars["name"], hostConfig, validateHostname, checkpoint, checkpointDir); err != nil {
159
+	if err := s.backend.ContainerStart(vars["name"], hostConfig, checkpoint, checkpointDir); err != nil {
161 160
 		return err
162 161
 	}
163 162
 
... ...
@@ -332,7 +331,6 @@ func (s *containerRouter) postContainerUpdate(ctx context.Context, w http.Respon
332 332
 		return err
333 333
 	}
334 334
 
335
-	version := httputils.VersionFromContext(ctx)
336 335
 	var updateConfig container.UpdateConfig
337 336
 
338 337
 	decoder := json.NewDecoder(r.Body)
... ...
@@ -346,8 +344,7 @@ func (s *containerRouter) postContainerUpdate(ctx context.Context, w http.Respon
346 346
 	}
347 347
 
348 348
 	name := vars["name"]
349
-	validateHostname := versions.GreaterThanOrEqualTo(version, "1.24")
350
-	resp, err := s.backend.ContainerUpdate(name, hostConfig, validateHostname)
349
+	resp, err := s.backend.ContainerUpdate(name, hostConfig)
351 350
 	if err != nil {
352 351
 		return err
353 352
 	}
... ...
@@ -372,14 +369,13 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
372 372
 	version := httputils.VersionFromContext(ctx)
373 373
 	adjustCPUShares := versions.LessThan(version, "1.19")
374 374
 
375
-	validateHostname := versions.GreaterThanOrEqualTo(version, "1.24")
376 375
 	ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
377 376
 		Name:             name,
378 377
 		Config:           config,
379 378
 		HostConfig:       hostConfig,
380 379
 		NetworkingConfig: networkingConfig,
381 380
 		AdjustCPUShares:  adjustCPUShares,
382
-	}, validateHostname)
381
+	})
383 382
 	if err != nil {
384 383
 		return err
385 384
 	}
... ...
@@ -116,7 +116,7 @@ type Backend interface {
116 116
 	// ContainerAttachRaw attaches to container.
117 117
 	ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error
118 118
 	// ContainerCreate creates a new Docker container and returns potential warnings
119
-	ContainerCreate(config types.ContainerCreateConfig, validateHostname bool) (container.ContainerCreateCreatedBody, error)
119
+	ContainerCreate(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
120 120
 	// ContainerRm removes a container specified by `id`.
121 121
 	ContainerRm(name string, config *types.ContainerRmConfig) error
122 122
 	// Commit creates a new Docker image from an existing Docker container.
... ...
@@ -124,7 +124,7 @@ type Backend interface {
124 124
 	// ContainerKill stops the container execution abruptly.
125 125
 	ContainerKill(containerID string, sig uint64) error
126 126
 	// ContainerStart starts a new container
127
-	ContainerStart(containerID string, hostConfig *container.HostConfig, validateHostname bool, checkpoint string, checkpointDir string) error
127
+	ContainerStart(containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
128 128
 	// ContainerWait stops processing until the given container is stopped.
129 129
 	ContainerWait(containerID string, timeout time.Duration) (int, error)
130 130
 	// ContainerUpdateCmdOnBuild updates container.Path and container.Args
... ...
@@ -301,7 +301,7 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
301 301
 		return nil
302 302
 	}
303 303
 
304
-	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig}, true)
304
+	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig})
305 305
 	if err != nil {
306 306
 		return err
307 307
 	}
... ...
@@ -180,7 +180,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD
180 180
 		return nil
181 181
 	}
182 182
 
183
-	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig}, true)
183
+	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig})
184 184
 	if err != nil {
185 185
 		return err
186 186
 	}
... ...
@@ -496,7 +496,7 @@ func (b *Builder) create() (string, error) {
496 496
 	c, err := b.docker.ContainerCreate(types.ContainerCreateConfig{
497 497
 		Config:     b.runConfig,
498 498
 		HostConfig: hostConfig,
499
-	}, true)
499
+	})
500 500
 	if err != nil {
501 501
 		return "", err
502 502
 	}
... ...
@@ -537,7 +537,7 @@ func (b *Builder) run(cID string) (err error) {
537 537
 		}
538 538
 	}()
539 539
 
540
-	if err := b.docker.ContainerStart(cID, nil, true, "", ""); err != nil {
540
+	if err := b.docker.ContainerStart(cID, nil, "", ""); err != nil {
541 541
 		close(finished)
542 542
 		if cancelErr := <-cancelErrCh; cancelErr != nil {
543 543
 			logrus.Debugf("Build cancelled (%v) and got an error from ContainerStart: %v",
... ...
@@ -28,8 +28,8 @@ type Backend interface {
28 28
 	FindNetwork(idName string) (libnetwork.Network, error)
29 29
 	SetupIngress(req clustertypes.NetworkCreateRequest, nodeIP string) error
30 30
 	PullImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
31
-	CreateManagedContainer(config types.ContainerCreateConfig, validateHostname bool) (container.ContainerCreateCreatedBody, error)
32
-	ContainerStart(name string, hostConfig *container.HostConfig, validateHostname bool, checkpoint string, checkpointDir string) error
31
+	CreateManagedContainer(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
32
+	ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
33 33
 	ContainerStop(name string, seconds *int) error
34 34
 	ContainerLogs(context.Context, string, *backend.ContainerLogsConfig, chan struct{}) error
35 35
 	ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
... ...
@@ -11,12 +11,10 @@ import (
11 11
 
12 12
 	"github.com/Sirupsen/logrus"
13 13
 	"github.com/docker/distribution/digest"
14
-	"github.com/docker/docker/api/server/httputils"
15 14
 	"github.com/docker/docker/api/types"
16 15
 	"github.com/docker/docker/api/types/backend"
17 16
 	containertypes "github.com/docker/docker/api/types/container"
18 17
 	"github.com/docker/docker/api/types/events"
19
-	"github.com/docker/docker/api/types/versions"
20 18
 	"github.com/docker/docker/daemon/cluster/convert"
21 19
 	executorpkg "github.com/docker/docker/daemon/cluster/executor"
22 20
 	"github.com/docker/docker/reference"
... ...
@@ -215,8 +213,6 @@ func (c *containerAdapter) waitForDetach(ctx context.Context) error {
215 215
 func (c *containerAdapter) create(ctx context.Context) error {
216 216
 	var cr containertypes.ContainerCreateCreatedBody
217 217
 	var err error
218
-	version := httputils.VersionFromContext(ctx)
219
-	validateHostname := versions.GreaterThanOrEqualTo(version, "1.24")
220 218
 
221 219
 	if cr, err = c.backend.CreateManagedContainer(types.ContainerCreateConfig{
222 220
 		Name:       c.container.name(),
... ...
@@ -224,7 +220,7 @@ func (c *containerAdapter) create(ctx context.Context) error {
224 224
 		HostConfig: c.container.hostConfig(),
225 225
 		// Use the first network in container create
226 226
 		NetworkingConfig: c.container.createNetworkingConfig(),
227
-	}, validateHostname); err != nil {
227
+	}); err != nil {
228 228
 		return err
229 229
 	}
230 230
 
... ...
@@ -263,9 +259,7 @@ func (c *containerAdapter) create(ctx context.Context) error {
263 263
 }
264 264
 
265 265
 func (c *containerAdapter) start(ctx context.Context) error {
266
-	version := httputils.VersionFromContext(ctx)
267
-	validateHostname := versions.GreaterThanOrEqualTo(version, "1.24")
268
-	return c.backend.ContainerStart(c.container.name(), nil, validateHostname, "", "")
266
+	return c.backend.ContainerStart(c.container.name(), nil, "", "")
269 267
 }
270 268
 
271 269
 func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) {
... ...
@@ -3,7 +3,6 @@ package daemon
3 3
 import (
4 4
 	"fmt"
5 5
 	"path/filepath"
6
-	"regexp"
7 6
 	"time"
8 7
 
9 8
 	"github.com/docker/docker/api/errors"
... ...
@@ -204,7 +203,7 @@ func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *
204 204
 
205 205
 // verifyContainerSettings performs validation of the hostconfig and config
206 206
 // structures.
207
-func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool, validateHostname bool) ([]string, error) {
207
+func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
208 208
 
209 209
 	// First perform verification of settings common across all platforms.
210 210
 	if config != nil {
... ...
@@ -222,18 +221,6 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostCon
222 222
 			}
223 223
 		}
224 224
 
225
-		// Validate if the given hostname is RFC 1123 (https://tools.ietf.org/html/rfc1123) compliant.
226
-		if validateHostname && len(config.Hostname) > 0 {
227
-			// RFC1123 specifies that 63 bytes is the maximium length
228
-			// Windows has the limitation of 63 bytes in length
229
-			// Linux hostname is limited to HOST_NAME_MAX=64, not including the terminating null byte.
230
-			// We limit the length to 63 bytes here to match RFC1035 and RFC1123.
231
-			matched, _ := regexp.MatchString("^(([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])\\.)*([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])$", config.Hostname)
232
-			if len(config.Hostname) > 63 || !matched {
233
-				return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname)
234
-			}
235
-		}
236
-
237 225
 		// Validate if Env contains empty variable or not (e.g., ``, `=foo`)
238 226
 		for _, env := range config.Env {
239 227
 			if _, err := opts.ValidateEnv(env); err != nil {
... ...
@@ -25,22 +25,22 @@ import (
25 25
 )
26 26
 
27 27
 // CreateManagedContainer creates a container that is managed by a Service
28
-func (daemon *Daemon) CreateManagedContainer(params types.ContainerCreateConfig, validateHostname bool) (containertypes.ContainerCreateCreatedBody, error) {
29
-	return daemon.containerCreate(params, true, validateHostname)
28
+func (daemon *Daemon) CreateManagedContainer(params types.ContainerCreateConfig) (containertypes.ContainerCreateCreatedBody, error) {
29
+	return daemon.containerCreate(params, true)
30 30
 }
31 31
 
32 32
 // ContainerCreate creates a regular container
33
-func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig, validateHostname bool) (containertypes.ContainerCreateCreatedBody, error) {
34
-	return daemon.containerCreate(params, false, validateHostname)
33
+func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig) (containertypes.ContainerCreateCreatedBody, error) {
34
+	return daemon.containerCreate(params, false)
35 35
 }
36 36
 
37
-func (daemon *Daemon) containerCreate(params types.ContainerCreateConfig, managed bool, validateHostname bool) (containertypes.ContainerCreateCreatedBody, error) {
37
+func (daemon *Daemon) containerCreate(params types.ContainerCreateConfig, managed bool) (containertypes.ContainerCreateCreatedBody, error) {
38 38
 	start := time.Now()
39 39
 	if params.Config == nil {
40 40
 		return containertypes.ContainerCreateCreatedBody{}, fmt.Errorf("Config cannot be empty in order to create a container")
41 41
 	}
42 42
 
43
-	warnings, err := daemon.verifyContainerSettings(params.HostConfig, params.Config, false, validateHostname)
43
+	warnings, err := daemon.verifyContainerSettings(params.HostConfig, params.Config, false)
44 44
 	if err != nil {
45 45
 		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err
46 46
 	}
... ...
@@ -19,7 +19,7 @@ import (
19 19
 )
20 20
 
21 21
 // ContainerStart starts a container.
22
-func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig, validateHostname bool, checkpoint string, checkpointDir string) error {
22
+func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
23 23
 	if checkpoint != "" && !daemon.HasExperimental() {
24 24
 		return apierrors.NewBadRequestError(fmt.Errorf("checkpoint is only supported in experimental mode"))
25 25
 	}
... ...
@@ -73,7 +73,7 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
73 73
 
74 74
 	// check if hostConfig is in line with the current system settings.
75 75
 	// It may happen cgroups are umounted or the like.
76
-	if _, err = daemon.verifyContainerSettings(container.HostConfig, nil, false, validateHostname); err != nil {
76
+	if _, err = daemon.verifyContainerSettings(container.HostConfig, nil, false); err != nil {
77 77
 		return err
78 78
 	}
79 79
 	// Adapt for old containers in case we have updates in this function and
... ...
@@ -7,10 +7,10 @@ import (
7 7
 )
8 8
 
9 9
 // ContainerUpdate updates configuration of the container
10
-func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig, validateHostname bool) (container.ContainerUpdateOKBody, error) {
10
+func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) {
11 11
 	var warnings []string
12 12
 
13
-	warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true, validateHostname)
13
+	warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true)
14 14
 	if err != nil {
15 15
 		return container.ContainerUpdateOKBody{Warnings: warnings}, err
16 16
 	}
... ...
@@ -4354,42 +4354,6 @@ func (s *DockerSuite) TestRunVolumeCopyFlag(c *check.C) {
4354 4354
 	c.Assert(err, checker.NotNil, check.Commentf(out))
4355 4355
 }
4356 4356
 
4357
-func (s *DockerSuite) TestRunTooLongHostname(c *check.C) {
4358
-	// Test case in #21445
4359
-	hostname1 := "this-is-a-way-too-long-hostname-but-it-should-give-a-nice-error.local"
4360
-	out, _, err := dockerCmdWithError("run", "--hostname", hostname1, "busybox", "echo", "test")
4361
-	c.Assert(err, checker.NotNil, check.Commentf("Expected docker run to fail!"))
4362
-	c.Assert(out, checker.Contains, "invalid hostname format:", check.Commentf("Expected to have 'invalid hostname format:' in the output, get: %s!", out))
4363
-
4364
-	// Additional test cases
4365
-	validHostnames := map[string]string{
4366
-		"hostname":    "hostname",
4367
-		"host-name":   "host-name",
4368
-		"hostname123": "hostname123",
4369
-		"123hostname": "123hostname",
4370
-		"hostname-of-63-bytes-long-should-be-valid-and-without-any-error": "hostname-of-63-bytes-long-should-be-valid-and-without-any-error",
4371
-	}
4372
-	for hostname := range validHostnames {
4373
-		dockerCmd(c, "run", "--hostname", hostname, "busybox", "echo", "test")
4374
-	}
4375
-
4376
-	invalidHostnames := map[string]string{
4377
-		"^hostname": "invalid hostname format: ^hostname",
4378
-		"hostname%": "invalid hostname format: hostname%",
4379
-		"host&name": "invalid hostname format: host&name",
4380
-		"-hostname": "invalid hostname format: -hostname",
4381
-		"host_name": "invalid hostname format: host_name",
4382
-		"hostname-of-64-bytes-long-should-be-invalid-and-be-with-an-error": "invalid hostname format: hostname-of-64-bytes-long-should-be-invalid-and-be-with-an-error",
4383
-	}
4384
-
4385
-	for hostname, expectedError := range invalidHostnames {
4386
-		out, _, err = dockerCmdWithError("run", "--hostname", hostname, "busybox", "echo", "test")
4387
-		c.Assert(err, checker.NotNil, check.Commentf("Expected docker run to fail!"))
4388
-		c.Assert(out, checker.Contains, expectedError, check.Commentf("Expected to have '%s' in the output, get: %s!", expectedError, out))
4389
-
4390
-	}
4391
-}
4392
-
4393 4357
 // Test case for #21976
4394 4358
 func (s *DockerSuite) TestRunDNSInHostMode(c *check.C) {
4395 4359
 	testRequires(c, DaemonIsLinux, NotUserNamespace)