Skip to content

Commit eed2618

Browse files
authored
feat: add function to return named slots (#13)
* feat: add function to return named slots * test requires as an array * ensure slot is represented with replicas * update generation to use replicas * ensure generated jobspec has slot at rack * allow attributes on the top level of jobspec These are for cluster state that is desired. We likely will want to move these into schedulable units. Signed-off-by: vsoch <[email protected]>
1 parent 3e57ee8 commit eed2618

File tree

5 files changed

+81
-79
lines changed

5 files changed

+81
-79
lines changed

examples/nextgen/v1/example1/example.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,10 @@ func main() {
6262
for _, slot := range slots {
6363
fmt.Println(slot)
6464
}
65+
66+
named := js.GetScheduledNamedSlots()
67+
fmt.Printf("Found %d scheduled named slots\n", len(named))
68+
for name := range named {
69+
fmt.Println(name)
70+
}
6571
}

pkg/nextgen/v1/convert.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ func NewSimpleJobspec(name, command string, nodes, tasks int32) (*Jobspec, error
2727
Count: nodes,
2828
}
2929

30-
// The slot is where we are doing an assessment for scheduling
31-
slot := Resource{
32-
Type: "slot",
33-
Count: int32(1),
34-
Label: name,
30+
// But we put it under the slot of a rack
31+
rackResource := Resource{
32+
Type: "rack",
33+
Replicas: 1,
34+
Label: name,
3535
}
3636

3737
// If tasks are defined, this is total tasks across the nodes
@@ -41,13 +41,11 @@ func NewSimpleJobspec(name, command string, nodes, tasks int32) (*Jobspec, error
4141
Type: "core",
4242
Count: tasks,
4343
}
44-
slot.With = []Resource{taskResource}
44+
nodeResource.With = []Resource{taskResource}
4545
}
4646

47-
// And then the entire resource spec is added to the top level node resource
48-
nodeResource.With = []Resource{slot}
49-
5047
// Resource name matches resources to named set
48+
rackResource.With = []Resource{nodeResource}
5149
resourceName := "task-resources"
5250

5351
// Tasks reference the slot and command
@@ -63,6 +61,6 @@ func NewSimpleJobspec(name, command string, nodes, tasks int32) (*Jobspec, error
6361
return &Jobspec{
6462
Version: jobspecVersion,
6563
Tasks: tasklist,
66-
Resources: Resources{resourceName: nodeResource},
64+
Resources: Resources{resourceName: rackResource},
6765
}, nil
6866
}

pkg/nextgen/v1/jobspec.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ func (js *Jobspec) GetSlots() []Resource {
4848
// a slot at the top level. We wrap in a faux slot
4949
fauxSlots = append(fauxSlots, generateFauxSlot(name, resource))
5050

51-
// Slot at the top level already!
52-
if resource.Type == "slot" {
51+
// If replicas > 0, we have a slot at the level already
52+
if resource.Replicas > 0 {
5353
slots = append(slots, resource)
5454
}
5555
for _, with := range resource.With {
@@ -88,15 +88,24 @@ func (js *Jobspec) GetScheduledSlots() []Resource {
8888
return scheduled
8989
}
9090

91+
// GetScheduledNamedSlots returns slots as a lookup by name
92+
func (js *Jobspec) GetScheduledNamedSlots() map[string]Resource {
93+
94+
slots := js.GetScheduledSlots()
95+
named := map[string]Resource{}
96+
for _, slot := range slots {
97+
named[slot.Label] = slot
98+
}
99+
return named
100+
}
101+
91102
// A fauxSlot will only be use if we don't have any actual slots
92103
func generateFauxSlot(name string, resource Resource) Resource {
93-
return Resource{
94-
Type: "slot",
95-
Label: name,
96-
Count: 1,
97-
Schedule: resource.Schedule,
98-
With: []Resource{resource},
104+
resource.Replicas = 1
105+
if resource.Label == "" {
106+
resource.Label = name
99107
}
108+
return resource
100109
}
101110

102111
// getSlots is a recursive helper function that takes resources explicitly

pkg/nextgen/v1/schema.json

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@
1212
"type": "integer",
1313
"enum": [1]
1414
},
15-
"requires": {"$ref": "#/definitions/requires"},
1615
"resources": {
1716
"type": "object",
1817
"patternProperties": {
1918
"^([a-z]|[|]|&|[0-9]+)+$": {"$ref": "#/definitions/resources"}
2019
}
2120
},
22-
"attributes": {"$ref": "#/definitions/attributes"},
2321
"groups": {"type": "array", "items": {"$ref": "#/definitions/group"}},
2422
"tasks": {"$ref": "#/definitions/tasks"},
23+
"attributes": {"$ref": "#/definitions/attributes"},
2524
"additionalProperties": false
2625
},
2726
"definitions": {
@@ -34,31 +33,28 @@
3433
"environment": {"type": "object"}
3534
}
3635
},
37-
"requires": {
38-
"description": "compatibility requirements",
39-
"type": "object"
40-
},
4136
"resources": {
4237
"description": "requested resources",
4338
"type": "object",
44-
"required": ["type", "count"],
39+
"required": ["type"],
4540
"properties": {
4641
"type": {"type": "string"},
47-
"schedule": {"type": "boolean"},
48-
"exclusive": {"type": "boolean"},
4942
"count": {"type": "integer", "minimum": 1},
50-
"unit": {"type": "string"},
51-
"with": {"$ref": "#/definitions/with"}
52-
},
53-
"additionalProperties": false
54-
},
55-
"with": {
56-
"type": "array",
57-
"minItems": 1,
58-
"items": {"$ref": "#/definitions/resources"}
43+
"requires": {
44+
"type": "array",
45+
"items": {"type": "object"}
46+
},
47+
"attributes": {"$ref": "#/definitions/attributes"},
48+
"schedule": {"type": "boolean"},
49+
"with": {
50+
"type": "array",
51+
"minItems": 1,
52+
"items": {"$ref": "#/definitions/resources"}
53+
}
54+
}
5955
},
6056
"steps": {
61-
"type": "array",
57+
"type": ["array"],
6258
"items": {
6359
"type": "object",
6460
"properties": {
@@ -76,15 +72,9 @@
7672
"items": {
7773
"type": "object",
7874
"properties": {
79-
"requires": {"$ref": "#/definitions/requires"},
80-
"resources": {
81-
"oneOf": [
82-
{"$ref": "#/definitions/resources"},
83-
{"type": "string"}
84-
]
85-
},
86-
"attributes": {"$ref": "#/definitions/attributes"},
75+
"resources": {"type": "string"},
8776
"group": {"type": "string"},
77+
"local": {"type": "boolean"},
8878
"name": {"type": "string"},
8979
"depends_on": {"type": "array", "items": {"type": "string"}},
9080
"replicas": {"type": "number", "minimum": 1, "default": 1},
@@ -102,18 +92,11 @@
10292
"type": "object",
10393
"properties": {
10494
"name": {"type": "string"},
105-
"requires": {"$ref": "#/definitions/requires"},
106-
"resources": {
107-
"oneOf": [
108-
{"$ref": "#/definitions/resources"},
109-
{"type": "string"}
110-
]
111-
},
112-
"attributes": {"$ref": "#/definitions/attributes"},
95+
"resources": {"type": "string"},
11396
"depends_on": {"type": "array", "items": {"type": "string"}},
114-
"tasks": {"$ref": "#/definitions/tasks"}
97+
"tasks": {"$ref": "#/definitions/tasks"},
98+
"groups": {"type": "array", "items": {"$ref": "#/definitions/group"}}
11599
},
116-
"additionalProperties": false
117-
}
100+
"additionalProperties": false }
118101
}
119102
}

pkg/nextgen/v1/types.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,50 @@ var (
44
jobspecVersion = 1
55
)
66

7+
// The JobSpec is what the user writes to describe their work
78
type Jobspec struct {
8-
Version int `json:"version" yaml:"version"`
9-
Name string `json:"name,omitempty" yaml:"name,omitempty"`
10-
Resources Resources `json:"resources,omitempty" yaml:"resources,omitempty"`
11-
Tasks Tasks `json:"tasks,omitempty" yaml:"tasks,omitempty"`
12-
Groups Groups `json:"groups,omitempty" yaml:"groups,omitempty"`
13-
Requires map[string]string `json:"requires,omitempty" yaml:"requires,omitempty"`
9+
Version int `json:"version" yaml:"version"`
10+
Name string `json:"name,omitempty" yaml:"name,omitempty"`
11+
Resources Resources `json:"resources,omitempty" yaml:"resources,omitempty"`
12+
Tasks Tasks `json:"tasks,omitempty" yaml:"tasks,omitempty"`
13+
Groups Groups `json:"groups,omitempty" yaml:"groups,omitempty"`
14+
Requires []Requires `json:"requires,omitempty" yaml:"requires,omitempty"`
15+
Attributes Attributes `json:"attributes,omitempty" yaml:"attributes,omitempty"`
1416
}
1517

1618
type Environment map[string]string
1719
type Resources map[string]Resource
20+
type Requires map[string]string
1821
type Tasks []Task
1922
type Groups []Group
2023

2124
type Task struct {
22-
Group string `json:"group,omitempty" yaml:"group,omitempty"`
23-
Name string `json:"name,omitempty" yaml:"name,omitempty"`
24-
Replicas int `json:"replicas,omitempty" yaml:"replicas,omitempty"`
25-
Resources string `json:"resources,omitempty" yaml:"resources,omitempty"`
26-
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
27-
Attributes Attributes `json:"attributes,omitempty" yaml:"attributes,omitempty"`
25+
Group string `json:"group,omitempty" yaml:"group,omitempty"`
26+
Name string `json:"name,omitempty" yaml:"name,omitempty"`
27+
Replicas int `json:"replicas,omitempty" yaml:"replicas,omitempty"`
28+
Resources string `json:"resources,omitempty" yaml:"resources,omitempty"`
29+
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
30+
Requires []Requires `json:"requires,omitempty" yaml:"requires,omitempty"`
2831
}
2932

3033
type Group struct {
31-
Name string `json:"name,omitempty" yaml:"name,omitempty"`
32-
Resources string `json:"resources,omitempty" yaml:"resources,omitempty"`
33-
Tasks Tasks `json:"tasks,omitempty" yaml:"tasks,omitempty"`
34-
Attributes Attributes `json:"attributes,omitempty" yaml:"attributes,omitempty"`
34+
Name string `json:"name,omitempty" yaml:"name,omitempty"`
35+
Tasks Tasks `json:"tasks,omitempty" yaml:"tasks,omitempty"`
36+
Groups Groups `json:"groups,omitempty" yaml:"groups,omitempty"`
37+
Resources string `json:"resources,omitempty" yaml:"resources,omitempty"`
3538
}
3639

3740
type Resource struct {
38-
Type string `yaml:"type,omitempty" json:"type,omitempty"`
39-
Unit string `yaml:"unit,omitempty" json:"unit,omitempty"`
40-
Count int32 `yaml:"count,omitempty" json:"count,omitempty"`
41-
With []Resource `yaml:"with,omitempty" json:"with,omitempty"`
42-
Label string `yaml:"label,omitempty" json:"label,omitempty"`
43-
Exclusive bool `yaml:"exclusive,omitempty" json:"exclusive,omitempty"`
44-
Schedule bool `yaml:"schedule,omitempty" json:"schedule,omitempty"`
41+
Type string `yaml:"type,omitempty" json:"type,omitempty"`
42+
Unit string `yaml:"unit,omitempty" json:"unit,omitempty"`
43+
Replicas int32 `yaml:"replicas,omitempty" json:"replicas,omitempty"`
44+
Count int32 `yaml:"count,omitempty" json:"count,omitempty"`
45+
With []Resource `yaml:"with,omitempty" json:"with,omitempty"`
46+
Label string `yaml:"label,omitempty" json:"label,omitempty"`
47+
Exclusive bool `yaml:"exclusive,omitempty" json:"exclusive,omitempty"`
48+
Requires []Requires `json:"requires,omitempty" yaml:"requires,omitempty"`
49+
Attributes Attributes `json:"attributes,omitempty" yaml:"attributes,omitempty"`
50+
Schedule bool `yaml:"schedule,omitempty" json:"schedule,omitempty"`
4551
}
4652

4753
type Attributes struct {

0 commit comments

Comments
 (0)