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 }