Skip to content

Commit

Permalink
allowed_exit_codes
Browse files Browse the repository at this point in the history
  • Loading branch information
pkazmierczak committed Aug 19, 2022
1 parent 6190282 commit 953c091
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 60 deletions.
12 changes: 8 additions & 4 deletions api/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -792,10 +792,11 @@ func (wc *WaitConfig) Copy() *WaitConfig {
}

type ChangeScript struct {
Command *string `mapstructure:"command" hcl:"command"`
Args []string `mapstructure:"args" hcl:"args,optional"`
Timeout *time.Duration `mapstructure:"timeout" hcl:"timeout,optional"`
FailOnError *bool `mapstructure:"fail_on_error" hcl:"fail_on_error"`
Command *string `mapstructure:"command" hcl:"command"`
Args []string `mapstructure:"args" hcl:"args,optional"`
Timeout *time.Duration `mapstructure:"timeout" hcl:"timeout,optional"`
FailOnError *bool `mapstructure:"fail_on_error" hcl:"fail_on_error"`
AllowedExitCodes []int `mapstructure:"allowed_exit_codes" hcl:"allowed_exit_codes"`
}

func (ch *ChangeScript) Canonicalize() {
Expand All @@ -811,6 +812,9 @@ func (ch *ChangeScript) Canonicalize() {
if ch.FailOnError == nil {
ch.FailOnError = pointerOf(false)
}
if ch.AllowedExitCodes == nil {
ch.AllowedExitCodes = []int{0}
}
}

type Template struct {
Expand Down
3 changes: 2 additions & 1 deletion client/allocrunner/taskrunner/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/hashicorp/nomad/client/taskenv"
"github.com/hashicorp/nomad/helper/pointer"
"github.com/hashicorp/nomad/nomad/structs"
"golang.org/x/exp/slices"
)

const (
Expand Down Expand Up @@ -556,7 +557,7 @@ func (tm *TaskTemplateManager) processScript(script *structs.ChangeScript, wg *s
)
return
}
if exitCode != 0 {
if !slices.Contains(script.AllowedExitCodes, exitCode) {
structs.NewTaskEvent(structs.TaskHookFailed).
SetDisplayMessage(
fmt.Sprintf(
Expand Down
36 changes: 20 additions & 16 deletions client/allocrunner/taskrunner/template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,10 +1224,11 @@ FOO={{key "bam"}}
DestPath: "test.env",
ChangeMode: structs.TemplateChangeModeScript,
ChangeScript: &structs.ChangeScript{
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Envvars: true,
}
Expand All @@ -1238,10 +1239,11 @@ BAR={{key "bar"}}
DestPath: "test2.env",
ChangeMode: structs.TemplateChangeModeScript,
ChangeScript: &structs.ChangeScript{
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Envvars: true,
}
Expand Down Expand Up @@ -1310,10 +1312,11 @@ FOO={{key "bam"}}
DestPath: "test.env",
ChangeMode: structs.TemplateChangeModeScript,
ChangeScript: &structs.ChangeScript{
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: true,
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: true,
AllowedExitCodes: []int{0},
},
Envvars: true,
}
Expand All @@ -1324,10 +1327,11 @@ BAR={{key "bar"}}
DestPath: "test2.env",
ChangeMode: structs.TemplateChangeModeScript,
ChangeScript: &structs.ChangeScript{
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
Command: "/bin/foo",
Args: []string{},
Timeout: 5 * time.Second,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Envvars: true,
}
Expand Down
9 changes: 5 additions & 4 deletions command/agent/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1271,10 +1271,11 @@ func apiChangeScriptToStructsChangeScript(changeScript *api.ChangeScript) *struc
}

return &structs.ChangeScript{
Command: *changeScript.Command,
Args: changeScript.Args,
Timeout: *changeScript.Timeout,
FailOnError: *changeScript.FailOnError,
Command: *changeScript.Command,
Args: changeScript.Args,
Timeout: *changeScript.Timeout,
FailOnError: *changeScript.FailOnError,
AllowedExitCodes: changeScript.AllowedExitCodes,
}
}

Expand Down
18 changes: 10 additions & 8 deletions command/agent/job_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2732,10 +2732,11 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
ChangeMode: pointer.Of("change"),
ChangeSignal: pointer.Of("signal"),
ChangeScript: &api.ChangeScript{
Command: pointer.Of("/bin/foo"),
Args: []string{"-h"},
Timeout: pointer.Of(5 * time.Second),
FailOnError: pointer.Of(false),
Command: pointer.Of("/bin/foo"),
Args: []string{"-h"},
Timeout: pointer.Of(5 * time.Second),
FailOnError: pointer.Of(false),
AllowedExitCodes: []int{0},
},
Splay: pointer.Of(1 * time.Minute),
Perms: pointer.Of("666"),
Expand Down Expand Up @@ -3145,10 +3146,11 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
ChangeMode: "change",
ChangeSignal: "SIGNAL",
ChangeScript: &structs.ChangeScript{
Command: "/bin/foo",
Args: []string{"-h"},
Timeout: 5 * time.Second,
FailOnError: false,
Command: "/bin/foo",
Args: []string{"-h"},
Timeout: 5 * time.Second,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Splay: 1 * time.Minute,
Perms: "666",
Expand Down
8 changes: 7 additions & 1 deletion jobspec/parse_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,13 @@ func parseTemplates(result *[]*api.Template, list *ast.ObjectList) error {
changeScriptBlock := o.Items[0]

// check for invalid fields
valid := []string{"command", "args", "timeout", "fail_on_error"}
valid := []string{
"command",
"args",
"timeout",
"fail_on_error",
"allowed_exit_codes",
}
if err := checkHCLKeys(changeScriptBlock.Val, valid); err != nil {
return multierror.Prefix(err, "change_script ->")
}
Expand Down
9 changes: 5 additions & 4 deletions jobspec/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,10 +388,11 @@ func TestParse(t *testing.T) {
DestPath: stringToPtr("bar"),
ChangeMode: stringToPtr(templateChangeModeScript),
ChangeScript: &api.ChangeScript{
Args: []string{"-debug", "-verbose"},
Command: stringToPtr("/bin/foo"),
Timeout: timeToPtr(5 * time.Second),
FailOnError: boolToPtr(false),
Args: []string{"-debug", "-verbose"},
Command: stringToPtr("/bin/foo"),
Timeout: timeToPtr(5 * time.Second),
FailOnError: boolToPtr(false),
AllowedExitCodes: []int{0},
},
Splay: timeToPtr(5 * time.Second),
Perms: stringToPtr("777"),
Expand Down
4 changes: 4 additions & 0 deletions jobspec2/parse_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,8 @@ func normalizeChangeScript(ch *api.ChangeScript) {
if ch.FailOnError == nil {
ch.FailOnError = pointer.Of(false)
}

if ch.AllowedExitCodes == nil {
ch.AllowedExitCodes = []int{0}
}
}
66 changes: 66 additions & 0 deletions nomad/structs/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"reflect"
"sort"
"strconv"
"strings"

"github.com/hashicorp/nomad/helper/flatmap"
Expand Down Expand Up @@ -1679,6 +1680,16 @@ func changeScriptDiff(old, new *ChangeScript, contextual bool) *ObjectDiff {
diff.Objects = append(diff.Objects, setDiff)
}

// AllowedExitCodes diffs
if setDiff := intSetDiff(
old.AllowedExitCodes,
new.AllowedExitCodes,
"AllowedExitCodes",
contextual,
); setDiff != nil {
diff.Objects = append(diff.Objects, setDiff)
}

return diff
}

Expand Down Expand Up @@ -2573,6 +2584,61 @@ func stringSetDiff(old, new []string, name string, contextual bool) *ObjectDiff
return diff
}

// intSetDiff diffs two sets of ints with the given name.
func intSetDiff(old, new []int, name string, contextual bool) *ObjectDiff {
oldMap := make(map[int]struct{}, len(old))
newMap := make(map[int]struct{}, len(new))
for _, o := range old {
oldMap[o] = struct{}{}
}
for _, n := range new {
newMap[n] = struct{}{}
}
if reflect.DeepEqual(oldMap, newMap) && !contextual {
return nil
}

diff := &ObjectDiff{Name: name}
var added, removed bool
for k := range oldMap {
kk := strconv.Itoa(k)
if _, ok := newMap[k]; !ok {
diff.Fields = append(diff.Fields, fieldDiff(kk, "", name, contextual))
removed = true
} else if contextual {
diff.Fields = append(diff.Fields, fieldDiff(kk, kk, name, contextual))
}
}

for k := range newMap {
kk := strconv.Itoa(k)
if _, ok := oldMap[k]; !ok {
diff.Fields = append(diff.Fields, fieldDiff("", kk, name, contextual))
added = true
}
}

sort.Sort(FieldDiffs(diff.Fields))

// Determine the type
if added && removed {
diff.Type = DiffTypeEdited
} else if added {
diff.Type = DiffTypeAdded
} else if removed {
diff.Type = DiffTypeDeleted
} else {
// Diff of an empty set
if len(diff.Fields) == 0 {
return nil
}

diff.Type = DiffTypeNone
}

return diff
}

// primitiveObjectDiff returns a diff of the passed objects' primitive fields.
// The filter field can be used to exclude fields from the diff. The name is the
// name of the objects. If contextual is set, non-changed fields will also be
Expand Down
60 changes: 44 additions & 16 deletions nomad/structs/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7043,10 +7043,11 @@ func TestTaskDiff(t *testing.T) {
ChangeMode: "bam",
ChangeSignal: "SIGHUP",
ChangeScript: &ChangeScript{
Command: "/bin/foo",
Args: []string{"-debug"},
Timeout: 5,
FailOnError: false,
Command: "/bin/foo",
Args: []string{"-debug"},
Timeout: 5,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Splay: 1,
Perms: "0644",
Expand All @@ -7064,10 +7065,11 @@ func TestTaskDiff(t *testing.T) {
ChangeMode: "bam2",
ChangeSignal: "SIGHUP2",
ChangeScript: &ChangeScript{
Command: "/bin/foo2",
Args: []string{"-debugs"},
Timeout: 6,
FailOnError: false,
Command: "/bin/foo2",
Args: []string{"-debugs"},
Timeout: 6,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Splay: 2,
Perms: "0666",
Expand All @@ -7086,10 +7088,11 @@ func TestTaskDiff(t *testing.T) {
ChangeMode: "bam",
ChangeSignal: "SIGHUP",
ChangeScript: &ChangeScript{
Command: "/bin/foo",
Args: []string{"-debug"},
Timeout: 5,
FailOnError: false,
Command: "/bin/foo",
Args: []string{"-debug"},
Timeout: 5,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Splay: 1,
Perms: "0644",
Expand All @@ -7107,10 +7110,11 @@ func TestTaskDiff(t *testing.T) {
ChangeMode: "bam3",
ChangeSignal: "SIGHUP3",
ChangeScript: &ChangeScript{
Command: "/bin/foo3",
Args: []string{"-debugss"},
Timeout: 7,
FailOnError: false,
Command: "/bin/foo3",
Args: []string{"-debugss"},
Timeout: 7,
FailOnError: false,
AllowedExitCodes: []int{0},
},
Splay: 3,
Perms: "0776",
Expand Down Expand Up @@ -7266,6 +7270,18 @@ func TestTaskDiff(t *testing.T) {
},
},
Objects: []*ObjectDiff{
{
Type: DiffTypeAdded,
Name: "AllowedExitCodes",
Fields: []*FieldDiff{
{
Type: DiffTypeAdded,
Name: "AllowedExitCodes",
Old: "",
New: "0",
},
},
},
{
Type: DiffTypeAdded,
Name: "Args",
Expand Down Expand Up @@ -7378,6 +7394,18 @@ func TestTaskDiff(t *testing.T) {
},
},
Objects: []*ObjectDiff{
{
Type: DiffTypeDeleted,
Name: "AllowedExitCodes",
Fields: []*FieldDiff{
{
Type: DiffTypeDeleted,
Name: "AllowedExitCodes",
Old: "0",
New: "",
},
},
},
{
Type: DiffTypeDeleted,
Name: "Args",
Expand Down
Loading

0 comments on commit 953c091

Please sign in to comment.