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 }