abra/cli/app/undeploy.go

138 lines
3.4 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"
2021-08-29 23:36:42 +00:00
"coopcloud.tech/abra/cli/internal"
appPkg "coopcloud.tech/abra/pkg/app"
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"
2024-07-16 23:23:12 +00:00
"coopcloud.tech/abra/pkg/config"
2023-02-19 09:28:18 +00:00
"coopcloud.tech/abra/pkg/formatter"
2024-07-07 21:45:37 +00:00
"coopcloud.tech/abra/pkg/log"
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"
2024-12-26 16:53:25 +00:00
"github.com/spf13/cobra"
2021-08-29 23:36:42 +00:00
)
2024-12-26 16:53:25 +00:00
var AppUndeployCommand = &cobra.Command{
Use: "undeploy <app> [flags]",
Aliases: []string{"un"},
Short: "Undeploy an app",
Long: `This does not destroy any application data.
However, you should remain vigilant, as your swarm installation will consider
any previously attached volumes as eligible for pruning once undeployed.
2024-12-26 16:53:25 +00:00
Passing "--prune/-p" does not remove those volumes.`,
Args: cobra.ExactArgs(1),
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
return autocomplete.AppNameComplete()
},
Run: func(cmd *cobra.Command, args []string) {
app := internal.ValidateApp(args)
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 {
2024-07-07 21:45:37 +00:00
log.Fatal(err)
2021-08-29 23:36:42 +00:00
}
2024-07-07 21:45:37 +00:00
log.Debugf("checking whether %s is already deployed", stackName)
2021-10-21 13:10:43 +00:00
deployMeta, err := stack.IsDeployed(context.Background(), cl, stackName)
2021-10-21 13:10:43 +00:00
if err != nil {
2024-07-07 21:45:37 +00:00
log.Fatal(err)
2021-10-21 13:10:43 +00:00
}
if !deployMeta.IsDeployed {
2024-07-07 21:45:37 +00:00
log.Fatalf("%s is not deployed?", app.Name)
2021-10-21 13:10:43 +00:00
}
2024-07-16 23:23:12 +00:00
chaosVersion := config.CHAOS_DEFAULT
2024-07-09 09:34:01 +00:00
if deployMeta.IsChaos {
chaosVersion = deployMeta.ChaosVersion
}
if err := internal.UndeployOverview(
app,
deployMeta.Version,
chaosVersion); err != nil {
2024-07-07 21:45:37 +00:00
log.Fatal(err)
2021-10-21 13:10:43 +00:00
}
rmOpts := stack.Remove{
Namespaces: []string{app.StackName()},
Detach: false,
}
if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil {
2024-07-07 21:45:37 +00:00
log.Fatal(err)
2021-08-29 23:36:42 +00:00
}
if prune {
if err := pruneApp(cl, app); err != nil {
2024-07-07 21:45:37 +00:00
log.Fatal(err)
}
}
if err := app.WriteRecipeVersion(deployMeta.Version, false); err != nil {
log.Fatalf("writing undeployed recipe version in env file: %s", err)
}
2023-02-15 02:25:37 +00:00
},
}
2024-12-26 16:53:25 +00:00
// 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(cl *dockerClient.Client, app appPkg.App) error {
stackName := app.StackName()
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
}
cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed)
log.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)
nr, err := cl.NetworksPrune(ctx, pruneFilters)
if err != nil {
return err
}
log.Infof("networks pruned: %d", len(nr.NetworksDeleted))
ir, err := cl.ImagesPrune(ctx, pruneFilters)
if err != nil {
return err
}
imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed)
log.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)
return nil
}
var (
prune bool
)
func init() {
AppUndeployCommand.Flags().BoolVarP(
&prune,
"prune",
"p",
false,
"prune unused containers, networks, and dangling images",
)
}