diff --git a/upup/pkg/fi/context.go b/upup/pkg/fi/context.go index 2c99e2bd90..622a05d213 100644 --- a/upup/pkg/fi/context.go +++ b/upup/pkg/fi/context.go @@ -127,11 +127,12 @@ func (c *Context) Render(a, e, changes Task) error { case LifecycleExistsAndValidates: return fmt.Errorf("Lifecycle set to ExistsAndValidates, but object was not found") case LifecycleExistsAndWarnIfChanges: - return fmt.Errorf("Lifecycle set to ExistsAndWarnIfChanges, but object was not found") + return NewExistsAndWarnIfChangesError("Lifecycle set to ExistsAndWarnIfChanges and object was not found.") } } else { switch *lifecycle { case LifecycleExistsAndValidates, LifecycleExistsAndWarnIfChanges: + out := os.Stderr changeList, err := buildChangeList(a, e, changes) if err != nil { @@ -239,3 +240,19 @@ func (c *Context) AddWarning(task Task, message string) { c.warnings = append(c.warnings, warning) glog.Warningf("warning during task %s: %s", task, message) } + +// ExistsAndWarnIfChangesError is the custom error return for fi.LifecycleExistsAndWarnIfChanges. +// This error is used when an object needs to fail validation, but let the user proceed with a warning. +type ExistsAndWarnIfChangesError struct { + msg string +} + +// NewWarnIfInsufficientAccessError is a builder for ExistsAndWarnIfChangesError. +func NewExistsAndWarnIfChangesError(message string) *ExistsAndWarnIfChangesError { + return &ExistsAndWarnIfChangesError{ + msg: message, + } +} + +// ExistsAndWarnIfChangesError implementation of the error interface. +func (e *ExistsAndWarnIfChangesError) Error() string { return e.msg } diff --git a/upup/pkg/fi/executor.go b/upup/pkg/fi/executor.go index 219c929d74..d313f59985 100644 --- a/upup/pkg/fi/executor.go +++ b/upup/pkg/fi/executor.go @@ -105,6 +105,15 @@ func (e *executor) RunTasks(taskMap map[string]Task, maxTaskDuration time.Durati for i, err := range taskErrors { ts := tasks[i] if err != nil { + // print warning message and continue like the task succeeded + if _, ok := err.(*ExistsAndWarnIfChangesError); ok { + glog.Warningf(err.Error()) + ts.done = true + ts.lastError = nil + progress = true + continue + } + remaining := time.Second * time.Duration(int(ts.deadline.Sub(time.Now()).Seconds())) glog.Warningf("error running task %q (%v remaining to succeed): %v", ts.key, remaining, err) errors = append(errors, err)