package server import ( "context" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "github.com/docker/docker/api/types/filters" "github.com/urfave/cli/v3" ) var allFilter bool var allFilterFlag = &cli.BoolFlag{ Name: "all", Aliases: []string{"a"}, Usage: "Remove all unused images not just dangling ones", Destination: &allFilter, } var volumesFilter bool var volumesFilterFlag = &cli.BoolFlag{ Name: "volumes", Aliases: []string{"v"}, Usage: "Prune volumes. This will remove app data, Be Careful!", Destination: &volumesFilter, } var serverPruneCommand = cli.Command{ Name: "prune", Aliases: []string{"p"}, Usage: "Prune resources on a server", UsageText: "abra server prune [options] ", HideHelpCommand: true, Description: `Prunes unused containers, networks, and dangling images. Use "-v/--volumes" to remove volumes that are not associated with a deployed app. This can result in unwanted data loss if not used carefully.`, ArgsUsage: "[]", Flags: []cli.Flag{ allFilterFlag, volumesFilterFlag, }, Before: internal.SubCommandBefore, EnableShellCompletion: true, ShellComplete: autocomplete.ServerNameComplete, Action: func(ctx context.Context, cmd *cli.Command) error { serverName := internal.ValidateServer(cmd) cl, err := client.New(serverName) if err != nil { log.Fatal(err) } var args filters.Args cr, err := cl.ContainersPrune(ctx, args) if err != nil { log.Fatal(err) } cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed) log.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed) nr, err := cl.NetworksPrune(ctx, args) if err != nil { log.Fatal(err) } log.Infof("networks pruned: %d", len(nr.NetworksDeleted)) pruneFilters := filters.NewArgs() if allFilter { log.Debugf("removing all images, not only dangling ones") pruneFilters.Add("dangling", "false") } ir, err := cl.ImagesPrune(ctx, pruneFilters) if err != nil { log.Fatal(err) } imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed) log.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed) if volumesFilter { vr, err := cl.VolumesPrune(ctx, args) if err != nil { log.Fatal(err) } volSpaceReclaimed := formatter.ByteCountSI(vr.SpaceReclaimed) log.Infof("volumes pruned: %d; space reclaimed: %s", len(vr.VolumesDeleted), volSpaceReclaimed) } return nil }, }