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

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  
     9  	"github.com/deislabs/cnab-go/action"
    10  	"github.com/deislabs/cnab-go/bundle"
    11  	"github.com/docker/app/internal"
    12  	"github.com/docker/app/internal/cliopts"
    13  	"github.com/docker/app/internal/cnab"
    14  	"github.com/docker/app/internal/inspect"
    15  	"github.com/docker/app/internal/packager"
    16  	"github.com/docker/cli/cli"
    17  	"github.com/docker/cli/cli/command"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  const inspectExample = `- $ docker app inspect my-running-app
    22  - $ docker app inspect my-running-app:1.0.0`
    23  
    24  type inspectOptions struct {
    25  	credentialOptions
    26  	pretty bool
    27  }
    28  
    29  func inspectCmd(dockerCli command.Cli, installerContext *cliopts.InstallerContextOptions) *cobra.Command {
    30  	var opts inspectOptions
    31  	cmd := &cobra.Command{
    32  		Use:     "inspect [OPTIONS] RUNNING_APP",
    33  		Short:   "Shows status, metadata, parameters and the list of services of a running App",
    34  		Example: inspectExample,
    35  		Args:    cli.ExactArgs(1),
    36  		RunE: func(cmd *cobra.Command, args []string) error {
    37  			return runInspect(dockerCli, args[0], opts, installerContext)
    38  		},
    39  	}
    40  	cmd.Flags().BoolVar(&opts.pretty, "pretty", false, "Pretty print the output")
    41  	opts.credentialOptions.addFlags(cmd.Flags())
    42  	return cmd
    43  }
    44  
    45  func runInspect(dockerCli command.Cli, appName string, inspectOptions inspectOptions, installerContext *cliopts.InstallerContextOptions) error {
    46  	_, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext())
    47  	if err != nil {
    48  		return err
    49  	}
    50  	installation, err := installationStore.Read(appName)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	if err := packager.CheckAppVersion(dockerCli.Err(), installation.Bundle); err != nil {
    55  		return err
    56  	}
    57  	creds, err := prepareCredentialSet(installation.Bundle, inspectOptions.CredentialSetOpts(dockerCli, credentialStore)...)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	defer muteDockerCli(dockerCli)()
    63  	var buf bytes.Buffer
    64  	driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, installerContext, &buf)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	a := &action.RunCustom{
    70  		Driver: driverImpl,
    71  	}
    72  	if inspectOptions.pretty && hasAction(installation.Bundle, internal.ActionStatusName) {
    73  		a.Action = internal.ActionStatusName
    74  	} else if hasAction(installation.Bundle, internal.ActionStatusJSONName) {
    75  		a.Action = internal.ActionStatusJSONName
    76  	} else {
    77  		return fmt.Errorf("inspect failed: status action is not supported by the App")
    78  	}
    79  	if err := a.Run(&installation.Claim, creds, cnab.WithRelocationMap(installation)); err != nil {
    80  		return fmt.Errorf("inspect failed: %s\n%s", err, errBuf)
    81  	}
    82  
    83  	if inspectOptions.pretty {
    84  		if err := inspect.Inspect(os.Stdout, installation, "pretty"); err != nil {
    85  			return err
    86  		}
    87  		fmt.Fprint(os.Stdout, buf.String())
    88  	} else {
    89  		var statusJSON interface{}
    90  		if err := json.Unmarshal(buf.Bytes(), &statusJSON); err != nil {
    91  			return err
    92  		}
    93  		js, err := json.MarshalIndent(struct {
    94  			AppInfo  inspect.AppInfo `json:",omitempty"`
    95  			Services interface{}     `json:",omitempty"`
    96  		}{
    97  			inspect.GetAppInfo(installation),
    98  			statusJSON,
    99  		}, "", "    ")
   100  		if err != nil {
   101  			return err
   102  		}
   103  		fmt.Fprint(os.Stdout, string(js))
   104  	}
   105  	return nil
   106  }
   107  
   108  func hasAction(bndl *bundle.Bundle, actionName string) bool {
   109  	_, ok := bndl.Actions[actionName]
   110  	return ok
   111  }