diff --git a/client/driver/docker.go b/client/driver/docker.go index d050e664e..79b535805 100644 --- a/client/driver/docker.go +++ b/client/driver/docker.go @@ -700,6 +700,9 @@ func (d *DockerDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, er return nil, err } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.docker: version of executor: %v", ver.Version) + // Return a driver handle h := &DockerHandle{ client: client, diff --git a/client/driver/exec.go b/client/driver/exec.go index 590bb90d2..136016113 100644 --- a/client/driver/exec.go +++ b/client/driver/exec.go @@ -187,6 +187,8 @@ func (d *ExecDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, erro return nil, fmt.Errorf("error connecting to plugin: %v", merrs.ErrorOrNil()) } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.exec : version of executor: %v", ver.Version) // Return a driver handle h := &execHandle{ pluginClient: client, diff --git a/client/driver/executor/executor.go b/client/driver/executor/executor.go index 82dc9c617..434d9c62b 100644 --- a/client/driver/executor/executor.go +++ b/client/driver/executor/executor.go @@ -37,6 +37,7 @@ type Executor interface { UpdateTask(task *structs.Task) error SyncServices(ctx *ConsulContext) error DeregisterServices() error + Version() (*ExecutorVersion, error) } // ConsulContext holds context to configure the consul client and run checks @@ -127,6 +128,15 @@ type SyslogServerState struct { Addr string } +// ExecutorVersion is the version of the executor +type ExecutorVersion struct { + Version string +} + +func (v *ExecutorVersion) GoString() string { + return v.Version +} + // UniversalExecutor is an implementation of the Executor which launches and // supervises processes. In addition to process supervision it provides resource // and file system isolation @@ -162,6 +172,11 @@ func NewExecutor(logger *log.Logger) Executor { } } +// Version returns the api version of the executor +func (e *UniversalExecutor) Version() (*ExecutorVersion, error) { + return &ExecutorVersion{Version: "1.0.0"}, nil +} + // LaunchCmd launches a process and returns it's state. It also configures an // applies isolation on certain platforms. func (e *UniversalExecutor) LaunchCmd(command *ExecCommand, ctx *ExecutorContext) (*ProcessState, error) { diff --git a/client/driver/executor_plugin.go b/client/driver/executor_plugin.go index c8561f74c..decb359e3 100644 --- a/client/driver/executor_plugin.go +++ b/client/driver/executor_plugin.go @@ -21,6 +21,7 @@ func init() { type ExecutorRPC struct { client *rpc.Client + logger *log.Logger } // LaunchCmdArgs wraps a user command and the args for the purposes of RPC @@ -81,8 +82,15 @@ func (e *ExecutorRPC) DeregisterServices() error { return e.client.Call("Plugin.DeregisterServices", new(interface{}), new(interface{})) } +func (e *ExecutorRPC) Version() (*executor.ExecutorVersion, error) { + var version executor.ExecutorVersion + err := e.client.Call("Plugin.Version", new(interface{}), &version) + return &version, err +} + type ExecutorRPCServer struct { - Impl executor.Executor + Impl executor.Executor + logger *log.Logger } func (e *ExecutorRPCServer) LaunchCmd(args LaunchCmdArgs, ps *executor.ProcessState) error { @@ -133,6 +141,14 @@ func (e *ExecutorRPCServer) DeregisterServices(args interface{}, resp *interface return e.Impl.DeregisterServices() } +func (e *ExecutorRPCServer) Version(args interface{}, version *executor.ExecutorVersion) error { + ver, err := e.Impl.Version() + if ver != nil { + *version = *ver + } + return err +} + type ExecutorPlugin struct { logger *log.Logger Impl *ExecutorRPCServer @@ -140,11 +156,11 @@ type ExecutorPlugin struct { func (p *ExecutorPlugin) Server(*plugin.MuxBroker) (interface{}, error) { if p.Impl == nil { - p.Impl = &ExecutorRPCServer{Impl: executor.NewExecutor(p.logger)} + p.Impl = &ExecutorRPCServer{Impl: executor.NewExecutor(p.logger), logger: p.logger} } return p.Impl, nil } func (p *ExecutorPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { - return &ExecutorRPC{client: c}, nil + return &ExecutorRPC{client: c, logger: p.logger}, nil } diff --git a/client/driver/java.go b/client/driver/java.go index 4e71ceb45..f371c89bf 100644 --- a/client/driver/java.go +++ b/client/driver/java.go @@ -254,6 +254,9 @@ func (d *JavaDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, erro return nil, fmt.Errorf("error connecting to plugin: %v", merrs.ErrorOrNil()) } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.java: version of executor: %v", ver.Version) + // Return a driver handle h := &javaHandle{ pluginClient: pluginClient, diff --git a/client/driver/qemu.go b/client/driver/qemu.go index e64633b88..31dc63f36 100644 --- a/client/driver/qemu.go +++ b/client/driver/qemu.go @@ -249,7 +249,7 @@ func (d *QemuDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, erro Reattach: id.PluginConfig.PluginConfig(), } - executor, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) + exec, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) if err != nil { d.logger.Println("[ERR] driver.qemu: error connecting to plugin so destroying plugin pid and user pid") if e := destroyPlugin(id.PluginConfig.Pid, id.UserPid); e != nil { @@ -258,10 +258,12 @@ func (d *QemuDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, erro return nil, fmt.Errorf("error connecting to plugin: %v", err) } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.qemu: version of executor: %v", ver.Version) // Return a driver handle h := &qemuHandle{ pluginClient: pluginClient, - executor: executor, + executor: exec, userPid: id.UserPid, allocDir: id.AllocDir, logger: d.logger, diff --git a/client/driver/raw_exec.go b/client/driver/raw_exec.go index e1619ab0a..c9610cdc2 100644 --- a/client/driver/raw_exec.go +++ b/client/driver/raw_exec.go @@ -158,7 +158,7 @@ func (d *RawExecDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, e pluginConfig := &plugin.ClientConfig{ Reattach: id.PluginConfig.PluginConfig(), } - executor, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) + exec, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) if err != nil { d.logger.Println("[ERR] driver.raw_exec: error connecting to plugin so destroying plugin pid and user pid") if e := destroyPlugin(id.PluginConfig.Pid, id.UserPid); e != nil { @@ -167,10 +167,13 @@ func (d *RawExecDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, e return nil, fmt.Errorf("error connecting to plugin: %v", err) } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.raw_exec: version of executor: %v", ver.Version) + // Return a driver handle h := &rawExecHandle{ pluginClient: pluginClient, - executor: executor, + executor: exec, userPid: id.UserPid, logger: d.logger, killTimeout: id.KillTimeout, diff --git a/client/driver/rkt.go b/client/driver/rkt.go index 4398beb9a..5e2f4e36e 100644 --- a/client/driver/rkt.go +++ b/client/driver/rkt.go @@ -286,7 +286,7 @@ func (d *RktDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, error pluginConfig := &plugin.ClientConfig{ Reattach: id.PluginConfig.PluginConfig(), } - executor, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) + exec, pluginClient, err := createExecutor(pluginConfig, d.config.LogOutput, d.config) if err != nil { d.logger.Println("[ERROR] driver.rkt: error connecting to plugin so destroying plugin pid and user pid") if e := destroyPlugin(id.PluginConfig.Pid, id.ExecutorPid); e != nil { @@ -295,12 +295,14 @@ func (d *RktDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, error return nil, fmt.Errorf("error connecting to plugin: %v", err) } + ver, _ := exec.Version() + d.logger.Printf("[DEBUG] driver.rkt: version of executor: %v", ver.Version) // Return a driver handle h := &rktHandle{ pluginClient: pluginClient, executorPid: id.ExecutorPid, allocDir: id.AllocDir, - executor: executor, + executor: exec, logger: d.logger, killTimeout: id.KillTimeout, maxKillTimeout: id.MaxKillTimeout,