Signed-off-by: Daniel Nephin <dnephin@docker.com>
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/api/types/swarm" |
| 11 | 11 |
"github.com/docker/docker/opts" |
| 12 | 12 |
runconfigopts "github.com/docker/docker/runconfig/opts" |
| 13 |
+ shlex "github.com/flynn-archive/go-shlex" |
|
| 13 | 14 |
"github.com/pkg/errors" |
| 14 | 15 |
"github.com/spf13/pflag" |
| 15 | 16 |
) |
| ... | ... |
@@ -157,6 +158,30 @@ func (opts *placementPrefOpts) Type() string {
|
| 157 | 157 |
return "pref" |
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 |
+// ShlexOpt is a flag Value which parses a string as a list of shell words |
|
| 161 |
+type ShlexOpt []string |
|
| 162 |
+ |
|
| 163 |
+// Set the value |
|
| 164 |
+func (s *ShlexOpt) Set(value string) error {
|
|
| 165 |
+ valueSlice, err := shlex.Split(value) |
|
| 166 |
+ *s = ShlexOpt(valueSlice) |
|
| 167 |
+ return err |
|
| 168 |
+} |
|
| 169 |
+ |
|
| 170 |
+// Type returns the tyep of the value |
|
| 171 |
+func (s *ShlexOpt) Type() string {
|
|
| 172 |
+ return "command" |
|
| 173 |
+} |
|
| 174 |
+ |
|
| 175 |
+func (s *ShlexOpt) String() string {
|
|
| 176 |
+ return fmt.Sprint(*s) |
|
| 177 |
+} |
|
| 178 |
+ |
|
| 179 |
+// Value returns the value as a string slice |
|
| 180 |
+func (s *ShlexOpt) Value() []string {
|
|
| 181 |
+ return []string(*s) |
|
| 182 |
+} |
|
| 183 |
+ |
|
| 160 | 184 |
type updateOptions struct {
|
| 161 | 185 |
parallelism uint64 |
| 162 | 186 |
delay time.Duration |
| ... | ... |
@@ -312,6 +337,7 @@ type serviceOptions struct {
|
| 312 | 312 |
labels opts.ListOpts |
| 313 | 313 |
containerLabels opts.ListOpts |
| 314 | 314 |
image string |
| 315 |
+ entrypoint ShlexOpt |
|
| 315 | 316 |
args []string |
| 316 | 317 |
hostname string |
| 317 | 318 |
env opts.ListOpts |
| ... | ... |
@@ -427,6 +453,7 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) {
|
| 427 | 427 |
ContainerSpec: swarm.ContainerSpec{
|
| 428 | 428 |
Image: opts.image, |
| 429 | 429 |
Args: opts.args, |
| 430 |
+ Command: opts.entrypoint.Value(), |
|
| 430 | 431 |
Env: currentEnv, |
| 431 | 432 |
Hostname: opts.hostname, |
| 432 | 433 |
Labels: runconfigopts.ConvertKVStringsToMap(opts.containerLabels.GetAll()), |
| ... | ... |
@@ -473,6 +500,7 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions) {
|
| 473 | 473 |
flags.StringVarP(&opts.user, flagUser, "u", "", "Username or UID (format: <name|uid>[:<group|gid>])") |
| 474 | 474 |
flags.StringVar(&opts.hostname, flagHostname, "", "Container hostname") |
| 475 | 475 |
flags.SetAnnotation(flagHostname, "version", []string{"1.25"})
|
| 476 |
+ flags.Var(&opts.entrypoint, flagEntrypoint, "Overwrite the default ENTRYPOINT of the image") |
|
| 476 | 477 |
|
| 477 | 478 |
flags.Var(&opts.resources.limitCPU, flagLimitCPU, "Limit CPUs") |
| 478 | 479 |
flags.Var(&opts.resources.limitMemBytes, flagLimitMemory, "Limit Memory") |
| ... | ... |
@@ -554,6 +582,7 @@ const ( |
| 554 | 554 |
flagDNSSearchRemove = "dns-search-rm" |
| 555 | 555 |
flagDNSSearchAdd = "dns-search-add" |
| 556 | 556 |
flagEndpointMode = "endpoint-mode" |
| 557 |
+ flagEntrypoint = "entrypoint" |
|
| 557 | 558 |
flagHost = "host" |
| 558 | 559 |
flagHostAdd = "host-add" |
| 559 | 560 |
flagHostRemove = "host-rm" |
| ... | ... |
@@ -17,7 +17,6 @@ import ( |
| 17 | 17 |
"github.com/docker/docker/opts" |
| 18 | 18 |
runconfigopts "github.com/docker/docker/runconfig/opts" |
| 19 | 19 |
"github.com/docker/go-connections/nat" |
| 20 |
- shlex "github.com/flynn-archive/go-shlex" |
|
| 21 | 20 |
"github.com/pkg/errors" |
| 22 | 21 |
"github.com/spf13/cobra" |
| 23 | 22 |
"github.com/spf13/pflag" |
| ... | ... |
@@ -38,7 +37,7 @@ func newUpdateCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 38 | 38 |
|
| 39 | 39 |
flags := cmd.Flags() |
| 40 | 40 |
flags.String("image", "", "Service image tag")
|
| 41 |
- flags.String("args", "", "Service command args")
|
|
| 41 |
+ flags.Var(&ShlexOpt{}, "args", "Service command args")
|
|
| 42 | 42 |
flags.Bool("rollback", false, "Rollback to previous specification")
|
| 43 | 43 |
flags.SetAnnotation("rollback", "version", []string{"1.25"})
|
| 44 | 44 |
flags.Bool("force", false, "Force update even if no changes require it")
|
| ... | ... |
@@ -258,6 +257,7 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
|
| 258 | 258 |
updateContainerLabels(flags, &cspec.Labels) |
| 259 | 259 |
updateString("image", &cspec.Image)
|
| 260 | 260 |
updateStringToSlice(flags, "args", &cspec.Args) |
| 261 |
+ updateStringToSlice(flags, flagEntrypoint, &cspec.Command) |
|
| 261 | 262 |
updateEnvironment(flags, &cspec.Env) |
| 262 | 263 |
updateString(flagWorkdir, &cspec.Dir) |
| 263 | 264 |
updateString(flagUser, &cspec.User) |
| ... | ... |
@@ -409,15 +409,12 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
|
| 409 | 409 |
return nil |
| 410 | 410 |
} |
| 411 | 411 |
|
| 412 |
-func updateStringToSlice(flags *pflag.FlagSet, flag string, field *[]string) error {
|
|
| 412 |
+func updateStringToSlice(flags *pflag.FlagSet, flag string, field *[]string) {
|
|
| 413 | 413 |
if !flags.Changed(flag) {
|
| 414 |
- return nil |
|
| 414 |
+ return |
|
| 415 | 415 |
} |
| 416 | 416 |
|
| 417 |
- value, _ := flags.GetString(flag) |
|
| 418 |
- valueSlice, err := shlex.Split(value) |
|
| 419 |
- *field = valueSlice |
|
| 420 |
- return err |
|
| 417 |
+ *field = flags.Lookup(flag).Value.(*ShlexOpt).Value() |
|
| 421 | 418 |
} |
| 422 | 419 |
|
| 423 | 420 |
func anyChanged(flags *pflag.FlagSet, fields ...string) bool {
|