From 1d380243fcfaab2f4f82fa594e25aae3626ec03d Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 14 Jun 2016 15:37:27 -0700 Subject: [PATCH] prevent some panics in 'service update' Signed-off-by: Victor Vieux --- api/client/service/opts.go | 46 +++++++++++++++----------- api/client/service/update.go | 62 +++++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 34 deletions(-) diff --git a/api/client/service/opts.go b/api/client/service/opts.go index d1f76fe0af..58c5f94f2d 100644 --- a/api/client/service/opts.go +++ b/api/client/service/opts.go @@ -440,21 +440,21 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) { flags.StringVarP(&opts.user, "user", "u", "", "Username or UID") flags.VarP(&opts.mounts, flagMount, "m", "Attach a mount to the service") - flags.Var(&opts.resources.limitCPU, "limit-cpu", "Limit CPUs") - flags.Var(&opts.resources.limitMemBytes, "limit-memory", "Limit Memory") - flags.Var(&opts.resources.resCPU, "reserve-cpu", "Reserve CPUs") - flags.Var(&opts.resources.resMemBytes, "reserve-memory", "Reserve Memory") + flags.Var(&opts.resources.limitCPU, flagLimitCPU, "Limit CPUs") + flags.Var(&opts.resources.limitMemBytes, flagLimitMemory, "Limit Memory") + flags.Var(&opts.resources.resCPU, flagReserveCPU, "Reserve CPUs") + flags.Var(&opts.resources.resMemBytes, flagReserveMemory, "Reserve Memory") flags.Var(&opts.stopGrace, "stop-grace-period", "Time to wait before force killing a container") flags.StringVar(&opts.mode, flagMode, "replicated", "Service mode (replicated or global)") flags.Var(&opts.replicas, flagReplicas, "Number of tasks") flags.StringVar(&opts.restartPolicy.condition, flagRestartCondition, "", "Restart when condition is met (none, on_failure, or any)") - flags.Var(&opts.restartPolicy.delay, "restart-delay", "Delay between restart attempts") - flags.Var(&opts.restartPolicy.maxAttempts, "restart-max-attempts", "Maximum number of restarts before giving up") - flags.Var(&opts.restartPolicy.window, "restart-window", "Window used to evalulate the restart policy") + flags.Var(&opts.restartPolicy.delay, flagRestartDelay, "Delay between restart attempts") + flags.Var(&opts.restartPolicy.maxAttempts, flagRestartMaxAttempts, "Maximum number of restarts before giving up") + flags.Var(&opts.restartPolicy.window, flagRestartWindow, "Window used to evalulate the restart policy") - flags.StringSliceVar(&opts.constraints, "constraint", []string{}, "Placement constraints") + flags.StringSliceVar(&opts.constraints, flagConstraint, []string{}, "Placement constraints") flags.Uint64Var(&opts.update.parallelism, flagUpdateParallelism, 1, "Maximum number of tasks updated simultaneously") flags.DurationVar(&opts.update.delay, flagUpdateDelay, time.Duration(0), "Delay between updates") @@ -465,15 +465,23 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) { } const ( - flagName = "name" - flagLabel = "label" - flagMount = "mount" - flagMode = "mode" - flagReplicas = "replicas" - flagPublish = "publish" - flagNetwork = "network" - flagRestartCondition = "restart-condition" - flagEndpointMode = "endpoint-mode" - flagUpdateParallelism = "update-parallelism" - flagUpdateDelay = "update-delay" + flagConstraint = "constraint" + flagName = "name" + flagLabel = "label" + flagLimitCPU = "limit-cpu" + flagLimitMemory = "limit-memory" + flagReserveCPU = "reserve-cpu" + flagReserveMemory = "reserve-memory" + flagMount = "mount" + flagMode = "mode" + flagReplicas = "replicas" + flagPublish = "publish" + flagNetwork = "network" + flagRestartCondition = "restart-condition" + flagRestartDelay = "restart-delay" + flagRestartMaxAttempts = "restart-max-attempts" + flagRestartWindow = "restart-window" + flagEndpointMode = "endpoint-mode" + flagUpdateParallelism = "update-parallelism" + flagUpdateDelay = "update-delay" ) diff --git a/api/client/service/update.go b/api/client/service/update.go index b57962cbb2..20bc386ba3 100644 --- a/api/client/service/update.go +++ b/api/client/service/update.go @@ -122,28 +122,56 @@ func mergeService(spec *swarm.ServiceSpec, flags *pflag.FlagSet) error { mergeString("user", &cspec.User) mergeMounts(flags, &cspec.Mounts) - mergeInt64Value("limit-cpu", &task.Resources.Limits.NanoCPUs) - mergeInt64Value("limit-memory", &task.Resources.Limits.MemoryBytes) - mergeInt64Value("reserve-cpu", &task.Resources.Reservations.NanoCPUs) - mergeInt64Value("reserve-memory", &task.Resources.Reservations.MemoryBytes) + if flags.Changed(flagLimitCPU) || flags.Changed(flagLimitMemory) { + if task.Resources == nil { + task.Resources = &swarm.ResourceRequirements{} + } + task.Resources.Limits = &swarm.Resources{} + mergeInt64Value(flagLimitCPU, &task.Resources.Limits.NanoCPUs) + mergeInt64Value(flagLimitMemory, &task.Resources.Limits.MemoryBytes) + + } + if flags.Changed(flagReserveCPU) || flags.Changed(flagReserveMemory) { + if task.Resources == nil { + task.Resources = &swarm.ResourceRequirements{} + } + task.Resources.Reservations = &swarm.Resources{} + mergeInt64Value(flagReserveCPU, &task.Resources.Reservations.NanoCPUs) + mergeInt64Value(flagReserveMemory, &task.Resources.Reservations.MemoryBytes) + } mergeDurationOpt("stop-grace-period", cspec.StopGracePeriod) - if flags.Changed(flagRestartCondition) { - value, _ := flags.GetString(flagRestartCondition) - task.RestartPolicy.Condition = swarm.RestartPolicyCondition(value) + if flags.Changed(flagRestartCondition) || flags.Changed(flagRestartDelay) || flags.Changed(flagRestartMaxAttempts) || flags.Changed(flagRestartWindow) { + if task.RestartPolicy == nil { + task.RestartPolicy = &swarm.RestartPolicy{} + } + + if flags.Changed(flagRestartCondition) { + value, _ := flags.GetString(flagRestartCondition) + task.RestartPolicy.Condition = swarm.RestartPolicyCondition(value) + } + mergeDurationOpt(flagRestartDelay, task.RestartPolicy.Delay) + mergeUint64Opt(flagRestartMaxAttempts, task.RestartPolicy.MaxAttempts) + mergeDurationOpt((flagRestartWindow), task.RestartPolicy.Window) + } + + if flags.Changed(flagConstraint) { + task.Placement = &swarm.Placement{} + mergeSlice(flagConstraint, &task.Placement.Constraints) } - mergeDurationOpt("restart-delay", task.RestartPolicy.Delay) - mergeUint64Opt("restart-max-attempts", task.RestartPolicy.MaxAttempts) - mergeDurationOpt("restart-window", task.RestartPolicy.Window) - mergeSlice("constraint", &task.Placement.Constraints) if err := mergeMode(flags, &spec.Mode); err != nil { return err } - mergeUint64(flagUpdateParallelism, &spec.UpdateConfig.Parallelism) - mergeDuration(flagUpdateDelay, &spec.UpdateConfig.Delay) + if flags.Changed(flagUpdateParallelism) || flags.Changed(flagUpdateDelay) { + if spec.UpdateConfig == nil { + spec.UpdateConfig = &swarm.UpdateConfig{} + } + mergeUint64(flagUpdateParallelism, &spec.UpdateConfig.Parallelism) + mergeDuration(flagUpdateDelay, &spec.UpdateConfig.Delay) + } mergeNetworks(flags, &spec.Networks) if flags.Changed(flagEndpointMode) { @@ -151,8 +179,12 @@ func mergeService(spec *swarm.ServiceSpec, flags *pflag.FlagSet) error { spec.EndpointSpec.Mode = swarm.ResolutionMode(value) } - mergePorts(flags, &spec.EndpointSpec.Ports) - + if flags.Changed(flagPublish) { + if spec.EndpointSpec == nil { + spec.EndpointSpec = &swarm.EndpointSpec{} + } + mergePorts(flags, &spec.EndpointSpec.Ports) + } return nil }