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