OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package main | 5 package main |
6 | 6 |
7 import ( | 7 import ( |
8 "encoding/json" | 8 "encoding/json" |
9 "io" | 9 "io" |
10 "os" | 10 "os" |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 298 |
299 // If we have configured a stream server, add it. | 299 // If we have configured a stream server, add it. |
300 if streamServer != nil { | 300 if streamServer != nil { |
301 b.AddStreamServer(streamServer) | 301 b.AddStreamServer(streamServer) |
302 streamServerOwned = false | 302 streamServerOwned = false |
303 } | 303 } |
304 | 304 |
305 // Add our pipes as direct streams, if configured. | 305 // Add our pipes as direct streams, if configured. |
306 if stdout != nil { | 306 if stdout != nil { |
307 if err := b.AddStream(stdout, cmd.stdout.properties());
err != nil { | 307 if err := b.AddStream(stdout, cmd.stdout.properties());
err != nil { |
308 » » » » return errors.Annotate(err).Reason("failed to at
tach STDOUT pipe stream").Err() | 308 » » » » return errors.Annotate(err, "failed to attach ST
DOUT pipe stream").Err() |
309 } | 309 } |
310 } | 310 } |
311 if stderr != nil { | 311 if stderr != nil { |
312 if err := b.AddStream(stderr, cmd.stderr.properties());
err != nil { | 312 if err := b.AddStream(stderr, cmd.stderr.properties());
err != nil { |
313 » » » » return errors.Annotate(err).Reason("failed to at
tach STDERR pipe stream").Err() | 313 » » » » return errors.Annotate(err, "failed to attach ST
DERR pipe stream").Err() |
314 } | 314 } |
315 } | 315 } |
316 | 316 |
317 // Execute the command. The bootstrapped application will begin
executing | 317 // Execute the command. The bootstrapped application will begin
executing |
318 // in the background. | 318 // in the background. |
319 if err := proc.Start(); err != nil { | 319 if err := proc.Start(); err != nil { |
320 » » » return errors.Annotate(err).Reason("failed to start boot
strapped process").Err() | 320 » » » return errors.Annotate(err, "failed to start bootstrappe
d process").Err() |
321 } | 321 } |
322 | 322 |
323 // Wait for the process' streams to finish. We must do this befo
re Wait() | 323 // Wait for the process' streams to finish. We must do this befo
re Wait() |
324 // on the process itself. | 324 // on the process itself. |
325 streamWG.Wait() | 325 streamWG.Wait() |
326 | 326 |
327 // Reap the process. | 327 // Reap the process. |
328 err := proc.Wait() | 328 err := proc.Wait() |
329 if rc, ok := exitcode.Get(err); ok { | 329 if rc, ok := exitcode.Get(err); ok { |
330 if rc != 0 { | 330 if rc != 0 { |
331 log.Fields{ | 331 log.Fields{ |
332 "returnCode": rc, | 332 "returnCode": rc, |
333 }.Errorf(a, "Command completed with non-zero ret
urn code.") | 333 }.Errorf(a, "Command completed with non-zero ret
urn code.") |
334 } | 334 } |
335 | 335 |
336 returnCode = rc | 336 returnCode = rc |
337 executed = true | 337 executed = true |
338 } else { | 338 } else { |
339 log.WithError(err).Errorf(a, "Command failed.") | 339 log.WithError(err).Errorf(a, "Command failed.") |
340 } | 340 } |
341 | 341 |
342 // Wait for our Butler to finish. | 342 // Wait for our Butler to finish. |
343 b.Activate() | 343 b.Activate() |
344 if err := b.Wait(); err != nil { | 344 if err := b.Wait(); err != nil { |
345 if err == context.Canceled { | 345 if err == context.Canceled { |
346 return err | 346 return err |
347 } | 347 } |
348 » » » return errors.Annotate(err).Reason("failed to Wait() for
Butler").Err() | 348 » » » return errors.Annotate(err, "failed to Wait() for Butler
").Err() |
349 } | 349 } |
350 | 350 |
351 return nil | 351 return nil |
352 }) | 352 }) |
353 if err != nil { | 353 if err != nil { |
354 logAnnotatedErr(a, err, "Error running bootstrapped Butler proce
ss:") | 354 logAnnotatedErr(a, err, "Error running bootstrapped Butler proce
ss:") |
355 } | 355 } |
356 | 356 |
357 if !executed { | 357 if !executed { |
358 return runtimeErrorReturnCode | 358 return runtimeErrorReturnCode |
(...skipping 13 matching lines...) Expand all Loading... |
372 | 372 |
373 func (cmd *runCommandRun) maybeWriteResult(ctx context.Context, r *bootstrapResu
lt.Result) error { | 373 func (cmd *runCommandRun) maybeWriteResult(ctx context.Context, r *bootstrapResu
lt.Result) error { |
374 if cmd.resultPath == "" { | 374 if cmd.resultPath == "" { |
375 return nil | 375 return nil |
376 } | 376 } |
377 | 377 |
378 log.Fields{ | 378 log.Fields{ |
379 "path": cmd.resultPath, | 379 "path": cmd.resultPath, |
380 }.Debugf(ctx, "Writing bootstrap result.") | 380 }.Debugf(ctx, "Writing bootstrap result.") |
381 if err := r.WriteJSON(cmd.resultPath); err != nil { | 381 if err := r.WriteJSON(cmd.resultPath); err != nil { |
382 » » return errors.Annotate(err).Reason("failed to write JSON file"). | 382 » » return errors.Annotate(err, "failed to write JSON file"). |
383 » » » D("path", cmd.resultPath).Err() | 383 » » » InternalReason("path(%s)", cmd.resultPath).Err() |
384 } | 384 } |
385 return nil | 385 return nil |
386 } | 386 } |
387 | 387 |
388 func (cmd *runCommandRun) loadJSONArgs() ([]string, error) { | 388 func (cmd *runCommandRun) loadJSONArgs() ([]string, error) { |
389 fd, err := os.Open(cmd.jsonArgsPath) | 389 fd, err := os.Open(cmd.jsonArgsPath) |
390 if err != nil { | 390 if err != nil { |
391 return nil, err | 391 return nil, err |
392 } | 392 } |
393 defer fd.Close() | 393 defer fd.Close() |
394 | 394 |
395 dec := json.NewDecoder(fd) | 395 dec := json.NewDecoder(fd) |
396 args := []string(nil) | 396 args := []string(nil) |
397 if err := dec.Decode(&args); err != nil { | 397 if err := dec.Decode(&args); err != nil { |
398 return nil, err | 398 return nil, err |
399 } | 399 } |
400 return args, nil | 400 return args, nil |
401 } | 401 } |
402 | 402 |
403 // callbackReadCloser invokes a callback method when closed. | 403 // callbackReadCloser invokes a callback method when closed. |
404 type callbackReadCloser struct { | 404 type callbackReadCloser struct { |
405 io.ReadCloser | 405 io.ReadCloser |
406 callback func() | 406 callback func() |
407 } | 407 } |
408 | 408 |
409 func (c *callbackReadCloser) Close() error { | 409 func (c *callbackReadCloser) Close() error { |
410 defer c.callback() | 410 defer c.callback() |
411 return c.ReadCloser.Close() | 411 return c.ReadCloser.Close() |
412 } | 412 } |
OLD | NEW |