github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/client/driver/executor_plugin.go (about)

     1  package driver
     2  
     3  import (
     4  	"encoding/gob"
     5  	"log"
     6  	"net/rpc"
     7  
     8  	"github.com/hashicorp/go-plugin"
     9  	"github.com/hashicorp/nomad/client/driver/executor"
    10  	cstructs "github.com/hashicorp/nomad/client/structs"
    11  	"github.com/hashicorp/nomad/nomad/structs"
    12  )
    13  
    14  // Registering these types since we have to serialize and de-serialize the Task
    15  // structs over the wire between drivers and the executor.
    16  func init() {
    17  	gob.Register([]interface{}{})
    18  	gob.Register(map[string]interface{}{})
    19  	gob.Register([]map[string]string{})
    20  	gob.Register([]map[string]int{})
    21  }
    22  
    23  type ExecutorRPC struct {
    24  	client *rpc.Client
    25  	logger *log.Logger
    26  }
    27  
    28  // LaunchCmdArgs wraps a user command and the args for the purposes of RPC
    29  type LaunchCmdArgs struct {
    30  	Cmd *executor.ExecCommand
    31  	Ctx *executor.ExecutorContext
    32  }
    33  
    34  // LaunchSyslogServerArgs wraps the executor context for the purposes of RPC
    35  type LaunchSyslogServerArgs struct {
    36  	Ctx *executor.ExecutorContext
    37  }
    38  
    39  // SyncServicesArgs wraps the consul context for the purposes of RPC
    40  type SyncServicesArgs struct {
    41  	Ctx *executor.ConsulContext
    42  }
    43  
    44  func (e *ExecutorRPC) LaunchCmd(cmd *executor.ExecCommand, ctx *executor.ExecutorContext) (*executor.ProcessState, error) {
    45  	var ps *executor.ProcessState
    46  	err := e.client.Call("Plugin.LaunchCmd", LaunchCmdArgs{Cmd: cmd, Ctx: ctx}, &ps)
    47  	return ps, err
    48  }
    49  
    50  func (e *ExecutorRPC) LaunchSyslogServer(ctx *executor.ExecutorContext) (*executor.SyslogServerState, error) {
    51  	var ss *executor.SyslogServerState
    52  	err := e.client.Call("Plugin.LaunchSyslogServer", LaunchSyslogServerArgs{Ctx: ctx}, &ss)
    53  	return ss, err
    54  }
    55  
    56  func (e *ExecutorRPC) Wait() (*executor.ProcessState, error) {
    57  	var ps executor.ProcessState
    58  	err := e.client.Call("Plugin.Wait", new(interface{}), &ps)
    59  	return &ps, err
    60  }
    61  
    62  func (e *ExecutorRPC) ShutDown() error {
    63  	return e.client.Call("Plugin.ShutDown", new(interface{}), new(interface{}))
    64  }
    65  
    66  func (e *ExecutorRPC) Exit() error {
    67  	return e.client.Call("Plugin.Exit", new(interface{}), new(interface{}))
    68  }
    69  
    70  func (e *ExecutorRPC) UpdateLogConfig(logConfig *structs.LogConfig) error {
    71  	return e.client.Call("Plugin.UpdateLogConfig", logConfig, new(interface{}))
    72  }
    73  
    74  func (e *ExecutorRPC) UpdateTask(task *structs.Task) error {
    75  	return e.client.Call("Plugin.UpdateTask", task, new(interface{}))
    76  }
    77  
    78  func (e *ExecutorRPC) SyncServices(ctx *executor.ConsulContext) error {
    79  	return e.client.Call("Plugin.SyncServices", SyncServicesArgs{Ctx: ctx}, new(interface{}))
    80  }
    81  
    82  func (e *ExecutorRPC) DeregisterServices() error {
    83  	return e.client.Call("Plugin.DeregisterServices", new(interface{}), new(interface{}))
    84  }
    85  
    86  func (e *ExecutorRPC) Version() (*executor.ExecutorVersion, error) {
    87  	var version executor.ExecutorVersion
    88  	err := e.client.Call("Plugin.Version", new(interface{}), &version)
    89  	return &version, err
    90  }
    91  
    92  func (e *ExecutorRPC) Stats() (*cstructs.TaskResourceUsage, error) {
    93  	var resourceUsage cstructs.TaskResourceUsage
    94  	err := e.client.Call("Plugin.Stats", new(interface{}), &resourceUsage)
    95  	return &resourceUsage, err
    96  }
    97  
    98  type ExecutorRPCServer struct {
    99  	Impl   executor.Executor
   100  	logger *log.Logger
   101  }
   102  
   103  func (e *ExecutorRPCServer) LaunchCmd(args LaunchCmdArgs, ps *executor.ProcessState) error {
   104  	state, err := e.Impl.LaunchCmd(args.Cmd, args.Ctx)
   105  	if state != nil {
   106  		*ps = *state
   107  	}
   108  	return err
   109  }
   110  
   111  func (e *ExecutorRPCServer) LaunchSyslogServer(args LaunchSyslogServerArgs, ss *executor.SyslogServerState) error {
   112  	state, err := e.Impl.LaunchSyslogServer(args.Ctx)
   113  	if state != nil {
   114  		*ss = *state
   115  	}
   116  	return err
   117  }
   118  
   119  func (e *ExecutorRPCServer) Wait(args interface{}, ps *executor.ProcessState) error {
   120  	state, err := e.Impl.Wait()
   121  	if state != nil {
   122  		*ps = *state
   123  	}
   124  	return err
   125  }
   126  
   127  func (e *ExecutorRPCServer) ShutDown(args interface{}, resp *interface{}) error {
   128  	return e.Impl.ShutDown()
   129  }
   130  
   131  func (e *ExecutorRPCServer) Exit(args interface{}, resp *interface{}) error {
   132  	return e.Impl.Exit()
   133  }
   134  
   135  func (e *ExecutorRPCServer) UpdateLogConfig(args *structs.LogConfig, resp *interface{}) error {
   136  	return e.Impl.UpdateLogConfig(args)
   137  }
   138  
   139  func (e *ExecutorRPCServer) UpdateTask(args *structs.Task, resp *interface{}) error {
   140  	return e.Impl.UpdateTask(args)
   141  }
   142  
   143  func (e *ExecutorRPCServer) SyncServices(args SyncServicesArgs, resp *interface{}) error {
   144  	return e.Impl.SyncServices(args.Ctx)
   145  }
   146  
   147  func (e *ExecutorRPCServer) DeregisterServices(args interface{}, resp *interface{}) error {
   148  	return e.Impl.DeregisterServices()
   149  }
   150  
   151  func (e *ExecutorRPCServer) Version(args interface{}, version *executor.ExecutorVersion) error {
   152  	ver, err := e.Impl.Version()
   153  	if ver != nil {
   154  		*version = *ver
   155  	}
   156  	return err
   157  }
   158  
   159  func (e *ExecutorRPCServer) Stats(args interface{}, resourceUsage *cstructs.TaskResourceUsage) error {
   160  	ru, err := e.Impl.Stats()
   161  	if ru != nil {
   162  		*resourceUsage = *ru
   163  	}
   164  	return err
   165  }
   166  
   167  type ExecutorPlugin struct {
   168  	logger *log.Logger
   169  	Impl   *ExecutorRPCServer
   170  }
   171  
   172  func (p *ExecutorPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
   173  	if p.Impl == nil {
   174  		p.Impl = &ExecutorRPCServer{Impl: executor.NewExecutor(p.logger), logger: p.logger}
   175  	}
   176  	return p.Impl, nil
   177  }
   178  
   179  func (p *ExecutorPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
   180  	return &ExecutorRPC{client: c, logger: p.logger}, nil
   181  }