From 20cdfe7a724ac16b6407473b9cbb9663d9e9fee3 Mon Sep 17 00:00:00 2001 From: vera Date: Tue, 14 Feb 2023 21:25:37 -0500 Subject: [PATCH 1/2] Adding server prune and undeploy prune --- cli/app/undeploy.go | 48 +++++++++++++++++++++++-- cli/server/prune.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ cli/server/server.go | 1 + 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 cli/server/prune.go diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 3d1c4d95..469682b9 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -2,15 +2,25 @@ package app import ( "context" + "fmt" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" stack "coopcloud.tech/abra/pkg/upstream/stack" + "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) +var prune bool + +var pruneFlag = &cli.BoolFlag{ + Name: "prune, p", + Destination: &prune, + Usage: "Prunes unused containers, networks, and dangling images for stack", +} + var appUndeployCommand = cli.Command{ Name: "undeploy", Aliases: []string{"un"}, @@ -18,18 +28,18 @@ var appUndeployCommand = cli.Command{ Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, + pruneFlag, }, Before: internal.SubCommandBefore, Usage: "Undeploy an app", Description: ` This does not destroy any of the application data. However, you should remain vigilant, as your swarm installation will consider any previously attached -volumes as eligiblef or pruning once undeployed. +volumes as eligible for pruning once undeployed. `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() - cl, err := client.New(app.Server) if err != nil { logrus.Fatal(err) @@ -57,5 +67,39 @@ volumes as eligiblef or pruning once undeployed. return nil }, + After: func(c *cli.Context) error { + if !prune { + return nil + } + app := internal.ValidateApp(c) + stackName := app.StackName() + cl, err := client.New(app.Server) + if err != nil { + logrus.Fatal(err) + } + ctx := context.Background() + + pruneFilters := filters.NewArgs() + stackSearch := fmt.Sprintf("%s*", stackName) + pruneFilters.Add("label", stackSearch) + cr, err := cl.ContainersPrune(ctx, pruneFilters) + if err != nil { + return err + } + logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed) + + nr, err := cl.NetworksPrune(ctx, pruneFilters) + if err != nil { + return err + } + logrus.Infof("Networks deleted %s", nr.NetworksDeleted) + + ir, err := cl.ImagesPrune(ctx, pruneFilters) + if err != nil { + return err + } + logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed) + return nil + }, BashComplete: autocomplete.AppNameComplete, } diff --git a/cli/server/prune.go b/cli/server/prune.go new file mode 100644 index 00000000..49b2084a --- /dev/null +++ b/cli/server/prune.go @@ -0,0 +1,85 @@ +package server + +import ( + "context" + + "coopcloud.tech/abra/cli/internal" + "coopcloud.tech/abra/pkg/client" + "github.com/docker/docker/api/types/filters" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var allFilter bool + +var allFilterFlag = &cli.BoolFlag{ + Name: "all, a", + Usage: "Remove all unused images not just dangling ones", + Destination: &allFilter, +} + +var volunesFilter bool + +var volumesFilterFlag = &cli.BoolFlag{ + Name: "volumes, v", + Usage: "Prune volumes", + Destination: &volunesFilter, +} + +var serverPruneCommand = cli.Command{ + Name: "prune", + Aliases: []string{"p"}, + Usage: "Prune a managed server; Runs a docker system prune", + Description: ` + Prunes unused containers, networks, and dangling images + `, + ArgsUsage: "[]", + Flags: []cli.Flag{ + allFilterFlag, + volumesFilterFlag, + internal.DebugFlag, + }, + Before: internal.SubCommandBefore, + Action: func(c *cli.Context) error { + // Leaving filters empty for now + var args filters.Args + serverName := internal.ValidateServer(c) + + cl, err := client.New(serverName) + if err != nil { + return err + } + ctx := context.Background() + cr, err := cl.ContainersPrune(ctx, args) + if err != nil { + return err + } + logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed) + + nr, err := cl.NetworksPrune(ctx, args) + if err != nil { + return err + } + logrus.Infof("Networks deleted %s", nr.NetworksDeleted) + + pruneFilters := filters.NewArgs() + if allFilter { + pruneFilters.Add("dangling", "false") + } + ir, err := cl.ImagesPrune(ctx, pruneFilters) + if err != nil { + return err + } + logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed) + + if volunesFilter { + vr, err := cl.VolumesPrune(ctx, args) + if err != nil { + return err + } + logrus.Infof("Volumes deleted: %s; Space reclaimed: %v", vr.VolumesDeleted, vr.SpaceReclaimed) + } + + return nil + }, +} diff --git a/cli/server/server.go b/cli/server/server.go index b0869244..034e6fd6 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -22,5 +22,6 @@ recipes, see available flags on "abra server add" for more. serverAddCommand, serverListCommand, serverRemoveCommand, + serverPruneCommand, }, } -- 2.40.1 From 0d8191bc3ed18140796911e6ec8e8a92ec2bdb56 Mon Sep 17 00:00:00 2001 From: vera Date: Fri, 17 Feb 2023 03:24:04 -0500 Subject: [PATCH 2/2] review cleanups --- cli/app/undeploy.go | 83 +++++++++++++++++++++++++-------------------- cli/server/prune.go | 22 ++++++------ 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 469682b9..79836d24 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -3,6 +3,7 @@ package app import ( "context" "fmt" + "time" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" @@ -18,7 +19,51 @@ var prune bool var pruneFlag = &cli.BoolFlag{ Name: "prune, p", Destination: &prune, - Usage: "Prunes unused containers, networks, and dangling images for stack", + Usage: "Prunes unused containers, networks, and dangling images for an app", +} + +func cleanup(c *cli.Context) error { + for { + if !prune { + return nil + } + app := internal.ValidateApp(c) + stackName := app.StackName() + cl, err := client.New(app.Server) + if err != nil { + logrus.Fatal(err) + } + ctx := context.Background() + + pruneFilters := filters.NewArgs() + stackSearch := fmt.Sprintf("%s*", stackName) + pruneFilters.Add("label", stackSearch) + cr, err := cl.ContainersPrune(ctx, pruneFilters) + if err != nil { + logrus.Errorf(err.Error()) + time.Sleep(time.Second) + continue + } + logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed) + + nr, err := cl.NetworksPrune(ctx, pruneFilters) + if err != nil { + logrus.Errorf(err.Error()) + time.Sleep(time.Second) + continue + } + logrus.Infof("Networks deleted %s", nr.NetworksDeleted) + + ir, err := cl.ImagesPrune(ctx, pruneFilters) + if err != nil { + logrus.Errorf(err.Error()) + time.Sleep(time.Second) + continue + } + logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed) + break + } + return nil } var appUndeployCommand = cli.Command{ @@ -64,41 +109,7 @@ volumes as eligible for pruning once undeployed. if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil { logrus.Fatal(err) } - - return nil - }, - After: func(c *cli.Context) error { - if !prune { - return nil - } - app := internal.ValidateApp(c) - stackName := app.StackName() - cl, err := client.New(app.Server) - if err != nil { - logrus.Fatal(err) - } - ctx := context.Background() - - pruneFilters := filters.NewArgs() - stackSearch := fmt.Sprintf("%s*", stackName) - pruneFilters.Add("label", stackSearch) - cr, err := cl.ContainersPrune(ctx, pruneFilters) - if err != nil { - return err - } - logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed) - - nr, err := cl.NetworksPrune(ctx, pruneFilters) - if err != nil { - return err - } - logrus.Infof("Networks deleted %s", nr.NetworksDeleted) - - ir, err := cl.ImagesPrune(ctx, pruneFilters) - if err != nil { - return err - } - logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed) + cleanup(c) return nil }, BashComplete: autocomplete.AppNameComplete, diff --git a/cli/server/prune.go b/cli/server/prune.go index 49b2084a..2d59947f 100644 --- a/cli/server/prune.go +++ b/cli/server/prune.go @@ -27,13 +27,11 @@ var volumesFilterFlag = &cli.BoolFlag{ } var serverPruneCommand = cli.Command{ - Name: "prune", - Aliases: []string{"p"}, - Usage: "Prune a managed server; Runs a docker system prune", - Description: ` - Prunes unused containers, networks, and dangling images - `, - ArgsUsage: "[]", + Name: "prune", + Aliases: []string{"p"}, + Usage: "Prune a managed server; Runs a docker system prune", + Description: "Prunes unused containers, networks, and dangling images", + ArgsUsage: "[]", Flags: []cli.Flag{ allFilterFlag, volumesFilterFlag, @@ -47,18 +45,18 @@ var serverPruneCommand = cli.Command{ cl, err := client.New(serverName) if err != nil { - return err + logrus.Fatal(err) } ctx := context.Background() cr, err := cl.ContainersPrune(ctx, args) if err != nil { - return err + logrus.Fatal(err) } logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed) nr, err := cl.NetworksPrune(ctx, args) if err != nil { - return err + logrus.Fatal(err) } logrus.Infof("Networks deleted %s", nr.NetworksDeleted) @@ -68,14 +66,14 @@ var serverPruneCommand = cli.Command{ } ir, err := cl.ImagesPrune(ctx, pruneFilters) if err != nil { - return err + logrus.Fatal(err) } logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed) if volunesFilter { vr, err := cl.VolumesPrune(ctx, args) if err != nil { - return err + logrus.Fatal(err) } logrus.Infof("Volumes deleted: %s; Space reclaimed: %v", vr.VolumesDeleted, vr.SpaceReclaimed) } -- 2.40.1