Ver código fonte

Fix network_mode "service:x"

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 4 anos atrás
pai
commit
c2dd40c161
3 arquivos alterados com 65 adições e 37 exclusões
  1. 42 37
      pkg/compose/convergence.go
  2. 7 0
      pkg/compose/run.go
  3. 16 0
      pkg/e2e/networks_test.go

+ 42 - 37
pkg/compose/convergence.go

@@ -109,53 +109,58 @@ func (c *convergence) apply(ctx context.Context, project *types.Project, options
 var mu sync.Mutex
 
 // updateProject updates project after service converged, so dependent services relying on `service:xx` can refer to actual containers.
-func (c *convergence) updateProject(project *types.Project, service string) {
-	containers := c.getObservedState(service)
-	if len(containers) == 0 {
-		return
-	}
-	container := containers[0]
-
+func (c *convergence) updateProject(project *types.Project, serviceName string) {
 	// operation is protected by a Mutex so that we can safely update project.Services while running concurrent convergence on services
 	mu.Lock()
 	defer mu.Unlock()
 
+	cnts := c.getObservedState(serviceName)
 	for i, s := range project.Services {
-		if d := getDependentServiceFromMode(s.NetworkMode); d == service {
-			s.NetworkMode = types.NetworkModeContainerPrefix + container.ID
-		}
-		if d := getDependentServiceFromMode(s.Ipc); d == service {
-			s.Ipc = types.NetworkModeContainerPrefix + container.ID
+		updateServices(&s, cnts)
+		project.Services[i] = s
+	}
+}
+
+func updateServices(service *types.ServiceConfig, cnts Containers) {
+	if len(cnts) == 0 {
+		return
+	}
+	cnt := cnts[0]
+	serviceName := cnt.Labels[api.ServiceLabel]
+
+	if d := getDependentServiceFromMode(service.NetworkMode); d == serviceName {
+		service.NetworkMode = types.NetworkModeContainerPrefix + cnt.ID
+	}
+	if d := getDependentServiceFromMode(service.Ipc); d == serviceName {
+		service.Ipc = types.NetworkModeContainerPrefix + cnt.ID
+	}
+	if d := getDependentServiceFromMode(service.Pid); d == serviceName {
+		service.Pid = types.NetworkModeContainerPrefix + cnt.ID
+	}
+	var links []string
+	for _, serviceLink := range service.Links {
+		parts := strings.Split(serviceLink, ":")
+		serviceName := serviceLink
+		serviceAlias := ""
+		if len(parts) == 2 {
+			serviceName = parts[0]
+			serviceAlias = parts[1]
 		}
-		if d := getDependentServiceFromMode(s.Pid); d == service {
-			s.Pid = types.NetworkModeContainerPrefix + container.ID
+		if serviceName != service.Name {
+			links = append(links, serviceLink)
+			continue
 		}
-		var links []string
-		for _, serviceLink := range s.Links {
-			parts := strings.Split(serviceLink, ":")
-			serviceName := serviceLink
-			serviceAlias := ""
-			if len(parts) == 2 {
-				serviceName = parts[0]
-				serviceAlias = parts[1]
-			}
-			if serviceName != service {
-				links = append(links, serviceLink)
-				continue
-			}
-			for _, container := range containers {
-				name := getCanonicalContainerName(container)
-				if serviceAlias != "" {
-					links = append(links,
-						fmt.Sprintf("%s:%s", name, serviceAlias))
-				}
+		for _, container := range cnts {
+			name := getCanonicalContainerName(container)
+			if serviceAlias != "" {
 				links = append(links,
-					fmt.Sprintf("%s:%s", name, name),
-					fmt.Sprintf("%s:%s", name, getContainerNameWithoutProject(container)))
+					fmt.Sprintf("%s:%s", name, serviceAlias))
 			}
-			s.Links = links
+			links = append(links,
+				fmt.Sprintf("%s:%s", name, name),
+				fmt.Sprintf("%s:%s", name, getContainerNameWithoutProject(container)))
 		}
-		project.Services[i] = s
+		service.Links = links
 	}
 }
 

+ 7 - 0
pkg/compose/run.go

@@ -164,6 +164,13 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project,
 			return "", err
 		}
 	}
+
+	observedState, err := s.getContainers(ctx, project.Name, oneOffInclude, true)
+	if err != nil {
+		return "", err
+	}
+	updateServices(&service, observedState)
+
 	created, err := s.createContainer(ctx, project, service, service.ContainerName, 1, opts.Detach && opts.AutoRemove, opts.UseNetworkAliases, true)
 	if err != nil {
 		return "", err

+ 16 - 0
pkg/e2e/networks_test.go

@@ -115,3 +115,19 @@ func TestIPAMConfig(t *testing.T) {
 		_ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
 	})
 }
+
+func TestNetworkModes(t *testing.T) {
+	c := NewParallelE2eCLI(t, binDir)
+
+	const projectName = "network_mode_service_run"
+
+	t.Run("run with service mode dependency", func(t *testing.T) {
+		res := c.RunDockerOrExitError("compose", "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "run", "mydb", "echo", "success")
+		res.Assert(t, icmd.Expected{Out: "success"})
+
+	})
+
+	t.Run("down", func(t *testing.T) {
+		_ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
+	})
+}