From a62a40d9ec15c87fec5294b0bf4a3bee71f15c21 Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:18:37 +0100 Subject: [PATCH] check that a container_name is used only once across all services declarations Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- loader/validate.go | 8 ++++++++ loader/validate_test.go | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/loader/validate.go b/loader/validate.go index 7d77609d..41fe65cf 100644 --- a/loader/validate.go +++ b/loader/validate.go @@ -29,6 +29,7 @@ import ( // checkConsistency validate a compose model is consistent func checkConsistency(project *types.Project) error { + containerNames := map[string]string{} for _, s := range project.Services { if s.Build == nil && s.Image == "" { return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid) @@ -123,6 +124,13 @@ func checkConsistency(project *types.Project) error { s.Deploy.Replicas = s.Scale } + if s.ContainerName != "" { + if existing, ok := containerNames[s.ContainerName]; ok { + return fmt.Errorf(`"services.%s": container name "%s" is already in use by "services.%s": %w`, s.Name, s.ContainerName, existing, errdefs.ErrInvalid) + } + containerNames[s.ContainerName] = s.Name + } + if s.GetScale() > 1 && s.ContainerName != "" { attr := "scale" if s.Scale == nil { diff --git a/loader/validate_test.go b/loader/validate_test.go index baa99775..7b19d6d2 100644 --- a/loader/validate_test.go +++ b/loader/validate_test.go @@ -259,3 +259,22 @@ func TestValidateDependsOn(t *testing.T) { err := checkConsistency(&project) assert.Error(t, err, `service "myservice" depends on undefined service missingservice: invalid compose project`) } + +func TestValidateContainerName(t *testing.T) { + project := types.Project{ + Services: types.Services{ + "myservice": { + Name: "myservice", + Image: "scratch", + ContainerName: "mycontainer", + }, + "myservice2": { + Name: "myservice2", + Image: "scratch", + ContainerName: "mycontainer", + }, + }, + } + err := checkConsistency(&project) + assert.Error(t, err, `"services.myservice2": container name "mycontainer" is already in use by "services.myservice": invalid compose project`) +}