github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/commands/remove.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/docker/app/internal/cliopts"
     8  	"github.com/docker/app/internal/cnab"
     9  	"github.com/docker/app/internal/packager"
    10  	"github.com/docker/app/internal/store"
    11  
    12  	"github.com/deislabs/cnab-go/driver"
    13  
    14  	"github.com/deislabs/cnab-go/action"
    15  	"github.com/deislabs/cnab-go/credentials"
    16  	"github.com/docker/cli/cli"
    17  	"github.com/docker/cli/cli/command"
    18  	multierror "github.com/hashicorp/go-multierror"
    19  	"github.com/spf13/cobra"
    20  )
    21  
    22  type removeOptions struct {
    23  	credentialOptions
    24  	force bool
    25  }
    26  
    27  func removeCmd(dockerCli command.Cli, installerContext *cliopts.InstallerContextOptions) *cobra.Command {
    28  	var opts removeOptions
    29  
    30  	cmd := &cobra.Command{
    31  		Use:     "rm [OPTIONS] RUNNING_APP",
    32  		Short:   "Remove a running App",
    33  		Aliases: []string{"remove"},
    34  		Example: `$ docker app rm myrunningapp`,
    35  		Args:    cli.RequiresMinArgs(1),
    36  		RunE: func(cmd *cobra.Command, args []string) error {
    37  			_, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext())
    38  			if err != nil {
    39  				return err
    40  			}
    41  
    42  			var failures *multierror.Error
    43  			for _, arg := range args {
    44  				if err := runRemove(dockerCli, arg, opts, installerContext, installationStore, credentialStore); err != nil {
    45  					failures = multierror.Append(failures, err)
    46  				}
    47  			}
    48  			return failures.ErrorOrNil()
    49  		},
    50  	}
    51  	opts.credentialOptions.addFlags(cmd.Flags())
    52  	cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "Force the removal of a running App")
    53  
    54  	return cmd
    55  }
    56  
    57  func runRemove(dockerCli command.Cli,
    58  	installationName string,
    59  	opts removeOptions,
    60  	installerContext *cliopts.InstallerContextOptions,
    61  	installationStore store.InstallationStore,
    62  	credentialStore store.CredentialStore) (mainErr error) {
    63  	installation, err := installationStore.Read(installationName)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	if err := packager.CheckAppVersion(dockerCli.Err(), installation.Bundle); err != nil {
    68  		return err
    69  	}
    70  
    71  	if opts.force {
    72  		defer func() {
    73  			if mainErr == nil {
    74  				return
    75  			}
    76  			if err := installationStore.Delete(installationName); err != nil {
    77  				fmt.Fprintf(os.Stderr, "failed to force deletion of running App %q: %s\n", installationName, err)
    78  				return
    79  			}
    80  			fmt.Fprintf(os.Stderr, "deletion forced for running App %q\n", installationName)
    81  		}()
    82  	}
    83  
    84  	defer muteDockerCli(dockerCli)()
    85  	driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, installerContext, os.Stdout)
    86  	if err != nil {
    87  		return err
    88  	}
    89  	creds, err := prepareCredentialSet(installation.Bundle, opts.CredentialSetOpts(dockerCli, credentialStore)...)
    90  	if err != nil {
    91  		return err
    92  	}
    93  	if err := credentials.Validate(creds, installation.Bundle.Credentials); err != nil {
    94  		return err
    95  	}
    96  	uninst := &action.Uninstall{
    97  		Driver: driverImpl,
    98  	}
    99  	cfgFunc := func(op *driver.Operation) error {
   100  		op.Out = dockerCli.Out()
   101  		return nil
   102  	}
   103  	if err := uninst.Run(&installation.Claim, creds, cfgFunc, cnab.WithRelocationMap(installation)); err != nil {
   104  		if err2 := installationStore.Store(installation); err2 != nil {
   105  			return fmt.Errorf("%s while %s", err2, errBuf)
   106  		}
   107  		return fmt.Errorf("Remove failed: %s\n%s", err, errBuf)
   108  	}
   109  	if err := installationStore.Delete(installationName); err != nil {
   110  		return fmt.Errorf("Failed to delete running App %q from the installation store: %s", installationName, err)
   111  	}
   112  	fmt.Fprintf(dockerCli.Out(), "App %q uninstalled on context %q\n", installationName, dockerCli.CurrentContext())
   113  	return nil
   114  }