2 * Copyright (C) 2017-2018 "IoT.bzh"
3 * Author Sebastien Douheret <sebastien@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
26 "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent.git/lib/xaapiv1"
27 "github.com/urfave/cli"
30 func initCmdExec(cmdDef *[]cli.Command) {
31 *cmdDef = append(*cmdDef, cli.Command{
33 Usage: "execute a command in XDS",
38 EnvVar: "XDS_PROJECT_ID",
39 Usage: "project ID you want to build (mandatory variable)",
44 Usage: "relative path into project",
49 Usage: "Cross Sdk ID to use to build project",
55 func execCmd(ctx *cli.Context) error {
56 prjID := ctx.String("id")
57 rPath := ctx.String("rpath")
58 sdkid := ctx.String("sdkid")
60 // Check mandatory args
62 return cli.NewExitError("project id must be set (see --id option)", 1)
65 argsCommand := make([]string, len(ctx.Args()))
66 copy(argsCommand, ctx.Args())
67 Log.Infof("Execute: /exec %v", argsCommand)
69 // Log useful info for debugging
70 ver := xaapiv1.XDSVersion{}
72 Log.Infof("XDS version: %v", ver)
74 // Process Socket IO events
75 type exitResult struct {
79 exitChan := make(chan exitResult, 1)
81 IOSkClient.On("disconnection", func(err error) {
82 Log.Debugf("WS disconnection event with err: %v\n", err)
83 exitChan <- exitResult{err, 2}
86 outFunc := func(timestamp, stdout, stderr string) {
88 if ctx.Bool("WithTimestamp") {
92 fmt.Printf("%s%s", tm, stdout)
95 fmt.Fprintf(os.Stderr, "%s%s", tm, stderr)
99 IOSkClient.On(xaapiv1.ExecOutEvent, func(ev xaapiv1.ExecOutMsg) {
100 outFunc(ev.Timestamp, ev.Stdout, ev.Stderr)
103 IOSkClient.On(xaapiv1.ExecExitEvent, func(ev xaapiv1.ExecExitMsg) {
104 exitChan <- exitResult{ev.Error, ev.Code}
107 IOSkClient.On(xaapiv1.EVTProjectChange, func(ev xaapiv1.EventMsg) {
108 prj, _ := ev.DecodeProjectConfig()
109 Log.Infof("Event %v (%v): %v", ev.Type, ev.Time, prj)
111 evReg := xaapiv1.EventRegisterArgs{Name: xaapiv1.EVTProjectChange}
112 if err := HTTPCli.Post("/events/register", &evReg, nil); err != nil {
113 return cli.NewExitError(err, 1)
116 // Retrieve the project definition
117 prj := xaapiv1.ProjectConfig{}
118 if err := HTTPCli.Get("/projects/"+prjID, &prj); err != nil {
119 return cli.NewExitError(err, 1)
122 // Auto setup rPath if needed
124 cwd, err := os.Getwd()
126 fldRp := prj.ClientPath
127 if !strings.HasPrefix(fldRp, "/") {
130 Log.Debugf("Try to auto-setup rPath: cwd=%s ; ClientPath=%s", cwd, fldRp)
131 if sp := strings.SplitAfter(cwd, fldRp); len(sp) == 2 {
132 rPath = strings.Trim(sp[1], "/")
133 Log.Debugf("Auto-setup rPath to: '%s'", rPath)
139 Log.Debugf("Command env: %v", EnvConfFileMap)
141 for k, v := range EnvConfFileMap {
142 env = append(env, k+"="+v)
145 // Send build command
146 args := xaapiv1.ExecArgs{
149 Cmd: strings.Trim(argsCommand[0], " "),
150 Args: argsCommand[1:],
156 LogPost("POST /exec %v", args)
157 if err := HTTPCli.Post("/exec", args, nil); err != nil {
158 return cli.NewExitError(err.Error(), 1)
163 case res := <-IOSkClient.ServerDiscoChan:
164 Log.Debugf("XDS Server disconnected %v", res)
165 return cli.NewExitError(res.error, res.code)
167 case res := <-exitChan:
170 Log.Debugln("Exit successfully")
172 if res.error != nil {
173 Log.Debugln("Exit with ERROR: ", res.error.Error())
174 errStr = res.error.Error()
176 return cli.NewExitError(errStr, res.code)