Bladeren bron

Allow links to be specified with only the name if this matches the alias

Signed-off-by: Antonio Murdaca <me@runcom.ninja>
Antonio Murdaca 10 jaren geleden
bovenliggende
commit
c6e6223ed7

+ 4 - 4
daemon/daemon.go

@@ -686,14 +686,14 @@ func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error
 func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
 func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
 	if hostConfig != nil && hostConfig.Links != nil {
 	if hostConfig != nil && hostConfig.Links != nil {
 		for _, l := range hostConfig.Links {
 		for _, l := range hostConfig.Links {
-			parts, err := parsers.PartParser("name:alias", l)
+			name, alias, err := parsers.ParseLink(l)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			child, err := daemon.Get(parts["name"])
+			child, err := daemon.Get(name)
 			if err != nil {
 			if err != nil {
 				//An error from daemon.Get() means this name could not be found
 				//An error from daemon.Get() means this name could not be found
-				return fmt.Errorf("Could not get container for %s", parts["name"])
+				return fmt.Errorf("Could not get container for %s", name)
 			}
 			}
 			for child.hostConfig.NetworkMode.IsContainer() {
 			for child.hostConfig.NetworkMode.IsContainer() {
 				parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
 				parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
@@ -705,7 +705,7 @@ func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.
 			if child.hostConfig.NetworkMode.IsHost() {
 			if child.hostConfig.NetworkMode.IsHost() {
 				return runconfig.ErrConflictHostNetworkAndLinks
 				return runconfig.ErrConflictHostNetworkAndLinks
 			}
 			}
-			if err := daemon.RegisterLink(container, child, parts["alias"]); err != nil {
+			if err := daemon.RegisterLink(container, child, alias); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}

+ 2 - 1
docs/man/docker-create.1.md

@@ -133,7 +133,8 @@ two memory nodes.
    Read labels from a file. Delimit each label with an EOL.
    Read labels from a file. Delimit each label with an EOL.
 
 
 **--link**=[]
 **--link**=[]
-   Add link to another container in the form of <name or id>:alias
+   Add link to another container in the form of <name or id>:alias or just
+   <name or id> in which case the alias will match the name.
 
 
 **--lxc-conf**=[]
 **--lxc-conf**=[]
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"

+ 2 - 1
docs/man/docker-run.1.md

@@ -232,7 +232,8 @@ ENTRYPOINT.
    Read in a line delimited file of labels
    Read in a line delimited file of labels
 
 
 **--link**=[]
 **--link**=[]
-   Add link to another container in the form of <name or id>:alias
+   Add link to another container in the form of <name or id>:alias or just <name or id>
+in which case the alias will match the name
 
 
    If the operator
    If the operator
 uses **--link** when starting the new client container, then the client
 uses **--link** when starting the new client container, then the client

+ 6 - 0
docs/sources/reference/commandline/cli.md

@@ -2136,6 +2136,12 @@ Guide.
 The `--link` flag will link the container named `/redis` into the newly
 The `--link` flag will link the container named `/redis` into the newly
 created container with the alias `redis`. The new container can access the
 created container with the alias `redis`. The new container can access the
 network and environment of the `redis` container via environment variables.
 network and environment of the `redis` container via environment variables.
+The `--link` flag will also just accept the form `<name or id>` in which case
+the alias will match the name. For instance, you could have written the previous
+example as:
+
+    $ docker run --link redis --name console ubuntu bash
+
 The `--name` flag will assign the name `console` to the newly created
 The `--name` flag will assign the name `console` to the newly created
 container.
 container.
 
 

+ 1 - 1
docs/sources/reference/run.md

@@ -927,7 +927,7 @@ or override the Dockerfile's exposed defaults:
                    Both hostPort and containerPort can be specified as a range of ports. 
                    Both hostPort and containerPort can be specified as a range of ports. 
                    When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g., `-p 1234-1236:1234-1236/tcp`)
                    When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g., `-p 1234-1236:1234-1236/tcp`)
                    (use 'docker port' to see the actual mapping)
                    (use 'docker port' to see the actual mapping)
-    --link=""  : Add link to another container (<name or id>:alias)
+    --link=""  : Add link to another container (<name or id>:alias or <name or id>)
 
 
 As mentioned previously, `EXPOSE` (and `--expose`) makes ports available
 As mentioned previously, `EXPOSE` (and `--expose`) makes ports available
 **in** a container for incoming connections. The port number on the
 **in** a container for incoming connections. The port number on the

+ 9 - 1
docs/sources/userguide/dockerlinks.md

@@ -114,7 +114,7 @@ You can also use `docker inspect` to return the container's name.
     $ docker inspect -f "{{ .Name }}" aed84ee21bde
     $ docker inspect -f "{{ .Name }}" aed84ee21bde
     /web
     /web
 
 
-> **Note:** 
+> **Note:**
 > Container names have to be unique. That means you can only call
 > Container names have to be unique. That means you can only call
 > one container `web`. If you want to re-use a container name you must delete
 > one container `web`. If you want to re-use a container name you must delete
 > the old container (with `docker rm`) before you can create a new
 > the old container (with `docker rm`) before you can create a new
@@ -151,6 +151,14 @@ earlier. The `--link` flag takes the form:
 
 
 Where `name` is the name of the container we're linking to and `alias` is an
 Where `name` is the name of the container we're linking to and `alias` is an
 alias for the link name. You'll see how that alias gets used shortly.
 alias for the link name. You'll see how that alias gets used shortly.
+The `--link` flag also takes the form:
+
+	--link <name or id>
+
+In which case the alias will match the name. You could have written the previous
+example as:
+
+    $ docker run -d -P --name web --link db training/webapp python app.py
 
 
 Next, inspect your linked containers with `docker inspect`:
 Next, inspect your linked containers with `docker inspect`:
 
 

+ 20 - 1
integration-cli/docker_cli_links_test.go

@@ -15,7 +15,6 @@ import (
 )
 )
 
 
 func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) {
 func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) {
-
 	runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
 	runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
 	out, _, _, err := runCommandWithStdoutStderr(runCmd)
 	out, _, _, err := runCommandWithStdoutStderr(runCmd)
 	if err != nil {
 	if err != nil {
@@ -331,3 +330,23 @@ func (s *DockerSuite) TestLinksEnvs(c *check.C) {
 		c.Fatalf("Incorrect output: %s", out)
 		c.Fatalf("Incorrect output: %s", out)
 	}
 	}
 }
 }
+
+func (s *DockerSuite) TestLinkShortDefinition(c *check.C) {
+	runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "shortlinkdef", "busybox", "top")
+	out, _, err := runCommandWithOutput(runCmd)
+	c.Assert(err, check.IsNil)
+
+	cid := strings.TrimSpace(out)
+	c.Assert(waitRun(cid), check.IsNil)
+
+	runCmd = exec.Command(dockerBinary, "run", "-d", "--name", "link2", "--link", "shortlinkdef", "busybox", "top")
+	out, _, err = runCommandWithOutput(runCmd)
+	c.Assert(err, check.IsNil)
+
+	cid2 := strings.TrimSpace(out)
+	c.Assert(waitRun(cid2), check.IsNil)
+
+	links, err := inspectFieldJSON(cid2, "HostConfig.Links")
+	c.Assert(err, check.IsNil)
+	c.Assert(links, check.Equals, "[\"/shortlinkdef:/link2/shortlinkdef\"]")
+}

+ 1 - 1
opts/opts.go

@@ -196,7 +196,7 @@ func ValidateAttach(val string) (string, error) {
 }
 }
 
 
 func ValidateLink(val string) (string, error) {
 func ValidateLink(val string) (string, error) {
-	if _, err := parsers.PartParser("name:alias", val); err != nil {
+	if _, _, err := parsers.ParseLink(val); err != nil {
 		return val, err
 		return val, err
 	}
 	}
 	return val, nil
 	return val, nil

+ 14 - 0
pkg/parsers/parsers.go

@@ -135,3 +135,17 @@ func ParsePortRange(ports string) (uint64, uint64, error) {
 	}
 	}
 	return start, end, nil
 	return start, end, nil
 }
 }
