X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=lib%2Fagent%2Fapiv1-exec.go;fp=lib%2Fagent%2Fapiv1-exec.go;h=83ec7aa008cfea09cc93ff91d50260cbd59bc4d4;hb=97ca1f277dc8b6973d6fa67add5593a9c395ce60;hp=0000000000000000000000000000000000000000;hpb=12a20d0905b0d3e7e0f4c9ec8ee619f683256d71;p=src%2Fxds%2Fxds-agent.git diff --git a/lib/agent/apiv1-exec.go b/lib/agent/apiv1-exec.go new file mode 100644 index 0000000..83ec7aa --- /dev/null +++ b/lib/agent/apiv1-exec.go @@ -0,0 +1,99 @@ +package agent + +import ( + "encoding/json" + "io/ioutil" + "net/http" + + "github.com/gin-gonic/gin" + common "github.com/iotbzh/xds-common/golib" +) + +// Only define useful fields +type ExecArgs struct { + ID string `json:"id" binding:"required"` +} + +// ExecCmd executes remotely a command +func (s *APIService) execCmd(c *gin.Context) { + s._execRequest("/exec", c) +} + +// execSignalCmd executes remotely a command +func (s *APIService) execSignalCmd(c *gin.Context) { + s._execRequest("/signal", c) +} + +func (s *APIService) _execRequest(url string, c *gin.Context) { + data, err := c.GetRawData() + if err != nil { + common.APIError(c, err.Error()) + } + + // First get Project ID to retrieve Server ID and send command to right server + id := c.Param("id") + if id == "" { + args := ExecArgs{} + // XXX - we cannot use c.BindJSON, so directly unmarshall it + // (see https://github.com/gin-gonic/gin/issues/1078) + if err := json.Unmarshal(data, &args); err != nil { + common.APIError(c, "Invalid arguments") + return + } + id = args.ID + } + prj := s.projects.Get(id) + if prj == nil { + common.APIError(c, "Unknown id") + return + } + + svr := (*prj).GetServer() + if svr == nil { + common.APIError(c, "Cannot identify XDS Server") + return + } + + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + sock := sess.IOSocket + if sock == nil { + common.APIError(c, "Websocket not established") + return + } + + // Forward XDSServer WS events to client WS + // TODO removed static event name list and get it from XDSServer + for _, evName := range []string{ + "exec:input", + "exec:output", + "exec:exit", + "exec:inferior-input", + "exec:inferior-output", + } { + evN := evName + svr.EventOn(evN, func(evData interface{}) { + (*sock).Emit(evN, evData) + }) + } + + // Forward back command to right server + response, err := svr.HTTPPostBody(url, string(data)) + if err != nil { + common.APIError(c, err.Error()) + return + } + + // Decode response + body, err := ioutil.ReadAll(response.Body) + if err != nil { + common.APIError(c, "Cannot read response body") + return + } + c.JSON(http.StatusOK, string(body)) + +}