Compare commits
2 Commits
0.7.0-rc3-
...
prune
Author | SHA1 | Date | |
---|---|---|---|
0d8191bc3e | |||
20cdfe7a72 |
@ -5,11 +5,9 @@
|
|||||||
|
|
||||||
- 3wordchant
|
- 3wordchant
|
||||||
- cassowary
|
- cassowary
|
||||||
- codegod100
|
|
||||||
- decentral1se
|
- decentral1se
|
||||||
- frando
|
- frando
|
||||||
- kawaiipunk
|
- kawaiipunk
|
||||||
- knoflook
|
- knoflook
|
||||||
- moritz
|
- moritz
|
||||||
- roxxers
|
- roxxers
|
||||||
- yksflip
|
|
||||||
|
@ -53,7 +53,7 @@ recipes.
|
|||||||
conf := runtime.New()
|
conf := runtime.New()
|
||||||
|
|
||||||
if !internal.Chaos {
|
if !internal.Chaos {
|
||||||
if err := recipe.EnsureUpToDate(app.Recipe, conf); err != nil {
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,8 @@ import (
|
|||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
|
||||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
dockerClient "github.com/docker/docker/client"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -25,56 +22,47 @@ var pruneFlag = &cli.BoolFlag{
|
|||||||
Usage: "Prunes unused containers, networks, and dangling images for an app",
|
Usage: "Prunes unused containers, networks, and dangling images for an app",
|
||||||
}
|
}
|
||||||
|
|
||||||
// pruneApp runs the equivalent of a "docker system prune" but only filtering
|
func cleanup(c *cli.Context) error {
|
||||||
// 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 {
|
for {
|
||||||
logrus.Debugf("polling for %s stack, waiting to be undeployed...", stackName)
|
if !prune {
|
||||||
|
return nil
|
||||||
services, err := stack.GetStackServices(ctx, cl, stackName)
|
}
|
||||||
|
app := internal.ValidateApp(c)
|
||||||
|
stackName := app.StackName()
|
||||||
|
cl, err := client.New(app.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
logrus.Fatal(err)
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
pruneFilters := filters.NewArgs()
|
pruneFilters := filters.NewArgs()
|
||||||
stackSearch := fmt.Sprintf("%s*", stackName)
|
stackSearch := fmt.Sprintf("%s*", stackName)
|
||||||
pruneFilters.Add("label", stackSearch)
|
pruneFilters.Add("label", stackSearch)
|
||||||
cr, err := cl.ContainersPrune(ctx, pruneFilters)
|
cr, err := cl.ContainersPrune(ctx, pruneFilters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
logrus.Errorf(err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed)
|
||||||
cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed)
|
|
||||||
logrus.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)
|
|
||||||
|
|
||||||
nr, err := cl.NetworksPrune(ctx, pruneFilters)
|
nr, err := cl.NetworksPrune(ctx, pruneFilters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
logrus.Errorf(err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Networks deleted %s", nr.NetworksDeleted)
|
||||||
logrus.Infof("networks pruned: %d", len(nr.NetworksDeleted))
|
|
||||||
|
|
||||||
ir, err := cl.ImagesPrune(ctx, pruneFilters)
|
ir, err := cl.ImagesPrune(ctx, pruneFilters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
logrus.Errorf(err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed)
|
|
||||||
logrus.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,14 +77,10 @@ var appUndeployCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Usage: "Undeploy an app",
|
Usage: "Undeploy an app",
|
||||||
BashComplete: autocomplete.AppNameComplete,
|
|
||||||
Description: `
|
Description: `
|
||||||
This does not destroy any of the application data.
|
This does not destroy any of the application data. However, you should remain
|
||||||
|
vigilant, as your swarm installation will consider any previously attached
|
||||||
However, you should remain vigilant, as your swarm installation will consider
|
volumes as eligible for pruning once undeployed.
|
||||||
any previously attached volumes as eligible for pruning once undeployed.
|
|
||||||
|
|
||||||
Passing "-p/--prune" does not remove those volumes.
|
|
||||||
`,
|
`,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(c)
|
||||||
@ -125,13 +109,8 @@ Passing "-p/--prune" does not remove those volumes.
|
|||||||
if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil {
|
if err := stack.RunRemove(context.Background(), cl, rmOpts); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
cleanup(c)
|
||||||
if prune {
|
|
||||||
if err := pruneApp(c, cl, app); err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
BashComplete: autocomplete.AppNameComplete,
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ recipes.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !internal.Chaos {
|
if !internal.Chaos {
|
||||||
if err := recipe.EnsureUpToDate(app.Recipe, conf); err != nil {
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/abra/pkg/runtime"
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -55,8 +54,6 @@ keys configured on your account.
|
|||||||
ArgsUsage: "[<recipe>]",
|
ArgsUsage: "[<recipe>]",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipeName := c.Args().First()
|
recipeName := c.Args().First()
|
||||||
conf := runtime.New()
|
|
||||||
|
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
internal.ValidateRecipe(c)
|
internal.ValidateRecipe(c)
|
||||||
}
|
}
|
||||||
@ -82,7 +79,7 @@ keys configured on your account.
|
|||||||
|
|
||||||
if !internal.SkipUpdates {
|
if !internal.SkipUpdates {
|
||||||
logrus.Warn(logMsg)
|
logrus.Warn(logMsg)
|
||||||
if err := recipe.UpdateRepositories(repos, recipeName, conf); err != nil {
|
if err := recipe.UpdateRepositories(repos, recipeName); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +97,7 @@ keys configured on your account.
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
versions, err := recipe.GetRecipeVersions(recipeMeta.Name, conf)
|
versions, err := recipe.GetRecipeVersions(recipeMeta.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Warn(err)
|
logrus.Warn(err)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ func DeployAction(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !Chaos {
|
if !Chaos {
|
||||||
if err := recipe.EnsureUpToDate(app.Recipe, conf); err != nil {
|
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,7 @@ func ensureServerFlag() error {
|
|||||||
func NewAction(c *cli.Context) error {
|
func NewAction(c *cli.Context) error {
|
||||||
recipe := ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false))
|
recipe := ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false))
|
||||||
|
|
||||||
conf := runtime.New(runtime.WithEnsureRecipeLatest(false))
|
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||||
if err := recipePkg.EnsureUpToDate(recipe.Name, conf); err != nil {
|
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +42,11 @@ func ValidateRecipe(c *cli.Context, opts ...runtime.Option) recipe.Recipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.EnsureRecipeLatest {
|
||||||
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logrus.Debugf("validated %s as recipe argument", recipeName)
|
logrus.Debugf("validated %s as recipe argument", recipeName)
|
||||||
|
|
||||||
@ -108,9 +110,11 @@ func ValidateRecipeWithPrompt(c *cli.Context, opts ...runtime.Option) recipe.Rec
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.EnsureRecipeLatest {
|
||||||
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logrus.Debugf("validated %s as recipe argument", recipeName)
|
logrus.Debugf("validated %s as recipe argument", recipeName)
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/abra/pkg/runtime"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -22,8 +21,6 @@ var recipeFetchCommand = cli.Command{
|
|||||||
BashComplete: autocomplete.RecipeNameComplete,
|
BashComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipeName := c.Args().First()
|
recipeName := c.Args().First()
|
||||||
conf := runtime.New()
|
|
||||||
|
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
internal.ValidateRecipe(c)
|
internal.ValidateRecipe(c)
|
||||||
return nil // ValidateRecipe ensures latest checkout
|
return nil // ValidateRecipe ensures latest checkout
|
||||||
@ -34,7 +31,7 @@ var recipeFetchCommand = cli.Command{
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := recipe.UpdateRepositories(repos, recipeName, conf); err != nil {
|
if err := recipe.UpdateRepositories(repos, recipeName); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
"coopcloud.tech/abra/pkg/lint"
|
"coopcloud.tech/abra/pkg/lint"
|
||||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/abra/pkg/runtime"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -26,9 +25,8 @@ var recipeLintCommand = cli.Command{
|
|||||||
BashComplete: autocomplete.RecipeNameComplete,
|
BashComplete: autocomplete.RecipeNameComplete,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := internal.ValidateRecipe(c)
|
recipe := internal.ValidateRecipe(c)
|
||||||
conf := runtime.New()
|
|
||||||
|
|
||||||
if err := recipePkg.EnsureUpToDate(recipe.Name, conf); err != nil {
|
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/abra/pkg/runtime"
|
|
||||||
"coopcloud.tech/tagcmp"
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
@ -61,9 +60,8 @@ You may invoke this command in "wizard" mode and be prompted for input:
|
|||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := internal.ValidateRecipeWithPrompt(c)
|
recipe := internal.ValidateRecipeWithPrompt(c)
|
||||||
conf := runtime.New()
|
|
||||||
|
|
||||||
if err := recipePkg.EnsureUpToDate(recipe.Name, conf); err != nil {
|
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,11 @@ var serverListCommand = cli.Command{
|
|||||||
|
|
||||||
tableColumns := []string{"name", "host", "user", "port"}
|
tableColumns := []string{"name", "host", "user", "port"}
|
||||||
table := formatter.CreateTable(tableColumns)
|
table := formatter.CreateTable(tableColumns)
|
||||||
|
if internal.MachineReadable {
|
||||||
|
defer table.JSONRender()
|
||||||
|
} else {
|
||||||
|
defer table.Render()
|
||||||
|
}
|
||||||
serverNames, err := config.ReadServerNames()
|
serverNames, err := config.ReadServerNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
@ -80,16 +84,6 @@ var serverListCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if internal.MachineReadable {
|
|
||||||
table.JSONRender()
|
|
||||||
} else {
|
|
||||||
if problemsFilter && table.NumLines() == 0 {
|
|
||||||
logrus.Info("all servers wired up correctly 👏")
|
|
||||||
} else {
|
|
||||||
table.Render()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -24,7 +22,7 @@ var volunesFilter bool
|
|||||||
|
|
||||||
var volumesFilterFlag = &cli.BoolFlag{
|
var volumesFilterFlag = &cli.BoolFlag{
|
||||||
Name: "volumes, v",
|
Name: "volumes, v",
|
||||||
Usage: "Prune volumes. This will remove app data, Be Careful!",
|
Usage: "Prune volumes",
|
||||||
Destination: &volunesFilter,
|
Destination: &volunesFilter,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,12 +30,7 @@ var serverPruneCommand = cli.Command{
|
|||||||
Name: "prune",
|
Name: "prune",
|
||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Usage: "Prune a managed server; Runs a docker system prune",
|
Usage: "Prune a managed server; Runs a docker system prune",
|
||||||
Description: `
|
Description: "Prunes unused containers, networks, and dangling images",
|
||||||
Prunes unused containers, networks, and dangling images.
|
|
||||||
|
|
||||||
If passing "-v/--volumes" then volumes not connected with a deployed app will
|
|
||||||
also be removed. This can result in unwanted data loss if not used carefully.
|
|
||||||
`,
|
|
||||||
ArgsUsage: "[<server>]",
|
ArgsUsage: "[<server>]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
allFilterFlag,
|
allFilterFlag,
|
||||||
@ -45,54 +38,44 @@ also be removed. This can result in unwanted data loss if not used carefully.
|
|||||||
internal.DebugFlag,
|
internal.DebugFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.ServerNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
|
// Leaving filters empty for now
|
||||||
var args filters.Args
|
var args filters.Args
|
||||||
|
|
||||||
serverName := internal.ValidateServer(c)
|
serverName := internal.ValidateServer(c)
|
||||||
|
|
||||||
cl, err := client.New(serverName)
|
cl, err := client.New(serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
cr, err := cl.ContainersPrune(ctx, args)
|
cr, err := cl.ContainersPrune(ctx, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Containers deleted: %s; Space reclaimed: %v", cr.ContainersDeleted, cr.SpaceReclaimed)
|
||||||
cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed)
|
|
||||||
logrus.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)
|
|
||||||
|
|
||||||
nr, err := cl.NetworksPrune(ctx, args)
|
nr, err := cl.NetworksPrune(ctx, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Networks deleted %s", nr.NetworksDeleted)
|
||||||
logrus.Infof("networks pruned: %d", len(nr.NetworksDeleted))
|
|
||||||
|
|
||||||
pruneFilters := filters.NewArgs()
|
pruneFilters := filters.NewArgs()
|
||||||
if allFilter {
|
if allFilter {
|
||||||
pruneFilters.Add("dangling", "false")
|
pruneFilters.Add("dangling", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
ir, err := cl.ImagesPrune(ctx, pruneFilters)
|
ir, err := cl.ImagesPrune(ctx, pruneFilters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Images deleted: %s; Space reclaimed: %v", ir.ImagesDeleted, ir.SpaceReclaimed)
|
||||||
imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed)
|
|
||||||
logrus.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)
|
|
||||||
|
|
||||||
if volunesFilter {
|
if volunesFilter {
|
||||||
vr, err := cl.VolumesPrune(ctx, args)
|
vr, err := cl.VolumesPrune(ctx, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
logrus.Infof("Volumes deleted: %s; Space reclaimed: %v", vr.VolumesDeleted, vr.SpaceReclaimed)
|
||||||
volSpaceReclaimed := formatter.ByteCountSI(vr.SpaceReclaimed)
|
|
||||||
logrus.Infof("volumes pruned: %d; space reclaimed: %s", len(vr.VolumesDeleted), volSpaceReclaimed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
@ -126,7 +125,6 @@ like tears in rain.
|
|||||||
internal.HetznerCloudAPITokenFlag,
|
internal.HetznerCloudAPITokenFlag,
|
||||||
},
|
},
|
||||||
Before: internal.SubCommandBefore,
|
Before: internal.SubCommandBefore,
|
||||||
BashComplete: autocomplete.ServerNameComplete,
|
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
serverName := internal.ValidateServer(c)
|
serverName := internal.ValidateServer(c)
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ func processRecipeRepoVersion(recipeName, version string, conf *runtime.Config)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := recipe.EnsureUpToDate(recipeName, conf); err != nil {
|
if err := recipe.EnsureUpToDate(recipeName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppNameComplete copletes app names.
|
// AppNameComplete copletes app names
|
||||||
func AppNameComplete(c *cli.Context) {
|
func AppNameComplete(c *cli.Context) {
|
||||||
appNames, err := config.GetAppNames()
|
appNames, err := config.GetAppNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -25,7 +25,7 @@ func AppNameComplete(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecipeNameComplete completes recipe names.
|
// RecipeNameComplete completes recipe names
|
||||||
func RecipeNameComplete(c *cli.Context) {
|
func RecipeNameComplete(c *cli.Context) {
|
||||||
catl, err := recipe.ReadRecipeCatalogue()
|
catl, err := recipe.ReadRecipeCatalogue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -41,23 +41,7 @@ func RecipeNameComplete(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerNameComplete completes server names.
|
// SubcommandComplete completes subcommands.
|
||||||
func ServerNameComplete(c *cli.Context) {
|
|
||||||
files, err := config.LoadAppFiles("")
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.NArg() > 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, appFile := range files {
|
|
||||||
fmt.Println(appFile.Server)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubcommandComplete completes sub-commands.
|
|
||||||
func SubcommandComplete(c *cli.Context) {
|
func SubcommandComplete(c *cli.Context) {
|
||||||
if c.NArg() > 0 {
|
if c.NArg() > 0 {
|
||||||
return
|
return
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -71,21 +70,3 @@ func StripTagMeta(image string) string {
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByteCountSI presents a human friendly representation of a byte count. See
|
|
||||||
// https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format.
|
|
||||||
func ByteCountSI(b uint64) string {
|
|
||||||
const unit = 1000
|
|
||||||
|
|
||||||
if b < unit {
|
|
||||||
return fmt.Sprintf("%d B", b)
|
|
||||||
}
|
|
||||||
|
|
||||||
div, exp := uint64(unit), 0
|
|
||||||
for n := b / unit; n >= unit; n /= unit {
|
|
||||||
div *= unit
|
|
||||||
exp++
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMGTPE"[exp])
|
|
||||||
}
|
|
||||||
|
@ -339,10 +339,6 @@ func EnsureVersion(recipeName, version string) error {
|
|||||||
|
|
||||||
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
|
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
|
||||||
func EnsureLatest(recipeName string, conf *runtime.Config) error {
|
func EnsureLatest(recipeName string, conf *runtime.Config) error {
|
||||||
if !conf.EnsureRecipeLatest {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||||
|
|
||||||
isClean, err := gitPkg.IsClean(recipeDir)
|
isClean, err := gitPkg.IsClean(recipeDir)
|
||||||
@ -587,11 +583,7 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EnsureUpToDate ensures that the local repo is synced to the remote
|
// EnsureUpToDate ensures that the local repo is synced to the remote
|
||||||
func EnsureUpToDate(recipeName string, conf *runtime.Config) error {
|
func EnsureUpToDate(recipeName string) error {
|
||||||
if !conf.EnsureRecipeLatest {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||||
|
|
||||||
isClean, err := gitPkg.IsClean(recipeDir)
|
isClean, err := gitPkg.IsClean(recipeDir)
|
||||||
@ -936,8 +928,10 @@ func ReadReposMetadata() (RepoCatalogue, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRecipeVersions retrieves all recipe versions.
|
// GetRecipeVersions retrieves all recipe versions.
|
||||||
func GetRecipeVersions(recipeName string, conf *runtime.Config) (RecipeVersions, error) {
|
func GetRecipeVersions(recipeName string, opts ...runtime.Option) (RecipeVersions, error) {
|
||||||
versions := RecipeVersions{}
|
versions := RecipeVersions{}
|
||||||
|
conf := runtime.New(opts...)
|
||||||
|
|
||||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||||
|
|
||||||
logrus.Debugf("attempting to open git repository in %s", recipeDir)
|
logrus.Debugf("attempting to open git repository in %s", recipeDir)
|
||||||
@ -1039,7 +1033,7 @@ func GetRecipeCatalogueVersions(recipeName string, catl RecipeCatalogue) ([]stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRepositories clones and updates all recipe repositories locally.
|
// UpdateRepositories clones and updates all recipe repositories locally.
|
||||||
func UpdateRepositories(repos RepoCatalogue, recipeName string, conf *runtime.Config) error {
|
func UpdateRepositories(repos RepoCatalogue, recipeName string) error {
|
||||||
var barLength int
|
var barLength int
|
||||||
if recipeName != "" {
|
if recipeName != "" {
|
||||||
barLength = 1
|
barLength = 1
|
||||||
@ -1073,7 +1067,7 @@ func UpdateRepositories(repos RepoCatalogue, recipeName string, conf *runtime.Co
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := EnsureUpToDate(rm.Name, conf); err != nil {
|
if err := EnsureUpToDate(rm.Name); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,7 @@ type Config struct {
|
|||||||
EnsureRecipeLatest bool // ensure the local recipe has latest changes
|
EnsureRecipeLatest bool // ensure the local recipe has latest changes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option modified a Config. The convetion for passing Options to functions is
|
// Option modified a Config.
|
||||||
// so far, only used in internal/validate.go. A Config is then constructed and
|
|
||||||
// passed down further into the code. This may change in the future but this is
|
|
||||||
// at least the abstraction so far.
|
|
||||||
type Option func(c *Config)
|
type Option func(c *Config)
|
||||||
|
|
||||||
// New instantiates a new Config.
|
// New instantiates a new Config.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ABRA_VERSION="0.6.0-beta"
|
ABRA_VERSION="0.6.0-beta"
|
||||||
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
||||||
RC_VERSION="0.7.0-rc3-beta"
|
RC_VERSION="0.7.0-rc2-beta"
|
||||||
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
|
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
|
Reference in New Issue
Block a user