Revision e125c67c daemons/ganeti-watcher
b/daemons/ganeti-watcher | ||
---|---|---|
40 | 40 |
from ganeti import serializer |
41 | 41 |
from ganeti import ssconf |
42 | 42 |
from ganeti import errors |
43 |
from ganeti import opcodes |
|
43 | 44 |
from ganeti import logger |
45 |
from ganeti import cli |
|
44 | 46 |
|
45 | 47 |
|
46 | 48 |
MAXTRIES = 5 |
... | ... | |
53 | 55 |
KEY_BOOT_ID = "bootid" |
54 | 56 |
|
55 | 57 |
|
58 |
# Global client object |
|
59 |
client = None |
|
60 |
|
|
61 |
|
|
56 | 62 |
class NotMasterError(errors.GenericError): |
57 | 63 |
"""Exception raised when this host is not the master.""" |
58 | 64 |
|
... | ... | |
237 | 243 |
"""Encapsulates the start of an instance. |
238 | 244 |
|
239 | 245 |
""" |
240 |
DoCmd(['gnt-instance', 'startup', '--lock-retries=15', self.name]) |
|
246 |
op = opcodes.OpStartupInstance(instance_name=self.name, |
|
247 |
force=False, |
|
248 |
extra_args=None) |
|
249 |
cli.SubmitOpCode(op, cl=client) |
|
241 | 250 |
|
242 | 251 |
def ActivateDisks(self): |
243 | 252 |
"""Encapsulates the activation of all disks of an instance. |
244 | 253 |
|
245 | 254 |
""" |
246 |
DoCmd(['gnt-instance', 'activate-disks', '--lock-retries=15', self.name]) |
|
247 |
|
|
248 |
|
|
249 |
def _RunListCmd(cmd): |
|
250 |
"""Runs a command and parses its output into lists. |
|
251 |
|
|
252 |
""" |
|
253 |
for line in DoCmd(cmd).stdout.splitlines(): |
|
254 |
yield line.split(':') |
|
255 |
op = opcodes.OpActivateInstanceDisks(instance_name=self.name) |
|
256 |
cli.SubmitOpCode(op, cl=client) |
|
255 | 257 |
|
256 | 258 |
|
257 | 259 |
def GetInstanceList(with_secondaries=None): |
258 | 260 |
"""Get a list of instances on this cluster. |
259 | 261 |
|
260 | 262 |
""" |
261 |
cmd = ['gnt-instance', 'list', '--lock-retries=15', '--no-headers', |
|
262 |
'--separator=:'] |
|
263 |
|
|
264 |
fields = 'name,oper_state,admin_state' |
|
263 |
fields = ["name", "oper_state", "admin_state"] |
|
265 | 264 |
|
266 | 265 |
if with_secondaries is not None: |
267 |
fields += ',snodes'
|
|
266 |
fields.append("snodes")
|
|
268 | 267 |
|
269 |
cmd.append('-o') |
|
270 |
cmd.append(fields) |
|
268 |
result = client.QueryInstances([], fields) |
|
271 | 269 |
|
272 | 270 |
instances = [] |
273 |
for fields in _RunListCmd(cmd):
|
|
271 |
for fields in result:
|
|
274 | 272 |
if with_secondaries is not None: |
275 | 273 |
(name, status, autostart, snodes) = fields |
276 | 274 |
|
277 |
if snodes == "-":
|
|
275 |
if not snodes:
|
|
278 | 276 |
continue |
279 | 277 |
|
280 | 278 |
for node in with_secondaries: |
281 |
if node in snodes.split(','):
|
|
279 |
if node in snodes: |
|
282 | 280 |
break |
283 | 281 |
else: |
284 | 282 |
continue |
... | ... | |
286 | 284 |
else: |
287 | 285 |
(name, status, autostart) = fields |
288 | 286 |
|
289 |
instances.append(Instance(name, status, autostart != "no"))
|
|
287 |
instances.append(Instance(name, status, autostart)) |
|
290 | 288 |
|
291 | 289 |
return instances |
292 | 290 |
|
... | ... | |
295 | 293 |
"""Get a dict mapping nodes to boot IDs. |
296 | 294 |
|
297 | 295 |
""" |
298 |
cmd = ['gnt-node', 'list', '--lock-retries=15', '--no-headers', |
|
299 |
'--separator=:', '-o', 'name,bootid'] |
|
300 |
|
|
301 |
ids = {} |
|
302 |
for fields in _RunListCmd(cmd): |
|
303 |
(name, bootid) = fields |
|
304 |
ids[name] = bootid |
|
305 |
|
|
306 |
return ids |
|
296 |
result = client.QueryNodes([], ["name", "bootid"]) |
|
297 |
return dict([(name, bootid) for name, bootid in result]) |
|
307 | 298 |
|
308 | 299 |
|
309 | 300 |
class Watcher(object): |
... | ... | |
408 | 399 |
"""Run gnt-cluster verify-disks. |
409 | 400 |
|
410 | 401 |
""" |
411 |
result = DoCmd(['gnt-cluster', 'verify-disks', '--lock-retries=15']) |
|
402 |
# TODO: What should we do here? |
|
403 |
result = DoCmd(['gnt-cluster', 'verify-disks']) |
|
412 | 404 |
if result.output: |
413 | 405 |
logging.info(result.output) |
414 | 406 |
|
... | ... | |
436 | 428 |
"""Main function. |
437 | 429 |
|
438 | 430 |
""" |
431 |
global client |
|
432 |
|
|
439 | 433 |
options, args = ParseOptions() |
440 | 434 |
|
441 | 435 |
logger.SetupLogging(constants.LOG_WATCHER, debug=options.debug) |
442 | 436 |
|
443 | 437 |
try: |
438 |
client = cli.GetClient() |
|
439 |
|
|
444 | 440 |
try: |
445 | 441 |
watcher = Watcher() |
446 | 442 |
except errors.ConfigurationError: |
447 | 443 |
# Just exit if there's no configuration |
448 | 444 |
sys.exit(constants.EXIT_SUCCESS) |
445 |
|
|
449 | 446 |
watcher.Run() |
450 | 447 |
except SystemExit: |
451 | 448 |
raise |
Also available in: Unified diff