Add container labels to service create/update

Swarm mode makes it possible through the API to set labels to containers
but not through command line. This tries to fix it.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
Vincent Demeester 2016-07-25 11:38:01 +02:00 committed by Tibor Vass
parent afac3361dc
commit 4031d70d1b
5 changed files with 81 additions and 48 deletions

View File

@ -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")

View File

@ -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"
)

View File

@ -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 {

View File

@ -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

View File

@ -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 [])