+
+func ParseLink(val string) (string, string, error) {
+	if val == "" {
+		return "", "", fmt.Errorf("empty string specified for links")
+	}
+	arr := strings.Split(val, ":")
+	if len(arr) > 2 {
+		return "", "", fmt.Errorf("bad format for links: %s", val)
+	}
+	if len(arr) == 1 {
+		return val, val, nil
+	}
+	return arr[0], arr[1], nil
+}

+ 32 - 0
pkg/parsers/parsers_test.go

@@ -123,3 +123,35 @@ func TestParsePortRangeIncorrectStartRange(t *testing.T) {
 		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
 		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
 	}
 	}
 }
 }
+
+func TestParseLink(t *testing.T) {
+	name, alias, err := ParseLink("name:alias")
+	if err != nil {
+		t.Fatalf("Expected not to error out on a valid name:alias format but got: %v", err)
+	}
+	if name != "name" {
+		t.Fatalf("Link name should have been name, got %s instead", name)
+	}
+	if alias != "alias" {
+		t.Fatalf("Link alias should have been alias, got %s instead", alias)
+	}
+	// short format definition
+	name, alias, err = ParseLink("name")
+	if err != nil {
+		t.Fatalf("Expected not to error out on a valid name only format but got: %v", err)
+	}
+	if name != "name" {
+		t.Fatalf("Link name should have been name, got %s instead", name)
+	}
+	if alias != "name" {
+		t.Fatalf("Link alias should have been name, got %s instead", alias)
+	}
+	// empty string link definition is not allowed
+	if _, _, err := ParseLink(""); err == nil || !strings.Contains(err.Error(), "empty string specified for links") {
+		t.Fatalf("Expected error 'empty string specified for links' but got: %v", err)
+	}
+	// more than two colons are not allowed
+	if _, _, err := ParseLink("link:alias:wrong"); err == nil || !strings.Contains(err.Error(), "bad format for links: link:alias:wrong") {
+		t.Fatalf("Expected error 'bad format for links: link:alias:wrong' but got: %v", err)
+	}
+}

+ 0 - 7
runconfig/config_test.go

@@ -45,13 +45,6 @@ func TestParseRunLinks(t *testing.T) {
 	if _, hostConfig := mustParse(t, ""); len(hostConfig.Links) != 0 {
 	if _, hostConfig := mustParse(t, ""); len(hostConfig.Links) != 0 {
 		t.Fatalf("Error parsing links. No link expected, received: %v", hostConfig.Links)
 		t.Fatalf("Error parsing links. No link expected, received: %v", hostConfig.Links)
 	}
 	}
-
-	if _, _, err := parse(t, "--link a"); err == nil {
-		t.Fatalf("Error parsing links. `--link a` should be an error but is not")
-	}
-	if _, _, err := parse(t, "--link"); err == nil {
-		t.Fatalf("Error parsing links. `--link` should be an error but is not")
-	}
 }
 }
 
 
 func TestParseRunAttach(t *testing.T) {
 func TestParseRunAttach(t *testing.T) {