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  }