X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=lib%2Fagent%2Fapiv1-exec.go;h=c1992675df7688f7308b55cb9271cd6b4aac133b;hb=02aec942b44eecd2ea9b311bb4ba2d60cce21e9a;hp=37070f7afab871cbef6dbf3ad447e6d9aaa3f064;hpb=4695555e178bcabe54c5bf82117c9c4cef5440b5;p=src%2Fxds%2Fxds-agent.git diff --git a/lib/agent/apiv1-exec.go b/lib/agent/apiv1-exec.go index 37070f7..c199267 100644 --- a/lib/agent/apiv1-exec.go +++ b/lib/agent/apiv1-exec.go @@ -6,17 +6,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" uuid "github.com/satori/go.uuid" ) -// ExecArgs Only define used fields -type ExecArgs struct { - ID string `json:"id" binding:"required"` - CmdID string `json:"cmdID"` // command unique ID -} - var execCmdID = 1 +var fwdFuncID []uuid.UUID // ExecCmd executes remotely a command func (s *APIService) execCmd(c *gin.Context) { @@ -34,7 +30,7 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { common.APIError(c, err.Error()) } - args := ExecArgs{} + args := apiv1.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 { @@ -43,11 +39,15 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { } // First get Project ID to retrieve Server ID and send command to right server - id := c.Param("id") - if id == "" { - id = args.ID + iid := c.Param("id") + if iid == "" { + iid = args.ID + } + id, err := s.projects.ResolveID(iid) + if err != nil { + common.APIError(c, err.Error()) + return } - prj := s.projects.Get(id) if prj == nil { common.APIError(c, "Unknown id") @@ -75,20 +75,28 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { // Forward XDSServer WS events to client WS // TODO removed static event name list and get it from XDSServer evtList := []string{ - "exec:input", - "exec:output", - "exec:inferior-input", - "exec:inferior-output", + apiv1.ExecInEvent, + apiv1.ExecOutEvent, + apiv1.ExecInferiorInEvent, + apiv1.ExecInferiorOutEvent, } - so := *sock - fwdFuncID := []uuid.UUID{} + for _, evName := range evtList { evN := evName - fwdFunc := func(evData interface{}) { + fwdFunc := func(pData interface{}, evData interface{}) error { + sid := pData.(string) + // IO socket can be nil when disconnected + so := s.sessions.IOSocketGet(sid) + if so == nil { + s.Log.Infof("%s not emitted: WS closed (sid:%s)", evN, sid) + return nil + } + // Forward event to Client/Dashboard - so.Emit(evN, evData) + (*so).Emit(evN, evData) + return nil } - id, err := svr.EventOn(evN, fwdFunc) + id, err := svr.EventOn(evN, sess.ID, fwdFunc) if err != nil { common.APIError(c, err.Error()) return @@ -98,16 +106,28 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { // Handle Exit event separately to cleanup registered listener var exitFuncID uuid.UUID - exitFunc := func(evData interface{}) { - so.Emit("exec:exit", evData) + exitFunc := func(pData interface{}, evData interface{}) error { + evN := apiv1.ExecExitEvent + sid := pData.(string) + + // IO socket can be nil when disconnected + so := s.sessions.IOSocketGet(sid) + if so == nil { + s.Log.Infof("%s not emitted: WS closed (sid:%s)", evN, sid) + return nil + } + + (*so).Emit(evN, evData) // cleanup listener for i, evName := range evtList { svr.EventOff(evName, fwdFuncID[i]) } - svr.EventOff("exec:exit", exitFuncID) + svr.EventOff(evN, exitFuncID) + + return nil } - exitFuncID, err = svr.EventOn("exec:exit", exitFunc) + exitFuncID, err = svr.EventOn(apiv1.ExecExitEvent, sess.ID, exitFunc) if err != nil { common.APIError(c, err.Error()) return @@ -127,5 +147,4 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { return } c.JSON(http.StatusOK, string(body)) - }