| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // 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 "fmt" | 9 "fmt" |
| 10 "io" | 10 "io" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 log.Errorf(log.SetError(a, err), "Failed to connect to s
tream server.") | 174 log.Errorf(log.SetError(a, err), "Failed to connect to s
tream server.") |
| 175 return runtimeErrorReturnCode | 175 return runtimeErrorReturnCode |
| 176 } | 176 } |
| 177 defer func() { | 177 defer func() { |
| 178 if streamServerOwned { | 178 if streamServerOwned { |
| 179 streamServer.Close() | 179 streamServer.Close() |
| 180 } | 180 } |
| 181 }() | 181 }() |
| 182 } | 182 } |
| 183 | 183 |
| 184 // We're about ready to execute our command. Initialize our Output insta
nce. |
| 185 // We want to do this before we execute our subprocess so that if this f
ails, |
| 186 // we don't have to interrupt an already-running process. |
| 187 output, err := a.configOutput() |
| 188 if err != nil { |
| 189 log.WithError(err).Errorf(a, "Failed to create output instance."
) |
| 190 return runtimeErrorReturnCode |
| 191 } |
| 192 defer output.Close() |
| 193 |
| 184 // Construct and execute the command | 194 // Construct and execute the command |
| 185 proc := ctxcmd.CtxCmd{ | 195 proc := ctxcmd.CtxCmd{ |
| 186 Cmd: exec.Command(commandPath, args...), | 196 Cmd: exec.Command(commandPath, args...), |
| 187 } | 197 } |
| 188 proc.Dir = cmd.chdir | 198 proc.Dir = cmd.chdir |
| 189 proc.Env = env.sorted() | 199 proc.Env = env.sorted() |
| 190 if cmd.stdin { | 200 if cmd.stdin { |
| 191 proc.Stdin = os.Stdin | 201 proc.Stdin = os.Stdin |
| 192 } | 202 } |
| 193 | 203 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 } | 279 } |
| 270 } else { | 280 } else { |
| 271 returnCode = 0 | 281 returnCode = 0 |
| 272 } | 282 } |
| 273 | 283 |
| 274 log.Fields{ | 284 log.Fields{ |
| 275 "returnCode": returnCode, | 285 "returnCode": returnCode, |
| 276 }.Infof(ctx, "Process completed.") | 286 }.Infof(ctx, "Process completed.") |
| 277 }() | 287 }() |
| 278 | 288 |
| 279 » err = a.Main(func(b *butler.Butler) error { | 289 » err = a.runWithButler(output, func(b *butler.Butler) error { |
| 280 // We will execute the bootstrapped command, then the Butler. Si
nce we are | 290 // We will execute the bootstrapped command, then the Butler. Si
nce we are |
| 281 // hooking the Butler up to the command, the Butler's execution
will be | 291 // hooking the Butler up to the command, the Butler's execution
will be |
| 282 // bounded by the availability of the command's STDOUT/STDERR st
reams. If | 292 // bounded by the availability of the command's STDOUT/STDERR st
reams. If |
| 283 // both of those close, the command is finished (as far as the B
utler is | 293 // both of those close, the command is finished (as far as the B
utler is |
| 284 // concerned). | 294 // concerned). |
| 285 | 295 |
| 286 // Execute the command. The bootstrapped application will begin
executing in | 296 // Execute the command. The bootstrapped application will begin
executing in |
| 287 // the background. | 297 // the background. |
| 288 | 298 |
| 289 // If we have configured a stream server, add it. | 299 // If we have configured a stream server, add it. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 args := []string(nil) | 348 args := []string(nil) |
| 339 if err := dec.Decode(&args); err != nil { | 349 if err := dec.Decode(&args); err != nil { |
| 340 return nil, err | 350 return nil, err |
| 341 } | 351 } |
| 342 return args, nil | 352 return args, nil |
| 343 } | 353 } |
| 344 | 354 |
| 345 // updateEnvironment adds common Butler bootstrapping environment variables | 355 // updateEnvironment adds common Butler bootstrapping environment variables |
| 346 // to the environment. | 356 // to the environment. |
| 347 func (cmd *runCommandRun) updateEnvironment(e environ, a *application) { | 357 func (cmd *runCommandRun) updateEnvironment(e environ, a *application) { |
| 348 » e.set(bootstrap.EnvStreamPrefix, string(a.butler.Prefix)) | 358 » e.set(bootstrap.EnvStreamPrefix, string(a.prefix)) |
| 349 » e.set(bootstrap.EnvStreamProject, string(a.butler.Project)) | 359 » e.set(bootstrap.EnvStreamProject, string(a.project)) |
| 350 | 360 |
| 351 // Set stream server path (if applicable) | 361 // Set stream server path (if applicable) |
| 352 if cmd.streamServerURI != "" { | 362 if cmd.streamServerURI != "" { |
| 353 e.set(bootstrap.EnvStreamServerPath, string(cmd.streamServerURI)
) | 363 e.set(bootstrap.EnvStreamServerPath, string(cmd.streamServerURI)
) |
| 354 } | 364 } |
| 355 } | 365 } |
| 356 | 366 |
| 357 // callbackReadCloser invokes a callback method when closed. | 367 // callbackReadCloser invokes a callback method when closed. |
| 358 type callbackReadCloser struct { | 368 type callbackReadCloser struct { |
| 359 io.ReadCloser | 369 io.ReadCloser |
| 360 callback func() | 370 callback func() |
| 361 } | 371 } |
| 362 | 372 |
| 363 func (c *callbackReadCloser) Close() error { | 373 func (c *callbackReadCloser) Close() error { |
| 364 defer c.callback() | 374 defer c.callback() |
| 365 return c.ReadCloser.Close() | 375 return c.ReadCloser.Close() |
| 366 } | 376 } |
| OLD | NEW |