1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
10
// Status used to represent the status of an entity, but has recently become
11
// and applies to "workloads" as well, which we don't currently model, for no
14
// Status values currently apply to machine (agents), unit (agents), unit
15
// (workloads), service (workloads), and volumes.
18
// StatusInfo holds a Status and associated information.
19
type StatusInfo struct {
22
Data map[string]interface{}
26
// StatusSetter represents a type whose status can be set.
27
type StatusSetter interface {
28
SetStatus(status Status, info string, data map[string]interface{}) error
31
// StatusGetter represents a type whose status can be read.
32
type StatusGetter interface {
33
Status() (StatusInfo, error)
36
// StatusHistoryGetter instances can fetch their status history.
37
type StatusHistoryGetter interface {
38
StatusHistory(size int) ([]StatusInfo, error)
41
// Status values common to machine and unit agents.
44
// The entity requires human intervention in order to operate
46
StatusError Status = "error"
48
// The entity is actively participating in the model.
49
// For unit agents, this is a state we preserve for backwards
50
// compatibility with scripts during the life of Juju 1.x.
51
// In Juju 2.x, the agent-state will remain “active” and scripts
52
// will watch the unit-state instead for signals of service readiness.
53
StatusStarted Status = "started"
56
// Status values specific to machine agents.
59
// The machine is not yet participating in the model.
60
StatusPending Status = "pending"
62
// The machine's agent will perform no further action, other than
63
// to set the unit to Dead at a suitable moment.
64
StatusStopped Status = "stopped"
66
// The machine ought to be signalling activity, but it cannot be
68
StatusDown Status = "down"
71
// Status values specific to unit agents.
74
// The machine on which a unit is to be hosted is still being
75
// spun up in the cloud.
76
StatusAllocating Status = "allocating"
78
// The machine on which this agent is running is being rebooted.
79
// The juju-agent should move from rebooting to idle when the reboot is complete.
80
StatusRebooting Status = "rebooting"
82
// The agent is running a hook or action. The human-readable message should reflect
83
// which hook or action is being run.
84
StatusExecuting Status = "executing"
86
// Once the agent is installed and running it will notify the Juju server and its state
87
// becomes "idle". It will stay "idle" until some action (e.g. it needs to run a hook) or
88
// error (e.g it loses contact with the Juju server) moves it to a different state.
89
StatusIdle Status = "idle"
91
// The unit agent has failed in some way,eg the agent ought to be signalling
92
// activity, but it cannot be detected. It might also be that the unit agent
93
// detected an unrecoverable condition and managed to tell the Juju server about it.
94
StatusFailed Status = "failed"
96
// The juju agent has has not communicated with the juju server for an unexpectedly long time;
97
// the unit agent ought to be signalling activity, but none has been detected.
98
StatusLost Status = "lost"
100
// ---- Outdated ----
101
// The unit agent is downloading the charm and running the install hook.
102
StatusInstalling Status = "installing"
104
// The unit is being destroyed; the agent will soon mark the unit as “dead”.
105
// In Juju 2.x this will describe the state of the agent rather than a unit.
106
StatusStopping Status = "stopping"
109
// Status values specific to services and units, reflecting the
110
// state of the software itself.
113
// The unit is not yet providing services, but is actively doing stuff
114
// in preparation for providing those services.
115
// This is a "spinning" state, not an error state.
116
// It reflects activity on the unit itself, not on peers or related units.
117
StatusMaintenance Status = "maintenance"
119
// This unit used to exist, we have a record of it (perhaps because of storage
120
// allocated for it that was flagged to survive it). Nonetheless, it is now gone.
121
StatusTerminated Status = "terminated"
123
// A unit-agent has finished calling install, config-changed, and start,
124
// but the charm has not called status-set yet.
125
StatusUnknown Status = "unknown"
127
// The unit is unable to progress to an active state because a service to
128
// which it is related is not running.
129
StatusWaiting Status = "waiting"
131
// The unit needs manual intervention to get back to the Active state.
132
StatusBlocked Status = "blocked"
134
// The unit believes it is correctly offering all the services it has
135
// been asked to offer.
136
StatusActive Status = "active"
139
// Status values specific to storage.
141
// StatusAttaching indicates that the storage is being attached to a
143
StatusAttaching Status = "attaching"
145
// StatusDetaching indicates that the storage is attached to a machine.
146
StatusAttached Status = "attached"
148
// StatusDetaching indicates that the storage is being detached
150
StatusDetaching Status = "detaching"
152
// StatusDetached indicates that the storage is not attached to any
154
StatusDetached Status = "detached"
156
// StatusDestroying indicates that the storage is being destroyed.
157
StatusDestroying Status = "destroying"
161
MessageInstalling = "installing charm software"
163
// StorageReadyMessage is the message set to the agent status when all storage
164
// attachments are properly done.
165
StorageReadyMessage = "storage ready"
167
// PreparingStorageMessage is the message set to the agent status before trying
168
// to attach storages.
169
PreparingStorageMessage = "preparing storage"
172
// KnownAgentStatus returns true if status has a known value for an agent.
173
// It includes every status that has ever been valid for a unit or machine agent.
174
// This is used by the apiserver client facade to filter out unknown values.
175
func (status Status) KnownAgentStatus() bool {
185
case //Deprecated status vales
199
// KnownWorkloadStatus returns true if status has a known value for a workload.
200
// It includes every status that has ever been valid for a unit agent.
201
// This is used by the apiserver client facade to filter out unknown values.
202
func (status Status) KnownWorkloadStatus() bool {
203
if ValidWorkloadStatus(status) {
207
case StatusError: // include error so that we can filter on what the spec says is valid
209
case // Deprecated statuses
221
// ValidWorkloadStatus returns true if status has a valid value (that is to say,
222
// a value that it's OK to set) for units or services.
223
func ValidWorkloadStatus(status Status) bool {
238
// WorkloadMatches returns true if the candidate matches status,
239
// taking into account that the candidate may be a legacy
240
// status value which has been deprecated.
241
func (status Status) WorkloadMatches(candidate Status) bool {
243
case status: // We could be holding an old status ourselves
245
case StatusDown, StatusStopped:
246
candidate = StatusTerminated
247
case StatusInstalling:
248
candidate = StatusMaintenance
250
candidate = StatusActive
252
return status == candidate
255
// Matches returns true if the candidate matches status,
256
// taking into account that the candidate may be a legacy
257
// status value which has been deprecated.
258
func (status Status) Matches(candidate Status) bool {
261
candidate = StatusLost
263
candidate = StatusActive
265
candidate = StatusStopping
267
return status == candidate
270
// TranslateLegacyAgentStatus returns the status value clients expect to see for
271
// agent-state in versions prior to 1.24
272
func TranslateToLegacyAgentState(agentStatus, workloadStatus Status, workloadMessage string) (Status, bool) {
273
// Originally AgentState (a member of api.UnitStatus) could hold one of:
280
// For compatibility reasons we convert modern states (from V2 uniter) into
281
// four of the old ones: StatusPending, StatusStarted, StatusStopped, or StatusError.
283
// For the purposes of deriving the legacy status, there's currently no better
284
// way to determine if a unit is installed.
285
// TODO(wallyworld) - use status history to see if start hook has run.
286
isInstalled := workloadStatus != StatusMaintenance || workloadMessage != MessageInstalling
289
case StatusAllocating:
290
return StatusPending, true
292
return StatusError, true
293
case StatusRebooting, StatusExecuting, StatusIdle, StatusLost, StatusFailed:
294
switch workloadStatus {
296
return StatusError, true
297
case StatusTerminated:
298
return StatusStopped, true
299
case StatusMaintenance:
301
return StatusStarted, true
303
return StatusPending, true
306
return StatusStarted, true