ソースを参照

swarm: add log driver support for services

Adds log driver support for service creation and update. Add flags
`--log-driver` and `--log-opt` to match `docker run`. Log drivers are
configured per service.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
Stephen J Day 9 年 前
コミット
e778ba2d5b

+ 30 - 0
api/client/service/opts.go

@@ -358,6 +358,27 @@ func convertPortToPortConfig(
 	return ports
 }
 
+type logDriverOptions struct {
+	name string
+	opts opts.ListOpts
+}
+
+func newLogDriverOptions() logDriverOptions {
+	return logDriverOptions{opts: opts.NewListOpts(runconfigopts.ValidateEnv)}
+}
+
+func (ldo *logDriverOptions) toLogDriver() *swarm.Driver {
+	if ldo.name == "" {
+		return nil
+	}
+
+	// set the log driver only if specified.
+	return &swarm.Driver{
+		Name:    ldo.name,
+		Options: runconfigopts.ConvertKVStringsToMap(ldo.opts.GetAll()),
+	}
+}
+
 // ValidatePort validates a string is in the expected format for a port definition
 func ValidatePort(value string) (string, error) {
 	portMappings, err := nat.ParsePortSpec(value)
@@ -392,6 +413,8 @@ type serviceOptions struct {
 	endpoint      endpointOptions
 
 	registryAuth bool
+
+	logDriver logDriverOptions
 }
 
 func newServiceOptions() *serviceOptions {
@@ -401,6 +424,7 @@ func newServiceOptions() *serviceOptions {
 		endpoint: endpointOptions{
 			ports: opts.NewListOpts(ValidatePort),
 		},
+		logDriver: newLogDriverOptions(),
 	}
 }
 
@@ -427,6 +451,7 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) {
 			Placement: &swarm.Placement{
 				Constraints: opts.constraints,
 			},
+			LogDriver: opts.logDriver.toLogDriver(),
 		},
 		Mode: swarm.ServiceMode{},
 		UpdateConfig: &swarm.UpdateConfig{
@@ -482,6 +507,9 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) {
 	flags.StringVar(&opts.endpoint.mode, flagEndpointMode, "", "Endpoint mode (vip or dnsrr)")
 
 	flags.BoolVar(&opts.registryAuth, flagRegistryAuth, false, "Send registry authentication details to Swarm agents")
+
+	flags.StringVar(&opts.logDriver.name, flagLogDriver, "", "Logging driver for service")
+	flags.Var(&opts.logDriver.opts, flagLogOpt, "Logging driver options")
 }
 
 const (
@@ -520,4 +548,6 @@ const (
 	flagUpdateParallelism  = "update-parallelism"
 	flagUser               = "user"
 	flagRegistryAuth       = "registry-auth"
+	flagLogDriver          = "log-driver"
+	flagLogOpt             = "log-opt"
 )

+ 29 - 0
api/client/service/update.go

@@ -211,6 +211,11 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
 		}
 		updatePorts(flags, &spec.EndpointSpec.Ports)
 	}
+
+	if err := updateLogDriver(flags, &spec.TaskTemplate); err != nil {
+		return err
+	}
+
 	return nil
 }
 
@@ -386,3 +391,27 @@ func updateReplicas(flags *pflag.FlagSet, serviceMode *swarm.ServiceMode) error
 	serviceMode.Replicated.Replicas = flags.Lookup(flagReplicas).Value.(*Uint64Opt).Value()
 	return nil
 }
+
+// updateLogDriver updates the log driver only if the log driver flag is set.
+// All options will be replaced with those provided on the command line.
+func updateLogDriver(flags *pflag.FlagSet, taskTemplate *swarm.TaskSpec) error {
+	if !flags.Changed(flagLogDriver) {
+		return nil
+	}
+
+	name, err := flags.GetString(flagLogDriver)
+	if err != nil {
+		return err
+	}
+
+	if name == "" {
+		return nil
+	}
+
+	taskTemplate.LogDriver = &swarm.Driver{
+		Name:    name,
+		Options: runconfigopts.ConvertKVStringsToMap(flags.Lookup(flagLogOpt).Value.(*opts.ListOpts).GetAll()),
+	}
+
+	return nil
+}

+ 24 - 0
daemon/cluster/convert/service.go

@@ -28,6 +28,7 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service {
 				Resources:     resourcesFromGRPC(s.Spec.Task.Resources),
 				RestartPolicy: restartPolicyFromGRPC(s.Spec.Task.Restart),
 				Placement:     placementFromGRPC(s.Spec.Task.Placement),
+				LogDriver:     driverFromGRPC(s.Spec.Task.LogDriver),
 			},
 
 			Networks:     networks,
@@ -86,6 +87,7 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
 		},
 		Task: swarmapi.TaskSpec{
 			Resources: resourcesToGRPC(s.TaskTemplate.Resources),
+			LogDriver: driverToGRPC(s.TaskTemplate.LogDriver),
 		},
 		Networks: networks,
 	}
@@ -251,3 +253,25 @@ func placementFromGRPC(p *swarmapi.Placement) *types.Placement {
 
 	return r
 }
+
+func driverFromGRPC(p *swarmapi.Driver) *types.Driver {
+	if p == nil {
+		return nil
+	}
+
+	return &types.Driver{
+		Name:    p.Name,
+		Options: p.Options,
+	}
+}
+
+func driverToGRPC(p *types.Driver) *swarmapi.Driver {
+	if p == nil {
+		return nil
+	}
+
+	return &swarmapi.Driver{
+		Name:    p.Name,
+		Options: p.Options,
+	}
+}

+ 1 - 0
daemon/cluster/convert/task.go

@@ -22,6 +22,7 @@ func TaskFromGRPC(t swarmapi.Task) types.Task {
 			Resources:     resourcesFromGRPC(t.Spec.Resources),
 			RestartPolicy: restartPolicyFromGRPC(t.Spec.Restart),
 			Placement:     placementFromGRPC(t.Spec.Placement),
+			LogDriver:     driverFromGRPC(t.Spec.LogDriver),
 		},
 		Status: types.TaskStatus{
 			State:   types.TaskState(strings.ToLower(t.Status.State.String())),