diff --git a/api/types/types.go b/api/types/types.go index bbaf2c5531..9493bd95e2 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -238,6 +238,8 @@ type PluginsInfo struct { Network []string // List of Authorization plugins registered Authorization []string + // List of Log plugins registered + Log []string } // ExecStartCheck is a temp struct used by execStart diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 8498dd8c55..8ded8124dc 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -90,6 +90,10 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { fmt.Fprintf(dockerCli.Out(), "\n") } + fmt.Fprintf(dockerCli.Out(), " Log:") + fmt.Fprintf(dockerCli.Out(), " %s", strings.Join(info.Plugins.Log, " ")) + fmt.Fprintf(dockerCli.Out(), "\n") + fmt.Fprintf(dockerCli.Out(), "Swarm: %v\n", info.Swarm.LocalNodeState) if info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive && info.Swarm.LocalNodeState != swarm.LocalNodeStateLocked { fmt.Fprintf(dockerCli.Out(), " NodeID: %s\n", info.Swarm.NodeID) diff --git a/daemon/cluster/executor/container/executor.go b/daemon/cluster/executor/container/executor.go index 6be0f3156c..98e0d10f1a 100644 --- a/daemon/cluster/executor/container/executor.go +++ b/daemon/cluster/executor/container/executor.go @@ -52,6 +52,7 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) { // the plugin list by default. addPlugins("Network", append([]string{"overlay"}, info.Plugins.Network...)) addPlugins("Authorization", info.Plugins.Authorization) + addPlugins("Log", info.Plugins.Log) // add v2 plugins v2Plugins, err := e.backend.PluginManager().List(filters.NewArgs()) @@ -62,11 +63,15 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) { continue } plgnTyp := typ.Capability - if typ.Capability == "volumedriver" { + switch typ.Capability { + case "volumedriver": plgnTyp = "Volume" - } else if typ.Capability == "networkdriver" { + case "networkdriver": plgnTyp = "Network" + case "logdriver": + plgnTyp = "Log" } + plugins[api.PluginDescription{ Type: plgnTyp, Name: plgn.Name, diff --git a/daemon/info.go b/daemon/info.go index 919e8ed3d1..b6c2565f44 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/cli/debug" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/logger" "github.com/docker/docker/dockerversion" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/parsers/kernel" @@ -175,6 +176,7 @@ func (daemon *Daemon) showPluginsInfo() types.PluginsInfo { pluginsInfo.Volume = volumedrivers.GetDriverList() pluginsInfo.Network = daemon.GetNetworkDriverList() pluginsInfo.Authorization = daemon.configStore.GetAuthorizationPlugins() + pluginsInfo.Log = logger.ListDrivers() return pluginsInfo } diff --git a/daemon/logger/factory.go b/daemon/logger/factory.go index 32d51effa8..32001590d9 100644 --- a/daemon/logger/factory.go +++ b/daemon/logger/factory.go @@ -2,6 +2,7 @@ package logger import ( "fmt" + "sort" "sync" containertypes "github.com/docker/docker/api/types/container" @@ -23,6 +24,22 @@ type logdriverFactory struct { m sync.Mutex } +func (lf *logdriverFactory) list() []string { + ls := make([]string, 0, len(lf.registry)) + lf.m.Lock() + for name := range lf.registry { + ls = append(ls, name) + } + lf.m.Unlock() + sort.Strings(ls) + return ls +} + +// ListDrivers gets the list of registered log driver names +func ListDrivers() []string { + return factory.list() +} + func (lf *logdriverFactory) register(name string, c Creator) error { if lf.driverRegistered(name) { return fmt.Errorf("logger: log driver named '%s' is already registered", name) diff --git a/integration-cli/docker_cli_plugins_logdriver_test.go b/integration-cli/docker_cli_plugins_logdriver_test.go index c5029e2527..d74256656a 100644 --- a/integration-cli/docker_cli_plugins_logdriver_test.go +++ b/integration-cli/docker_cli_plugins_logdriver_test.go @@ -1,9 +1,13 @@ package main import ( + "encoding/json" + "net/http" "strings" + "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/checker" + "github.com/docker/docker/integration-cli/request" "github.com/go-check/check" ) @@ -25,3 +29,21 @@ func (s *DockerSuite) TestPluginLogDriver(c *check.C) { dockerCmd(c, "plugin", "disable", pluginName) dockerCmd(c, "plugin", "rm", pluginName) } + +// Make sure log drivers are listed in info, and v2 plugins are not. +func (s *DockerSuite) TestPluginLogDriverInfoList(c *check.C) { + testRequires(c, IsAmd64, DaemonIsLinux) + pluginName := "cpuguy83/docker-logdriver-test" + + dockerCmd(c, "plugin", "install", pluginName) + status, body, err := request.SockRequest("GET", "/info", nil, daemonHost()) + c.Assert(status, checker.Equals, http.StatusOK) + c.Assert(err, checker.IsNil) + + var info types.Info + err = json.Unmarshal(body, &info) + c.Assert(err, checker.IsNil) + drivers := strings.Join(info.Plugins.Log, " ") + c.Assert(drivers, checker.Contains, "json-file") + c.Assert(drivers, checker.Not(checker.Contains), pluginName) +}