github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/commands/update.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/deislabs/cnab-go/driver" 8 9 "github.com/deislabs/cnab-go/action" 10 "github.com/deislabs/cnab-go/credentials" 11 "github.com/docker/app/internal/bundle" 12 "github.com/docker/app/internal/cliopts" 13 "github.com/docker/app/internal/cnab" 14 "github.com/docker/app/internal/packager" 15 "github.com/docker/cli/cli/command" 16 "github.com/spf13/cobra" 17 ) 18 19 type updateOptions struct { 20 cliopts.ParametersOptions 21 credentialOptions 22 bundleOrDockerApp string 23 } 24 25 func updateCmd(dockerCli command.Cli, installerContext *cliopts.InstallerContextOptions) *cobra.Command { 26 var opts updateOptions 27 cmd := &cobra.Command{ 28 Use: "update [OPTIONS] RUNNING_APP", 29 Short: "Update a running App", 30 Example: `$ docker app update myrunningapp --set key=value`, 31 Args: cobra.ExactArgs(1), 32 RunE: func(cmd *cobra.Command, args []string) error { 33 return runUpdate(dockerCli, args[0], opts, installerContext) 34 }, 35 } 36 opts.ParametersOptions.AddFlags(cmd.Flags()) 37 opts.credentialOptions.addFlags(cmd.Flags()) 38 cmd.Flags().StringVar(&opts.bundleOrDockerApp, "image", "", "Override the running App with another App image") 39 40 return cmd 41 } 42 43 func runUpdate(dockerCli command.Cli, installationName string, opts updateOptions, installerContext *cliopts.InstallerContextOptions) error { 44 imageStore, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext()) 45 if err != nil { 46 return err 47 } 48 49 installation, err := installationStore.Read(installationName) 50 if err != nil { 51 return err 52 } 53 54 if IsInstallationFailed(installation) { 55 return fmt.Errorf("Running App %q cannot be updated, please use 'docker app run' instead", installationName) 56 } 57 58 if opts.bundleOrDockerApp != "" { 59 b, _, err := cnab.ResolveBundle(dockerCli, imageStore, opts.bundleOrDockerApp) 60 if err != nil { 61 return err 62 } 63 installation.Bundle = b.Bundle 64 } 65 if err := packager.CheckAppVersion(dockerCli.Err(), installation.Bundle); err != nil { 66 return err 67 } 68 69 if err := bundle.MergeBundleParameters(installation, 70 bundle.WithFileParameters(opts.ParametersFiles), 71 bundle.WithCommandLineParameters(opts.Overrides), 72 bundle.WithSendRegistryAuth(opts.sendRegistryAuth), 73 ); err != nil { 74 return err 75 } 76 77 defer muteDockerCli(dockerCli)() 78 driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, installerContext, os.Stdout) 79 if err != nil { 80 return err 81 } 82 creds, err := prepareCredentialSet(installation.Bundle, opts.CredentialSetOpts(dockerCli, credentialStore)...) 83 if err != nil { 84 return err 85 } 86 if err := credentials.Validate(creds, installation.Bundle.Credentials); err != nil { 87 return err 88 } 89 u := &action.Upgrade{ 90 Driver: driverImpl, 91 } 92 cfgFunc := func(op *driver.Operation) error { 93 op.Out = dockerCli.Out() 94 return nil 95 } 96 err = u.Run(&installation.Claim, creds, cfgFunc, cnab.WithRelocationMap(installation)) 97 err2 := installationStore.Store(installation) 98 if err != nil { 99 return fmt.Errorf("Update failed: %s\n%s", err, errBuf) 100 } 101 if err2 != nil { 102 return err2 103 } 104 fmt.Fprintf(dockerCli.Out(), "Running App %q updated on context %q\n", installationName, dockerCli.CurrentContext()) 105 return nil 106 }