github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/runner/jujuc/status-get.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 11 "github.com/juju/juju/status" 12 ) 13 14 // StatusGetCommand implements the status-get command. 15 type StatusGetCommand struct { 16 cmd.CommandBase 17 ctx Context 18 includeData bool 19 serviceWide bool 20 out cmd.Output 21 } 22 23 func NewStatusGetCommand(ctx Context) (cmd.Command, error) { 24 return &StatusGetCommand{ctx: ctx}, nil 25 } 26 27 func (c *StatusGetCommand) Info() *cmd.Info { 28 doc := ` 29 By default, only the status value is printed. 30 If the --include-data flag is passed, the associated data are printed also. 31 ` 32 return &cmd.Info{ 33 Name: "status-get", 34 Args: "[--include-data] [--application]", 35 Purpose: "print status information", 36 Doc: doc, 37 } 38 } 39 40 func (c *StatusGetCommand) SetFlags(f *gnuflag.FlagSet) { 41 c.out.AddFlags(f, "smart", cmd.DefaultFormatters) 42 f.BoolVar(&c.includeData, "include-data", false, "print all status data") 43 f.BoolVar(&c.serviceWide, "application", false, "print status for all units of this application if this unit is the leader") 44 } 45 46 func (c *StatusGetCommand) Init(args []string) error { 47 return cmd.CheckEmpty(args) 48 } 49 50 // StatusInfo is a record of the status information for a service or a unit's workload. 51 type StatusInfo struct { 52 Tag string 53 Status string 54 Info string 55 Data map[string]interface{} 56 } 57 58 // ApplicationStatusInfo holds StatusInfo for an Application and all its Units. 59 type ApplicationStatusInfo struct { 60 Application StatusInfo 61 Units []StatusInfo 62 } 63 64 func toDetails(info StatusInfo, includeData bool) map[string]interface{} { 65 details := make(map[string]interface{}) 66 details["status"] = info.Status 67 if includeData { 68 data := make(map[string]interface{}) 69 for k, v := range info.Data { 70 data[k] = v 71 } 72 details["status-data"] = data 73 details["message"] = info.Info 74 } 75 return details 76 } 77 78 func (c *StatusGetCommand) ApplicationStatus(ctx *cmd.Context) error { 79 serviceStatus, err := c.ctx.ApplicationStatus() 80 if err != nil { 81 if errors.IsNotImplemented(err) { 82 return c.out.Write(ctx, status.Unknown) 83 } 84 return errors.Annotatef(err, "finding service status") 85 } 86 if !c.includeData && c.out.Name() == "smart" { 87 return c.out.Write(ctx, serviceStatus.Application.Status) 88 } 89 statusDetails := make(map[string]interface{}) 90 details := toDetails(serviceStatus.Application, c.includeData) 91 92 units := make(map[string]interface{}, len(serviceStatus.Units)) 93 for _, unit := range serviceStatus.Units { 94 units[unit.Tag] = toDetails(unit, c.includeData) 95 } 96 details["units"] = units 97 statusDetails["application-status"] = details 98 c.out.Write(ctx, statusDetails) 99 100 return nil 101 102 } 103 104 func (c *StatusGetCommand) unitOrServiceStatus(ctx *cmd.Context) error { 105 var err error 106 107 if c.serviceWide { 108 return c.ApplicationStatus(ctx) 109 } 110 111 unitStatus, err := c.ctx.UnitStatus() 112 if err != nil { 113 if errors.IsNotImplemented(err) { 114 return c.out.Write(ctx, status.Unknown) 115 } 116 return errors.Annotatef(err, "finding workload status") 117 } 118 if !c.includeData && c.out.Name() == "smart" { 119 return c.out.Write(ctx, unitStatus.Status) 120 } 121 c.out.Write(ctx, toDetails(*unitStatus, c.includeData)) 122 return nil 123 } 124 125 func (c *StatusGetCommand) Run(ctx *cmd.Context) error { 126 return c.unitOrServiceStatus(ctx) 127 }