Merge pull request #9855 from hashicorp/b-shadow-err
command: show shadow errors to the user
This commit is contained in:
commit
cda968a23a
|
@ -136,6 +136,9 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
}
|
||||
}
|
||||
|
||||
// This is going to keep track of shadow errors
|
||||
var shadowErr error
|
||||
|
||||
// Build the context based on the arguments given
|
||||
ctx, planned, err := c.Context(contextOpts{
|
||||
Destroy: c.Destroy,
|
||||
|
@ -189,6 +192,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
c.Ui.Error(fmt.Sprintf("Error configuring: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "input operation:"))
|
||||
}
|
||||
}
|
||||
if !validateContext(ctx, c.Ui) {
|
||||
return 1
|
||||
|
@ -208,6 +217,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
"Error creating plan: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "plan operation:"))
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the state hook for continuous state updates
|
||||
|
@ -229,6 +244,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
go func() {
|
||||
defer close(doneCh)
|
||||
state, applyErr = ctx.Apply()
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "apply operation:"))
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for the apply to finish or for us to be interrupted so
|
||||
|
@ -304,6 +325,9 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
}
|
||||
}
|
||||
|
||||
// If we have an error in the shadow graph, let the user know.
|
||||
c.outputShadowError(shadowErr, applyErr == nil)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -460,6 +460,42 @@ func (m *Meta) addModuleDepthFlag(flags *flag.FlagSet, moduleDepth *int) {
|
|||
}
|
||||
}
|
||||
|
||||
// outputShadowError outputs the error from ctx.ShadowError. If the
|
||||
// error is nil then nothing happens. If output is false then it isn't
|
||||
// outputted to the user (you can define logic to guard against outputting).
|
||||
func (m *Meta) outputShadowError(err error, output bool) bool {
|
||||
// Do nothing if no error
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// If not outputting, do nothing
|
||||
if !output {
|
||||
return false
|
||||
}
|
||||
|
||||
// Output!
|
||||
m.Ui.Output(m.Colorize().Color(fmt.Sprintf(
|
||||
"[reset][bold][yellow]\nExperimental feature failure! Please report a bug.\n\n"+
|
||||
"This is not an error. Your Terraform operation completed successfully.\n"+
|
||||
"Your real infrastructure is unaffected by this message.\n\n"+
|
||||
"[reset][yellow]While running, Terraform sometimes tests experimental features in the\n"+
|
||||
"background. These features cannot affect real state and never touch\n"+
|
||||
"real infrastructure. If the features work properly, you see nothing.\n"+
|
||||
"If the features fail, this message appears.\n\n"+
|
||||
"The following failures happened while running experimental features.\n"+
|
||||
"Please report a Terraform bug so that future Terraform versions that\n"+
|
||||
"enable these features can be improved!\n\n"+
|
||||
"You can report an issue at: https://github.com/hashicorp/terraform/issues\n\n"+
|
||||
"%s\n\n"+
|
||||
"This is not an error. Your terraform operation completed successfully\n"+
|
||||
"and your real infrastructure is unaffected by this message.",
|
||||
err,
|
||||
)))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// contextOpts are the options used to load a context from a command.
|
||||
type contextOpts struct {
|
||||
// Path to the directory where the root module is.
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
|
@ -57,6 +58,9 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
countHook := new(CountHook)
|
||||
c.Meta.extraHooks = []terraform.Hook{countHook}
|
||||
|
||||
// This is going to keep track of shadow errors
|
||||
var shadowErr error
|
||||
|
||||
ctx, _, err := c.Context(contextOpts{
|
||||
Destroy: destroy,
|
||||
Path: path,
|
||||
|
@ -73,6 +77,12 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "input operation:"))
|
||||
}
|
||||
|
||||
if !validateContext(ctx, c.Ui) {
|
||||
return 1
|
||||
}
|
||||
|
@ -138,6 +148,15 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
countHook.ToChange,
|
||||
countHook.ToRemove+countHook.ToRemoveAndAdd)))
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "plan operation:"))
|
||||
}
|
||||
|
||||
// If we have an error in the shadow graph, let the user know.
|
||||
c.outputShadowError(shadowErr, true)
|
||||
|
||||
if detailed {
|
||||
return 2
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
|
@ -79,6 +80,9 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
}
|
||||
}
|
||||
|
||||
// This is going to keep track of shadow errors
|
||||
var shadowErr error
|
||||
|
||||
// Build the context based on the arguments given
|
||||
ctx, _, err := c.Context(contextOpts{
|
||||
Path: configPath,
|
||||
|
@ -95,6 +99,12 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "input operation:"))
|
||||
}
|
||||
|
||||
if !validateContext(ctx, c.Ui) {
|
||||
return 1
|
||||
}
|
||||
|
@ -115,6 +125,15 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
c.Ui.Output(c.Colorize().Color(outputs))
|
||||
}
|
||||
|
||||
// Record any shadow errors for later
|
||||
if err := ctx.ShadowError(); err != nil {
|
||||
shadowErr = multierror.Append(shadowErr, multierror.Prefix(
|
||||
err, "refresh operation:"))
|
||||
}
|
||||
|
||||
// If we have an error in the shadow graph, let the user know.
|
||||
c.outputShadowError(shadowErr, true)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue