diff --git a/.changelog/11013.txt b/.changelog/11013.txt new file mode 100644 index 000000000000..0dadfa14e9ec --- /dev/null +++ b/.changelog/11013.txt @@ -0,0 +1,4 @@ + +```release-note:bug +deployments: Fixed a bug where multi-group deployments don't get auto-promoted when one group has no canaries. +``` diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 71793496c4c8..13f2125ee34e 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -4302,19 +4302,24 @@ func (j *Job) Warnings() error { var mErr multierror.Error // Check the groups - ap := 0 + hasAutoPromote, allAutoPromote := false, true + for _, tg := range j.TaskGroups { if err := tg.Warnings(j); err != nil { outer := fmt.Errorf("Group %q has warnings: %v", tg.Name, err) mErr.Errors = append(mErr.Errors, outer) } - if tg.Update != nil && tg.Update.AutoPromote { - ap += 1 + + if u := tg.Update; u != nil { + hasAutoPromote = hasAutoPromote || u.AutoPromote + + // Having no canaries implies auto-promotion since there are no canaries to promote. + allAutoPromote = allAutoPromote && (u.Canary == 0 || u.AutoPromote) } } // Check AutoPromote, should be all or none - if ap > 0 && ap < len(j.TaskGroups) { + if hasAutoPromote && !allAutoPromote { err := fmt.Errorf("auto_promote must be true for all groups to enable automatic promotion") mErr.Errors = append(mErr.Errors, err) } @@ -8877,7 +8882,7 @@ func (d *Deployment) HasAutoPromote() bool { return false } for _, group := range d.TaskGroups { - if !group.AutoPromote { + if group.DesiredCanaries > 0 && !group.AutoPromote { return false } } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 5d19f8b01b6b..2409f7021fb9 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -200,6 +200,27 @@ func TestJob_Warnings(t *testing.T) { { Update: &UpdateStrategy{ AutoPromote: false, + Canary: 1, + }, + }, + }, + }, + }, + { + Name: "no error for mixed but implied AutoPromote", + Expected: []string{}, + Job: &Job{ + Type: JobTypeService, + TaskGroups: []*TaskGroup{ + { + Update: &UpdateStrategy{ + AutoPromote: true, + }, + }, + { + Update: &UpdateStrategy{ + AutoPromote: false, + Canary: 0, }, }, },