diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 63ac47f5fac4..c2fdfb1fbb5a 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -2500,10 +2500,13 @@ func validateServices(t *Task) error { outer := fmt.Errorf("service[%d] %+q validation failed: %s", i, service.Name, err) mErr.Errors = append(mErr.Errors, outer) } - if _, ok := knownServices[service.Name]; ok { + + // Ensure that services with the same name are not being registered for + // the same port + if _, ok := knownServices[service.Name+service.PortLabel]; ok { mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q is duplicate", service.Name)) } - knownServices[service.Name] = struct{}{} + knownServices[service.Name+service.PortLabel] = struct{}{} if service.PortLabel != "" { servicePorts[service.PortLabel] = append(servicePorts[service.PortLabel], service.Name) diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 4ba18b65ce92..018ae1618fa9 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -509,10 +509,21 @@ func TestTask_Validate_Services(t *testing.T) { } s2 := &Service{ - Name: "service-name", + Name: "service-name", + PortLabel: "bar", + } + + s3 := &Service{ + Name: "service-A", + PortLabel: "a", + } + s4 := &Service{ + Name: "service-A", + PortLabel: "b", } ephemeralDisk := DefaultEphemeralDisk() + ephemeralDisk.SizeMB = 200 task := &Task{ Name: "web", Driver: "docker", @@ -523,15 +534,34 @@ func TestTask_Validate_Services(t *testing.T) { }, Services: []*Service{s1, s2}, } - ephemeralDisk.SizeMB = 200 + + task1 := &Task{ + Name: "web", + Driver: "docker", + Resources: DefaultResources(), + Services: []*Service{s3, s4}, + LogConfig: DefaultLogConfig(), + } + task1.Resources.Networks = []*NetworkResource{ + &NetworkResource{ + MBits: 10, + DynamicPorts: []Port{ + Port{ + Label: "a", + Value: 1000, + }, + Port{ + Label: "b", + Value: 2000, + }, + }, + }, + } err := task.Validate(ephemeralDisk) if err == nil { t.Fatal("expected an error") } - if !strings.Contains(err.Error(), "referenced by services service-name does not exist") { - t.Fatalf("err: %s", err) - } if !strings.Contains(err.Error(), "service \"service-name\" is duplicate") { t.Fatalf("err: %v", err) @@ -548,6 +578,10 @@ func TestTask_Validate_Services(t *testing.T) { if !strings.Contains(err.Error(), "cannot be less than") { t.Fatalf("err: %v", err) } + + if err = task1.Validate(ephemeralDisk); err != nil { + t.Fatalf("err : %v", err) + } } func TestTask_Validate_Service_Check(t *testing.T) {