Skip to content

Commit

Permalink
sort secrets and configs to ensure idempotence
Browse files Browse the repository at this point in the history
`docker stack deploy` keeps restarting services it doesn't need to (no changes)
because the entries' order gets randomized at some previous (de)serialization.
Maybe it would be worth looking into this at a higher level and ensure
all (de)serialization happens in an ordered collection.

This quick fix sorts secrets and configs (in place, mutably) which ensures the
same order for each run.

Based on
moby/moby#30506

Fixes
moby/moby#34746

Signed-off-by: Peter Nagy <xificurC@gmail.com>
  • Loading branch information
pnagy committed Sep 8, 2017
1 parent af94015 commit 34f8c0f
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions cli/compose/convert/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,13 @@ func convertServiceSecrets(
})
}

return servicecli.ParseSecrets(client, refs)
secrets, err := servicecli.ParseSecrets(client, refs)
if err != nil {
return nil, err
}
// sort to ensure idempotence (don't restart services just because the entries are in different order)
sort.SliceStable(secrets, func(i, j int) bool { return secrets[i].SecretName < secrets[j].SecretName })
return secrets, err
}

// TODO: fix configs API so that ConfigsAPIClient is not required here
Expand Down Expand Up @@ -346,7 +352,13 @@ func convertServiceConfigObjs(
})
}

return servicecli.ParseConfigs(client, refs)
configs, err := servicecli.ParseConfigs(client, refs)
if err != nil {
return nil, err
}
// sort to ensure idempotence (don't restart services just because the entries are in different order)
sort.SliceStable(configs, func(i, j int) bool { return configs[i].ConfigName < configs[j].ConfigName })
return configs, err
}

func uint32Ptr(value uint32) *uint32 {
Expand Down

0 comments on commit 34f8c0f

Please sign in to comment.