jobspec: default constraints to hard, parse update configuration
This commit is contained in:
parent
50f0a4a78a
commit
86fd4632fe
|
@ -6,6 +6,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/hcl"
|
||||
hclobj "github.com/hashicorp/hcl/hcl"
|
||||
|
@ -76,6 +77,7 @@ func parseJob(result *structs.Job, obj *hclobj.Object) error {
|
|||
}
|
||||
delete(m, "constraint")
|
||||
delete(m, "meta")
|
||||
delete(m, "update")
|
||||
|
||||
// Set the ID and name to the object key
|
||||
result.ID = obj.Key
|
||||
|
@ -98,6 +100,13 @@ func parseJob(result *structs.Job, obj *hclobj.Object) error {
|
|||
}
|
||||
}
|
||||
|
||||
// If we have an update strategy, then parse that
|
||||
if o := obj.Get("update", false); o != nil {
|
||||
if err := parseUpdate(&result.Update, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Parse out meta fields. These are in HCL as a list so we need
|
||||
// to iterate over them and merge them.
|
||||
if metaO := obj.Get("meta", false); metaO != nil {
|
||||
|
@ -221,6 +230,11 @@ func parseConstraints(result *[]*structs.Constraint, obj *hclobj.Object) error {
|
|||
m["RTarget"] = m["value"]
|
||||
m["Operand"] = m["operator"]
|
||||
|
||||
// Default constraint to being hard
|
||||
if _, ok := m["hard"]; !ok {
|
||||
m["hard"] = true
|
||||
}
|
||||
|
||||
// Build the constraint
|
||||
var c structs.Constraint
|
||||
if err := mapstructure.WeakDecode(m, &c); err != nil {
|
||||
|
@ -362,3 +376,38 @@ func parseResources(result *structs.Resources, obj *hclobj.Object) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseUpdate(result *structs.UpdateStrategy, obj *hclobj.Object) error {
|
||||
if obj.Len() > 1 {
|
||||
return fmt.Errorf("only one 'update' block allowed per job")
|
||||
}
|
||||
|
||||
for _, o := range obj.Elem(false) {
|
||||
var m map[string]interface{}
|
||||
if err := hcl.DecodeObject(&m, o); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, key := range []string{"stagger", "Stagger"} {
|
||||
if raw, ok := m[key]; ok {
|
||||
switch v := raw.(type) {
|
||||
case string:
|
||||
dur, err := time.ParseDuration(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid stagger time '%s'", raw)
|
||||
}
|
||||
m[key] = dur
|
||||
case int:
|
||||
m[key] = time.Duration(v) * time.Second
|
||||
default:
|
||||
return fmt.Errorf("invalid type for stagger time '%s'",
|
||||
raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := mapstructure.WeakDecode(m, result); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
@ -31,12 +32,18 @@ func TestParse(t *testing.T) {
|
|||
|
||||
Constraints: []*structs.Constraint{
|
||||
&structs.Constraint{
|
||||
Hard: true,
|
||||
LTarget: "kernel.os",
|
||||
RTarget: "windows",
|
||||
Operand: "=",
|
||||
},
|
||||
},
|
||||
|
||||
Update: structs.UpdateStrategy{
|
||||
Stagger: 60 * time.Second,
|
||||
MaxParallel: 2,
|
||||
},
|
||||
|
||||
TaskGroups: []*structs.TaskGroup{
|
||||
&structs.TaskGroup{
|
||||
Name: "outside",
|
||||
|
@ -60,6 +67,7 @@ func TestParse(t *testing.T) {
|
|||
Count: 5,
|
||||
Constraints: []*structs.Constraint{
|
||||
&structs.Constraint{
|
||||
Hard: true,
|
||||
LTarget: "kernel.os",
|
||||
RTarget: "linux",
|
||||
Operand: "=",
|
||||
|
@ -101,6 +109,7 @@ func TestParse(t *testing.T) {
|
|||
},
|
||||
Constraints: []*structs.Constraint{
|
||||
&structs.Constraint{
|
||||
Hard: true,
|
||||
LTarget: "kernel.arch",
|
||||
RTarget: "amd64",
|
||||
Operand: "=",
|
||||
|
|
|
@ -14,6 +14,11 @@ job "binstore-storagelocker" {
|
|||
value = "windows"
|
||||
}
|
||||
|
||||
update {
|
||||
stagger = "60s"
|
||||
max_parallel = 2
|
||||
}
|
||||
|
||||
task "outside" {
|
||||
driver = "java"
|
||||
config {
|
||||
|
|
Loading…
Reference in New Issue