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 }