~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/status_model.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2014 Canonical Ltd.
2
 
// Licensed under the AGPLv3, see LICENCE file for details.
3
 
 
4
 
package state
5
 
 
6
 
import (
7
 
        "time"
8
 
)
9
 
 
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
12
 
// very clear reason.
13
 
//
14
 
// Status values currently apply to machine (agents), unit (agents), unit
15
 
// (workloads), service (workloads), and volumes.
16
 
type Status string
17
 
 
18
 
// StatusInfo holds a Status and associated information.
19
 
type StatusInfo struct {
20
 
        Status  Status
21
 
        Message string
22
 
        Data    map[string]interface{}
23
 
        Since   *time.Time
24
 
}
25
 
 
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
29
 
}
30
 
 
31
 
// StatusGetter represents a type whose status can be read.
32
 
type StatusGetter interface {
33
 
        Status() (StatusInfo, error)
34
 
}
35
 
 
36
 
// StatusHistoryGetter instances can fetch their status history.
37
 
type StatusHistoryGetter interface {
38
 
        StatusHistory(size int) ([]StatusInfo, error)
39
 
}
40
 
 
41
 
// Status values common to machine and unit agents.
42
 
const (
43
 
 
44
 
        // The entity requires human intervention in order to operate
45
 
        // correctly.
46
 
        StatusError Status = "error"
47
 
 
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"
54
 
)
55
 
 
56
 
// Status values specific to machine agents.
57
 
const (
58
 
 
59
 
        // The machine is not yet participating in the model.
60
 
        StatusPending Status = "pending"
61
 
 
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"
65
 
 
66
 
        // The machine ought to be signalling activity, but it cannot be
67
 
        // detected.
68
 
        StatusDown Status = "down"
69
 
)
70
 
 
71
 
// Status values specific to unit agents.
72
 
const (
73
 
 
74
 
        // The machine on which a unit is to be hosted is still being
75
 
        // spun up in the cloud.
76
 
        StatusAllocating Status = "allocating"
77
 
 
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"
81
 
 
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"
85
 
 
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"
90
 
 
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"
95
 
 
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"
99
 
 
100
 
        // ---- Outdated ----
101
 
        // The unit agent is downloading the charm and running the install hook.
102
 
        StatusInstalling Status = "installing"
103
 
 
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"
107
 
)
108
 
 
109
 
// Status values specific to services and units, reflecting the
110
 
// state of the software itself.
111
 
const (
112
 
 
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"
118
 
 
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"
122
 
 
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"
126
 
 
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"
130
 
 
131
 
        // The unit needs manual intervention to get back to the Active state.
132
 
        StatusBlocked Status = "blocked"
133
 
 
134
 
        // The unit believes it is correctly offering all the services it has
135
 
        // been asked to offer.
136
 
        StatusActive Status = "active"
137
 
)
138
 
 
139
 
// Status values specific to storage.
140
 
const (
141
 
        // StatusAttaching indicates that the storage is being attached to a
142
 
        // machine.
143
 
        StatusAttaching Status = "attaching"
144
 
 
145
 
        // StatusDetaching indicates that the storage is attached to a machine.
146
 
        StatusAttached Status = "attached"
147
 
 
148
 
        // StatusDetaching indicates that the storage is being detached
149
 
        // from a machine.
150
 
        StatusDetaching Status = "detaching"
151
 
 
152
 
        // StatusDetached indicates that the storage is not attached to any
153
 
        // machine.
154
 
        StatusDetached Status = "detached"
155
 
 
156
 
        // StatusDestroying indicates that the storage is being destroyed.
157
 
        StatusDestroying Status = "destroying"
158
 
)
159
 
 
160
 
const (
161
 
        MessageInstalling = "installing charm software"
162
 
 
163
 
        // StorageReadyMessage is the message set to the agent status when all storage
164
 
        // attachments are properly done.
165
 
        StorageReadyMessage = "storage ready"
166
 
 
167
 
        // PreparingStorageMessage is the message set to the agent status before trying
168
 
        // to attach storages.
169
 
        PreparingStorageMessage = "preparing storage"
170
 
)
171
 
 
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 {
176
 
        switch status {
177
 
        case
178
 
                StatusAllocating,
179
 
                StatusError,
180
 
                StatusFailed,
181
 
                StatusRebooting,
182
 
                StatusExecuting,
183
 
                StatusIdle:
184
 
                return true
185
 
        case //Deprecated status vales
186
 
                StatusPending,
187
 
                StatusStarted,
188
 
                StatusStopped,
189
 
                StatusInstalling,
190
 
                StatusActive,
191
 
                StatusStopping,
192
 
                StatusDown:
193
 
                return true
194
 
        default:
195
 
                return false
196
 
        }
197
 
}
198
 
 
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) {
204
 
                return true
205
 
        }
206
 
        switch status {
207
 
        case StatusError: // include error so that we can filter on what the spec says is valid
208
 
                return true
209
 
        case // Deprecated statuses
210
 
                StatusPending,
211
 
                StatusInstalling,
212
 
                StatusStarted,
213
 
                StatusStopped,
214
 
                StatusDown:
215
 
                return true
216
 
        default:
217
 
                return false
218
 
        }
219
 
}
220
 
 
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 {
224
 
        switch status {
225
 
        case
226
 
                StatusBlocked,
227
 
                StatusMaintenance,
228
 
                StatusWaiting,
229
 
                StatusActive,
230
 
                StatusUnknown,
231
 
                StatusTerminated:
232
 
                return true
233
 
        default:
234
 
                return false
235
 
        }
236
 
}
237
 
 
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 {
242
 
        switch candidate {
243
 
        case status: // We could be holding an old status ourselves
244
 
                return true
245
 
        case StatusDown, StatusStopped:
246
 
                candidate = StatusTerminated
247
 
        case StatusInstalling:
248
 
                candidate = StatusMaintenance
249
 
        case StatusStarted:
250
 
                candidate = StatusActive
251
 
        }
252
 
        return status == candidate
253
 
}
254
 
 
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 {
259
 
        switch candidate {
260
 
        case StatusDown:
261
 
                candidate = StatusLost
262
 
        case StatusStarted:
263
 
                candidate = StatusActive
264
 
        case StatusStopped:
265
 
                candidate = StatusStopping
266
 
        }
267
 
        return status == candidate
268
 
}
269
 
 
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:
274
 
        // StatusPending
275
 
        // StatusInstalled
276
 
        // StatusStarted
277
 
        // StatusStopped
278
 
        // StatusError
279
 
        // StatusDown
280
 
        // For compatibility reasons we convert modern states (from V2 uniter) into
281
 
        // four of the old ones: StatusPending, StatusStarted, StatusStopped, or StatusError.
282
 
 
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
287
 
 
288
 
        switch agentStatus {
289
 
        case StatusAllocating:
290
 
                return StatusPending, true
291
 
        case StatusError:
292
 
                return StatusError, true
293
 
        case StatusRebooting, StatusExecuting, StatusIdle, StatusLost, StatusFailed:
294
 
                switch workloadStatus {
295
 
                case StatusError:
296
 
                        return StatusError, true
297
 
                case StatusTerminated:
298
 
                        return StatusStopped, true
299
 
                case StatusMaintenance:
300
 
                        if isInstalled {
301
 
                                return StatusStarted, true
302
 
                        } else {
303
 
                                return StatusPending, true
304
 
                        }
305
 
                default:
306
 
                        return StatusStarted, true
307
 
                }
308
 
        }
309
 
        return "", false
310
 
}