"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) {
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 {
}
// 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")
// 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
// 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
return
}
c.JSON(http.StatusOK, string(body))
-
}