From b38d35ae1cfff687b0ce220e11818936b0f5c3b1 Mon Sep 17 00:00:00 2001 From: Lorena Rangel Date: Tue, 15 Jun 2021 11:00:07 +0200 Subject: [PATCH 1/2] set container links and external links in network Signed-off-by: Lorena Rangel --- .../fixtures/network-alias/compose.yaml | 2 + local/e2e/compose/networks_test.go | 9 +++- pkg/compose/convergence.go | 50 +++++++++++++++++-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/local/e2e/compose/fixtures/network-alias/compose.yaml b/local/e2e/compose/fixtures/network-alias/compose.yaml index e96175939..f74726fe0 100644 --- a/local/e2e/compose/fixtures/network-alias/compose.yaml +++ b/local/e2e/compose/fixtures/network-alias/compose.yaml @@ -2,6 +2,8 @@ services: container1: image: nginx + links: + - container2:container container2: image: nginx diff --git a/local/e2e/compose/networks_test.go b/local/e2e/compose/networks_test.go index da86ce99a..03d5714c2 100644 --- a/local/e2e/compose/networks_test.go +++ b/local/e2e/compose/networks_test.go @@ -71,7 +71,7 @@ func TestNetworks(t *testing.T) { }) } -func TestNetworkAliasses(t *testing.T) { +func TestNetworkAliassesAndLinks(t *testing.T) { c := NewParallelE2eCLI(t, binDir) const projectName = "network_alias_e2e" @@ -80,11 +80,16 @@ func TestNetworkAliasses(t *testing.T) { c.RunDockerCmd("compose", "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "up", "-d") }) - t.Run("curl", func(t *testing.T) { + t.Run("curl alias", func(t *testing.T) { res := c.RunDockerCmd("compose", "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "exec", "-T", "container1", "curl", "http://alias-of-container2/") assert.Assert(t, strings.Contains(res.Stdout(), "Welcome to nginx!"), res.Stdout()) }) + t.Run("curl links", func(t *testing.T) { + res := c.RunDockerCmd("compose", "-f", "./fixtures/network-alias/compose.yaml", "--project-name", projectName, "exec", "-T", "container1", "curl", "container") + assert.Assert(t, strings.Contains(res.Stdout(), "Welcome to nginx!"), res.Stdout()) + }) + t.Run("down", func(t *testing.T) { _ = c.RunDockerCmd("compose", "--project-name", projectName, "down") }) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 37a169b3c..99b68efe0 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "strconv" + "strings" "time" "github.com/compose-spec/compose-go/types" @@ -317,8 +318,14 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types createdContainer := moby.Container{ ID: created.ID, Labels: containerConfig.Labels, + Names: []string{"/" + name}, } cState.Add(createdContainer) + + links, err := s.getLinks(ctx, service) + if err != nil { + return err + } for _, netName := range service.NetworksByPriority() { netwrk := project.Networks[netName] cfg := service.Networks[netName] @@ -330,7 +337,7 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types } } - err = s.connectContainerToNetwork(ctx, created.ID, netwrk.Name, cfg, aliases...) + err = s.connectContainerToNetwork(ctx, created.ID, netwrk.Name, cfg, links, aliases...) if err != nil { return err } @@ -338,7 +345,7 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types return nil } -func (s *composeService) connectContainerToNetwork(ctx context.Context, id string, netwrk string, cfg *types.ServiceNetworkConfig, aliases ...string) error { +func (s *composeService) connectContainerToNetwork(ctx context.Context, id string, netwrk string, cfg *types.ServiceNetworkConfig, links []string, aliases ...string) error { var ( ipv4ddress string ipv6Address string @@ -347,10 +354,16 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin ipv4ddress = cfg.Ipv4Address ipv6Address = cfg.Ipv6Address } - err := s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{ + err := s.apiClient.NetworkDisconnect(ctx, netwrk, id, false) + if err != nil { + return err + } + + err = s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{ Aliases: aliases, IPAddress: ipv4ddress, GlobalIPv6Address: ipv6Address, + Links: links, }) if err != nil { return err @@ -358,6 +371,37 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin return nil } +func (s *composeService) getLinks(ctx context.Context, service types.ServiceConfig) ([]string, error) { + cState, err := GetContextContainerState(ctx) + if err != nil { + return nil, err + } + links := []string{} + for _, serviceLink := range service.Links { + s := strings.Split(serviceLink, ":") + serviceName := serviceLink + serviceAlias := "" + if len(s) == 2 { + serviceName = s[0] + serviceAlias = s[1] + } + containers := cState.GetContainers() + depServiceContainers := containers.filter(isService(serviceName)) + for _, container := range depServiceContainers { + name := getCanonicalContainerName(container) + if serviceAlias != "" { + links = append(links, + fmt.Sprintf("%s:%s", name, serviceAlias)) + } + links = append(links, + fmt.Sprintf("%s:%s", name, name), + fmt.Sprintf("%s:%s", name, getContainerNameWithoutProject(container))) + } + } + links = append(links, service.ExternalLinks...) + return links, nil +} + func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string) (bool, error) { containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, service) if err != nil { From b5d3eda22357492a0c72150f040b7915278d5461 Mon Sep 17 00:00:00 2001 From: Lorena Rangel Date: Tue, 15 Jun 2021 22:56:24 +0200 Subject: [PATCH 2/2] only disconnect active networks in a container Signed-off-by: Lorena Rangel --- pkg/compose/convergence.go | 40 +++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 99b68efe0..5565ab0ef 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -315,13 +315,19 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types if err != nil { return err } + inspectedContainer, err := s.apiClient.ContainerInspect(ctx, created.ID) + if err != nil { + return err + } createdContainer := moby.Container{ - ID: created.ID, - Labels: containerConfig.Labels, - Names: []string{"/" + name}, + ID: inspectedContainer.ID, + Labels: inspectedContainer.Config.Labels, + Names: []string{inspectedContainer.Name}, + NetworkSettings: &moby.SummaryNetworkSettings{ + Networks: inspectedContainer.NetworkSettings.Networks, + }, } cState.Add(createdContainer) - links, err := s.getLinks(ctx, service) if err != nil { return err @@ -336,7 +342,15 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types aliases = append(aliases, cfg.Aliases...) } } - + if val, ok := createdContainer.NetworkSettings.Networks[netwrk.Name]; ok { + if shortIDAliasExists(createdContainer.ID, val.Aliases...) { + continue + } + err := s.apiClient.NetworkDisconnect(ctx, netwrk.Name, createdContainer.ID, false) + if err != nil { + return err + } + } err = s.connectContainerToNetwork(ctx, created.ID, netwrk.Name, cfg, links, aliases...) if err != nil { return err @@ -345,6 +359,15 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types return nil } +func shortIDAliasExists(containerID string, aliases ...string) bool { + for _, alias := range aliases { + if alias == containerID[:12] { + return true + } + } + return false +} + func (s *composeService) connectContainerToNetwork(ctx context.Context, id string, netwrk string, cfg *types.ServiceNetworkConfig, links []string, aliases ...string) error { var ( ipv4ddress string @@ -354,12 +377,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin ipv4ddress = cfg.Ipv4Address ipv6Address = cfg.Ipv6Address } - err := s.apiClient.NetworkDisconnect(ctx, netwrk, id, false) - if err != nil { - return err - } - - err = s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{ + err := s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{ Aliases: aliases, IPAddress: ipv4ddress, GlobalIPv6Address: ipv6Address,