From 248e0c63db2b0314356ebd9848e6d26a2b5ba733 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 16 Sep 2013 22:30:48 +0000 Subject: [PATCH] Add port and ip for links --- api.go | 2 +- api_params.go | 3 ++- commands.go | 2 +- container.go | 54 +++++++++++++++++++++++++++++++++---------------- links.go | 6 +++--- runtime_test.go | 2 +- utils.go | 6 ++++-- 7 files changed, 49 insertions(+), 26 deletions(-) diff --git a/api.go b/api.go index ee7fe3d89..ecce8ee7f 100644 --- a/api.go +++ b/api.go @@ -963,7 +963,7 @@ func getLinksJSON(srv *Server, version float64, w http.ResponseWriter, r *http.R links := srv.runtime.links.Get(name) for _, l := range links { - out = append(out, APILink{l.To, l.From, l.Addr, l.Alias}) + out = append(out, APILink{l.To, l.From, l.IP, fmt.Sprint(l.Port), l.Alias}) } w.Header().Add("Content-Type", "application/json") diff --git a/api_params.go b/api_params.go index b3540ba70..ecf3fac8b 100644 --- a/api_params.go +++ b/api_params.go @@ -124,6 +124,7 @@ type APICopy struct { type APILink struct { To string From string - Addr string + IP string + Port string Alias string } diff --git a/commands.go b/commands.go index 6f527a99f..b1204fcd3 100644 --- a/commands.go +++ b/commands.go @@ -1136,7 +1136,7 @@ func (cli *DockerCli) CmdLink(args ...string) error { fmt.Fprintf(w, "FROM\tTO\tADDRESS\tALIAS") fmt.Fprintf(w, "\n") for _, l := range links { - fmt.Fprintf(w, "%s\t%s\t%s\t%s", l.From, l.To, l.Addr, l.Alias) + fmt.Fprintf(w, "%s\t%s\t%s\t%s", l.From, l.To, fmt.Sprintf("%s:%s", l.IP, l.Port), l.Alias) fmt.Fprintf(w, "\n") } w.Flush() diff --git a/container.go b/container.go index 6e85bf006..fb68ca7b9 100644 --- a/container.go +++ b/container.go @@ -114,19 +114,19 @@ type PortBinding struct { HostPort string } -// tcp/80 +// 80/tcp type Port string func (p Port) Proto() string { - return strings.Split(string(p), "/")[0] -} - -func (p Port) Port() string { return strings.Split(string(p), "/")[1] } +func (p Port) Port() string { + return strings.Split(string(p), "/")[0] +} + func NewPort(proto, port string) Port { - return Port(fmt.Sprintf("%s/%s", proto, port)) + return Port(fmt.Sprintf("%s/%s", port, proto)) } func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig, *flag.FlagSet, error) { @@ -831,21 +831,15 @@ func (container *Container) Start(hostConfig *HostConfig) error { runtime := container.runtime for _, l := range hostConfig.Links { linkedContainer := runtime.Get(l.From) + if linkedContainer == nil { return fmt.Errorf("Cannot locate container for link: %s AS %s", l.From, l.Alias) } - if !linkedContainer.State.Running { - return fmt.Errorf("Cannot link a non running container: %s AS %s", l.From, l.Alias) + if err := linkedContainer.AcceptLink(l); err != nil { + return err } - - // Check for linkedContainer exposed ports - // - // Hide ports that are not requested - - l.To = utils.TruncateID(container.ID) - l.Addr = fmt.Sprintf("%s:%s", linkedContainer.NetworkSettings.IPAddress, l.Port) - if err := runtime.links.RegisterLink(l); err != nil { - return nil + if err := container.Link(linkedContainer, &l); err != nil { + return err } params = append(params, "-e", l.ToEnv()) } @@ -1375,3 +1369,29 @@ func (container *Container) Copy(resource string) (Archive, error) { } return TarFilter(basePath, Uncompressed, filter) } + +func (container *Container) AcceptLink(l Link) error { + if !container.State.Running { + return fmt.Errorf("Cannot accept link on a non running container: %s AS %s", l.From, l.Alias) + } + if !container.Exposes(l.Port) { + return fmt.Errorf("Cannot accept link to %s because %s is not exposed", container.ID, l.Port) + } + return nil +} + +func (container *Container) Link(c *Container, l *Link) error { + l.To = utils.TruncateID(container.ID) + l.IP = c.NetworkSettings.IPAddress + + if err := container.runtime.links.RegisterLink(*l); err != nil { + return err + } + return nil +} + +// Returns true if the container exposes a certain port +func (container *Container) Exposes(p Port) bool { + _, exists := container.Config.ExposedPorts[p] + return exists +} diff --git a/links.go b/links.go index cf716d6ae..40812e6d1 100644 --- a/links.go +++ b/links.go @@ -9,9 +9,9 @@ import ( type Link struct { From string To string - Addr string + IP string + Port Port Alias string - Port string } type LinkRepository struct { @@ -19,7 +19,7 @@ type LinkRepository struct { } func (l *Link) ToEnv() string { - return fmt.Sprintf("%s_ADDR=%s", strings.ToUpper(l.Alias), l.Addr) + return fmt.Sprintf("%s_ADDR=%s://%s:%s", strings.ToUpper(l.Alias), l.Port.Proto(), l.IP, l.Port.Port()) } func NewLinkRepository(root string) (*LinkRepository, error) { diff --git a/runtime_test.go b/runtime_test.go index 4caddc0ca..dd111f752 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -298,7 +298,7 @@ func startEchoServerContainer(t *testing.T, proto string) (*Runtime, *Container, } t.Log("Trying port", strPort) ep := make(map[Port]struct{}, 1) - p = Port(fmt.Sprintf("%s/%s", proto, strPort)) + p = Port(fmt.Sprintf("%s/%s", strPort, proto)) ep[p] = struct{}{} container, _, err = runtime.Create(&Config{ diff --git a/utils.go b/utils.go index c0548e45b..d526d372b 100644 --- a/utils.go +++ b/utils.go @@ -242,6 +242,7 @@ func parsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding, return exposedPorts, bindings, nil } +// Splits a port in the format of port/proto func splitProtoPort(rawPort string) (string, string) { parts := strings.Split(rawPort, "/") l := len(parts) @@ -251,7 +252,7 @@ func splitProtoPort(rawPort string) (string, string) { if l == 1 { return "tcp", rawPort } - return parts[1], parts[0] + return parts[0], parts[1] } func parsePort(rawPort string) (int, error) { @@ -289,11 +290,12 @@ func parseLink(rawLink string) (Link, error) { if err != nil { return Link{}, err } + port := NewPort(splitProtoPort(parts["port"])) return Link{ From: parts["id"], Alias: parts["alias"], - Port: parts["port"], + Port: port, }, nil }