Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix network_mode "service:x" #8792

Merged
merged 1 commit into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 42 additions & 37 deletions pkg/compose/convergence.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
ulyssessouza marked this conversation as resolved.
Show resolved Hide resolved
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
}
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/compose/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions pkg/e2e/networks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
})
}