From c877e07205a694fe5c240c765a72ab7632e8d40a Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Mon, 25 Jul 2016 23:53:20 -0700 Subject: [PATCH] service update: Don't assume existing pointers in spec are valid When updating values in the spec according to CLI flags, don't write into the existing pointers. They may be nil. Instead, update them to point to the new value we're writing. Signed-off-by: Aaron Lehmann Upstream-commit: f9c920a1266197c2b6f0378b58f22246037fda7a Component: engine --- .../engine/api/client/service/update.go | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/components/engine/api/client/service/update.go b/components/engine/api/client/service/update.go index c9de40e0e6..ac1eac3cac 100644 --- a/components/engine/api/client/service/update.go +++ b/components/engine/api/client/service/update.go @@ -98,7 +98,6 @@ func runUpdate(dockerCli *client.DockerCli, flags *pflag.FlagSet, serviceID stri } func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { - updateString := func(flag string, field *string) { if flags.Changed(flag) { *field, _ = flags.GetString(flag) @@ -117,9 +116,10 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { } } - updateDurationOpt := func(flag string, field *time.Duration) { + updateDurationOpt := func(flag string, field **time.Duration) { if flags.Changed(flag) { - *field = *flags.Lookup(flag).Value.(*DurationOpt).Value() + val := *flags.Lookup(flag).Value.(*DurationOpt).Value() + *field = &val } } @@ -129,9 +129,10 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { } } - updateUint64Opt := func(flag string, field *uint64) { + updateUint64Opt := func(flag string, field **uint64) { if flags.Changed(flag) { - *field = *flags.Lookup(flag).Value.(*Uint64Opt).Value() + val := *flags.Lookup(flag).Value.(*Uint64Opt).Value() + *field = &val } } @@ -159,7 +160,6 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { taskResources().Limits = &swarm.Resources{} updateInt64Value(flagLimitCPU, &task.Resources.Limits.NanoCPUs) updateInt64Value(flagLimitMemory, &task.Resources.Limits.MemoryBytes) - } if flags.Changed(flagReserveCPU) || flags.Changed(flagReserveMemory) { taskResources().Reservations = &swarm.Resources{} @@ -167,7 +167,7 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { updateInt64Value(flagReserveMemory, &task.Resources.Reservations.MemoryBytes) } - updateDurationOpt(flagStopGracePeriod, cspec.StopGracePeriod) + updateDurationOpt(flagStopGracePeriod, &cspec.StopGracePeriod) if anyChanged(flags, flagRestartCondition, flagRestartDelay, flagRestartMaxAttempts, flagRestartWindow) { if task.RestartPolicy == nil { @@ -178,9 +178,9 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { value, _ := flags.GetString(flagRestartCondition) task.RestartPolicy.Condition = swarm.RestartPolicyCondition(value) } - updateDurationOpt(flagRestartDelay, task.RestartPolicy.Delay) - updateUint64Opt(flagRestartMaxAttempts, task.RestartPolicy.MaxAttempts) - updateDurationOpt((flagRestartWindow), task.RestartPolicy.Window) + updateDurationOpt(flagRestartDelay, &task.RestartPolicy.Delay) + updateUint64Opt(flagRestartMaxAttempts, &task.RestartPolicy.MaxAttempts) + updateDurationOpt(flagRestartWindow, &task.RestartPolicy.Window) } if anyChanged(flags, flagConstraintAdd, flagConstraintRemove) { @@ -206,6 +206,9 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { updateNetworks(flags, &spec.Networks) if flags.Changed(flagEndpointMode) { value, _ := flags.GetString(flagEndpointMode) + if spec.EndpointSpec == nil { + spec.EndpointSpec = &swarm.EndpointSpec{} + } spec.EndpointSpec.Mode = swarm.ResolutionMode(value) } @@ -409,7 +412,7 @@ func updateReplicas(flags *pflag.FlagSet, serviceMode *swarm.ServiceMode) error return nil } - if serviceMode.Replicated == nil { + if serviceMode == nil || serviceMode.Replicated == nil { return fmt.Errorf("replicas can only be used with replicated mode") } serviceMode.Replicated.Replicas = flags.Lookup(flagReplicas).Value.(*Uint64Opt).Value()