github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/plugin/rpc/cli_rpc_server.go (about) 1 package rpc 2 3 import ( 4 "github.com/cloudfoundry/cli/cf/terminal" 5 "github.com/cloudfoundry/cli/plugin" 6 "github.com/codegangsta/cli" 7 8 "fmt" 9 "net" 10 "net/rpc" 11 "strconv" 12 ) 13 14 type CliRpcService struct { 15 listener net.Listener 16 stopCh chan struct{} 17 Pinged bool 18 RpcCmd *CliRpcCmd 19 } 20 21 type CliRpcCmd struct { 22 PluginMetadata *plugin.PluginMetadata 23 coreCommandRunner *cli.App 24 outputCapture terminal.OutputCapture 25 terminalOutputSwitch terminal.TerminalOutputSwitch 26 } 27 28 func NewRpcService(commandRunner *cli.App, outputCapture terminal.OutputCapture, terminalOutputSwitch terminal.TerminalOutputSwitch) (*CliRpcService, error) { 29 rpcService := &CliRpcService{ 30 RpcCmd: &CliRpcCmd{ 31 PluginMetadata: &plugin.PluginMetadata{}, 32 coreCommandRunner: commandRunner, 33 outputCapture: outputCapture, 34 terminalOutputSwitch: terminalOutputSwitch, 35 }, 36 } 37 38 err := rpc.Register(rpcService.RpcCmd) 39 if err != nil { 40 return nil, err 41 } 42 43 return rpcService, nil 44 } 45 46 func (cli *CliRpcService) Stop() { 47 close(cli.stopCh) 48 cli.listener.Close() 49 } 50 51 func (cli *CliRpcService) Port() string { 52 return strconv.Itoa(cli.listener.Addr().(*net.TCPAddr).Port) 53 } 54 55 func (cli *CliRpcService) Start() error { 56 var err error 57 58 cli.stopCh = make(chan struct{}) 59 60 cli.listener, err = net.Listen("tcp", "127.0.0.1:0") 61 if err != nil { 62 return err 63 } 64 65 go func() { 66 for { 67 conn, err := cli.listener.Accept() 68 if err != nil { 69 select { 70 case <-cli.stopCh: 71 return 72 default: 73 fmt.Println(err) 74 } 75 } else { 76 go rpc.ServeConn(conn) 77 } 78 } 79 }() 80 81 return nil 82 } 83 84 func (cmd *CliRpcCmd) SetPluginMetadata(pluginMetadata plugin.PluginMetadata, retVal *bool) error { 85 cmd.PluginMetadata = &pluginMetadata 86 *retVal = true 87 return nil 88 } 89 90 func (cmd *CliRpcCmd) DisableTerminalOutput(disable bool, retVal *bool) error { 91 cmd.terminalOutputSwitch.DisableTerminalOutput(disable) 92 *retVal = true 93 return nil 94 } 95 96 func (cmd *CliRpcCmd) CallCoreCommand(args []string, retVal *bool) error { 97 defer func() { 98 recover() 99 }() 100 101 err := cmd.coreCommandRunner.Run(append([]string{"CF_NAME"}, args...)) 102 103 if err != nil { 104 *retVal = false 105 return err 106 } 107 108 *retVal = true 109 return nil 110 } 111 112 func (cmd *CliRpcCmd) GetOutputAndReset(args bool, retVal *[]string) error { 113 *retVal = cmd.outputCapture.GetOutputAndReset() 114 return nil 115 }