aboutsummaryrefslogtreecommitdiffstats
path: root/lib/apiv1
diff options
context:
space:
mode:
authorSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-27 23:10:33 +0200
committerSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-27 23:10:33 +0200
commit330cffa06c3efea42a42ca8e908b8b24db6bba3f (patch)
tree84e444d3ab66a1b8334c9c94f853a384ae34de84 /lib/apiv1
parent0805255ee01103c500f2aae8845850b3dae6a0b6 (diff)
Wait folder insync before sending exit event.
By default wait folder insync. Set ExitImmediate param to true to send exit event immedialty without waiting folder synchronization.
Diffstat (limited to 'lib/apiv1')
-rw-r--r--lib/apiv1/exec.go42
-rw-r--r--lib/apiv1/make.go27
2 files changed, 59 insertions, 10 deletions
diff --git a/lib/apiv1/exec.go b/lib/apiv1/exec.go
index 895807d..675f6fb 100644
--- a/lib/apiv1/exec.go
+++ b/lib/apiv1/exec.go
@@ -12,13 +12,14 @@ import (
// ExecArgs JSON parameters of /exec command
type ExecArgs struct {
- ID string `json:"id" binding:"required"`
- SdkID string `json:"sdkid"` // sdk ID to use for setting env
- Cmd string `json:"cmd" binding:"required"`
- Args []string `json:"args"`
- Env []string `json:"env"`
- RPath string `json:"rpath"` // relative path into project
- CmdTimeout int `json:"timeout"` // command completion timeout in Second
+ ID string `json:"id" binding:"required"`
+ SdkID string `json:"sdkid"` // sdk ID to use for setting env
+ Cmd string `json:"cmd" binding:"required"`
+ Args []string `json:"args"`
+ Env []string `json:"env"`
+ RPath string `json:"rpath"` // relative path into project
+ ExitImmediate bool `json:"exitImmediate"` // when true, exit event sent immediately when command exited (IOW, don't wait file synchronization)
+ CmdTimeout int `json:"timeout"` // command completion timeout in Second
}
// ExecOutMsg Message send on each output (stdout+stderr) of executed command
@@ -122,7 +123,7 @@ func (s *APIService) execCmd(c *gin.Context) {
}
// Define callback for output
- eCB := func(sid string, id int, code int, err error) {
+ eCB := func(sid string, id int, code int, err error, data *map[string]interface{}) {
s.log.Debugf("Command [Cmd ID %d] exited: code %d, error: %v", id, code, err)
// IO socket can be nil when disconnected
@@ -132,6 +133,30 @@ func (s *APIService) execCmd(c *gin.Context) {
return
}
+ // Retrieve project ID and RootPath
+ prjID := (*data)["ID"].(string)
+ exitImm := (*data)["ExitImmediate"].(bool)
+
+ // XXX - workaround to be sure that Syncthing detected all changes
+ if err := s.mfolder.ForceSync(prjID); err != nil {
+ s.log.Errorf("Error while syncing folder %s: %v", prjID, err)
+ }
+ if !exitImm {
+ // Wait end of file sync
+ // FIXME pass as argument
+ tmo := 60
+ for t := tmo; t > 0; t-- {
+ s.log.Debugf("Wait file insync for %s (%d/%d)", prjID, t, tmo)
+ if sync, err := s.mfolder.IsFolderInSync(prjID); sync || err != nil {
+ if err != nil {
+ s.log.Errorf("ERROR IsFolderInSync (%s): %v", prjID, err)
+ }
+ break
+ }
+ time.Sleep(time.Second)
+ }
+ }
+
// FIXME replace by .BroadcastTo a room
e := (*so).Emit(ExecExitEvent, ExecExitMsg{
CmdID: strconv.Itoa(id),
@@ -164,6 +189,7 @@ func (s *APIService) execCmd(c *gin.Context) {
data := make(map[string]interface{})
data["ID"] = prj.ID
data["RootPath"] = prj.RootPath
+ data["ExitImmediate"] = args.ExitImmediate
err := common.ExecPipeWs(cmd, args.Env, sop, sess.ID, cmdID, execTmo, s.log, oCB, eCB, &data)
if err != nil {
diff --git a/lib/apiv1/make.go b/lib/apiv1/make.go
index 098e41c..d015d2b 100644
--- a/lib/apiv1/make.go
+++ b/lib/apiv1/make.go
@@ -2,6 +2,7 @@ package apiv1
import (
"net/http"
+ "strings"
"time"
@@ -95,7 +96,16 @@ func (s *APIService) buildMake(c *gin.Context) {
s.log.Infof("%s not emitted: WS closed - sid: %s - msg id:%d", MakeOutEvent, sid, id)
return
}
- s.log.Debugf("%s emitted - WS sid %s - id:%d", MakeOutEvent, sid, id)
+
+ // Retrieve project ID and RootPath
+ prjID := (*data)["ID"].(string)
+ prjRootPath := (*data)["RootPath"].(string)
+
+ // Cleanup any references to internal rootpath in stdout & stderr
+ stdout = strings.Replace(stdout, prjRootPath, "", -1)
+ stderr = strings.Replace(stderr, prjRootPath, "", -1)
+
+ s.log.Debugf("%s emitted - WS sid %s - id:%d - prjID:%s", MakeOutEvent, sid, id, prjID)
// FIXME replace by .BroadcastTo a room
err := (*so).Emit(MakeOutEvent, MakeOutMsg{
@@ -110,7 +120,7 @@ func (s *APIService) buildMake(c *gin.Context) {
}
// Define callback for output
- eCB := func(sid string, id int, code int, err error) {
+ eCB := func(sid string, id int, code int, err error, data *map[string]interface{}) {
s.log.Debugf("Command [Cmd ID %d] exited: code %d, error: %v", id, code, err)
// IO socket can be nil when disconnected
@@ -120,6 +130,14 @@ func (s *APIService) buildMake(c *gin.Context) {
return
}
+ // Retrieve project ID and RootPath
+ prjID := (*data)["ID"].(string)
+
+ // XXX - workaround to be sure that Syncthing detected all changes
+ if err := s.mfolder.ForceSync(prjID); err != nil {
+ s.log.Errorf("Error while syncing folder %s: %v", prjID, err)
+ }
+
// FIXME replace by .BroadcastTo a room
e := (*so).Emit(MakeExitEvent, MakeExitMsg{
CmdID: strconv.Itoa(id),
@@ -148,6 +166,11 @@ func (s *APIService) buildMake(c *gin.Context) {
}
s.log.Debugf("Execute [Cmd ID %d]: %v", cmdID, cmd)
+
+ data := make(map[string]interface{})
+ data["ID"] = prj.ID
+ data["RootPath"] = prj.RootPath
+
err := common.ExecPipeWs(cmd, args.Env, sop, sess.ID, cmdID, execTmo, s.log, oCB, eCB, nil)
if err != nil {
common.APIError(c, err.Error())