Преглед на файлове

Merge pull request #1793 from lorenrh/il-102-links

Nicolas De loof преди 4 години
родител
ревизия
796d08d778
променени са 3 файла, в които са добавени 76 реда и са изтрити 7 реда
  1. 2 0
      local/e2e/compose/fixtures/network-alias/compose.yaml
  2. 7 2
      local/e2e/compose/networks_test.go
  3. 67 5
      pkg/compose/convergence.go

+ 2 - 0
local/e2e/compose/fixtures/network-alias/compose.yaml

@@ -2,6 +2,8 @@ services:
 
   container1:
     image: nginx
+    links:
+      - container2:container
 
   container2:
     image: nginx

+ 7 - 2
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")
 	})

+ 67 - 5
pkg/compose/convergence.go

@@ -20,6 +20,7 @@ import (
 	"context"
 	"fmt"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/compose-spec/compose-go/types"
@@ -314,11 +315,23 @@ 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,
+		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
+	}
 	for _, netName := range service.NetworksByPriority() {
 		netwrk := project.Networks[netName]
 		cfg := service.Networks[netName]
@@ -329,8 +342,16 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
 				aliases = append(aliases, cfg.Aliases...)
 			}
 		}
-
-		err = s.connectContainerToNetwork(ctx, created.ID, netwrk.Name, 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
 		}
@@ -338,7 +359,16 @@ 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 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
 		ipv6Address string
@@ -351,6 +381,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
 		Aliases:           aliases,
 		IPAddress:         ipv4ddress,
 		GlobalIPv6Address: ipv6Address,
+		Links:             links,
 	})
 	if err != nil {
 		return err
@@ -358,6 +389,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 {