| 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 |