github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/hypervisor/rpcd/connectToVmSerialPort.go (about) 1 package rpcd 2 3 import ( 4 "io" 5 6 "github.com/Cloud-Foundations/Dominator/lib/errors" 7 "github.com/Cloud-Foundations/Dominator/lib/srpc" 8 "github.com/Cloud-Foundations/Dominator/proto/hypervisor" 9 ) 10 11 func (t *srpcType) ConnectToVmSerialPort(conn *srpc.Conn) error { 12 var request hypervisor.ConnectToVmSerialPortRequest 13 if err := conn.Decode(&request); err != nil { 14 return err 15 } 16 closeNotifier := make(chan error, 1) 17 input, output, err := t.manager.ConnectToVmSerialPort(request.IpAddress, 18 conn.GetAuthInformation(), request.PortNumber) 19 if input != nil { 20 defer close(input) 21 } 22 e := conn.Encode(hypervisor.ConnectToVmSerialPortResponse{ 23 Error: errors.ErrorToString(err)}) 24 if e != nil { 25 return e 26 } 27 if e := conn.Flush(); e != nil { 28 return e 29 } 30 if err != nil { 31 return err 32 } 33 go func() { // Read from connection and write to input until EOF. 34 buffer := make([]byte, 256) 35 for { 36 if nRead, err := conn.Read(buffer); err != nil { 37 if err != io.EOF { 38 closeNotifier <- err 39 } else { 40 closeNotifier <- srpc.ErrorCloseClient 41 } 42 return 43 } else { 44 for _, char := range buffer[:nRead] { 45 input <- char 46 } 47 } 48 } 49 }() 50 // Read from output until closure or transmission error. 51 for { 52 select { 53 case data, ok := <-output: 54 var buffer []byte 55 if !ok { 56 buffer = []byte("VM serial port closed\n") 57 } else { 58 buffer = readData(data, output) 59 } 60 if _, err := conn.Write(buffer); err != nil { 61 return err 62 } 63 if err := conn.Flush(); err != nil { 64 return err 65 } 66 if !ok { 67 return srpc.ErrorCloseClient 68 } 69 case err := <-closeNotifier: 70 return err 71 } 72 } 73 } 74 75 func readData(firstByte byte, moreBytes <-chan byte) []byte { 76 buffer := make([]byte, 1, len(moreBytes)+1) 77 buffer[0] = firstByte 78 for { 79 select { 80 case char, ok := <-moreBytes: 81 if !ok { 82 return buffer 83 } 84 buffer = append(buffer, char) 85 default: 86 return buffer 87 } 88 } 89 }