From fba20b981b91701c74d3afd061b98f3b98bcaec5 Mon Sep 17 00:00:00 2001 From: Christopher Obbard Date: Wed, 5 Jan 2022 12:09:27 +0000 Subject: [PATCH] actions/recipe: Fix handling of action cleanup errors Unify the recipe action to handle action cleanup errors in the same way as Debos handles the cleanup functions. Specifically: - run all cleanup functions, even if a previous one failed, - run cleanup functions in the reverse order to the action, - report all errors during cleanup. Fixes: 74df488fb6b0 ("actions: Add recipe action") Signed-off-by: Christopher Obbard --- actions/recipe_action.go | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/actions/recipe_action.go b/actions/recipe_action.go index 9fa3b1c9..6887f1ef 100644 --- a/actions/recipe_action.go +++ b/actions/recipe_action.go @@ -125,11 +125,17 @@ func (recipe *RecipeAction) Run(context *debos.DebosContext) error { return nil } -func (recipe *RecipeAction) Cleanup(context *debos.DebosContext) error { +func (recipe *RecipeAction) Cleanup(context *debos.DebosContext) (err error) { for _, a := range recipe.Actions.Actions { - if err := a.Cleanup(&recipe.context); err != nil { - return err - } + defer func(action debos.Action) { + cleanup_err := action.Cleanup(context) + + /* Cannot bubble multiple errors, so check for an error locally and + * return a generic error if the child recipe failed to cleanup. */ + if defer_exitcode := debos.CheckError(context, cleanup_err, action, "Cleanup"); defer_exitcode != 0 { + err = errors.New("Child recipe failed") + } + }(a) } return nil @@ -145,11 +151,17 @@ func (recipe *RecipeAction) PostMachine(context *debos.DebosContext) error { return nil } -func (recipe *RecipeAction) PostMachineCleanup(context *debos.DebosContext) error { +func (recipe *RecipeAction) PostMachineCleanup(context *debos.DebosContext) (err error) { for _, a := range recipe.Actions.Actions { - if err := a.PostMachineCleanup(&recipe.context); err != nil { - return err - } + defer func(action debos.Action) { + cleanup_err := action.PostMachineCleanup(context) + + /* Cannot bubble multiple errors, so check for an error locally and + * return a generic error if the child recipe failed to cleanup. */ + if defer_exitcode := debos.CheckError(context, cleanup_err, action, "PostMachineCleanup"); defer_exitcode != 0 { + err = errors.New("Child recipe failed") + } + }(a) } return nil