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 <xificurC@gmail.com>
This commit is contained in:
pnagy 2017-09-07 11:04:10 +02:00
parent af94015b8c
commit 27e8bdf32b
1 changed files with 14 additions and 2 deletions

View File

@ -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 // 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 { func uint32Ptr(value uint32) *uint32 {