浏览代码

Merge pull request #23552 from vieux/prevent_panics

prevent some panics in 'service update'
Tõnis Tiigi 9 年之前
父节点
当前提交
aa1b507af6
共有 2 个文件被更改,包括 74 次插入34 次删除
  1. 27 19
      api/client/service/opts.go
  2. 47 15
      api/client/service/update.go

+ 27 - 19
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.StringVarP(&opts.user, "user", "u", "", "Username or UID")
 	flags.VarP(&opts.mounts, flagMount, "m", "Attach a mount to the service")
 	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.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.StringVar(&opts.mode, flagMode, "replicated", "Service mode (replicated or global)")
 	flags.Var(&opts.replicas, flagReplicas, "Number of tasks")
 	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.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.Uint64Var(&opts.update.parallelism, flagUpdateParallelism, 1, "Maximum number of tasks updated simultaneously")
 	flags.DurationVar(&opts.update.delay, flagUpdateDelay, time.Duration(0), "Delay between updates")
 	flags.DurationVar(&opts.update.delay, flagUpdateDelay, time.Duration(0), "Delay between updates")
@@ -465,15 +465,23 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) {
 }
 }
 
 
 const (
 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"
 )
 )

+ 47 - 15
api/client/service/update.go

@@ -122,28 +122,56 @@ func mergeService(spec *swarm.ServiceSpec, flags *pflag.FlagSet) error {
 	mergeString("user", &cspec.User)
 	mergeString("user", &cspec.User)
 	mergeMounts(flags, &cspec.Mounts)
 	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)
 	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 {
 	if err := mergeMode(flags, &spec.Mode); err != nil {
 		return err
 		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)
 	mergeNetworks(flags, &spec.Networks)
 	if flags.Changed(flagEndpointMode) {
 	if flags.Changed(flagEndpointMode) {
@@ -151,8 +179,12 @@ func mergeService(spec *swarm.ServiceSpec, flags *pflag.FlagSet) error {
 		spec.EndpointSpec.Mode = swarm.ResolutionMode(value)
 		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
 	return nil
 }
 }