github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/commands/image/render.go (about) 1 package image 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 8 "github.com/deislabs/cnab-go/action" 9 "github.com/deislabs/cnab-go/driver" 10 "github.com/docker/app/internal" 11 bdl "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 appstore "github.com/docker/app/internal/store" 16 "github.com/docker/cli/cli" 17 "github.com/docker/cli/cli/command" 18 "github.com/docker/cli/cli/config" 19 "github.com/pkg/errors" 20 "github.com/spf13/cobra" 21 ) 22 23 type renderOptions struct { 24 cliopts.ParametersOptions 25 formatDriver string 26 renderOutput string 27 } 28 29 func renderCmd(dockerCli command.Cli, installerContext *cliopts.InstallerContextOptions) *cobra.Command { 30 var opts renderOptions 31 cmd := &cobra.Command{ 32 Use: "render [OPTIONS] APP_IMAGE", 33 Short: "Render the Compose file for an App image", 34 Example: `$ docker app render myrepo/myapp:1.0.0 --set key=value --parameters-file myparam.yml`, 35 Args: cli.ExactArgs(1), 36 Hidden: true, 37 RunE: func(cmd *cobra.Command, args []string) error { 38 return runRender(dockerCli, args[0], opts, installerContext) 39 }, 40 } 41 opts.ParametersOptions.AddFlags(cmd.Flags()) 42 cmd.Flags().StringVarP(&opts.renderOutput, "output", "o", "-", "Output file") 43 cmd.Flags().StringVar(&opts.formatDriver, "formatter", "yaml", "Configure the output format (yaml|json)") 44 45 return cmd 46 } 47 48 func runRender(dockerCli command.Cli, appname string, opts renderOptions, installerContext *cliopts.InstallerContextOptions) error { 49 var w io.Writer = os.Stdout 50 if opts.renderOutput != "-" { 51 f, err := os.Create(opts.renderOutput) 52 if err != nil { 53 return err 54 } 55 defer f.Close() 56 w = f 57 } 58 59 s, err := appstore.NewApplicationStore(config.Dir()) 60 if err != nil { 61 return err 62 } 63 imageStore, err := s.ImageStore() 64 if err != nil { 65 return err 66 } 67 img, ref, err := cnab.GetBundle(dockerCli, imageStore, appname) 68 if err != nil { 69 return errors.Wrapf(err, "could not render %q: no such App image", appname) 70 } 71 if err := packager.CheckAppVersion(dockerCli.Err(), img.Bundle); err != nil { 72 return err 73 } 74 installation, err := appstore.NewInstallation("custom-action", ref.String(), img) 75 if err != nil { 76 return err 77 } 78 79 if err := bdl.MergeBundleParameters(installation, 80 bdl.WithFileParameters(opts.ParametersFiles), 81 bdl.WithCommandLineParameters(opts.Overrides), 82 ); err != nil { 83 return err 84 } 85 86 defer muteDockerCli(dockerCli)() 87 driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, installerContext, w) 88 if err != nil { 89 return err 90 } 91 action := &action.RunCustom{ 92 Action: internal.ActionRenderName, 93 Driver: driverImpl, 94 } 95 installation.Parameters[internal.ParameterRenderFormatName] = opts.formatDriver 96 97 cfgFunc := func(op *driver.Operation) error { 98 op.Out = w 99 return nil 100 } 101 102 if err := action.Run(&installation.Claim, nil, cfgFunc, cnab.WithRelocationMap(installation)); err != nil { 103 return fmt.Errorf("render failed: %s\n%s", err, errBuf) 104 } 105 return nil 106 }