8 "github.com/gin-gonic/gin"
9 common "github.com/iotbzh/xds-common/golib"
10 uuid "github.com/satori/go.uuid"
13 // ExecArgs Only define used fields
14 type ExecArgs struct {
15 ID string `json:"id" binding:"required"`
16 CmdID string `json:"cmdID"` // command unique ID
21 // ExecCmd executes remotely a command
22 func (s *APIService) execCmd(c *gin.Context) {
23 s._execRequest("/exec", c)
26 // execSignalCmd executes remotely a command
27 func (s *APIService) execSignalCmd(c *gin.Context) {
28 s._execRequest("/signal", c)
31 func (s *APIService) _execRequest(cmd string, c *gin.Context) {
32 data, err := c.GetRawData()
34 common.APIError(c, err.Error())
38 // XXX - we cannot use c.BindJSON, so directly unmarshall it
39 // (see https://github.com/gin-gonic/gin/issues/1078)
40 if err := json.Unmarshal(data, &args); err != nil {
41 common.APIError(c, "Invalid arguments")
45 // First get Project ID to retrieve Server ID and send command to right server
51 prj := s.projects.Get(id)
53 common.APIError(c, "Unknown id")
57 svr := (*prj).GetServer()
59 common.APIError(c, "Cannot identify XDS Server")
63 // Retrieve session info
64 sess := s.sessions.Get(c)
66 common.APIError(c, "Unknown sessions")
71 common.APIError(c, "Websocket not established")
75 // Forward XDSServer WS events to client WS
76 // TODO removed static event name list and get it from XDSServer
80 "exec:inferior-input",
81 "exec:inferior-output",
84 fwdFuncID := []uuid.UUID{}
85 for _, evName := range evtList {
87 fwdFunc := func(evData interface{}) {
88 // Forward event to Client/Dashboard
91 id, err := svr.EventOn(evN, fwdFunc)
93 common.APIError(c, err.Error())
96 fwdFuncID = append(fwdFuncID, id)
99 // Handle Exit event separately to cleanup registered listener
100 var exitFuncID uuid.UUID
101 exitFunc := func(evData interface{}) {
102 so.Emit("exec:exit", evData)
105 for i, evName := range evtList {
106 svr.EventOff(evName, fwdFuncID[i])
108 svr.EventOff("exec:exit", exitFuncID)
110 exitFuncID, err = svr.EventOn("exec:exit", exitFunc)
112 common.APIError(c, err.Error())
116 // Forward back command to right server
117 response, err := svr.SendCommand(cmd, data)
119 common.APIError(c, err.Error())
124 body, err := ioutil.ReadAll(response.Body)
126 common.APIError(c, "Cannot read response body")
129 c.JSON(http.StatusOK, string(body))