command: show shadow errors to the user
This commit is contained in:
parent
7291376c2d
commit
d429e82661
|
@ -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
|
// Build the context based on the arguments given
|
||||||
ctx, planned, err := c.Context(contextOpts{
|
ctx, planned, err := c.Context(contextOpts{
|
||||||
Destroy: c.Destroy,
|
Destroy: c.Destroy,
|
||||||
|
@ -189,6 +192,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
c.Ui.Error(fmt.Sprintf("Error configuring: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error configuring: %s", err))
|
||||||
return 1
|
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) {
|
if !validateContext(ctx, c.Ui) {
|
||||||
return 1
|
return 1
|
||||||
|
@ -208,6 +217,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
"Error creating plan: %s", err))
|
"Error creating plan: %s", err))
|
||||||
return 1
|
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
|
// Setup the state hook for continuous state updates
|
||||||
|
@ -229,6 +244,12 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
go func() {
|
go func() {
|
||||||
defer close(doneCh)
|
defer close(doneCh)
|
||||||
state, applyErr = ctx.Apply()
|
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
|
// 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
|
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.
|
// contextOpts are the options used to load a context from a command.
|
||||||
type contextOpts struct {
|
type contextOpts struct {
|
||||||
// Path to the directory where the root module is.
|
// Path to the directory where the root module is.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,6 +58,9 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
countHook := new(CountHook)
|
countHook := new(CountHook)
|
||||||
c.Meta.extraHooks = []terraform.Hook{countHook}
|
c.Meta.extraHooks = []terraform.Hook{countHook}
|
||||||
|
|
||||||
|
// This is going to keep track of shadow errors
|
||||||
|
var shadowErr error
|
||||||
|
|
||||||
ctx, _, err := c.Context(contextOpts{
|
ctx, _, err := c.Context(contextOpts{
|
||||||
Destroy: destroy,
|
Destroy: destroy,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
@ -73,6 +77,12 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
return 1
|
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) {
|
if !validateContext(ctx, c.Ui) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -138,6 +148,15 @@ func (c *PlanCommand) Run(args []string) int {
|
||||||
countHook.ToChange,
|
countHook.ToChange,
|
||||||
countHook.ToRemove+countHook.ToRemoveAndAdd)))
|
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 {
|
if detailed {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"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
|
// Build the context based on the arguments given
|
||||||
ctx, _, err := c.Context(contextOpts{
|
ctx, _, err := c.Context(contextOpts{
|
||||||
Path: configPath,
|
Path: configPath,
|
||||||
|
@ -95,6 +99,12 @@ func (c *RefreshCommand) Run(args []string) int {
|
||||||
return 1
|
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) {
|
if !validateContext(ctx, c.Ui) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -115,6 +125,15 @@ func (c *RefreshCommand) Run(args []string) int {
|
||||||
c.Ui.Output(c.Colorize().Color(outputs))
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue