abra/cli/app/undeploy.go

139 lines
3.5 KiB
Go
Raw Normal View History

package app
2021-08-29 23:36:42 +00:00
import (
"context"
2023-02-15 02:25:37 +00:00
"fmt"
2023-02-17 08:24:04 +00:00
"time"
2021-08-29 23:36:42 +00:00
"coopcloud.tech/abra/cli/internal"
2021-12-11 23:17:39 +00:00
"coopcloud.tech/abra/pkg/autocomplete"
2021-09-05 19:37:03 +00:00
"coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config"
2023-02-19 09:28:18 +00:00
"coopcloud.tech/abra/pkg/formatter"
stack "coopcloud.tech/abra/pkg/upstream/stack"
2023-02-15 02:25:37 +00:00
"github.com/docker/docker/api/types/filters"
dockerClient "github.com/docker/docker/client"
2021-08-29 23:36:42 +00:00
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
2021-08-29 23:36:42 +00:00
)
2023-02-15 02:25:37 +00:00
var prune bool
var pruneFlag = &cli.BoolFlag{
Name: "prune, p",
Destination: &prune,
2023-02-17 08:24:04 +00:00
Usage: "Prunes unused containers, networks, and dangling images for an app",
}
// pruneApp runs the equivalent of a "docker system prune" but only filtering
// against resources connected with the app deployment. It is not a system wide
// prune. Volumes are not pruned to avoid unwated data loss.
func pruneApp(c *cli.Context, cl *dockerClient.Client, app config.App) error {
stackName := app.StackName()
ctx := context.Background()
for {
logrus.Debugf("polling for %s stack, waiting to be undeployed...", stackName)
2023-02-17 08:24:04 +00:00
services, err := stack.GetStackServices(ctx, cl, stackName)
2023-02-17 08:24:04 +00:00
if err != nil {
return err
2023-02-17 08:24:04 +00:00
}
if len(services) == 0 {
logrus.Debugf("%s undeployed, moving on with pruning logic", stackName)
time.Sleep(time.Second) // give runtime more time to tear down related state
break
2023-02-17 08:24:04 +00:00
}
time.Sleep(time.Second)
}
2023-02-17 08:24:04 +00:00
pruneFilters := filters.NewArgs()
stackSearch := fmt.Sprintf("%s*", stackName)
pruneFilters.Add("label", stackSearch)
cr, err := cl.ContainersPrune(ctx, pruneFilters)
if err != nil {
return err
}
2023-02-19 09:28:18 +00:00
cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed)
logrus.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)
nr, err := cl.NetworksPrune(ctx, pruneFilters)
if err != nil {
return err
2023-02-17 08:24:04 +00:00
}
2023-02-19 09:28:18 +00:00
logrus.Infof("networks pruned: %d", len(nr.NetworksDeleted))
ir, err := cl.ImagesPrune(ctx, pruneFilters)
if err != nil {
return err
}
2023-02-19 09:28:18 +00:00
imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed)
logrus.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)
2023-02-17 08:24:04 +00:00
return nil
2023-02-15 02:25:37 +00:00
}
var appUndeployCommand = cli.Command{
2022-01-25 12:48:04 +00:00
Name: "undeploy",
Aliases: []string{"un"},
ArgsUsage: "<domain>",
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
2023-02-15 02:25:37 +00:00
pruneFlag,
},
Before: internal.SubCommandBefore,
Usage: "Undeploy an app",
BashComplete: autocomplete.AppNameComplete,
2021-09-04 23:34:56 +00:00
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 eligible for pruning once undeployed.
Passing "-p/--prune" does not remove those volumes.
2021-09-04 23:34:56 +00:00
`,
2021-08-29 23:36:42 +00:00
Action: func(c *cli.Context) error {
2023-09-07 16:50:25 +00:00
app := internal.ValidateApp(c)
2021-10-21 13:10:43 +00:00
stackName := app.StackName()
cl, err := client.New(app.Server)
2021-08-29 23:36:42 +00:00
if err != nil {
logrus.Fatal(err)
}
2021-12-25 01:03:09 +00:00
logrus.Debugf("checking whether %s is already deployed", stackName)
2021-10-21 13:10:43 +00:00
isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName)
2021-10-21 13:10:43 +00:00
if err != nil {
logrus.Fatal(err)
}
if !isDeployed {
2022-01-01 16:22:19 +00:00
logrus.Fatalf("%s is not deployed?", app.Name)
2021-10-21 13:10:43 +00:00
}
2023-09-07 16:50:25 +00:00
if err := internal.DeployOverview(app, deployedVersion, "continue with undeploy?"); err != nil {
2021-10-21 13:10:43 +00:00
logrus.Fatal(err)
}
rmOpts := stack.Remove{Namespaces: []string{app.StackName()}}
if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil {
2021-08-29 23:36:42 +00:00
logrus.Fatal(err)
}
if prune {
if err := pruneApp(c, cl, app); err != nil {
logrus.Fatal(err)
}
}
2023-02-15 02:25:37 +00:00
return nil
},
}