Adding server prune and undeploy prune #278

Merged
decentral1se merged 2 commits from codegod100/abra:prune into main 2023-02-17 08:53:47 +00:00
3 changed files with 142 additions and 3 deletions

View File

@ -2,15 +2,70 @@ package app
import (
"context"
"fmt"
"time"
"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,
codegod100 marked this conversation as resolved
Review

stack 👉 an app

`stack` 👉 `an app`
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{
Name: "undeploy",
codegod100 marked this conversation as resolved Outdated

Hmmm, I'm not sure we should be putting this in After as it has some not obvious runtime behaviour (see https://pkg.go.dev/github.com/urfave/cli/v2#AfterFunc) and also the --prune is part of the normal functioning of the sub-command, not a thing to happen after execution? Perhaps abstracting to a function and calling from the main Action?

Hmmm, I'm not sure we should be putting this in `After` as it has some not obvious runtime behaviour (see https://pkg.go.dev/github.com/urfave/cli/v2#AfterFunc) and also the `--prune` is part of the normal functioning of the sub-command, not a thing to happen after execution? Perhaps abstracting to a function and calling from the main `Action`?

this part? it is run even if Action() panics
The issue I was trying to tackle is that pruning while docker container is still running is kinda pointless. when we run abra app undeploy It takes clock time for the container to spin down. maybe we put an arbitrary wait in there? I hate doing that but not sure another way since we are done talking to docker by the time the actual spindown happens.

this part? `it is run even if Action() panics` The issue I was trying to tackle is that pruning while docker container is still running is kinda pointless. when we run `abra app undeploy` It takes clock time for the container to spin down. maybe we put an arbitrary wait in there? I hate doing that but not sure another way since we are done talking to docker by the time the actual spindown happens.

Aha, I see. Could you just poll every second for the stack until it goes away? Then you can drop into the pruning logic after and still keep it all in the main Action code path.

Aha, I see. Could you just poll every second for the stack until it goes away? Then you can drop into the pruning logic after and still keep it all in the main `Action` code path.
Aliases: []string{"un"},
@ -18,6 +73,7 @@ var appUndeployCommand = cli.Command{
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
pruneFlag,
},
Before: internal.SubCommandBefore,
Usage: "Undeploy an app",
@ -29,7 +85,6 @@ volumes as eligiblef or pruning once undeployed.
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
stackName := app.StackName()
codegod100 marked this conversation as resolved Outdated

logrus.Fatal(err)

`logrus.Fatal(err)`
cl, err := client.New(app.Server)
if err != nil {
logrus.Fatal(err)
@ -54,7 +109,7 @@ volumes as eligiblef or pruning once undeployed.
if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil {
logrus.Fatal(err)
}
cleanup(c)
return nil
},
BashComplete: autocomplete.AppNameComplete,

83
cli/server/prune.go Normal file
View File

@ -0,0 +1,83 @@
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",
codegod100 marked this conversation as resolved Outdated

Could be a "..." oneliner after all?

Could be a `"..."` oneliner after all?
ArgsUsage: "[<server>]",
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 {
logrus.Fatal(err)
}
ctx := context.Background()
codegod100 marked this conversation as resolved
Review

logrus.Fatal(err)

`logrus.Fatal(err)`
cr, err := cl.ContainersPrune(ctx, args)
if err != nil {
logrus.Fatal(err)
}
logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed)
codegod100 marked this conversation as resolved
Review

logrus.Fatal(err)

`logrus.Fatal(err)`
nr, err := cl.NetworksPrune(ctx, args)
if err != nil {
logrus.Fatal(err)
}
logrus.Infof("Networks deleted %s", nr.NetworksDeleted)
codegod100 marked this conversation as resolved
Review

logrus.Fatal(err)

`logrus.Fatal(err)`
pruneFilters := filters.NewArgs()
if allFilter {
pruneFilters.Add("dangling", "false")
}
ir, err := cl.ImagesPrune(ctx, pruneFilters)
if err != nil {
logrus.Fatal(err)
}
logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed)
codegod100 marked this conversation as resolved
Review

logrus.Fatal(err)

`logrus.Fatal(err)`
if volunesFilter {
vr, err := cl.VolumesPrune(ctx, args)
if err != nil {
logrus.Fatal(err)
}
logrus.Infof("Volumes deleted: %s; Space reclaimed: %v", vr.VolumesDeleted, vr.SpaceReclaimed)
codegod100 marked this conversation as resolved
Review

logrus.Fatal(err)

`logrus.Fatal(err)`
}
return nil
},
}

View File

@ -22,5 +22,6 @@ recipes, see available flags on "abra server add" for more.
serverAddCommand,
serverListCommand,
serverRemoveCommand,
serverPruneCommand,
},
}