src/main.go

changeset 8
2e9b3f85c949
parent 6
66cb1937078f
child 9
eef1439666f7
equal deleted inserted replaced
7:ec0d28411e6a 8:2e9b3f85c949
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "encoding/json" 5 "encoding/json"
6 "encoding/xml" 6 "encoding/xml"
7 "errors"
7 "fmt" 8 "fmt"
8 "log" 9 "log"
9 "os" 10 "os"
10 "os/exec" 11 "os/exec"
11 "path" 12 "path"
24 25
25 type BuildEnv struct { 26 type BuildEnv struct {
26 Name string `xml:"name,attr"` 27 Name string `xml:"name,attr"`
27 Host string `xml:"host"` 28 Host string `xml:"host"`
28 User string `xml:"user"` 29 User string `xml:"user"`
30 OS string `xml:"os"`
29 } 31 }
30 32
31 type Build struct { 33 type Build struct {
32 Name string `xml:"name,attr"` 34 Name string `xml:"name,attr"`
33 IsPlatform string `xml:"isplatform,attr"` 35 IsPlatform string `xml:"isplatform,attr"`
281 if !host_is_available(env.Host) { 283 if !host_is_available(env.Host) {
282 log.Print("skip unavailable host ", env.Host) 284 log.Print("skip unavailable host ", env.Host)
283 continue 285 continue
284 } 286 }
285 287
286 // steps: 288 // exec posix or windows build script
287 // upload build.tar.gz 289 var result BuildEnvResult
288 // extract build.tar.gz on the buildenv host and run build.sh 290 var err error
289 291 if env.OS == "windows" {
290 // upload using scp 292 result, err = exec_win_buildenv(config, repo, &env, tmp_dir)
291 cmd := exec.Command("scp", path.Join(tmp_dir, "build.tar.gz"), env.Host+":") 293 } else {
292 log.Print("scp: ", cmd.Args) 294 result, err = exec_posix_buildenv(config, repo, &env, tmp_dir)
293 if err := cmd.Run(); err != nil { 295 }
294 log.Print("cannot copy build env to ", env.Host) 296 if err != nil {
297 log.Print("buildenv exec error: ", err)
295 continue 298 continue
296 } 299 }
297 300
298 // run build.sh 301 buildResults = append(buildResults, result)
299 build_dir := "build"
300 remote_command := fmt.Sprintf("sh -c 'rm -Rf %[1]s; mkdir -p %[1]s; gzip -dc build.tar.gz | tar xf - -C %[1]s ; (cd %[1]s; ./build.sh)'", build_dir)
301 log.Printf("host: %s: command: %s", env.Host, remote_command)
302
303 var outb, errb bytes.Buffer
304 cmd = exec.Command("ssh", "-t", env.Host, remote_command)
305 cmd.Stdout = &outb
306 cmd.Stderr = &errb
307 err := cmd.Run()
308 log.Printf("host: %s: stdout: %s", env.Host, outb.String())
309 if err != nil {
310 log.Print("cannot execute build.sh on buildenv host ", env.Host)
311 log.Print("stderr: ", errb.String())
312 continue
313 }
314
315 // download result
316 cmd.Stdout = nil
317 cmd.Stderr = nil
318 cmd = exec.Command("scp", "-r", env.Host+":"+build_dir+"/result", tmp_dir)
319 log.Print("scp: ", cmd.Args)
320 if err := cmd.Run(); err != nil {
321 log.Print("cannot get result from buildenv")
322 continue
323 }
324
325 // parse result
326 resultData, err := os.ReadFile(path.Join(tmp_dir, "result/result.json"))
327 if err != nil {
328 log.Print("cannot read result from buildenv")
329 continue
330 }
331
332 var results []Result
333 if err := json.Unmarshal(resultData, &results); err != nil {
334 log.Print("cannot parse result.json")
335 continue
336 }
337
338 // store the actual Build pointer in the result
339 for i := range results {
340 results[i].Build = get_build(repo.Build, results[i].Id)
341 }
342 log.Print("buildenv finished ", env.Name)
343
344 envResult := BuildEnvResult{Env: &env, Results: results}
345 buildResults = append(buildResults, envResult)
346 } 302 }
347 303
348 return buildResults 304 return buildResults
305 }
306
307 func exec_posix_buildenv(config *Config, repo *Repository, env *BuildEnv, tmp_dir string) (BuildEnvResult, error) {
308 result := BuildEnvResult{}
309
310 // steps:
311 // upload build.tar.gz
312 // extract build.tar.gz on the buildenv host and run build.sh
313
314 // upload using scp
315 cmd := exec.Command("scp", path.Join(tmp_dir, "build.tar.gz"), env.Host+":")
316 log.Print("scp: ", cmd.Args)
317 if err := cmd.Run(); err != nil {
318 return result, errors.New("cannot copy build env to " + env.Host)
319 }
320
321 // run build.sh
322 build_dir := "build"
323 remote_command := fmt.Sprintf("sh -c 'rm -Rf %[1]s; mkdir -p %[1]s; gzip -dc build.tar.gz | tar xf - -C %[1]s ; (cd %[1]s; ./build.sh)'", build_dir)
324 log.Printf("host: %s: command: %s", env.Host, remote_command)
325
326 var outb, errb bytes.Buffer
327 cmd = exec.Command("ssh", "-t", env.Host, remote_command)
328 cmd.Stdout = &outb
329 cmd.Stderr = &errb
330 err := cmd.Run()
331 log.Printf("host: %s: stdout: %s", env.Host, outb.String())
332 if err != nil {
333 log.Print("stderr: ", errb.String())
334 return result, errors.New("cannot execute build.sh on buildenv host " + env.Host)
335 }
336
337 // download result
338 cmd.Stdout = nil
339 cmd.Stderr = nil
340 cmd = exec.Command("scp", "-r", env.Host+":"+build_dir+"/result", tmp_dir)
341 log.Print("scp: ", cmd.Args)
342 if err := cmd.Run(); err != nil {
343 return result, errors.New("cannot get result from buildenv")
344 }
345
346 // parse result
347 resultData, err := os.ReadFile(path.Join(tmp_dir, "result/result.json"))
348 if err != nil {
349 return result, errors.New("cannot read result from buildenv")
350 }
351
352 var results []Result
353 if err := json.Unmarshal(resultData, &results); err != nil {
354 return result, errors.New("cannot parse result.json")
355 }
356
357 // store the actual Build pointer in the result
358 for i := range results {
359 results[i].Build = get_build(repo.Build, results[i].Id)
360 }
361 log.Print("buildenv finished ", env.Name)
362
363 return BuildEnvResult{Env: env, Results: results}, nil
364 }
365
366 func exec_win_buildenv(config *Config, repo *Repository, env *BuildEnv, tmp_dir string) (BuildEnvResult, error) {
367 result := BuildEnvResult{}
368 return result, nil
349 } 369 }
350 370
351 func get_commit_info(repo_dir string) *Commit { 371 func get_commit_info(repo_dir string) *Commit {
352 var outb, errb bytes.Buffer 372 var outb, errb bytes.Buffer
353 373

mercurial