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  }