OLD | NEW |
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package instancepoller | 4 package instancepoller |
5 | 5 |
6 import ( | 6 import ( |
7 "fmt" | 7 "fmt" |
8 "time" | 8 "time" |
9 | 9 |
10 "github.com/juju/loggo" | 10 "github.com/juju/loggo" |
(...skipping 24 matching lines...) Expand all Loading... |
35 Id() string | 35 Id() string |
36 InstanceId() (instance.Id, error) | 36 InstanceId() (instance.Id, error) |
37 Addresses() []instance.Address | 37 Addresses() []instance.Address |
38 SetAddresses(...instance.Address) error | 38 SetAddresses(...instance.Address) error |
39 InstanceStatus() (string, error) | 39 InstanceStatus() (string, error) |
40 SetInstanceStatus(status string) error | 40 SetInstanceStatus(status string) error |
41 String() string | 41 String() string |
42 Refresh() error | 42 Refresh() error |
43 Life() state.Life | 43 Life() state.Life |
44 Status() (status params.Status, info string, data params.StatusData, err
error) | 44 Status() (status params.Status, info string, data params.StatusData, err
error) |
| 45 IsManual() (bool, error) |
45 } | 46 } |
46 | 47 |
47 type instanceInfo struct { | 48 type instanceInfo struct { |
48 addresses []instance.Address | 49 addresses []instance.Address |
49 status string | 50 status string |
50 } | 51 } |
51 | 52 |
52 type machineContext interface { | 53 type machineContext interface { |
53 killAll(err error) | 54 killAll(err error) |
54 instanceInfo(id instance.Id) (instanceInfo, error) | 55 instanceInfo(id instance.Id) (instanceInfo, error) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 // We don't know about the machine - start | 126 // We don't know about the machine - start |
126 // a goroutine to deal with it. | 127 // a goroutine to deal with it. |
127 m, err := p.context.getMachine(id) | 128 m, err := p.context.getMachine(id) |
128 if errors.IsNotFoundError(err) { | 129 if errors.IsNotFoundError(err) { |
129 logger.Warningf("watcher gave notification of no
n-existent machine %q", id) | 130 logger.Warningf("watcher gave notification of no
n-existent machine %q", id) |
130 continue | 131 continue |
131 } | 132 } |
132 if err != nil { | 133 if err != nil { |
133 return err | 134 return err |
134 } | 135 } |
| 136 // We don't poll manual machines. |
| 137 isManual, err := m.IsManual() |
| 138 if err != nil { |
| 139 return err |
| 140 } |
| 141 if isManual { |
| 142 continue |
| 143 } |
135 c = make(chan struct{}) | 144 c = make(chan struct{}) |
136 p.machines[id] = c | 145 p.machines[id] = c |
137 go runMachine(p.context.newMachineContext(), m, c, p.mac
hineDead) | 146 go runMachine(p.context.newMachineContext(), m, c, p.mac
hineDead) |
138 } else { | 147 } else { |
139 c <- struct{}{} | 148 c <- struct{}{} |
140 } | 149 } |
141 } | 150 } |
142 return nil | 151 return nil |
143 } | 152 } |
144 | 153 |
(...skipping 19 matching lines...) Expand all Loading... |
164 | 173 |
165 func machineLoop(context machineContext, m machine, changed <-chan struct{}) err
or { | 174 func machineLoop(context machineContext, m machine, changed <-chan struct{}) err
or { |
166 // Use a short poll interval when initially waiting for | 175 // Use a short poll interval when initially waiting for |
167 // a machine's address and machine agent to start, and a long one when i
t already | 176 // a machine's address and machine agent to start, and a long one when i
t already |
168 // has an address and the machine agent is started. | 177 // has an address and the machine agent is started. |
169 pollInterval := ShortPoll | 178 pollInterval := ShortPoll |
170 pollInstance := true | 179 pollInstance := true |
171 for { | 180 for { |
172 if pollInstance { | 181 if pollInstance { |
173 instInfo, err := pollInstanceInfo(context, m) | 182 instInfo, err := pollInstanceInfo(context, m) |
174 » » » if err != nil { | 183 » » » if err != nil && !state.IsNotProvisionedError(err) { |
175 // If the provider doesn't implement Addresses/S
tatus now, | 184 // If the provider doesn't implement Addresses/S
tatus now, |
176 // it never will until we're upgraded, so don't
bother | 185 // it never will until we're upgraded, so don't
bother |
177 // asking any more. We could use less resources | 186 // asking any more. We could use less resources |
178 // by taking down the entire worker, but this is
easier for now | 187 // by taking down the entire worker, but this is
easier for now |
179 // (and hopefully the local provider will implem
ent | 188 // (and hopefully the local provider will implem
ent |
180 // Addresses/Status in the not-too-distant futur
e), | 189 // Addresses/Status in the not-too-distant futur
e), |
181 // so we won't need to worry about this case at
all. | 190 // so we won't need to worry about this case at
all. |
182 if errors.IsNotImplementedError(err) { | 191 if errors.IsNotImplementedError(err) { |
183 pollInterval = 365 * 24 * time.Hour | 192 pollInterval = 365 * 24 * time.Hour |
184 } else { | 193 } else { |
185 return err | 194 return err |
186 } | 195 } |
187 } | 196 } |
188 » » » machineStatus, _, _, err := m.Status() | 197 » » » machineStatus := params.StatusPending |
189 » » » if err != nil { | 198 » » » if err == nil { |
190 » » » » logger.Warningf("cannot get current machine stat
us for machine %v: %v", m.Id(), err) | 199 » » » » if machineStatus, _, _, err = m.Status(); err !=
nil { |
| 200 » » » » » logger.Warningf("cannot get current mach
ine status for machine %v: %v", m.Id(), err) |
| 201 » » » » } |
191 } | 202 } |
192 if len(instInfo.addresses) > 0 && instInfo.status != ""
&& machineStatus == params.StatusStarted { | 203 if len(instInfo.addresses) > 0 && instInfo.status != ""
&& machineStatus == params.StatusStarted { |
193 // We've got at least one address and a status a
nd instance is started, so poll infrequently. | 204 // We've got at least one address and a status a
nd instance is started, so poll infrequently. |
194 pollInterval = LongPoll | 205 pollInterval = LongPoll |
195 } else if pollInterval < LongPoll { | 206 } else if pollInterval < LongPoll { |
196 // We have no addresses or not started - poll in
creasingly rarely | 207 // We have no addresses or not started - poll in
creasingly rarely |
197 // until we do. | 208 // until we do. |
198 pollInterval = time.Duration(float64(pollInterva
l) * ShortPollBackoff) | 209 pollInterval = time.Duration(float64(pollInterva
l) * ShortPollBackoff) |
199 } | 210 } |
200 pollInstance = false | 211 pollInstance = false |
(...skipping 12 matching lines...) Expand all Loading... |
213 } | 224 } |
214 } | 225 } |
215 } | 226 } |
216 } | 227 } |
217 | 228 |
218 // pollInstanceInfo checks the current provider addresses and status | 229 // pollInstanceInfo checks the current provider addresses and status |
219 // for the given machine's instance, and sets them on the machine if they've cha
nged. | 230 // for the given machine's instance, and sets them on the machine if they've cha
nged. |
220 func pollInstanceInfo(context machineContext, m machine) (instInfo instanceInfo,
err error) { | 231 func pollInstanceInfo(context machineContext, m machine) (instInfo instanceInfo,
err error) { |
221 instInfo = instanceInfo{} | 232 instInfo = instanceInfo{} |
222 instId, err := m.InstanceId() | 233 instId, err := m.InstanceId() |
223 » if err != nil && !state.IsNotProvisionedError(err) { | 234 » // We can't ask the machine for its addresses if it isn't provisioned ye
t. |
| 235 » if state.IsNotProvisionedError(err) { |
| 236 » » return instInfo, err |
| 237 » } |
| 238 » if err != nil { |
224 return instInfo, fmt.Errorf("cannot get machine's instance id: %
v", err) | 239 return instInfo, fmt.Errorf("cannot get machine's instance id: %
v", err) |
225 } | 240 } |
226 instInfo, err = context.instanceInfo(instId) | 241 instInfo, err = context.instanceInfo(instId) |
227 if err != nil { | 242 if err != nil { |
228 if errors.IsNotImplementedError(err) { | 243 if errors.IsNotImplementedError(err) { |
229 return instInfo, err | 244 return instInfo, err |
230 } | 245 } |
231 logger.Warningf("cannot get instance info for instance %q: %v",
instId, err) | 246 logger.Warningf("cannot get instance info for instance %q: %v",
instId, err) |
232 return instInfo, nil | 247 return instInfo, nil |
233 } | 248 } |
(...skipping 24 matching lines...) Expand all Loading... |
258 if len(a0) != len(a1) { | 273 if len(a0) != len(a1) { |
259 return false | 274 return false |
260 } | 275 } |
261 for i := range a0 { | 276 for i := range a0 { |
262 if a0[i] != a1[i] { | 277 if a0[i] != a1[i] { |
263 return false | 278 return false |
264 } | 279 } |
265 } | 280 } |
266 return true | 281 return true |
267 } | 282 } |
OLD | NEW |