From 07063de2bf8b444ec63eac1f56f6298bf63b0a26 Mon Sep 17 00:00:00 2001 From: telyn Date: Mon, 24 Sep 2018 14:39:28 +0100 Subject: [PATCH] Add RecursiveDeleteGroupError --- cmd/bytemark/commands/delete/group.go | 21 +++++++++++++-------- cmd/bytemark/util/errors.go | 18 ++++++++++++++++++ cmd/bytemark/util/exit.go | 7 +++++-- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/cmd/bytemark/commands/delete/group.go b/cmd/bytemark/commands/delete/group.go index aac68df4..47d55184 100644 --- a/cmd/bytemark/commands/delete/group.go +++ b/cmd/bytemark/commands/delete/group.go @@ -10,7 +10,6 @@ import ( "github.com/BytemarkHosting/bytemark-client/cmd/bytemark/util" "github.com/BytemarkHosting/bytemark-client/lib" "github.com/BytemarkHosting/bytemark-client/lib/brain" - "github.com/BytemarkHosting/bytemark-client/util/log" "github.com/urfave/cli" ) @@ -43,12 +42,11 @@ If --recursive is specified, all servers in the group will be purged. Otherwise, } err = promptForRecursiveDeleteGroup(ctx) - ctx.Debug("promptForRecursiveDeleteGroup sezz %s", err) if err != nil { return } - err = deleteVmsInGroup(ctx, &groupName, ctx.Group) + err = deleteVmsInGroup(ctx, groupName, ctx.Group) if err != nil { return } @@ -57,7 +55,7 @@ If --recursive is specified, all servers in the group will be purged. Otherwise, } err = ctx.Client().DeleteGroup(groupName) if err == nil { - log.Logf("Group %s deleted successfully.\r\n", groupName.String()) + ctx.Log("\nGroup %s deleted successfully.", groupName.String()) } return }), @@ -83,19 +81,26 @@ func promptForRecursiveDeleteGroup(ctx *app.Context) error { return nil } -func deleteVmsInGroup(ctx *app.Context, name *lib.GroupName, group *brain.Group) error { - ctx.Log("Purging all VMs in %s...", name) +func deleteVmsInGroup(ctx *app.Context, name lib.GroupName, group *brain.Group) error { + ctx.Log("\nPurging all VMs in %s...", name) + + recurseErr := util.RecursiveDeleteGroupError{Group: name, Errors: map[string]error{}} vmn := lib.VirtualMachineName{Group: name.Group, Account: name.Account} for _, vm := range group.VirtualMachines { vmn.VirtualMachine = vm.Name - ctx.Log("%s...", vm.Name) + ctx.Logf("%s...", vm.Name) + err := ctx.Client().DeleteVirtualMachine(vmn, true) if err != nil { - return err + ctx.Log("failed") + recurseErr.Errors[vm.Name] = err } ctx.Log("deleted") } + if len(recurseErr.Errors) > 0 { + return recurseErr + } return nil } diff --git a/cmd/bytemark/util/errors.go b/cmd/bytemark/util/errors.go index b82e3eb6..800624da 100644 --- a/cmd/bytemark/util/errors.go +++ b/cmd/bytemark/util/errors.go @@ -2,6 +2,7 @@ package util import ( "fmt" + "strings" "github.com/BytemarkHosting/bytemark-client/lib" ) @@ -35,3 +36,20 @@ type WontDeleteGroupWithVMsError struct { func (e WontDeleteGroupWithVMsError) Error() string { return fmt.Sprintf("Group %s contains servers, will not be deleted without --recursive\r\n", e.Group) } + +// RecursiveDeleteGroupError is returned by delete group when called with --recursive, when deleting VMs. +type RecursiveDeleteGroupError struct { + Group lib.GroupName + // Map of VirtualMachine names to the error that occurred when trying to delete them. + // N.B. that this will not contain nil errors for VMs that were successfully deleted. + Errors map[string]error +} + +func (e RecursiveDeleteGroupError) Error() string { + strs := make([]string, 0, len(e.Errors)) + for vm, err := range e.Errors { + strs = append(strs, fmt.Sprintf("%s: %s", vm, err)) + } + + return fmt.Sprintf("Errors occurred while deleting VMs in group %s: \n\t%s", e.Group, strings.Join(strs, "\n\t")) +} diff --git a/cmd/bytemark/util/exit.go b/cmd/bytemark/util/exit.go index 3c8e8374..89c1134c 100644 --- a/cmd/bytemark/util/exit.go +++ b/cmd/bytemark/util/exit.go @@ -244,12 +244,15 @@ func ProcessError(err error, message ...string) ExitCode { case lib.NotFoundError: errorMessage = err.Error() exitCode = ExitCodeNotFound - case WontDeleteGroupWithVMsError: + case RecursiveDeleteGroupError: errorMessage = err.Error() - exitCode = ExitCodeWontDeletePopulated + exitCode = ExitCodeAPIInternalError case UserRequestedExit: errorMessage = "" exitCode = ExitCodeUserExit + case WontDeleteGroupWithVMsError: + errorMessage = err.Error() + exitCode = ExitCodeWontDeletePopulated case *syscall.Errno: errorMessage = fmt.Sprintf("A command we tried to execute failed. The operating system gave us the error code %d", e) exitCode = ExitCodeUnknownError