jobspec: ensure service uniqueness in job validation
This commit is contained in:
parent
d83aae253f
commit
e5978a9cbf
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
servicedisco: Fixed a bug where non-unique services would escape job validation
|
||||
```
|
|
@ -6628,6 +6628,19 @@ func (tg *TaskGroup) validateServices() error {
|
|||
// Accumulate task names in this group
|
||||
taskSet := set.New[string](len(tg.Tasks))
|
||||
|
||||
// each service in a group must be unique (i.e. used in MakeAllocServiceID)
|
||||
type unique struct {
|
||||
name string
|
||||
task string
|
||||
port string
|
||||
}
|
||||
|
||||
// Accumulate service IDs in this group
|
||||
idSet := set.New[unique](0)
|
||||
|
||||
// Accumulate IDs that are duplicates
|
||||
idDuplicateSet := set.New[unique](0)
|
||||
|
||||
// Accumulate the providers used for this task group. Currently, Nomad only
|
||||
// allows the use of a single service provider within a task group.
|
||||
providerSet := set.New[string](1)
|
||||
|
@ -6642,6 +6655,7 @@ func (tg *TaskGroup) validateServices() error {
|
|||
}
|
||||
|
||||
for _, service := range task.Services {
|
||||
|
||||
// Ensure no task-level checks specify a task
|
||||
for _, check := range service.Checks {
|
||||
if check.TaskName != "" {
|
||||
|
@ -6649,6 +6663,13 @@ func (tg *TaskGroup) validateServices() error {
|
|||
}
|
||||
}
|
||||
|
||||
// Track that we have seen this service id
|
||||
id := unique{service.Name, task.Name, service.PortLabel}
|
||||
if !idSet.Insert(id) {
|
||||
// accumulate duplicates for a single error later on
|
||||
idDuplicateSet.Insert(id)
|
||||
}
|
||||
|
||||
// Track that we have seen this service provider
|
||||
providerSet.Insert(service.Provider)
|
||||
}
|
||||
|
@ -6656,6 +6677,13 @@ func (tg *TaskGroup) validateServices() error {
|
|||
|
||||
for i, service := range tg.Services {
|
||||
|
||||
// Track that we have seen this service id
|
||||
id := unique{service.Name, "group", service.PortLabel}
|
||||
if !idSet.Insert(id) {
|
||||
// accumulate duplicates for a single error later on
|
||||
idDuplicateSet.Insert(id)
|
||||
}
|
||||
|
||||
// Track that we have seen this service provider
|
||||
providerSet.Insert(service.Provider)
|
||||
|
||||
|
@ -6688,6 +6716,25 @@ func (tg *TaskGroup) validateServices() error {
|
|||
}
|
||||
}
|
||||
|
||||
// Produce an error of any services which are not unique enough in the group
|
||||
// i.e. have same <task, name, port>
|
||||
if idDuplicateSet.Size() > 0 {
|
||||
mErr.Errors = append(mErr.Errors,
|
||||
fmt.Errorf(
|
||||
"Services are not unique: %s",
|
||||
idDuplicateSet.String(
|
||||
func(u unique) string {
|
||||
s := u.task + "->" + u.name
|
||||
if u.port != "" {
|
||||
s += ":" + u.port
|
||||
}
|
||||
return s
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// The initial feature release of native service discovery only allows for
|
||||
// a single service provider to be used across all services in a task
|
||||
// group.
|
||||
|
|
Loading…
Reference in New Issue