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  }