github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/unitagent.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/juju/status" 9 "github.com/juju/names" 10 ) 11 12 // UnitAgent represents the state of a service's unit agent. 13 type UnitAgent struct { 14 st *State 15 tag names.Tag 16 name string 17 status.StatusHistoryGetter 18 } 19 20 func newUnitAgent(st *State, tag names.Tag, name string) *UnitAgent { 21 unitAgent := &UnitAgent{ 22 st: st, 23 tag: tag, 24 name: name, 25 } 26 27 return unitAgent 28 } 29 30 // String returns the unit agent as string. 31 func (u *UnitAgent) String() string { 32 return u.name 33 } 34 35 // Status returns the status of the unit agent. 36 func (u *UnitAgent) Status() (status.StatusInfo, error) { 37 info, err := getStatus(u.st, u.globalKey(), "agent") 38 if err != nil { 39 return status.StatusInfo{}, errors.Trace(err) 40 } 41 // The current health spec says when a hook error occurs, the workload should 42 // be in error state, but the state model more correctly records the agent 43 // itself as being in error. So we'll do that model translation here. 44 // TODO(fwereade): this should absolutely not be happpening in the model. 45 if info.Status == status.StatusError { 46 return status.StatusInfo{ 47 Status: status.StatusIdle, 48 Message: "", 49 Data: map[string]interface{}{}, 50 Since: info.Since, 51 }, nil 52 } 53 return info, nil 54 } 55 56 // SetStatus sets the status of the unit agent. The optional values 57 // allow to pass additional helpful status data. 58 func (u *UnitAgent) SetStatus(unitAgentStatus status.Status, info string, data map[string]interface{}) (err error) { 59 switch unitAgentStatus { 60 case status.StatusIdle, status.StatusExecuting, status.StatusRebooting, status.StatusFailed: 61 case status.StatusError: 62 if info == "" { 63 return errors.Errorf("cannot set status %q without info", unitAgentStatus) 64 } 65 case status.StatusAllocating, status.StatusLost: 66 return errors.Errorf("cannot set status %q", unitAgentStatus) 67 default: 68 return errors.Errorf("cannot set invalid status %q", unitAgentStatus) 69 } 70 return setStatus(u.st, setStatusParams{ 71 badge: "agent", 72 globalKey: u.globalKey(), 73 status: unitAgentStatus, 74 message: info, 75 rawData: data, 76 }) 77 } 78 79 // StatusHistory returns a slice of at most <size> StatusInfo items 80 // representing past statuses for this agent. 81 func (u *UnitAgent) StatusHistory(size int) ([]status.StatusInfo, error) { 82 return statusHistory(u.st, u.globalKey(), size) 83 } 84 85 // unitAgentGlobalKey returns the global database key for the named unit. 86 func unitAgentGlobalKey(name string) string { 87 return "u#" + name 88 } 89 90 // globalKey returns the global database key for the unit. 91 func (u *UnitAgent) globalKey() string { 92 return unitAgentGlobalKey(u.name) 93 } 94 95 // Tag returns a names.Tag identifying this agent's unit. 96 func (u *UnitAgent) Tag() names.Tag { 97 return u.tag 98 }