github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/status/status.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package status 5 6 import ( 7 "fmt" 8 "os" 9 "strconv" 10 11 "github.com/juju/cmd" 12 "github.com/juju/errors" 13 "github.com/juju/loggo" 14 "launchpad.net/gnuflag" 15 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/cmd/modelcmd" 18 "github.com/juju/juju/juju/osenv" 19 ) 20 21 var logger = loggo.GetLogger("juju.cmd.juju.status") 22 23 type statusAPI interface { 24 Status(patterns []string) (*params.FullStatus, error) 25 Close() error 26 } 27 28 // NewStatusCommand returns a new command, which reports on the 29 // runtime state of various system entities. 30 func NewStatusCommand() cmd.Command { 31 return modelcmd.Wrap(&statusCommand{}) 32 } 33 34 type statusCommand struct { 35 modelcmd.ModelCommandBase 36 out cmd.Output 37 patterns []string 38 isoTime bool 39 api statusAPI 40 } 41 42 var usageSummary = ` 43 Displays the current status of Juju, services, and units.`[1:] 44 45 var usageDetails = ` 46 By default (without argument), the status of Juju and all services and all 47 units will be displayed. 48 Service or unit names may be used as output filters (the '*' can be used 49 as a wildcard character). 50 In addition to matched services and units, related machines, services, and 51 units will also be displayed. If a subordinate unit is matched, then its 52 principal unit will be displayed. If a principal unit is matched, then all 53 of its subordinates will be displayed. 54 Explanation of the different formats: 55 - {short|line|oneline}: List units and their subordinates. For each 56 unit, the IP address and agent status are listed. 57 - summary: Displays the subnet(s) and port(s) the model utilises. 58 Also displays aggregate information about: 59 - MACHINES: total #, and # in each state. 60 - UNITS: total #, and # in each state. 61 - SERVICES: total #, and # exposed of each service. 62 - tabular (default): Displays information in a tabular format in these sections: 63 - Machines: ID, STATE, DNS, INS-ID, SERIES, AZ 64 - Services: NAME, EXPOSED, CHARM 65 - Units: ID, STATE, VERSION, MACHINE, PORTS, PUBLIC-ADDRESS 66 - Also displays subordinate units. 67 - yaml: Displays information on machines, services, and units in yaml format. 68 Note: AZ above is the cloud region's availability zone. 69 70 Examples: 71 juju status 72 juju status mysql 73 juju status nova-* 74 ` 75 76 func (c *statusCommand) Info() *cmd.Info { 77 return &cmd.Info{ 78 Name: "status", 79 Args: "[filter pattern ...]", 80 Purpose: usageSummary, 81 Doc: usageDetails, 82 Aliases: []string{"show-status"}, 83 } 84 } 85 86 func (c *statusCommand) SetFlags(f *gnuflag.FlagSet) { 87 f.BoolVar(&c.isoTime, "utc", false, "Display time as UTC in RFC3339 format") 88 89 defaultFormat := "tabular" 90 91 c.out.AddFlags(f, defaultFormat, map[string]cmd.Formatter{ 92 "yaml": cmd.FormatYaml, 93 "json": cmd.FormatJson, 94 "short": FormatOneline, 95 "oneline": FormatOneline, 96 "line": FormatOneline, 97 "tabular": FormatTabular, 98 "summary": FormatSummary, 99 }) 100 } 101 102 func (c *statusCommand) Init(args []string) error { 103 c.patterns = args 104 // If use of ISO time not specified on command line, 105 // check env var. 106 if !c.isoTime { 107 var err error 108 envVarValue := os.Getenv(osenv.JujuStatusIsoTimeEnvKey) 109 if envVarValue != "" { 110 if c.isoTime, err = strconv.ParseBool(envVarValue); err != nil { 111 return errors.Annotatef(err, "invalid %s env var, expected true|false", osenv.JujuStatusIsoTimeEnvKey) 112 } 113 } 114 } 115 return nil 116 } 117 118 var newApiClientForStatus = func(c *statusCommand) (statusAPI, error) { 119 return c.NewAPIClient() 120 } 121 122 func (c *statusCommand) Run(ctx *cmd.Context) error { 123 apiclient, err := newApiClientForStatus(c) 124 if err != nil { 125 return errors.Trace(err) 126 } 127 defer apiclient.Close() 128 129 status, err := apiclient.Status(c.patterns) 130 if err != nil { 131 if status == nil { 132 // Status call completely failed, there is nothing to report 133 return err 134 } 135 // Display any error, but continue to print status if some was returned 136 fmt.Fprintf(ctx.Stderr, "%v\n", err) 137 } else if status == nil { 138 return errors.Errorf("unable to obtain the current status") 139 } 140 141 formatter := NewStatusFormatter(status, c.isoTime) 142 formatted := formatter.format() 143 return c.out.Write(ctx, formatted) 144 }