use '-' as separator by default for image name

Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
This commit is contained in:
Guillaume Lours 2022-07-29 18:55:22 +02:00
parent b49bd7c6ce
commit 150fd4b8cf
No known key found for this signature in database
10 changed files with 41 additions and 41 deletions

View File

@ -159,15 +159,15 @@ func (o *projectOptions) toProject(services []string, po ...cli.ProjectOptionsFn
return nil, compose.WrapComposeError(err) return nil, compose.WrapComposeError(err)
} }
if o.Compatibility || utils.StringToBool(options.Environment["COMPOSE_COMPATIBILITY"]) {
api.Separator = "_"
}
project, err := cli.ProjectFromOptions(options) project, err := cli.ProjectFromOptions(options)
if err != nil { if err != nil {
return nil, compose.WrapComposeError(err) return nil, compose.WrapComposeError(err)
} }
if o.Compatibility || utils.StringToBool(project.Environment["COMPOSE_COMPATIBILITY"]) {
compose.Separator = "_"
}
ef := o.EnvFile ef := o.EnvFile
if ef != "" && !filepath.IsAbs(ef) { if ef != "" && !filepath.IsAbs(ef) {
ef, err = filepath.Abs(ef) ef, err = filepath.Abs(ef)

View File

@ -446,11 +446,14 @@ const (
UserCancel UserCancel
) )
// Separator is used for naming components
var Separator = "-"
// GetImageNameOrDefault computes the default image name for a service, used to tag built images // GetImageNameOrDefault computes the default image name for a service, used to tag built images
func GetImageNameOrDefault(service types.ServiceConfig, projectName string) string { func GetImageNameOrDefault(service types.ServiceConfig, projectName string) string {
imageName := service.Image imageName := service.Image
if imageName == "" { if imageName == "" {
imageName = projectName + "_" + service.Name imageName = projectName + Separator + service.Name
} }
return imageName return imageName
} }

View File

@ -36,9 +36,6 @@ import (
"github.com/sanathkr/go-yaml" "github.com/sanathkr/go-yaml"
) )
// Separator is used for naming components
var Separator = "-"
// NewComposeService create a local implementation of the compose.Service API // NewComposeService create a local implementation of the compose.Service API
func NewComposeService(dockerCli command.Cli) api.Service { func NewComposeService(dockerCli command.Cli) api.Service {
return &composeService{ return &composeService{

View File

@ -261,7 +261,7 @@ func mustRecreate(expected types.ServiceConfig, actual moby.Container, policy st
} }
func getContainerName(projectName string, service types.ServiceConfig, number int) string { func getContainerName(projectName string, service types.ServiceConfig, number int) string {
name := strings.Join([]string{projectName, service.Name, strconv.Itoa(number)}, Separator) name := strings.Join([]string{projectName, service.Name, strconv.Itoa(number)}, api.Separator)
if service.ContainerName != "" { if service.ContainerName != "" {
name = service.ContainerName name = service.ContainerName
} }
@ -553,8 +553,8 @@ func (s composeService) getLinks(ctx context.Context, projectName string, servic
containerName := getCanonicalContainerName(c) containerName := getCanonicalContainerName(c)
links = append(links, links = append(links,
format(containerName, linkName), format(containerName, linkName),
format(containerName, linkServiceName+Separator+strconv.Itoa(number)), format(containerName, linkServiceName+api.Separator+strconv.Itoa(number)),
format(containerName, strings.Join([]string{projectName, linkServiceName, strconv.Itoa(number)}, Separator)), format(containerName, strings.Join([]string{projectName, linkServiceName, strconv.Itoa(number)}, api.Separator)),
) )
} }
} }
@ -568,7 +568,7 @@ func (s composeService) getLinks(ctx context.Context, projectName string, servic
containerName := getCanonicalContainerName(c) containerName := getCanonicalContainerName(c)
links = append(links, links = append(links,
format(containerName, service.Name), format(containerName, service.Name),
format(containerName, strings.TrimPrefix(containerName, projectName+Separator)), format(containerName, strings.TrimPrefix(containerName, projectName+api.Separator)),
format(containerName, containerName), format(containerName, containerName),
) )
} }

View File

@ -80,7 +80,7 @@ func TestBuildVolumeMount(t *testing.T) {
func TestServiceImageName(t *testing.T) { func TestServiceImageName(t *testing.T) {
assert.Equal(t, api.GetImageNameOrDefault(composetypes.ServiceConfig{Image: "myImage"}, "myProject"), "myImage") assert.Equal(t, api.GetImageNameOrDefault(composetypes.ServiceConfig{Image: "myImage"}, "myProject"), "myImage")
assert.Equal(t, api.GetImageNameOrDefault(composetypes.ServiceConfig{Name: "aService"}, "myProject"), "myProject_aService") assert.Equal(t, api.GetImageNameOrDefault(composetypes.ServiceConfig{Name: "aService"}, "myProject"), "myProject-aService")
} }
func TestPrepareNetworkLabels(t *testing.T) { func TestPrepareNetworkLabels(t *testing.T) {

View File

@ -31,30 +31,30 @@ func TestLocalComposeBuild(t *testing.T) {
t.Run("build named and unnamed images", func(t *testing.T) { t.Run("build named and unnamed images", func(t *testing.T) {
// ensure local test run does not reuse previously build image // ensure local test run does not reuse previously build image
c.RunDockerOrExitError(t, "rmi", "build-test_nginx") c.RunDockerOrExitError(t, "rmi", "build-test-nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx") c.RunDockerOrExitError(t, "rmi", "custom-nginx")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build") res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build")
res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
c.RunDockerCmd(t, "image", "inspect", "build-test_nginx") c.RunDockerCmd(t, "image", "inspect", "build-test-nginx")
c.RunDockerCmd(t, "image", "inspect", "custom-nginx") c.RunDockerCmd(t, "image", "inspect", "custom-nginx")
}) })
t.Run("build with build-arg", func(t *testing.T) { t.Run("build with build-arg", func(t *testing.T) {
// ensure local test run does not reuse previously build image // ensure local test run does not reuse previously build image
c.RunDockerOrExitError(t, "rmi", "build-test_nginx") c.RunDockerOrExitError(t, "rmi", "build-test-nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx") c.RunDockerOrExitError(t, "rmi", "custom-nginx")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build", "--build-arg", "FOO=BAR") c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build", "--build-arg", "FOO=BAR")
res := c.RunDockerCmd(t, "image", "inspect", "build-test_nginx") res := c.RunDockerCmd(t, "image", "inspect", "build-test-nginx")
res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`}) res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`})
}) })
t.Run("build with build-arg set by env", func(t *testing.T) { t.Run("build with build-arg set by env", func(t *testing.T) {
// ensure local test run does not reuse previously build image // ensure local test run does not reuse previously build image
c.RunDockerOrExitError(t, "rmi", "build-test_nginx") c.RunDockerOrExitError(t, "rmi", "build-test-nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx") c.RunDockerOrExitError(t, "rmi", "custom-nginx")
icmd.RunCmd(c.NewDockerComposeCmd(t, icmd.RunCmd(c.NewDockerComposeCmd(t,
@ -67,20 +67,20 @@ func TestLocalComposeBuild(t *testing.T) {
cmd.Env = append(cmd.Env, "FOO=BAR") cmd.Env = append(cmd.Env, "FOO=BAR")
}) })
res := c.RunDockerCmd(t, "image", "inspect", "build-test_nginx") res := c.RunDockerCmd(t, "image", "inspect", "build-test-nginx")
res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`}) res.Assert(t, icmd.Expected{Out: `"FOO": "BAR"`})
}) })
t.Run("build with multiple build-args ", func(t *testing.T) { t.Run("build with multiple build-args ", func(t *testing.T) {
// ensure local test run does not reuse previously build image // ensure local test run does not reuse previously build image
c.RunDockerOrExitError(t, "rmi", "-f", "multi-args_multiargs") c.RunDockerOrExitError(t, "rmi", "-f", "multi-args-multiargs")
cmd := c.NewDockerComposeCmd(t, "--project-directory", "fixtures/build-test/multi-args", "build") cmd := c.NewDockerComposeCmd(t, "--project-directory", "fixtures/build-test/multi-args", "build")
icmd.RunCmd(cmd, func(cmd *icmd.Cmd) { icmd.RunCmd(cmd, func(cmd *icmd.Cmd) {
cmd.Env = append(cmd.Env, "DOCKER_BUILDKIT=0") cmd.Env = append(cmd.Env, "DOCKER_BUILDKIT=0")
}) })
res := c.RunDockerCmd(t, "image", "inspect", "multi-args_multiargs") res := c.RunDockerCmd(t, "image", "inspect", "multi-args-multiargs")
res.Assert(t, icmd.Expected{Out: `"RESULT": "SUCCESS"`}) res.Assert(t, icmd.Expected{Out: `"RESULT": "SUCCESS"`})
}) })
@ -131,7 +131,7 @@ func TestLocalComposeBuild(t *testing.T) {
}) })
t.Run("build as part of up", func(t *testing.T) { t.Run("build as part of up", func(t *testing.T) {
c.RunDockerOrExitError(t, "rmi", "build-test_nginx") c.RunDockerOrExitError(t, "rmi", "build-test-nginx")
c.RunDockerOrExitError(t, "rmi", "custom-nginx") c.RunDockerOrExitError(t, "rmi", "custom-nginx")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d") res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d")
@ -145,7 +145,7 @@ func TestLocalComposeBuild(t *testing.T) {
output := HTTPGetWithRetry(t, "http://localhost:8070", http.StatusOK, 2*time.Second, 20*time.Second) output := HTTPGetWithRetry(t, "http://localhost:8070", http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(output, "Hello from Nginx container")) assert.Assert(t, strings.Contains(output, "Hello from Nginx container"))
c.RunDockerCmd(t, "image", "inspect", "build-test_nginx") c.RunDockerCmd(t, "image", "inspect", "build-test-nginx")
c.RunDockerCmd(t, "image", "inspect", "custom-nginx") c.RunDockerCmd(t, "image", "inspect", "custom-nginx")
}) })
@ -164,7 +164,7 @@ func TestLocalComposeBuild(t *testing.T) {
t.Run("cleanup build project", func(t *testing.T) { t.Run("cleanup build project", func(t *testing.T) {
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down") c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down")
c.RunDockerCmd(t, "rmi", "build-test_nginx") c.RunDockerCmd(t, "rmi", "build-test-nginx")
c.RunDockerCmd(t, "rmi", "custom-nginx") c.RunDockerCmd(t, "rmi", "custom-nginx")
}) })
} }
@ -216,10 +216,10 @@ func TestBuildImageDependencies(t *testing.T) {
t.Cleanup(resetState) t.Cleanup(resetState)
// the image should NOT exist now // the image should NOT exist now
res := cli.RunDockerOrExitError(t, "image", "inspect", "build-dependencies_service") res := cli.RunDockerOrExitError(t, "image", "inspect", "build-dependencies-service")
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{
ExitCode: 1, ExitCode: 1,
Err: "Error: No such image: build-dependencies_service", Err: "Error: No such image: build-dependencies-service",
}) })
res = cli.RunDockerComposeCmd(t, "build") res = cli.RunDockerComposeCmd(t, "build")
@ -227,8 +227,8 @@ func TestBuildImageDependencies(t *testing.T) {
res = cli.RunDockerCmd(t, res = cli.RunDockerCmd(t,
"image", "inspect", "--format={{ index .RepoTags 0 }}", "image", "inspect", "--format={{ index .RepoTags 0 }}",
"build-dependencies_service") "build-dependencies-service")
res.Assert(t, icmd.Expected{Out: "build-dependencies_service:latest"}) res.Assert(t, icmd.Expected{Out: "build-dependencies-service:latest"})
} }
t.Run("ClassicBuilder", func(t *testing.T) { t.Run("ClassicBuilder", func(t *testing.T) {

View File

@ -3,10 +3,10 @@ services:
image: nginx image: nginx
container_name: frontend container_name: frontend
volumes: volumes:
- project_data:/data - project-data:/data
volumes: volumes:
project_data: project-data:
driver: local driver: local
driver_opts: driver_opts:
type: none type: none

View File

@ -30,10 +30,10 @@ func TestNetworks(t *testing.T) {
// fixture is shared with TestNetworkModes and is not safe to run concurrently // fixture is shared with TestNetworkModes and is not safe to run concurrently
c := NewCLI(t) c := NewCLI(t)
const projectName = "network_e2e" const projectName = "network-e2e"
t.Run("ensure we do not reuse previous networks", func(t *testing.T) { t.Run("ensure we do not reuse previous networks", func(t *testing.T) {
c.RunDockerOrExitError(t, "network", "rm", projectName+"_dbnet") c.RunDockerOrExitError(t, "network", "rm", projectName+"-dbnet")
c.RunDockerOrExitError(t, "network", "rm", "microservices") c.RunDockerOrExitError(t, "network", "rm", "microservices")
}) })
@ -125,7 +125,7 @@ func TestIPAMConfig(t *testing.T) {
const projectName = "ipam_e2e" const projectName = "ipam_e2e"
t.Run("ensure we do not reuse previous networks", func(t *testing.T) { t.Run("ensure we do not reuse previous networks", func(t *testing.T) {
c.RunDockerOrExitError(t, "network", "rm", projectName+"_default") c.RunDockerOrExitError(t, "network", "rm", projectName+"-default")
}) })
t.Run("up", func(t *testing.T) { t.Run("up", func(t *testing.T) {

View File

@ -37,7 +37,7 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) {
t.Run("display on compose build", func(t *testing.T) { t.Run("display on compose build", func(t *testing.T) {
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p",
"scan-msg-test-compose-build", "build") "scan-msg-test-compose-build", "build")
defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-compose-build_nginx") defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-compose-build-nginx")
res.Assert(t, icmd.Expected{Err: utils.ScanSuggestMsg}) res.Assert(t, icmd.Expected{Err: utils.ScanSuggestMsg})
}) })
@ -45,16 +45,16 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) {
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-quiet", res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-quiet",
"build", "--quiet") "build", "--quiet")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined()) assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
res = c.RunDockerCmd(t, "rmi", "-f", "scan-msg-test-quiet_nginx") res = c.RunDockerCmd(t, "rmi", "-f", "scan-msg-test-quiet-nginx")
assert.Assert(t, !strings.Contains(res.Combined(), "No such image")) assert.Assert(t, !strings.Contains(res.Combined(), "No such image"))
res = c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-q", res = c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-q",
"build", "-q") "build", "-q")
defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-q_nginx") defer c.RunDockerOrExitError(t, "rmi", "-f", "scan-msg-test-q-nginx")
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined()) assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
}) })
_ = c.RunDockerOrExitError(t, "rmi", "scan-msg-test_nginx") _ = c.RunDockerOrExitError(t, "rmi", "scan-msg-test-nginx")
t.Run("display on compose up if image is built", func(t *testing.T) { t.Run("display on compose up if image is built", func(t *testing.T) {
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up", res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up",

View File

@ -35,8 +35,8 @@ func TestLocalComposeVolume(t *testing.T) {
t.Run("up with build and no image name, volume", func(t *testing.T) { t.Run("up with build and no image name, volume", func(t *testing.T) {
// ensure local test run does not reuse previously build image // ensure local test run does not reuse previously build image
c.RunDockerOrExitError(t, "rmi", "compose-e2e-volume_nginx") c.RunDockerOrExitError(t, "rmi", "compose-e2e-volume-nginx")
c.RunDockerOrExitError(t, "volume", "rm", projectName+"_staticVol") c.RunDockerOrExitError(t, "volume", "rm", projectName+"-staticVol")
c.RunDockerOrExitError(t, "volume", "rm", "myvolume") c.RunDockerOrExitError(t, "volume", "rm", "myvolume")
c.RunDockerComposeCmd(t, "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", c.RunDockerComposeCmd(t, "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up",
"-d") "-d")
@ -88,7 +88,7 @@ func TestLocalComposeVolume(t *testing.T) {
t.Run("cleanup volume project", func(t *testing.T) { t.Run("cleanup volume project", func(t *testing.T) {
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "--volumes") c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "--volumes")
ls := c.RunDockerCmd(t, "volume", "ls").Stdout() ls := c.RunDockerCmd(t, "volume", "ls").Stdout()
assert.Assert(t, !strings.Contains(ls, projectName+"_staticVol")) assert.Assert(t, !strings.Contains(ls, projectName+"-staticVol"))
assert.Assert(t, !strings.Contains(ls, "myvolume")) assert.Assert(t, !strings.Contains(ls, "myvolume"))
}) })
} }
@ -107,7 +107,7 @@ func TestProjectVolumeBind(t *testing.T) {
c.RunDockerComposeCmd(t, "--project-name", projectName, "down") c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
c.RunDockerOrExitError(t, "volume", "rm", "-f", projectName+"_project_data").Assert(t, icmd.Success) c.RunDockerOrExitError(t, "volume", "rm", "-f", projectName+"-project-data").Assert(t, icmd.Success)
cmd := c.NewCmdWithEnv([]string{"TEST_DIR=" + tmpDir}, cmd := c.NewCmdWithEnv([]string{"TEST_DIR=" + tmpDir},
"docker", "compose", "--project-directory", "fixtures/project-volume-bind-test", "--project-name", projectName, "up", "-d") "docker", "compose", "--project-directory", "fixtures/project-volume-bind-test", "--project-name", projectName, "up", "-d")
icmd.RunCmd(cmd).Assert(t, icmd.Success) icmd.RunCmd(cmd).Assert(t, icmd.Success)