github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 "io" 9 "os" 10 "strconv" 11 12 "github.com/juju/cmd" 13 "github.com/juju/errors" 14 "github.com/juju/gnuflag" 15 "github.com/juju/loggo" 16 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/cmd/modelcmd" 19 "github.com/juju/juju/juju/osenv" 20 ) 21 22 var logger = loggo.GetLogger("juju.cmd.juju.status") 23 24 type statusAPI interface { 25 Status(patterns []string) (*params.FullStatus, error) 26 Close() error 27 } 28 29 // NewStatusCommand returns a new command, which reports on the 30 // runtime state of various system entities. 31 func NewStatusCommand() cmd.Command { 32 return modelcmd.Wrap(&statusCommand{}) 33 } 34 35 type statusCommand struct { 36 modelcmd.ModelCommandBase 37 out cmd.Output 38 patterns []string 39 isoTime bool 40 api statusAPI 41 42 color bool 43 } 44 45 var usageSummary = ` 46 Reports the current status of the model, machines, applications and units.`[1:] 47 48 var usageDetails = ` 49 By default (without argument), the status of the model, including all 50 applications and units will be output. 51 52 Application or unit names may be used as output filters (the '*' can be used as 53 a wildcard character). In addition to matched applications and units, related 54 machines, applications, and units will also be displayed. If a subordinate unit 55 is matched, then its principal unit will be displayed. If a principal unit is 56 matched, then all of its subordinates will be displayed. 57 58 The available output formats are: 59 60 - tabular (default): Displays status in a tabular format with a separate table 61 for the model, machines, applications, relations (if any) and units. 62 Note: in this format, the AZ column refers to the cloud region's 63 availability zone. 64 - {short|line|oneline}: List units and their subordinates. For each unit, the IP 65 address and agent status are listed. 66 - summary: Displays the subnet(s) and port(s) the model utilises. Also displays 67 aggregate information about: 68 - MACHINES: total #, and # in each state. 69 - UNITS: total #, and # in each state. 70 - APPLICATIONS: total #, and # exposed of each application. 71 - yaml: Displays information about the model, machines, applications, and units 72 in structured YAML format. 73 - json: Displays information about the model, machines, applications, and units 74 in structured JSON format. 75 76 Examples: 77 juju show-status 78 juju show-status mysql 79 juju show-status nova-* 80 81 See also: 82 machines 83 show-model 84 show-status-log 85 storage 86 ` 87 88 func (c *statusCommand) Info() *cmd.Info { 89 return &cmd.Info{ 90 Name: "show-status", 91 Args: "[filter pattern ...]", 92 Purpose: usageSummary, 93 Doc: usageDetails, 94 Aliases: []string{"status"}, 95 } 96 } 97 98 func (c *statusCommand) SetFlags(f *gnuflag.FlagSet) { 99 c.ModelCommandBase.SetFlags(f) 100 f.BoolVar(&c.isoTime, "utc", false, "Display time as UTC in RFC3339 format") 101 f.BoolVar(&c.color, "color", false, "Force use of ANSI color codes") 102 103 defaultFormat := "tabular" 104 105 c.out.AddFlags(f, defaultFormat, map[string]cmd.Formatter{ 106 "yaml": cmd.FormatYaml, 107 "json": cmd.FormatJson, 108 "short": FormatOneline, 109 "oneline": FormatOneline, 110 "line": FormatOneline, 111 "tabular": c.FormatTabular, 112 "summary": FormatSummary, 113 }) 114 } 115 116 func (c *statusCommand) Init(args []string) error { 117 c.patterns = args 118 // If use of ISO time not specified on command line, 119 // check env var. 120 if !c.isoTime { 121 var err error 122 envVarValue := os.Getenv(osenv.JujuStatusIsoTimeEnvKey) 123 if envVarValue != "" { 124 if c.isoTime, err = strconv.ParseBool(envVarValue); err != nil { 125 return errors.Annotatef(err, "invalid %s env var, expected true|false", osenv.JujuStatusIsoTimeEnvKey) 126 } 127 } 128 } 129 return nil 130 } 131 132 var newAPIClientForStatus = func(c *statusCommand) (statusAPI, error) { 133 return c.NewAPIClient() 134 } 135 136 func (c *statusCommand) Run(ctx *cmd.Context) error { 137 apiclient, err := newAPIClientForStatus(c) 138 if err != nil { 139 return errors.Trace(err) 140 } 141 defer apiclient.Close() 142 143 status, err := apiclient.Status(c.patterns) 144 if err != nil { 145 if status == nil { 146 // Status call completely failed, there is nothing to report 147 return err 148 } 149 // Display any error, but continue to print status if some was returned 150 fmt.Fprintf(ctx.Stderr, "%v\n", err) 151 } else if status == nil { 152 return errors.Errorf("unable to obtain the current status") 153 } 154 155 formatter := newStatusFormatter(status, c.ControllerName(), c.isoTime) 156 formatted, err := formatter.format() 157 if err != nil { 158 return err 159 } 160 return c.out.Write(ctx, formatted) 161 } 162 163 func (c *statusCommand) FormatTabular(writer io.Writer, value interface{}) error { 164 return FormatTabular(writer, c.color, value) 165 }