// Run runs the command, and returns the result as an error. func (c *Cmd) Run() error { if err := c.Start(); err != nil { return err } err := c.Wait() if exitError, ok := err.(*exec.ExitError); ok && exitError != nil { status := exitError.ProcessState.Sys().(syscall.WaitStatus) if status.Exited() { return cmd.NewRcPassthroughError(status.ExitStatus()) } } return err }
func (c *RunCommand) Run(ctx *cmd.Context) error { var result *exec.ExecResponse var err error if c.noContext { result, err = c.executeNoContext() } else { result, err = c.executeInUnitContext() } if err != nil { return errors.Trace(err) } ctx.Stdout.Write(result.Stdout) ctx.Stderr.Write(result.Stderr) return cmd.NewRcPassthroughError(result.Code) }
func (c *RunCommand) Run(ctx *cmd.Context) error { client, err := getRunAPIClient(c) if err != nil { return err } defer client.Close() var runResults []params.RunResult if c.all { runResults, err = client.RunOnAllMachines(c.commands, c.timeout) } else { params := params.RunParams{ Commands: c.commands, Timeout: c.timeout, Machines: c.machines, Services: c.services, Units: c.units, } runResults, err = client.Run(params) } if err != nil { return block.ProcessBlockedError(err, block.BlockChange) } // If we are just dealing with one result, AND we are using the smart // format, then pretend we were running it locally. if len(runResults) == 1 && c.out.Name() == "smart" { result := runResults[0] ctx.Stdout.Write(result.Stdout) ctx.Stderr.Write(result.Stderr) if result.Error != "" { // Convert the error string back into an error object. return fmt.Errorf("%s", result.Error) } if result.Code != 0 { return cmd.NewRcPassthroughError(result.Code) } return nil } c.out.Write(ctx, ConvertRunResults(runResults)) return nil }
func (c *PluginCommand) Run(ctx *cmd.Context) error { command := exec.Command(c.name, c.args...) command.Env = append(os.Environ(), []string{ osenv.JujuModelEnvKey + "=" + c.ConnectionName()}..., ) // Now hook up stdin, stdout, stderr command.Stdin = ctx.Stdin command.Stdout = ctx.Stdout command.Stderr = ctx.Stderr // And run it! err := command.Run() if exitError, ok := err.(*exec.ExitError); ok && exitError != nil { status := exitError.ProcessState.Sys().(syscall.WaitStatus) if status.Exited() { return cmd.NewRcPassthroughError(status.ExitStatus()) } } return err }
func (s *CmdSuite) TestIsErrSilent(c *gc.C) { c.Assert(cmd.IsErrSilent(cmd.ErrSilent), gc.Equals, true) c.Assert(cmd.IsErrSilent(cmd.NewRcPassthroughError(99)), gc.Equals, true) c.Assert(cmd.IsErrSilent(fmt.Errorf("noisy")), gc.Equals, false) }
func (c *runCommand) Run(ctx *cmd.Context) error { client, err := getRunAPIClient(c) if err != nil { return err } defer client.Close() var runResults []params.ActionResult if c.all { runResults, err = client.RunOnAllMachines(c.commands, c.timeout) } else { params := params.RunParams{ Commands: c.commands, Timeout: c.timeout, Machines: c.machines, Services: c.services, Units: c.units, } runResults, err = client.Run(params) } if err != nil { return block.ProcessBlockedError(err, block.BlockChange) } actionsToQuery := []actionQuery{} for _, result := range runResults { if result.Error != nil { fmt.Fprintf(ctx.GetStderr(), "couldn't queue one action: %v", result.Error) continue } actionTag, err := names.ParseActionTag(result.Action.Tag) if err != nil { fmt.Fprintf(ctx.GetStderr(), "got invalid action tag %v for receiver %v", result.Action.Tag, result.Action.Receiver) continue } receiverTag, err := names.ActionReceiverFromTag(result.Action.Receiver) if err != nil { fmt.Fprintf(ctx.GetStderr(), "got invalid action receiver tag %v for action %v", result.Action.Receiver, result.Action.Tag) continue } var receiverType string switch receiverTag.(type) { case names.UnitTag: receiverType = "UnitId" case names.MachineTag: receiverType = "MachineId" default: receiverType = "ReceiverId" } actionsToQuery = append(actionsToQuery, actionQuery{ actionTag: actionTag, receiver: actionReceiver{ receiverType: receiverType, tag: receiverTag, }}) } if len(actionsToQuery) == 0 { return errors.New("no actions were successfully enqueued, aborting") } values := []interface{}{} for len(actionsToQuery) > 0 { actionResults, err := client.Actions(entities(actionsToQuery)) if err != nil { return errors.Trace(err) } newActionsToQuery := []actionQuery{} for i, result := range actionResults.Results { if result.Error == nil { switch result.Status { case params.ActionRunning, params.ActionPending: newActionsToQuery = append(newActionsToQuery, actionsToQuery[i]) continue } } values = append(values, ConvertActionResults(result, actionsToQuery[i])) } actionsToQuery = newActionsToQuery // TODO: use a watcher instead of sleeping // this should be easier once we implement action grouping <-afterFunc(1 * time.Second) } // If we are just dealing with one result, AND we are using the smart // format, then pretend we were running it locally. if len(values) == 1 && c.out.Name() == "smart" { result, ok := values[0].(map[string]interface{}) if !ok { return errors.New("couldn't read action output") } if res, ok := result["Error"].(string); ok { return errors.New(res) } ctx.Stdout.Write(formatOutput(result, "Stdout")) ctx.Stderr.Write(formatOutput(result, "Stderr")) if code, ok := result["ReturnCode"].(int); ok && code != 0 { return cmd.NewRcPassthroughError(code) } // Message should always contain only errors. if res, ok := result["Message"].(string); ok && res != "" { ctx.Stderr.Write([]byte(res)) } return nil } return c.out.Write(ctx, values) }