8 "github.com/iotbzh/xds-agent/lib/apiv1"
9 "github.com/urfave/cli"
12 func initCmdExec(cmdDef *[]cli.Command) {
13 *cmdDef = append(*cmdDef, cli.Command{
15 Usage: "execute a command in XDS",
20 EnvVar: "XDS_PROJECT_ID",
21 Usage: "project ID you want to build (mandatory variable)",
26 Usage: "relative path into project",
31 Usage: "Cross Sdk ID to use to build project",
37 func exec(ctx *cli.Context) error {
38 prjID := ctx.String("id")
39 rPath := ctx.String("rPath")
40 sdkid := ctx.String("sdkid")
42 // Check mandatory args
44 return cli.NewExitError("project id must be set (see --id option)", 1)
47 argsCommand := make([]string, len(ctx.Args()))
48 copy(argsCommand, ctx.Args())
49 Log.Infof("Execute: /exec %v", argsCommand)
51 // Log useful info for debugging
52 ver := apiv1.XDSVersion{}
54 Log.Infof("XDS version: %v", ver)
56 // Process Socket IO events
57 type exitResult struct {
61 exitChan := make(chan exitResult, 1)
63 IOsk.On("disconnection", func(err error) {
64 Log.Debugf("WS disconnection event with err: %v\n", err)
65 exitChan <- exitResult{err, 2}
68 outFunc := func(timestamp, stdout, stderr string) {
70 if ctx.Bool("WithTimestamp") {
74 fmt.Printf("%s%s", tm, stdout)
77 fmt.Fprintf(os.Stderr, "%s%s", tm, stderr)
81 IOsk.On(apiv1.ExecOutEvent, func(ev apiv1.ExecOutMsg) {
82 outFunc(ev.Timestamp, ev.Stdout, ev.Stderr)
85 IOsk.On(apiv1.ExecExitEvent, func(ev apiv1.ExecExitMsg) {
86 exitChan <- exitResult{ev.Error, ev.Code}
89 IOsk.On(apiv1.EVTProjectChange, func(ev apiv1.EventMsg) {
90 prj, _ := ev.DecodeProjectConfig()
91 Log.Infof("Event %v (%v): %v", ev.Type, ev.Time, prj)
93 evReg := apiv1.EventRegisterArgs{Name: apiv1.EVTProjectChange}
94 if err := HTTPCli.Post("/events/register", &evReg, nil); err != nil {
95 return cli.NewExitError(err, 1)
98 // Retrieve the project definition
99 prj := apiv1.ProjectConfig{}
100 if err := HTTPCli.Get("/projects/"+prjID, &prj); err != nil {
101 return cli.NewExitError(err, 1)
104 // Auto setup rPath if needed
106 cwd, err := os.Getwd()
108 fldRp := prj.ClientPath
109 if !strings.HasPrefix(fldRp, "/") {
112 Log.Debugf("Try to auto-setup rPath: cwd=%s ; ClientPath=%s", cwd, fldRp)
113 if sp := strings.SplitAfter(cwd, fldRp); len(sp) == 2 {
114 rPath = strings.Trim(sp[1], "/")
115 Log.Debugf("Auto-setup rPath to: '%s'", rPath)
121 Log.Debugf("Command env: %v", EnvConfFileMap)
123 for k, v := range EnvConfFileMap {
124 env = append(env, k+"="+v)
127 // Send build command
128 args := apiv1.ExecArgs{
131 Cmd: strings.Trim(argsCommand[0], " "),
132 Args: argsCommand[1:],
138 LogPost("POST /exec %v", args)
139 if err := HTTPCli.Post("/exec", args, nil); err != nil {
140 return cli.NewExitError(err.Error(), 1)
145 case res := <-exitChan:
148 Log.Debugln("Exit successfully")
150 if res.error != nil {
151 Log.Debugln("Exit with ERROR: ", res.error.Error())
152 errStr = res.error.Error()
154 return cli.NewExitError(errStr, res.code)