8 "github.com/gin-gonic/gin"
9 "github.com/iotbzh/xds-agent/lib/apiv1"
10 common "github.com/iotbzh/xds-common/golib"
11 uuid "github.com/satori/go.uuid"
16 // ExecCmd executes remotely a command
17 func (s *APIService) execCmd(c *gin.Context) {
18 s._execRequest("/exec", c)
21 // execSignalCmd executes remotely a command
22 func (s *APIService) execSignalCmd(c *gin.Context) {
23 s._execRequest("/signal", c)
26 func (s *APIService) _execRequest(cmd string, c *gin.Context) {
27 data, err := c.GetRawData()
29 common.APIError(c, err.Error())
32 args := apiv1.ExecArgs{}
33 // XXX - we cannot use c.BindJSON, so directly unmarshall it
34 // (see https://github.com/gin-gonic/gin/issues/1078)
35 if err := json.Unmarshal(data, &args); err != nil {
36 common.APIError(c, "Invalid arguments")
40 // First get Project ID to retrieve Server ID and send command to right server
46 prj := s.projects.Get(id)
48 common.APIError(c, "Unknown id")
52 svr := (*prj).GetServer()
54 common.APIError(c, "Cannot identify XDS Server")
58 // Retrieve session info
59 sess := s.sessions.Get(c)
61 common.APIError(c, "Unknown sessions")
66 common.APIError(c, "Websocket not established")
70 // Forward XDSServer WS events to client WS
71 // TODO removed static event name list and get it from XDSServer
75 apiv1.ExecInferiorInEvent,
76 apiv1.ExecInferiorOutEvent,
79 fwdFuncID := []uuid.UUID{}
80 for _, evName := range evtList {
82 fwdFunc := func(evData interface{}) {
83 // Forward event to Client/Dashboard
86 id, err := svr.EventOn(evN, fwdFunc)
88 common.APIError(c, err.Error())
91 fwdFuncID = append(fwdFuncID, id)
94 // Handle Exit event separately to cleanup registered listener
95 var exitFuncID uuid.UUID
96 exitFunc := func(evData interface{}) {
97 so.Emit(apiv1.ExecExitEvent, evData)
100 for i, evName := range evtList {
101 svr.EventOff(evName, fwdFuncID[i])
103 svr.EventOff(apiv1.ExecExitEvent, exitFuncID)
105 exitFuncID, err = svr.EventOn(apiv1.ExecExitEvent, exitFunc)
107 common.APIError(c, err.Error())
111 // Forward back command to right server
112 response, err := svr.SendCommand(cmd, data)
114 common.APIError(c, err.Error())
119 body, err := ioutil.ReadAll(response.Body)
121 common.APIError(c, "Cannot read response body")
124 c.JSON(http.StatusOK, string(body))