deployments: canary=0 is implicitly autopromote (#11013)

In a multi-task-group job, treat 0 canary groups as auto-promote.

This change fixes an edge case where Nomad requires a manual promotion,
if the job had any group with canary=0 and rest of groups having
auto_promote set.

Co-authored-by: Michael Schurter <mschurter@hashicorp.com>
This commit is contained in:
Mahmood Ali 2021-08-10 17:06:40 -04:00 committed by GitHub
parent efcc8bf082
commit bfc766357e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 5 deletions

4
.changelog/11013.txt Normal file
View File

@ -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.
```

View File

@ -4302,19 +4302,24 @@ func (j *Job) Warnings() error {
var mErr multierror.Error var mErr multierror.Error
// Check the groups // Check the groups
ap := 0 hasAutoPromote, allAutoPromote := false, true
for _, tg := range j.TaskGroups { for _, tg := range j.TaskGroups {
if err := tg.Warnings(j); err != nil { if err := tg.Warnings(j); err != nil {
outer := fmt.Errorf("Group %q has warnings: %v", tg.Name, err) outer := fmt.Errorf("Group %q has warnings: %v", tg.Name, err)
mErr.Errors = append(mErr.Errors, outer) 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 // 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") err := fmt.Errorf("auto_promote must be true for all groups to enable automatic promotion")
mErr.Errors = append(mErr.Errors, err) mErr.Errors = append(mErr.Errors, err)
} }
@ -8877,7 +8882,7 @@ func (d *Deployment) HasAutoPromote() bool {
return false return false
} }
for _, group := range d.TaskGroups { for _, group := range d.TaskGroups {
if !group.AutoPromote { if group.DesiredCanaries > 0 && !group.AutoPromote {
return false return false
} }
} }

View File

@ -200,6 +200,27 @@ func TestJob_Warnings(t *testing.T) {
{ {
Update: &UpdateStrategy{ Update: &UpdateStrategy{
AutoPromote: false, 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,
}, },
}, },
}, },