github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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/envcmd" 18 "github.com/juju/juju/juju/osenv" 19 ) 20 21 var logger = loggo.GetLogger("juju.cmd.juju.status") 22 23 type StatusCommand struct { 24 envcmd.EnvCommandBase 25 out cmd.Output 26 patterns []string 27 isoTime bool 28 } 29 30 var statusDoc = ` 31 This command will report on the runtime state of various system entities. 32 33 There are a number of ways to format the status output: 34 35 - {short|line|oneline}: List units and their subordinates. For each 36 unit, the IP address and agent status are listed. 37 - summary: Displays the subnet(s) and port(s) the environment utilises. 38 Also displays aggregate information about: 39 - MACHINES: total #, and # in each state. 40 - UNITS: total #, and # in each state. 41 - SERVICES: total #, and # exposed of each service. 42 - tabular: Displays information in a tabular format in these sections: 43 - Machines: ID, STATE, VERSION, DNS, INS-ID, SERIES, HARDWARE 44 - Services: NAME, EXPOSED, CHARM 45 - Units: ID, STATE, VERSION, MACHINE, PORTS, PUBLIC-ADDRESS 46 - Also displays subordinate units. 47 - yaml (DEFAULT): Displays information on machines, services, and units 48 in the yaml format. 49 50 Service or unit names may be specified to filter the status to only those 51 services and units that match, along with the related machines, services 52 and units. If a subordinate unit is matched, then its principal unit will 53 be displayed. If a principal unit is matched, then all of its subordinates 54 will be displayed. 55 56 Wildcards ('*') may be specified in service/unit names to match any sequence 57 of characters. For example, 'nova-*' will match any service whose name begins 58 with 'nova-': 'nova-compute', 'nova-volume', etc. 59 ` 60 61 func (c *StatusCommand) Info() *cmd.Info { 62 return &cmd.Info{ 63 Name: "status", 64 Args: "[pattern ...]", 65 Purpose: "output status information about an environment", 66 Doc: statusDoc, 67 Aliases: []string{"stat"}, 68 } 69 } 70 71 func (c *StatusCommand) SetFlags(f *gnuflag.FlagSet) { 72 f.BoolVar(&c.isoTime, "utc", false, "display time as UTC in RFC3339 format") 73 74 oneLineFormatter := FormatOneline 75 defaultFormat := "yaml" 76 if c.CompatVersion() > 1 { 77 defaultFormat = "tabular" 78 oneLineFormatter = FormatOnelineV2 79 } 80 81 c.out.AddFlags(f, defaultFormat, map[string]cmd.Formatter{ 82 "yaml": cmd.FormatYaml, 83 "json": cmd.FormatJson, 84 "short": oneLineFormatter, 85 "oneline": oneLineFormatter, 86 "line": oneLineFormatter, 87 "tabular": FormatTabular, 88 "summary": FormatSummary, 89 }) 90 } 91 92 func (c *StatusCommand) Init(args []string) error { 93 c.patterns = args 94 // If use of ISO time not specified on command line, 95 // check env var. 96 if !c.isoTime { 97 var err error 98 envVarValue := os.Getenv(osenv.JujuStatusIsoTimeEnvKey) 99 if envVarValue != "" { 100 if c.isoTime, err = strconv.ParseBool(envVarValue); err != nil { 101 return errors.Annotatef(err, "invalid %s env var, expected true|false", osenv.JujuStatusIsoTimeEnvKey) 102 } 103 } 104 } 105 return nil 106 } 107 108 var connectionError = `Unable to connect to environment %q. 109 Please check your credentials or use 'juju bootstrap' to create a new environment. 110 111 Error details: 112 %v 113 ` 114 115 type statusAPI interface { 116 Status(patterns []string) (*params.FullStatus, error) 117 Close() error 118 } 119 120 var newApiClientForStatus = func(c *StatusCommand) (statusAPI, error) { 121 return c.NewAPIClient() 122 } 123 124 func (c *StatusCommand) Run(ctx *cmd.Context) error { 125 126 apiclient, err := newApiClientForStatus(c) 127 if err != nil { 128 return errors.Errorf(connectionError, c.ConnectionName(), err) 129 } 130 defer apiclient.Close() 131 132 status, err := apiclient.Status(c.patterns) 133 if err != nil { 134 if status == nil { 135 // Status call completely failed, there is nothing to report 136 return err 137 } 138 // Display any error, but continue to print status if some was returned 139 fmt.Fprintf(ctx.Stderr, "%v\n", err) 140 } else if status == nil { 141 return errors.Errorf("unable to obtain the current status") 142 } 143 144 formatter := newStatusFormatter(status, c.CompatVersion(), c.isoTime) 145 formatted := formatter.format() 146 return c.out.Write(ctx, formatted) 147 }