mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #13074 from runcom/11824-short-link-if-equals-alias
Allow links to be specified with only the name if it matches the alias
This commit is contained in:
commit
8cc93856e3
11 changed files with 91 additions and 17 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,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"
|
||||||
|
|
|
@ -238,7 +238,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
|
||||||
|
|
|
@ -2138,6 +2138,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.
|
||||||
|
|
||||||
|
|
|
@ -942,7 +942,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
|
||||||
|
|
|
@ -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`:
|
||||||
|
|
||||||
|
|
|
@ -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\"]")
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue