OLD | NEW |
---|---|
1 /* | 1 /* |
2 Utilities for isolating and swarming. See swarming_test.go for usage exa mples. | 2 Utilities for isolating and swarming. See swarming_test.go for usage exa mples. |
3 */ | 3 */ |
4 package swarming | 4 package swarming |
5 | 5 |
6 import ( | 6 import ( |
7 "bytes" | 7 "bytes" |
8 "encoding/json" | 8 "encoding/json" |
9 "fmt" | 9 "fmt" |
10 "io/ioutil" | 10 "io/ioutil" |
11 "os" | 11 "os" |
12 "path" | 12 "path" |
13 "strconv" | 13 "strconv" |
14 "time" | 14 "time" |
15 | 15 |
16 "github.com/skia-dev/glog" | 16 "github.com/skia-dev/glog" |
17 "go.skia.org/infra/go/exec" | 17 "go.skia.org/infra/go/exec" |
18 "go.skia.org/infra/go/gitinfo" | 18 "go.skia.org/infra/go/gitinfo" |
19 "go.skia.org/infra/go/util" | 19 "go.skia.org/infra/go/util" |
20 ) | 20 ) |
21 | 21 |
22 const ( | 22 const ( |
23 » ISOLATE_BINARY = "isolate" | 23 » ISOLATE_BINARY = "isolate" |
24 » ISOLATE_SERVER = "isolateserver.appspot.com" | 24 » ISOLATE_SERVER = "isolateserver.appspot.com" |
25 » SWARMING_SERVER = "chromium-swarm.appspot.com" | 25 » SWARMING_SERVER = "chromium-swarm.appspot.com" |
26 » LUCI_CLIENT_REPO = "https://github.com/luci/client-py" | 26 » LUCI_CLIENT_REPO = "https://github.com/luci/client-py" |
27 » IO_TIMEOUT = 20 * time.Minute | 27 » RECOMMENDED_IO_TIMEOUT = 20 * time.Minute |
28 » HARD_TIMEOUT = 1 * time.Hour | 28 » RECOMMENDED_HARD_TIMEOUT = 1 * time.Hour |
29 » RECOMMENDED_PRIORITY = 90 | 29 » RECOMMENDED_PRIORITY = 90 |
30 » RECOMMENDED_EXPIRATION = 4 * time.Hour | 30 » RECOMMENDED_EXPIRATION = 4 * time.Hour |
31 ) | 31 ) |
32 | 32 |
33 type SwarmingClient struct { | 33 type SwarmingClient struct { |
34 WorkDir string | 34 WorkDir string |
35 IsolatedServer string | 35 IsolatedServer string |
36 SwarmingServer string | 36 SwarmingServer string |
37 } | 37 } |
38 | 38 |
39 type SwarmingTask struct { | 39 type SwarmingTask struct { |
40 Title string | 40 Title string |
(...skipping 13 matching lines...) Expand all Loading... | |
54 | 54 |
55 type ShardOutputFormat struct { | 55 type ShardOutputFormat struct { |
56 ExitCode string `json:"exit_code"` | 56 ExitCode string `json:"exit_code"` |
57 Output string `json:"output"` | 57 Output string `json:"output"` |
58 } | 58 } |
59 | 59 |
60 type TaskOutputFormat struct { | 60 type TaskOutputFormat struct { |
61 Shards []ShardOutputFormat `json:"shards"` | 61 Shards []ShardOutputFormat `json:"shards"` |
62 } | 62 } |
63 | 63 |
64 func (t *SwarmingTask) Trigger(s *SwarmingClient) error { | 64 func (t *SwarmingTask) Trigger(s *SwarmingClient, hardTimeout, ioTimeout time.Du ration) error { |
65 swarmingBinary := path.Join(s.WorkDir, "client-py", "swarming.py") | 65 swarmingBinary := path.Join(s.WorkDir, "client-py", "swarming.py") |
66 if err := _VerifyBinaryExists(swarmingBinary); err != nil { | 66 if err := _VerifyBinaryExists(swarmingBinary); err != nil { |
67 return fmt.Errorf("Could not find swarming binary: %s", err) | 67 return fmt.Errorf("Could not find swarming binary: %s", err) |
68 } | 68 } |
69 | 69 |
70 // Run swarming trigger. | 70 // Run swarming trigger. |
71 dumpJSON := path.Join(t.OutputDir, fmt.Sprintf("%s-trigger-output.json", t.Title)) | 71 dumpJSON := path.Join(t.OutputDir, fmt.Sprintf("%s-trigger-output.json", t.Title)) |
72 triggerArgs := []string{ | 72 triggerArgs := []string{ |
73 "trigger", | 73 "trigger", |
74 "--swarming", s.SwarmingServer, | 74 "--swarming", s.SwarmingServer, |
75 "--isolate-server", s.IsolatedServer, | 75 "--isolate-server", s.IsolatedServer, |
76 "--priority", strconv.Itoa(t.Priority), | 76 "--priority", strconv.Itoa(t.Priority), |
77 "--shards", strconv.Itoa(1), | 77 "--shards", strconv.Itoa(1), |
78 "--task-name", t.Title, | 78 "--task-name", t.Title, |
79 "--dump-json", dumpJSON, | 79 "--dump-json", dumpJSON, |
80 "--expiration", strconv.FormatFloat(t.Expiration.Seconds(), 'f', 0, 64), | 80 "--expiration", strconv.FormatFloat(t.Expiration.Seconds(), 'f', 0, 64), |
81 » » "--io-timeout", strconv.FormatFloat(IO_TIMEOUT.Seconds(), 'f', 0 , 64), | 81 » » "--io-timeout", strconv.FormatFloat(ioTimeout.Seconds(), 'f', 0, 64), |
82 » » "--hard-timeout", strconv.FormatFloat(HARD_TIMEOUT.Seconds(), 'f ', 0, 64), | 82 » » "--hard-timeout", strconv.FormatFloat(hardTimeout.Seconds(), 'f' , 0, 64), |
83 "--verbose", | 83 "--verbose", |
84 } | 84 } |
85 for k, v := range t.Dimensions { | 85 for k, v := range t.Dimensions { |
86 triggerArgs = append(triggerArgs, "--dimension", k, v) | 86 triggerArgs = append(triggerArgs, "--dimension", k, v) |
87 } | 87 } |
88 if t.Idempotent { | 88 if t.Idempotent { |
89 triggerArgs = append(triggerArgs, "--idempotent") | 89 triggerArgs = append(triggerArgs, "--idempotent") |
90 } | 90 } |
91 triggerArgs = append(triggerArgs, t.IsolatedHash) | 91 triggerArgs = append(triggerArgs, t.IsolatedHash) |
92 | 92 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 } | 235 } |
236 var tasksToHashes map[string]string | 236 var tasksToHashes map[string]string |
237 if err := json.NewDecoder(bytes.NewReader(dumpFile)).Decode(&tasksToHash es); err != nil { | 237 if err := json.NewDecoder(bytes.NewReader(dumpFile)).Decode(&tasksToHash es); err != nil { |
238 return nil, fmt.Errorf("Could not decode %s: %s", dumpJSON, err) | 238 return nil, fmt.Errorf("Could not decode %s: %s", dumpJSON, err) |
239 } | 239 } |
240 | 240 |
241 return tasksToHashes, nil | 241 return tasksToHashes, nil |
242 } | 242 } |
243 | 243 |
244 // Trigger swarming using the specified hashes and dimensions. | 244 // Trigger swarming using the specified hashes and dimensions. |
245 func (s *SwarmingClient) TriggerSwarmingTasks(tasksToHashes map[string]string, d imensions map[string]string, priority int, expiration time.Duration, idempotent bool) ([]*SwarmingTask, error) { | 245 func (s *SwarmingClient) TriggerSwarmingTasks(tasksToHashes map[string]string, d imensions map[string]string, priority int, expiration, hardTimeout, ioTimeout ti me.Duration, idempotent bool) ([]*SwarmingTask, error) { |
246 tasks := []*SwarmingTask{} | 246 tasks := []*SwarmingTask{} |
247 | 247 |
248 for taskName, hash := range tasksToHashes { | 248 for taskName, hash := range tasksToHashes { |
249 taskOutputDir := path.Join(s.WorkDir, taskName) | 249 taskOutputDir := path.Join(s.WorkDir, taskName) |
250 if err := os.MkdirAll(taskOutputDir, 0700); err != nil { | 250 if err := os.MkdirAll(taskOutputDir, 0700); err != nil { |
251 return nil, fmt.Errorf("Could not create %s: %s", taskOu tputDir, err) | 251 return nil, fmt.Errorf("Could not create %s: %s", taskOu tputDir, err) |
252 } | 252 } |
253 task := &SwarmingTask{ | 253 task := &SwarmingTask{ |
254 Title: taskName, | 254 Title: taskName, |
255 IsolatedHash: hash, | 255 IsolatedHash: hash, |
256 OutputDir: taskOutputDir, | 256 OutputDir: taskOutputDir, |
257 Dimensions: dimensions, | 257 Dimensions: dimensions, |
258 Priority: priority, | 258 Priority: priority, |
259 Expiration: expiration, | 259 Expiration: expiration, |
260 Idempotent: idempotent, | 260 Idempotent: idempotent, |
261 } | 261 } |
262 » » if err := task.Trigger(s); err != nil { | 262 » » if err := task.Trigger(s, hardTimeout, ioTimeout); err != nil { |
263 return nil, fmt.Errorf("Could not trigger task %s: %s", taskName, err) | 263 return nil, fmt.Errorf("Could not trigger task %s: %s", taskName, err) |
264 } | 264 } |
265 » » glog.Infof("Triggered the task: %s", task) | 265 » » glog.Infof("Triggered the task: %v", task) |
266 tasks = append(tasks, task) | 266 tasks = append(tasks, task) |
267 } | 267 } |
268 | 268 |
269 return tasks, nil | 269 return tasks, nil |
270 } | 270 } |
271 | 271 |
272 func (s *SwarmingClient) Cleanup() { | 272 func (s *SwarmingClient) Cleanup() { |
273 if err := os.RemoveAll(s.WorkDir); err != nil { | 273 if err := os.RemoveAll(s.WorkDir); err != nil { |
274 glog.Errorf("Could not cleanup swarming work dir: %s", err) | 274 glog.Errorf("Could not cleanup swarming work dir: %s", err) |
275 } | 275 } |
276 } | 276 } |
277 | 277 |
278 func _VerifyBinaryExists(binary string) error { | 278 func _VerifyBinaryExists(binary string) error { |
279 err := exec.Run(&exec.Command{ | 279 err := exec.Run(&exec.Command{ |
280 Name: binary, | 280 Name: binary, |
281 Args: []string{"help"}, | 281 Args: []string{"help"}, |
282 Timeout: 60 * time.Second, | 282 Timeout: 60 * time.Second, |
283 » » LogStdout: true, | 283 » » LogStdout: false, |
rmistry
2016/05/18 13:10:48
Eliminating noise in logs.
| |
284 LogStderr: true, | 284 LogStderr: true, |
285 }) | 285 }) |
286 if err != nil { | 286 if err != nil { |
287 return fmt.Errorf("Error finding the binary %s: %s", binary, err ) | 287 return fmt.Errorf("Error finding the binary %s: %s", binary, err ) |
288 } | 288 } |
289 return nil | 289 return nil |
290 } | 290 } |
OLD | NEW |