From 27e8bdf32bbcc49ff3f8201b6da26aba567aa58e Mon Sep 17 00:00:00 2001 From: pnagy Date: Thu, 7 Sep 2017 11:04:10 +0200 Subject: [PATCH] sort secrets and configs to ensure idempotence `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 https://github.com/moby/moby/pull/30506 Fixes https://github.com/moby/moby/issues/34746 Signed-off-by: Peter Nagy --- cli/compose/convert/service.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index bdccb888bf..c4473ba084 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -295,7 +295,13 @@ func convertServiceSecrets( }) } - return servicecli.ParseSecrets(client, refs) + secrs, 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(secrs, func(i, j int) bool { return secrs[i].SecretName < secrs[j].SecretName }) + return secrs, err } // TODO: fix configs API so that ConfigsAPIClient is not required here @@ -346,7 +352,13 @@ func convertServiceConfigObjs( }) } - return servicecli.ParseConfigs(client, refs) + confs, 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(confs, func(i, j int) bool { return confs[i].ConfigName < confs[j].ConfigName }) + return confs, err } func uint32Ptr(value uint32) *uint32 {