github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/commands/helptool.go (about)

     1  // Copyright 2013, 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package commands
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/gnuflag"
    13  	"gopkg.in/juju/charm.v6"
    14  
    15  	jujucmd "github.com/juju/juju/cmd"
    16  	"github.com/juju/juju/core/network"
    17  	"github.com/juju/juju/storage"
    18  	"github.com/juju/juju/worker/uniter/runner/jujuc"
    19  )
    20  
    21  // dummyHookContext implements hooks.Context,
    22  // as expected by hooks.NewCommand.
    23  type dummyHookContext struct{ jujuc.Context }
    24  
    25  func (dummyHookContext) AddMetrics(_, _ string, _ time.Time) error {
    26  	return nil
    27  }
    28  func (dummyHookContext) UnitName() string {
    29  	return ""
    30  }
    31  func (dummyHookContext) SetPodSpec(specYaml string) error {
    32  	return nil
    33  }
    34  func (dummyHookContext) PublicAddress() (string, error) {
    35  	return "", errors.NotFoundf("PublicAddress")
    36  }
    37  func (dummyHookContext) PrivateAddress() (string, error) {
    38  	return "", errors.NotFoundf("PrivateAddress")
    39  }
    40  func (dummyHookContext) AvailabilityZone() (string, error) {
    41  	return "", errors.NotFoundf("AvailabilityZone")
    42  }
    43  func (dummyHookContext) OpenPort(protocol string, port int) error {
    44  	return nil
    45  }
    46  func (dummyHookContext) ClosePort(protocol string, port int) error {
    47  	return nil
    48  }
    49  func (dummyHookContext) OpenedPorts() []network.PortRange {
    50  	return nil
    51  }
    52  func (dummyHookContext) ConfigSettings() (charm.Settings, error) {
    53  	return charm.NewConfig().DefaultSettings(), nil
    54  }
    55  func (dummyHookContext) HookRelation() (jujuc.ContextRelation, error) {
    56  	return nil, errors.NotFoundf("HookRelation")
    57  }
    58  func (dummyHookContext) RemoteUnitName() (string, error) {
    59  	return "", errors.NotFoundf("RemoteUnitName")
    60  }
    61  func (dummyHookContext) Relation(id int) (jujuc.ContextRelation, error) {
    62  	return nil, errors.NotFoundf("Relation")
    63  }
    64  func (dummyHookContext) RelationIds() ([]int, error) {
    65  	return []int{}, errors.NotFoundf("RelationIds")
    66  }
    67  
    68  func (dummyHookContext) RequestReboot(prio jujuc.RebootPriority) error {
    69  	return nil
    70  }
    71  
    72  func (dummyHookContext) HookStorageInstance() (*storage.StorageInstance, error) {
    73  	return nil, errors.NotFoundf("HookStorageInstance")
    74  }
    75  
    76  func (dummyHookContext) HookStorage() (jujuc.ContextStorageAttachment, error) {
    77  	return nil, errors.NotFoundf("HookStorage")
    78  }
    79  
    80  func (dummyHookContext) StorageInstance(id string) (*storage.StorageInstance, error) {
    81  	return nil, errors.NotFoundf("StorageInstance")
    82  }
    83  
    84  func (dummyHookContext) UnitStatus() (*jujuc.StatusInfo, error) {
    85  	return &jujuc.StatusInfo{}, nil
    86  }
    87  
    88  func (dummyHookContext) SetStatus(jujuc.StatusInfo) error {
    89  	return nil
    90  }
    91  
    92  func (dummyHookContext) Component(name string) (jujuc.ContextComponent, error) {
    93  	return nil, nil
    94  }
    95  
    96  func newHelpToolCommand() cmd.Command {
    97  	return &helpToolCommand{}
    98  }
    99  
   100  type helpToolCommand struct {
   101  	cmd.CommandBase
   102  	tool string
   103  }
   104  
   105  func (t *helpToolCommand) Info() *cmd.Info {
   106  	return jujucmd.Info(&cmd.Info{
   107  		Name:    "hook-tool",
   108  		Args:    "[tool]",
   109  		Purpose: "Show help on a Juju charm hook tool.",
   110  		Doc:     helpToolDoc,
   111  		Aliases: []string{
   112  			"help-tool", // TODO (anastasimac 2017-11-1) This should be removed in Juju 3.
   113  			"hook-tools"},
   114  	})
   115  }
   116  
   117  func (t *helpToolCommand) Init(args []string) error {
   118  	tool, err := cmd.ZeroOrOneArgs(args)
   119  	if err == nil {
   120  		t.tool = tool
   121  	}
   122  	return err
   123  }
   124  
   125  func (c *helpToolCommand) Run(ctx *cmd.Context) error {
   126  	if c.tool == "" {
   127  		fmt.Fprintf(ctx.Stdout, listHookTools())
   128  	} else {
   129  		c, err := jujuc.NewCommand(dummyHookContext{}, c.tool)
   130  		if err != nil {
   131  			return err
   132  		}
   133  		info := c.Info()
   134  		f := gnuflag.NewFlagSetWithFlagKnownAs(info.Name, gnuflag.ContinueOnError, cmd.FlagAlias(c, "option"))
   135  		c.SetFlags(f)
   136  		ctx.Stdout.Write(info.Help(f))
   137  	}
   138  	return nil
   139  }
   140  
   141  var helpToolDoc = fmt.Sprintf(`
   142  Juju charms can access a series of built-in helpers called 'hook-tools'.
   143  These are useful for the charm to be able to inspect its running environment.
   144  Currently available charm hook tools are:
   145  
   146  %v
   147  Examples:
   148  
   149      For help on a specific tool, supply the name of that tool, for example:
   150  
   151          juju hook-tool unit-get
   152  
   153  `, listHookTools())
   154  
   155  func listHookTools() string {
   156  	all := ""
   157  	// Ripped from SuperCommand. We could Run() a SuperCommand
   158  	// with "help commands", but then the implicit "help" command
   159  	// shows up.
   160  	names := jujuc.CommandNames()
   161  	cmds := []cmd.Command{}
   162  	longest := 0
   163  	for _, name := range names {
   164  		if c, err := jujuc.NewCommand(dummyHookContext{}, name); err == nil {
   165  			// On Windows name has a '.exe' suffix, while Info().Name does not
   166  			name := c.Info().Name
   167  			if len(name) > longest {
   168  				longest = len(name)
   169  			}
   170  			cmds = append(cmds, c)
   171  		}
   172  	}
   173  	for _, c := range cmds {
   174  		info := c.Info()
   175  		all += fmt.Sprintf("    %-*s  %s\n", longest, info.Name, info.Purpose)
   176  	}
   177  	return all
   178  }