diff options
Diffstat (limited to 'lib/xdsserver/apiv1-make.go')
-rw-r--r-- | lib/xdsserver/apiv1-make.go | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/lib/xdsserver/apiv1-make.go b/lib/xdsserver/apiv1-make.go new file mode 100644 index 0000000..bcb4d95 --- /dev/null +++ b/lib/xdsserver/apiv1-make.go @@ -0,0 +1,214 @@ +package xdsserver + +import ( + "github.com/gin-gonic/gin" + common "github.com/iotbzh/xds-common/golib" +) + +/* TODO: Deprecated - should be removed +// MakeArgs is the parameters (json format) of /make command +type MakeArgs struct { + ID string `json:"id"` + SdkID string `json:"sdkID"` // sdk ID to use for setting env + CmdID string `json:"cmdID"` // command unique ID + Args []string `json:"args"` // args to pass to make command + 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 +} + +// MakeOutMsg Message send on each output (stdout+stderr) of make command +type MakeOutMsg struct { + CmdID string `json:"cmdID"` + Timestamp string `json:"timestamp"` + Stdout string `json:"stdout"` + Stderr string `json:"stderr"` +} + +// MakeExitMsg Message send on make command exit +type MakeExitMsg struct { + CmdID string `json:"cmdID"` + Timestamp string `json:"timestamp"` + Code int `json:"code"` + Error error `json:"error"` +} + +// MakeOutEvent Event send in WS when characters are received on stdout/stderr +const MakeOutEvent = "make:output" + +// MakeExitEvent Event send in WS when command exited +const MakeExitEvent = "make:exit" + +var makeCommandID = 1 +*/ + +func (s *APIService) buildMake(c *gin.Context) { + common.APIError(c, "/make route is not longer supported, use /exec instead") + + /* + var args MakeArgs + + if c.BindJSON(&args) != nil { + common.APIError(c, "Invalid arguments") + return + } + + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + sop := sess.IOSocket + if sop == nil { + common.APIError(c, "Websocket not established") + return + } + + // Allow to pass id in url (/make/:id) or as JSON argument + idArg := c.Param("id") + if idArg == "" { + idArg = args.ID + } + if idArg == "" { + common.APIError(c, "Invalid id") + return + } + id, err := s.mfolders.ResolveID(idArg) + if err != nil { + common.APIError(c, err.Error()) + return + } + pf := s.mfolders.Get(id) + if pf == nil { + common.APIError(c, "Unknown id") + return + } + folder := *pf + prj := folder.GetConfig() + + execTmo := args.CmdTimeout + if execTmo == 0 { + // TODO get default timeout from config.json file + execTmo = 24 * 60 * 60 // 1 day + } + + // TODO merge all code below with exec.go + + // Define callback for output + var oCB common.EmitOutputCB + oCB = func(sid string, cmdID string, stdout, stderr string, data *map[string]interface{}) { + // 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 - msg id:%s", MakeOutEvent, sid, cmdID) + return + } + + // 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{ + CmdID: cmdID, + Timestamp: time.Now().String(), + Stdout: stdout, + Stderr: stderr, + }) + if err != nil { + s.log.Errorf("WS Emit : %v", err) + } + } + + // Define callback for output + eCB := func(sid string, cmdID string, code int, err error, data *map[string]interface{}) { + s.log.Debugf("Command [Cmd ID %s] exited: code %d, error: %v", cmdID, code, err) + + // IO socket can be nil when disconnected + so := s.sessions.IOSocketGet(sid) + if so == nil { + s.log.Infof("%s not emitted - WS closed (id:%s", MakeExitEvent, cmdID) + 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.mfolders.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.mfolders.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(MakeExitEvent, MakeExitMsg{ + CmdID: id, + Timestamp: time.Now().String(), + Code: code, + Error: err, + }) + if e != nil { + s.log.Errorf("WS Emit : %v", e) + } + } + + // Unique ID for each commands + if args.CmdID == "" { + args.CmdID = s.cfg.ServerUID[:18] + "_" + strconv.Itoa(makeCommandID) + makeCommandID++ + } + cmd := []string{} + + // Retrieve env command regarding Sdk ID + if envCmd := s.sdks.GetEnvCmd(args.SdkID, prj.DefaultSdk); len(envCmd) > 0 { + cmd = append(cmd, envCmd...) + cmd = append(cmd, "&&") + } + + cmd = append(cmd, "cd", folder.GetFullPath(args.RPath), "&&", "make") + if len(args.Args) > 0 { + cmd = append(cmd, args.Args...) + } + + s.log.Debugf("Execute [Cmd ID %d]: %v", args.CmdID, cmd) + + 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, args.CmdID, execTmo, s.log, oCB, eCB, &data) + if err != nil { + common.APIError(c, err.Error()) + return + } + + c.JSON(http.StatusOK, + gin.H{ + "status": "OK", + "cmdID": args.CmdID, + }) + */ +} |