cellarspoon
b61b8f0d2a
All checks were successful
continuous-integration/drone/push Build is passing
You can't delete regardless of -f if an app is deployed, the runtime will error out. Best just deal with this for all cases then on our side.
157 lines
3.9 KiB
Go
157 lines
3.9 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"coopcloud.tech/abra/cli/internal"
|
|
"coopcloud.tech/abra/pkg/autocomplete"
|
|
"coopcloud.tech/abra/pkg/client"
|
|
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
|
"github.com/AlecAivazis/survey/v2"
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/filters"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
// Volumes stores the variable from VolumesFlag
|
|
var Volumes bool
|
|
|
|
// VolumesFlag is used to specify if volumes should be deleted when deleting an app
|
|
var VolumesFlag = &cli.BoolFlag{
|
|
Name: "volumes",
|
|
Value: false,
|
|
Destination: &Volumes,
|
|
}
|
|
|
|
var appRemoveCommand = &cli.Command{
|
|
Name: "remove",
|
|
Usage: "Remove an already undeployed app",
|
|
Aliases: []string{"rm"},
|
|
Flags: []cli.Flag{
|
|
VolumesFlag,
|
|
internal.ForceFlag,
|
|
},
|
|
Action: func(c *cli.Context) error {
|
|
app := internal.ValidateApp(c)
|
|
|
|
if !internal.Force {
|
|
response := false
|
|
prompt := &survey.Confirm{
|
|
Message: fmt.Sprintf("about to remove %s, are you sure?", app.Name),
|
|
}
|
|
if err := survey.AskOne(prompt, &response); err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
if !response {
|
|
logrus.Fatal("aborting as requested")
|
|
}
|
|
}
|
|
|
|
cl, err := client.New(app.Server)
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
|
|
isDeployed, _, err := stack.IsDeployed(c.Context, cl, app.StackName())
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
if isDeployed {
|
|
logrus.Fatalf("%s is still deployed. Run \"abra app undeploy %s \" or pass --force", app.Name, app.Name)
|
|
}
|
|
|
|
fs := filters.NewArgs()
|
|
fs.Add("name", app.StackName())
|
|
secretList, err := cl.SecretList(c.Context, types.SecretListOptions{Filters: fs})
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
|
|
secrets := make(map[string]string)
|
|
var secretNames []string
|
|
|
|
for _, cont := range secretList {
|
|
secrets[cont.Spec.Annotations.Name] = cont.ID // we have to map the names to ID's
|
|
secretNames = append(secretNames, cont.Spec.Annotations.Name)
|
|
}
|
|
|
|
if len(secrets) > 0 {
|
|
var secretNamesToRemove []string
|
|
|
|
if !internal.Force {
|
|
secretsPrompt := &survey.MultiSelect{
|
|
Message: "which secrets do you want to remove?",
|
|
Help: "'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode is enabled",
|
|
VimMode: true,
|
|
Options: secretNames,
|
|
Default: secretNames,
|
|
}
|
|
if err := survey.AskOne(secretsPrompt, &secretNamesToRemove); err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
}
|
|
|
|
for _, name := range secretNamesToRemove {
|
|
err := cl.SecretRemove(c.Context, secrets[name])
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
logrus.Info(fmt.Sprintf("secret: %s removed", name))
|
|
}
|
|
} else {
|
|
logrus.Info("no secrets to remove")
|
|
}
|
|
|
|
volumeListOKBody, err := cl.VolumeList(c.Context, fs)
|
|
volumeList := volumeListOKBody.Volumes
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
|
|
var vols []string
|
|
for _, vol := range volumeList {
|
|
vols = append(vols, vol.Name)
|
|
}
|
|
|
|
if len(vols) > 0 {
|
|
if Volumes {
|
|
var removeVols []string
|
|
if !internal.Force {
|
|
volumesPrompt := &survey.MultiSelect{
|
|
Message: "which volumes do you want to remove?",
|
|
Help: "'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode is enabled",
|
|
VimMode: true,
|
|
Options: vols,
|
|
Default: vols,
|
|
}
|
|
if err := survey.AskOne(volumesPrompt, &removeVols); err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
}
|
|
for _, vol := range removeVols {
|
|
err := cl.VolumeRemove(c.Context, vol, internal.Force) // last argument is for force removing
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
logrus.Info(fmt.Sprintf("volume %s removed", vol))
|
|
}
|
|
} else {
|
|
logrus.Info("no volumes were removed")
|
|
}
|
|
} else {
|
|
logrus.Info("no volumes to remove")
|
|
}
|
|
|
|
err = os.Remove(app.Path)
|
|
if err != nil {
|
|
logrus.Fatal(err)
|
|
}
|
|
logrus.Info(fmt.Sprintf("file: %s removed", app.Path))
|
|
|
|
return nil
|
|
},
|
|
BashComplete: autocomplete.AppNameComplete,
|
|
}
|