mirror of
https://github.com/docker/compose.git
synced 2025-07-23 13:45:00 +02:00
Fix links resolution
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
This commit is contained in:
parent
709190312c
commit
b725c56c42
@ -448,7 +448,7 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
|
|||||||
Networks: inspectedContainer.NetworkSettings.Networks,
|
Networks: inspectedContainer.NetworkSettings.Networks,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
links := append(service.Links, service.ExternalLinks...)
|
links := s.getLinks(ctx, project.Name, service, number)
|
||||||
for _, netName := range service.NetworksByPriority() {
|
for _, netName := range service.NetworksByPriority() {
|
||||||
netwrk := project.Networks[netName]
|
netwrk := project.Networks[netName]
|
||||||
cfg := service.Networks[netName]
|
cfg := service.Networks[netName]
|
||||||
@ -476,6 +476,64 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
|
|||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getLinks mimics V1 compose/service.py::Service::_get_links()
|
||||||
|
func (s composeService) getLinks(ctx context.Context, projectName string, service types.ServiceConfig, number int) []string {
|
||||||
|
var links []string
|
||||||
|
format := func(k, v string) string {
|
||||||
|
return fmt.Sprintf("%s:%s", k, v)
|
||||||
|
}
|
||||||
|
getServiceContainers := func(serviceName string) (Containers, error) {
|
||||||
|
return s.getContainers(ctx, projectName, oneOffExclude, true, serviceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rawLink := range service.Links {
|
||||||
|
linkSplit := strings.Split(rawLink, ":")
|
||||||
|
linkServiceName := linkSplit[0]
|
||||||
|
l := linkServiceName
|
||||||
|
if len(linkSplit) == 2 {
|
||||||
|
l = linkSplit[1] // linkName if informed like in: "serviceName:linkName"
|
||||||
|
}
|
||||||
|
cnts, err := getServiceContainers(linkServiceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, c := range cnts {
|
||||||
|
containerName := getCanonicalContainerName(c)
|
||||||
|
links = append(links,
|
||||||
|
format(containerName, l),
|
||||||
|
format(containerName, strings.Join([]string{linkServiceName, strconv.Itoa(number)}, Separator)),
|
||||||
|
format(containerName, strings.Join([]string{projectName, linkServiceName, strconv.Itoa(number)}, Separator)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if service.Labels[api.OneoffLabel] == "True" {
|
||||||
|
cnts, err := getServiceContainers(service.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, c := range cnts {
|
||||||
|
containerName := getCanonicalContainerName(c)
|
||||||
|
links = append(links,
|
||||||
|
format(containerName, service.Name),
|
||||||
|
format(containerName, strings.TrimPrefix(containerName, projectName+Separator)),
|
||||||
|
format(containerName, containerName),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rawExtLink := range service.ExternalLinks {
|
||||||
|
extLinkSplit := strings.Split(rawExtLink, ":")
|
||||||
|
externalLink := extLinkSplit[0]
|
||||||
|
linkName := externalLink
|
||||||
|
if len(extLinkSplit) == 2 {
|
||||||
|
linkName = extLinkSplit[1]
|
||||||
|
}
|
||||||
|
links = append(links, format(externalLink, linkName))
|
||||||
|
}
|
||||||
|
return links
|
||||||
|
}
|
||||||
|
|
||||||
func shortIDAliasExists(containerID string, aliases ...string) bool {
|
func shortIDAliasExists(containerID string, aliases ...string) bool {
|
||||||
for _, alias := range aliases {
|
for _, alias := range aliases {
|
||||||
if alias == containerID[:12] {
|
if alias == containerID[:12] {
|
||||||
|
@ -17,10 +17,16 @@
|
|||||||
package compose
|
package compose
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
|
"github.com/docker/compose/v2/pkg/mocks"
|
||||||
|
moby "github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,3 +52,128 @@ func TestContainerName(t *testing.T) {
|
|||||||
_, err = getScale(s)
|
_, err = getScale(s)
|
||||||
assert.Error(t, err, fmt.Sprintf(doubledContainerNameWarning, s.Name, s.ContainerName))
|
assert.Error(t, err, fmt.Sprintf(doubledContainerNameWarning, s.Name, s.ContainerName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServiceLinks(t *testing.T) {
|
||||||
|
const dbContainerName = "/" + testProject + "-db-1"
|
||||||
|
const webContainerName = "/" + testProject + "-web-1"
|
||||||
|
s := types.ServiceConfig{
|
||||||
|
Name: "web",
|
||||||
|
Scale: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
containerListOptions := moby.ContainerListOptions{
|
||||||
|
Filters: filters.NewArgs(
|
||||||
|
projectFilter(testProject),
|
||||||
|
serviceFilter("db"),
|
||||||
|
oneOffFilter(false),
|
||||||
|
),
|
||||||
|
All: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("service links default", func(t *testing.T) {
|
||||||
|
mockCtrl := gomock.NewController(t)
|
||||||
|
defer mockCtrl.Finish()
|
||||||
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
|
tested.apiClient = apiClient
|
||||||
|
|
||||||
|
s.Links = []string{"db"}
|
||||||
|
|
||||||
|
c := testContainer("db", dbContainerName, false)
|
||||||
|
apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil)
|
||||||
|
|
||||||
|
links := tested.getLinks(context.Background(), testProject, s, 1)
|
||||||
|
|
||||||
|
assert.Equal(t, len(links), 3)
|
||||||
|
assert.Equal(t, links[0], "testProject-db-1:db")
|
||||||
|
assert.Equal(t, links[1], "testProject-db-1:db-1")
|
||||||
|
assert.Equal(t, links[2], "testProject-db-1:testProject-db-1")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("service links", func(t *testing.T) {
|
||||||
|
mockCtrl := gomock.NewController(t)
|
||||||
|
defer mockCtrl.Finish()
|
||||||
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
|
tested.apiClient = apiClient
|
||||||
|
|
||||||
|
s.Links = []string{"db:db"}
|
||||||
|
|
||||||
|
c := testContainer("db", dbContainerName, false)
|
||||||
|
|
||||||
|
apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil)
|
||||||
|
links := tested.getLinks(context.Background(), testProject, s, 1)
|
||||||
|
|
||||||
|
assert.Equal(t, len(links), 3)
|
||||||
|
assert.Equal(t, links[0], "testProject-db-1:db")
|
||||||
|
assert.Equal(t, links[1], "testProject-db-1:db-1")
|
||||||
|
assert.Equal(t, links[2], "testProject-db-1:testProject-db-1")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("service links name", func(t *testing.T) {
|
||||||
|
mockCtrl := gomock.NewController(t)
|
||||||
|
defer mockCtrl.Finish()
|
||||||
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
|
tested.apiClient = apiClient
|
||||||
|
|
||||||
|
s.Links = []string{"db:dbname"}
|
||||||
|
|
||||||
|
c := testContainer("db", dbContainerName, false)
|
||||||
|
apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil)
|
||||||
|
|
||||||
|
links := tested.getLinks(context.Background(), testProject, s, 1)
|
||||||
|
|
||||||
|
assert.Equal(t, len(links), 3)
|
||||||
|
assert.Equal(t, links[0], "testProject-db-1:dbname")
|
||||||
|
assert.Equal(t, links[1], "testProject-db-1:db-1")
|
||||||
|
assert.Equal(t, links[2], "testProject-db-1:testProject-db-1")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("service links external links", func(t *testing.T) {
|
||||||
|
mockCtrl := gomock.NewController(t)
|
||||||
|
defer mockCtrl.Finish()
|
||||||
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
|
tested.apiClient = apiClient
|
||||||
|
|
||||||
|
s.Links = []string{"db:dbname"}
|
||||||
|
s.ExternalLinks = []string{"db1:db2"}
|
||||||
|
|
||||||
|
c := testContainer("db", dbContainerName, false)
|
||||||
|
apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil)
|
||||||
|
|
||||||
|
links := tested.getLinks(context.Background(), testProject, s, 1)
|
||||||
|
assert.Equal(t, len(links), 4)
|
||||||
|
assert.Equal(t, links[0], "testProject-db-1:dbname")
|
||||||
|
assert.Equal(t, links[1], "testProject-db-1:db-1")
|
||||||
|
assert.Equal(t, links[2], "testProject-db-1:testProject-db-1")
|
||||||
|
|
||||||
|
// ExternalLink
|
||||||
|
assert.Equal(t, links[3], "db1:db2")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("service links itself oneoff", func(t *testing.T) {
|
||||||
|
mockCtrl := gomock.NewController(t)
|
||||||
|
defer mockCtrl.Finish()
|
||||||
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
|
tested.apiClient = apiClient
|
||||||
|
|
||||||
|
s.Links = []string{}
|
||||||
|
s.ExternalLinks = []string{}
|
||||||
|
s.Labels = s.Labels.Add(api.OneoffLabel, "True")
|
||||||
|
|
||||||
|
c := testContainer("web", webContainerName, true)
|
||||||
|
containerListOptionsOneOff := moby.ContainerListOptions{
|
||||||
|
Filters: filters.NewArgs(
|
||||||
|
projectFilter(testProject),
|
||||||
|
serviceFilter("web"),
|
||||||
|
oneOffFilter(false),
|
||||||
|
),
|
||||||
|
All: true,
|
||||||
|
}
|
||||||
|
apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptionsOneOff).Return([]moby.Container{c}, nil)
|
||||||
|
|
||||||
|
links := tested.getLinks(context.Background(), testProject, s, 1)
|
||||||
|
assert.Equal(t, len(links), 3)
|
||||||
|
assert.Equal(t, links[0], "testProject-web-1:web")
|
||||||
|
assert.Equal(t, links[1], "testProject-web-1:web-1")
|
||||||
|
assert.Equal(t, links[2], "testProject-web-1:testProject-web-1")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user