summaryrefslogtreecommitdiffstats
path: root/lib/agent/apiv1-exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/agent/apiv1-exec.go')
-rw-r--r--lib/agent/apiv1-exec.go66
1 files changed, 49 insertions, 17 deletions
diff --git a/lib/agent/apiv1-exec.go b/lib/agent/apiv1-exec.go
index 83ec7aa..37070f7 100644
--- a/lib/agent/apiv1-exec.go
+++ b/lib/agent/apiv1-exec.go
@@ -7,13 +7,17 @@ import (
"github.com/gin-gonic/gin"
common "github.com/iotbzh/xds-common/golib"
+ uuid "github.com/satori/go.uuid"
)
-// Only define useful fields
+// ExecArgs Only define used fields
type ExecArgs struct {
- ID string `json:"id" binding:"required"`
+ ID string `json:"id" binding:"required"`
+ CmdID string `json:"cmdID"` // command unique ID
}
+var execCmdID = 1
+
// ExecCmd executes remotely a command
func (s *APIService) execCmd(c *gin.Context) {
s._execRequest("/exec", c)
@@ -24,24 +28,26 @@ func (s *APIService) execSignalCmd(c *gin.Context) {
s._execRequest("/signal", c)
}
-func (s *APIService) _execRequest(url string, c *gin.Context) {
+func (s *APIService) _execRequest(cmd string, c *gin.Context) {
data, err := c.GetRawData()
if err != nil {
common.APIError(c, err.Error())
}
+ 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
+ }
+
// 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")
@@ -68,21 +74,47 @@ func (s *APIService) _execRequest(url string, c *gin.Context) {
// Forward XDSServer WS events to client WS
// TODO removed static event name list and get it from XDSServer
- for _, evName := range []string{
+ evtList := []string{
"exec:input",
"exec:output",
- "exec:exit",
"exec:inferior-input",
"exec:inferior-output",
- } {
+ }
+ so := *sock
+ fwdFuncID := []uuid.UUID{}
+ for _, evName := range evtList {
evN := evName
- svr.EventOn(evN, func(evData interface{}) {
- (*sock).Emit(evN, evData)
- })
+ fwdFunc := func(evData interface{}) {
+ // Forward event to Client/Dashboard
+ so.Emit(evN, evData)
+ }
+ id, err := svr.EventOn(evN, fwdFunc)
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+ fwdFuncID = append(fwdFuncID, id)
+ }
+
+ // Handle Exit event separately to cleanup registered listener
+ var exitFuncID uuid.UUID
+ exitFunc := func(evData interface{}) {
+ so.Emit("exec:exit", evData)
+
+ // cleanup listener
+ for i, evName := range evtList {
+ svr.EventOff(evName, fwdFuncID[i])
+ }
+ svr.EventOff("exec:exit", exitFuncID)
+ }
+ exitFuncID, err = svr.EventOn("exec:exit", exitFunc)
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
}
// Forward back command to right server
- response, err := svr.HTTPPostBody(url, string(data))
+ response, err := svr.SendCommand(cmd, data)
if err != nil {
common.APIError(c, err.Error())
return