diff --git a/api/client/service/create.go b/api/client/service/create.go index f6210be288..e55b2a4723 100644 --- a/api/client/service/create.go +++ b/api/client/service/create.go @@ -30,6 +30,7 @@ func newCreateCommand(dockerCli *client.DockerCli) *cobra.Command { addServiceFlags(cmd, opts) flags.VarP(&opts.labels, flagLabel, "l", "Service labels") + flags.Var(&opts.containerLabels, flagContainerLabel, "Container labels") flags.VarP(&opts.env, flagEnv, "e", "Set environment variables") flags.Var(&opts.mounts, flagMount, "Attach a mount to the service") flags.StringSliceVar(&opts.constraints, flagConstraint, []string{}, "Placement constraints") diff --git a/api/client/service/opts.go b/api/client/service/opts.go index 6e20b9e83c..187c77f263 100644 --- a/api/client/service/opts.go +++ b/api/client/service/opts.go @@ -392,14 +392,15 @@ func ValidatePort(value string) (string, error) { } type serviceOptions struct { - name string - labels opts.ListOpts - image string - args []string - env opts.ListOpts - workdir string - user string - mounts MountOpt + name string + labels opts.ListOpts + containerLabels opts.ListOpts + image string + args []string + env opts.ListOpts + workdir string + user string + mounts MountOpt resources resourceOptions stopGrace DurationOpt @@ -420,8 +421,9 @@ type serviceOptions struct { func newServiceOptions() *serviceOptions { return &serviceOptions{ - labels: opts.NewListOpts(runconfigopts.ValidateEnv), - env: opts.NewListOpts(runconfigopts.ValidateEnv), + labels: opts.NewListOpts(runconfigopts.ValidateEnv), + containerLabels: opts.NewListOpts(runconfigopts.ValidateEnv), + env: opts.NewListOpts(runconfigopts.ValidateEnv), endpoint: endpointOptions{ ports: opts.NewListOpts(ValidatePort), }, @@ -442,6 +444,7 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) { Image: opts.image, Args: opts.args, Env: opts.env.GetAll(), + Labels: runconfigopts.ConvertKVStringsToMap(opts.containerLabels.GetAll()), Dir: opts.workdir, User: opts.user, Mounts: opts.mounts.Value(), @@ -516,42 +519,45 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) { } const ( - flagConstraint = "constraint" - flagConstraintRemove = "constraint-rm" - flagConstraintAdd = "constraint-add" - flagEndpointMode = "endpoint-mode" - flagEnv = "env" - flagEnvRemove = "env-rm" - flagEnvAdd = "env-add" - flagLabel = "label" - flagLabelRemove = "label-rm" - flagLabelAdd = "label-add" - flagLimitCPU = "limit-cpu" - flagLimitMemory = "limit-memory" - flagMode = "mode" - flagMount = "mount" - flagMountRemove = "mount-rm" - flagMountAdd = "mount-add" - flagName = "name" - flagNetwork = "network" - flagNetworkRemove = "network-rm" - flagNetworkAdd = "network-add" - flagPublish = "publish" - flagPublishRemove = "publish-rm" - flagPublishAdd = "publish-add" - flagReplicas = "replicas" - flagReserveCPU = "reserve-cpu" - flagReserveMemory = "reserve-memory" - flagRestartCondition = "restart-condition" - flagRestartDelay = "restart-delay" - flagRestartMaxAttempts = "restart-max-attempts" - flagRestartWindow = "restart-window" - flagStopGracePeriod = "stop-grace-period" - flagUpdateDelay = "update-delay" - flagUpdateFailureAction = "update-failure-action" - flagUpdateParallelism = "update-parallelism" - flagUser = "user" - flagRegistryAuth = "with-registry-auth" - flagLogDriver = "log-driver" - flagLogOpt = "log-opt" + flagConstraint = "constraint" + flagConstraintRemove = "constraint-rm" + flagConstraintAdd = "constraint-add" + flagContainerLabel = "container-label" + flagContainerLabelRemove = "container-label-rm" + flagContainerLabelAdd = "container-label-add" + flagEndpointMode = "endpoint-mode" + flagEnv = "env" + flagEnvRemove = "env-rm" + flagEnvAdd = "env-add" + flagLabel = "label" + flagLabelRemove = "label-rm" + flagLabelAdd = "label-add" + flagLimitCPU = "limit-cpu" + flagLimitMemory = "limit-memory" + flagMode = "mode" + flagMount = "mount" + flagMountRemove = "mount-rm" + flagMountAdd = "mount-add" + flagName = "name" + flagNetwork = "network" + flagNetworkRemove = "network-rm" + flagNetworkAdd = "network-add" + flagPublish = "publish" + flagPublishRemove = "publish-rm" + flagPublishAdd = "publish-add" + flagReplicas = "replicas" + flagReserveCPU = "reserve-cpu" + flagReserveMemory = "reserve-memory" + flagRestartCondition = "restart-condition" + flagRestartDelay = "restart-delay" + flagRestartMaxAttempts = "restart-max-attempts" + flagRestartWindow = "restart-window" + flagStopGracePeriod = "stop-grace-period" + flagUpdateDelay = "update-delay" + flagUpdateFailureAction = "update-failure-action" + flagUpdateParallelism = "update-parallelism" + flagUser = "user" + flagRegistryAuth = "with-registry-auth" + flagLogDriver = "log-driver" + flagLogOpt = "log-opt" ) diff --git a/api/client/service/update.go b/api/client/service/update.go index 6f3953f1af..392daf06b3 100644 --- a/api/client/service/update.go +++ b/api/client/service/update.go @@ -38,11 +38,13 @@ func newUpdateCommand(dockerCli *client.DockerCli) *cobra.Command { flags.Var(newListOptsVar(), flagEnvRemove, "Remove an environment variable") flags.Var(newListOptsVar(), flagLabelRemove, "Remove a label by its key") + flags.Var(newListOptsVar(), flagContainerLabelRemove, "Remove a container label by its key") flags.Var(newListOptsVar(), flagMountRemove, "Remove a mount by its target path") flags.Var(newListOptsVar(), flagPublishRemove, "Remove a published port by its target port") flags.Var(newListOptsVar(), flagNetworkRemove, "Remove a network by name") flags.Var(newListOptsVar(), flagConstraintRemove, "Remove a constraint") flags.Var(&opts.labels, flagLabelAdd, "Add or update service labels") + flags.Var(&opts.containerLabels, flagContainerLabelAdd, "Add or update container labels") flags.Var(&opts.env, flagEnvAdd, "Add or update environment variables") flags.Var(&opts.mounts, flagMountAdd, "Add or update a mount on a service") flags.StringSliceVar(&opts.constraints, flagConstraintAdd, []string{}, "Add or update placement constraints") @@ -145,6 +147,7 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error { updateString(flagName, &spec.Name) updateLabels(flags, &spec.Labels) + updateContainerLabels(flags, &cspec.Labels) updateString("image", &cspec.Image) updateStringToSlice(flags, "args", &cspec.Args) updateEnvironment(flags, &cspec.Env) @@ -248,6 +251,26 @@ func updatePlacement(flags *pflag.FlagSet, placement *swarm.Placement) { placement.Constraints = removeItems(placement.Constraints, toRemove, itemKey) } +func updateContainerLabels(flags *pflag.FlagSet, field *map[string]string) { + if flags.Changed(flagContainerLabelAdd) { + if field == nil { + *field = map[string]string{} + } + + values := flags.Lookup(flagContainerLabelAdd).Value.(*opts.ListOpts).GetAll() + for key, value := range runconfigopts.ConvertKVStringsToMap(values) { + (*field)[key] = value + } + } + + if field != nil && flags.Changed(flagContainerLabelRemove) { + toRemove := flags.Lookup(flagContainerLabelRemove).Value.(*opts.ListOpts).GetAll() + for _, label := range toRemove { + delete(*field, label) + } + } +} + func updateLabels(flags *pflag.FlagSet, field *map[string]string) { if flags.Changed(flagLabelAdd) { if *field == nil { diff --git a/docs/reference/commandline/service_create.md b/docs/reference/commandline/service_create.md index b47fd7e0cd..bd29552ba3 100644 --- a/docs/reference/commandline/service_create.md +++ b/docs/reference/commandline/service_create.md @@ -18,6 +18,7 @@ Create a new service Options: --constraint value Placement constraints (default []) + --container-label value Service container labels (default []) --endpoint-mode string Endpoint mode (vip or dnsrr) -e, --env value Set environment variables (default []) --help Print usage diff --git a/docs/reference/commandline/service_update.md b/docs/reference/commandline/service_update.md index e65556e483..8d49fe0638 100644 --- a/docs/reference/commandline/service_update.md +++ b/docs/reference/commandline/service_update.md @@ -20,6 +20,8 @@ Options: --args string Service command args --constraint-add value Add or update placement constraints (default []) --constraint-rm value Remove a constraint (default []) + --container-label-add value Add or update container labels (default []) + --container-label-rm value Remove a container label by its key (default []) --endpoint-mode string Endpoint mode (vip or dnsrr) --env-add value Add or update environment variables (default []) --env-rm value Remove an environment variable (default [])