diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index c247bef15..593ba5b62 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -159,15 +159,15 @@ func (o *projectOptions) toProject(services []string, po ...cli.ProjectOptionsFn return nil, compose.WrapComposeError(err) } + if o.Compatibility || utils.StringToBool(options.Environment["COMPOSE_COMPATIBILITY"]) { + api.Separator = "_" + } + project, err := cli.ProjectFromOptions(options) if err != nil { return nil, compose.WrapComposeError(err) } - if o.Compatibility || utils.StringToBool(project.Environment["COMPOSE_COMPATIBILITY"]) { - compose.Separator = "_" - } - ef := o.EnvFile if ef != "" && !filepath.IsAbs(ef) { ef, err = filepath.Abs(ef) diff --git a/pkg/api/api.go b/pkg/api/api.go index 43f6745a6..30b1ac06e 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -446,11 +446,14 @@ const ( UserCancel ) +// Separator is used for naming components +var Separator = "-" + // GetImageNameOrDefault computes the default image name for a service, used to tag built images func GetImageNameOrDefault(service types.ServiceConfig, projectName string) string { imageName := service.Image if imageName == "" { - imageName = projectName + "_" + service.Name + imageName = projectName + Separator + service.Name } return imageName } diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index 5f7446e08..bfd4bdbf1 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -36,9 +36,6 @@ import ( "github.com/sanathkr/go-yaml" ) -// Separator is used for naming components -var Separator = "-" - // NewComposeService create a local implementation of the compose.Service API func NewComposeService(dockerCli command.Cli) api.Service { return &composeService{ diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 25b021cd8..4489cd2fd 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -261,7 +261,7 @@ func mustRecreate(expected types.ServiceConfig, actual moby.Container, policy st } 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 != "" { name = service.ContainerName } @@ -553,8 +553,8 @@ func (s composeService) getLinks(ctx context.Context, projectName string, servic containerName := getCanonicalContainerName(c) links = append(links, format(containerName, linkName), - format(containerName, linkServiceName+Separator+strconv.Itoa(number)), - format(containerName, strings.Join([]string{projectName, linkServiceName, strconv.Itoa(number)}, Separator)), + format(containerName, linkServiceName+api.Separator+strconv.Itoa(number)), + 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) links = append(links, format(containerName, service.Name), - format(containerName, strings.TrimPrefix(containerName, projectName+Separator)), + format(containerName, strings.TrimPrefix(containerName, projectName+api.Separator)), format(containerName, containerName), ) } diff --git a/pkg/compose/create_test.go b/pkg/compose/create_test.go index cc44478e1..4b6140460 100644 --- a/pkg/compose/create_test.go +++ b/pkg/compose/create_test.go @@ -80,7 +80,7 @@ func TestBuildVolumeMount(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{Name: "aService"}, "myProject"), "myProject_aService") + assert.Equal(t, api.GetImageNameOrDefault(composetypes.ServiceConfig{Name: "aService"}, "myProject"), "myProject-aService") } func TestPrepareNetworkLabels(t *testing.T) { diff --git a/pkg/e2e/build_test.go b/pkg/e2e/build_test.go index 154a7e3e1..178ed7f9b 100644 --- a/pkg/e2e/build_test.go +++ b/pkg/e2e/build_test.go @@ -31,30 +31,30 @@ func TestLocalComposeBuild(t *testing.T) { t.Run("build named and unnamed images", func(t *testing.T) { // 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") res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build") 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") }) t.Run("build with build-arg", func(t *testing.T) { // 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.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"`}) }) t.Run("build with build-arg set by env", func(t *testing.T) { // 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") icmd.RunCmd(c.NewDockerComposeCmd(t, @@ -67,20 +67,20 @@ func TestLocalComposeBuild(t *testing.T) { 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"`}) }) t.Run("build with multiple build-args ", func(t *testing.T) { // 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") icmd.RunCmd(cmd, func(cmd *icmd.Cmd) { 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"`}) }) @@ -131,7 +131,7 @@ func TestLocalComposeBuild(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") 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) 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") }) @@ -164,7 +164,7 @@ func TestLocalComposeBuild(t *testing.T) { t.Run("cleanup build project", func(t *testing.T) { 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") }) } @@ -216,10 +216,10 @@ func TestBuildImageDependencies(t *testing.T) { t.Cleanup(resetState) // 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{ ExitCode: 1, - Err: "Error: No such image: build-dependencies_service", + Err: "Error: No such image: build-dependencies-service", }) res = cli.RunDockerComposeCmd(t, "build") @@ -227,8 +227,8 @@ func TestBuildImageDependencies(t *testing.T) { res = cli.RunDockerCmd(t, "image", "inspect", "--format={{ index .RepoTags 0 }}", - "build-dependencies_service") - res.Assert(t, icmd.Expected{Out: "build-dependencies_service:latest"}) + "build-dependencies-service") + res.Assert(t, icmd.Expected{Out: "build-dependencies-service:latest"}) } t.Run("ClassicBuilder", func(t *testing.T) { diff --git a/pkg/e2e/fixtures/project-volume-bind-test/docker-compose.yml b/pkg/e2e/fixtures/project-volume-bind-test/docker-compose.yml index aba0bf47e..7e1795719 100644 --- a/pkg/e2e/fixtures/project-volume-bind-test/docker-compose.yml +++ b/pkg/e2e/fixtures/project-volume-bind-test/docker-compose.yml @@ -3,10 +3,10 @@ services: image: nginx container_name: frontend volumes: - - project_data:/data + - project-data:/data volumes: - project_data: + project-data: driver: local driver_opts: type: none diff --git a/pkg/e2e/networks_test.go b/pkg/e2e/networks_test.go index 2fa84bd6b..96558d300 100644 --- a/pkg/e2e/networks_test.go +++ b/pkg/e2e/networks_test.go @@ -30,10 +30,10 @@ func TestNetworks(t *testing.T) { // fixture is shared with TestNetworkModes and is not safe to run concurrently c := NewCLI(t) - const projectName = "network_e2e" + const projectName = "network-e2e" 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") }) @@ -125,7 +125,7 @@ func TestIPAMConfig(t *testing.T) { const projectName = "ipam_e2e" 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) { diff --git a/pkg/e2e/scan_message_test.go b/pkg/e2e/scan_message_test.go index 4204ef3d2..789eda0a6 100644 --- a/pkg/e2e/scan_message_test.go +++ b/pkg/e2e/scan_message_test.go @@ -37,7 +37,7 @@ func TestDisplayScanMessageAfterBuild(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", "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}) }) @@ -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", "build", "--quiet") 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")) res = c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test-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()) }) - _ = 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) { res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-build-test/compose.yaml", "-p", "scan-msg-test", "up", diff --git a/pkg/e2e/volumes_test.go b/pkg/e2e/volumes_test.go index c07bfaadb..fc6cd31c1 100644 --- a/pkg/e2e/volumes_test.go +++ b/pkg/e2e/volumes_test.go @@ -35,8 +35,8 @@ func TestLocalComposeVolume(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 - c.RunDockerOrExitError(t, "rmi", "compose-e2e-volume_nginx") - c.RunDockerOrExitError(t, "volume", "rm", projectName+"_staticVol") + c.RunDockerOrExitError(t, "rmi", "compose-e2e-volume-nginx") + c.RunDockerOrExitError(t, "volume", "rm", projectName+"-staticVol") c.RunDockerOrExitError(t, "volume", "rm", "myvolume") c.RunDockerComposeCmd(t, "--project-directory", "fixtures/volume-test", "--project-name", projectName, "up", "-d") @@ -88,7 +88,7 @@ func TestLocalComposeVolume(t *testing.T) { t.Run("cleanup volume project", func(t *testing.T) { c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "--volumes") 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")) }) } @@ -107,7 +107,7 @@ func TestProjectVolumeBind(t *testing.T) { 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}, "docker", "compose", "--project-directory", "fixtures/project-volume-bind-test", "--project-name", projectName, "up", "-d") icmd.RunCmd(cmd).Assert(t, icmd.Success)