| OLD | NEW |
| 1 // Utility that contains methods for both CT master and worker scripts. | 1 // Utility that contains methods for both CT master and worker scripts. |
| 2 package util | 2 package util |
| 3 | 3 |
| 4 import ( | 4 import ( |
| 5 "bufio" | 5 "bufio" |
| 6 "fmt" | 6 "fmt" |
| 7 "io" |
| 7 "io/ioutil" | 8 "io/ioutil" |
| 8 "os" | 9 "os" |
| 9 "os/exec" | |
| 10 "path/filepath" | 10 "path/filepath" |
| 11 "strconv" | 11 "strconv" |
| 12 "strings" | |
| 13 "time" | 12 "time" |
| 14 | 13 |
| 14 "go.skia.org/infra/go/exec" |
| 15 "go.skia.org/infra/go/util" | 15 "go.skia.org/infra/go/util" |
| 16 | 16 |
| 17 "github.com/skia-dev/glog" | 17 "github.com/skia-dev/glog" |
| 18 ) | 18 ) |
| 19 | 19 |
| 20 const ( | 20 const ( |
| 21 MAX_SYNC_TRIES = 3 | 21 MAX_SYNC_TRIES = 3 |
| 22 ) | 22 ) |
| 23 | 23 |
| 24 // GetCTWorkers returns an array of all CT workers. | 24 // GetCTWorkers returns an array of all CT workers. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 if err := os.Remove(taskFilePath); err != nil { | 79 if err := os.Remove(taskFilePath); err != nil { |
| 80 glog.Errorf("Could not delete %s: %s", taskFilePath, err) | 80 glog.Errorf("Could not delete %s: %s", taskFilePath, err) |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 func TimeTrack(start time.Time, name string) { | 84 func TimeTrack(start time.Time, name string) { |
| 85 elapsed := time.Since(start) | 85 elapsed := time.Since(start) |
| 86 glog.Infof("===== %s took %s =====", name, elapsed) | 86 glog.Infof("===== %s took %s =====", name, elapsed) |
| 87 } | 87 } |
| 88 | 88 |
| 89 // WriteLog implements the io.Writer interface and writes to glog and an output | 89 // ExecuteCmd executes the specified binary with the specified args and env. Std
out and Stderr are |
| 90 // file (if specified). | 90 // written to stdout and stderr respectively if specified. If not specified then
Stdout and Stderr |
| 91 type WriteLog struct { | 91 // will be outputted only to glog. |
| 92 » LogFunc func(format string, args ...interface{}) | 92 func ExecuteCmd(binary string, args, env []string, timeout time.Duration, stdout
, stderr io.Writer) error { |
| 93 » OutputFile *os.File | 93 » return exec.Run(&exec.Command{ |
| 94 } | 94 » » Name: binary, |
| 95 | 95 » » Args: args, |
| 96 func (wl WriteLog) Write(p []byte) (n int, err error) { | 96 » » Env: env, |
| 97 » wl.LogFunc("%s", string(p)) | 97 » » InheritPath: true, |
| 98 » // Write to file if specified. | 98 » » Timeout: timeout, |
| 99 » if wl.OutputFile != nil { | 99 » » LogStdout: true, |
| 100 » » if n, err := wl.OutputFile.WriteString(string(p)); err != nil { | 100 » » Stdout: stdout, |
| 101 » » » glog.Errorf("Could not write to %s: %s", wl.OutputFile.N
ame(), err) | 101 » » LogStderr: true, |
| 102 » » » return n, err | 102 » » Stderr: stderr, |
| 103 » » } | 103 » }) |
| 104 » } | |
| 105 » return len(p), nil | |
| 106 } | |
| 107 | |
| 108 // ExecuteCmd executes the specified binary with the specified args and env. | |
| 109 // Stdout and Stderr are written to stdoutFile and stderrFile respectively if | |
| 110 // specified. If not specified then stdout and stderr will be outputted only to | |
| 111 // glog. Note: It is the responsibility of the caller to close stdoutFile and | |
| 112 // stderrFile. | |
| 113 func ExecuteCmd(binary string, args, env []string, timeout time.Duration, stdout
File, stderrFile *os.File) error { | |
| 114 » // Add the current PATH to the env. | |
| 115 » env = append(env, "PATH="+os.Getenv("PATH")) | |
| 116 | |
| 117 » // Create the cmd obj. | |
| 118 » cmd := exec.Command(binary, args...) | |
| 119 » cmd.Env = env | |
| 120 | |
| 121 » // Attach WriteLog to command. | |
| 122 » cmd.Stdout = WriteLog{LogFunc: glog.Infof, OutputFile: stdoutFile} | |
| 123 » cmd.Stderr = WriteLog{LogFunc: glog.Errorf, OutputFile: stderrFile} | |
| 124 | |
| 125 » // Execute cmd. | |
| 126 » glog.Infof("Executing %s %s", strings.Join(cmd.Env, " "), strings.Join(c
md.Args, " ")) | |
| 127 » util.LogErr(cmd.Start()) | |
| 128 » done := make(chan error) | |
| 129 » go func() { | |
| 130 » » done <- cmd.Wait() | |
| 131 » }() | |
| 132 » select { | |
| 133 » case <-time.After(timeout): | |
| 134 » » if err := cmd.Process.Kill(); err != nil { | |
| 135 » » » return fmt.Errorf("Failed to kill timed out process: %s"
, err) | |
| 136 » » } | |
| 137 » » <-done // allow goroutine to exit | |
| 138 » » glog.Errorf("Command killed since it took longer than %f secs",
timeout.Seconds()) | |
| 139 » » return fmt.Errorf("Command killed since it took longer than %f s
ecs", timeout.Seconds()) | |
| 140 » case err := <-done: | |
| 141 » » if err != nil { | |
| 142 » » » return fmt.Errorf("Process done with error: %s", err) | |
| 143 » » } | |
| 144 » } | |
| 145 » return nil | |
| 146 } | 104 } |
| 147 | 105 |
| 148 // SyncDir runs "git pull" and "gclient sync" on the specified directory. | 106 // SyncDir runs "git pull" and "gclient sync" on the specified directory. |
| 149 func SyncDir(dir string) error { | 107 func SyncDir(dir string) error { |
| 150 err := os.Chdir(dir) | 108 err := os.Chdir(dir) |
| 151 if err != nil { | 109 if err != nil { |
| 152 return fmt.Errorf("Could not chdir to %s: %s", dir, err) | 110 return fmt.Errorf("Could not chdir to %s: %s", dir, err) |
| 153 } | 111 } |
| 154 | 112 |
| 155 for i := 0; i < MAX_SYNC_TRIES; i++ { | 113 for i := 0; i < MAX_SYNC_TRIES; i++ { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 } | 176 } |
| 219 | 177 |
| 220 // CleanTmpDir deletes all tmp files from the caller because telemetry tends to | 178 // CleanTmpDir deletes all tmp files from the caller because telemetry tends to |
| 221 // generate a lot of temporary artifacts there and they take up root disk space. | 179 // generate a lot of temporary artifacts there and they take up root disk space. |
| 222 func CleanTmpDir() { | 180 func CleanTmpDir() { |
| 223 files, _ := ioutil.ReadDir(os.TempDir()) | 181 files, _ := ioutil.ReadDir(os.TempDir()) |
| 224 for _, f := range files { | 182 for _, f := range files { |
| 225 util.RemoveAll(filepath.Join(os.TempDir(), f.Name())) | 183 util.RemoveAll(filepath.Join(os.TempDir(), f.Name())) |
| 226 } | 184 } |
| 227 } | 185 } |
| OLD | NEW |