Revision d6fb3aea lib/hypervisor/hv_kvm.py
b/lib/hypervisor/hv_kvm.py | ||
---|---|---|
348 | 348 |
return self.data == other.data |
349 | 349 |
|
350 | 350 |
|
351 |
class QmpConnection: |
|
352 |
"""Connection to the QEMU Monitor using the QEMU Monitor Protocol (QMP). |
|
353 |
|
|
354 |
""" |
|
355 |
_FIRST_MESSAGE_KEY = "QMP" |
|
356 |
_EVENT_KEY = "event" |
|
357 |
_ERROR_KEY = "error" |
|
358 |
_RETURN_KEY = RETURN_KEY = "return" |
|
359 |
_ACTUAL_KEY = ACTUAL_KEY = "actual" |
|
360 |
_ERROR_CLASS_KEY = "class" |
|
361 |
_ERROR_DATA_KEY = "data" |
|
362 |
_ERROR_DESC_KEY = "desc" |
|
363 |
_EXECUTE_KEY = "execute" |
|
364 |
_ARGUMENTS_KEY = "arguments" |
|
365 |
_CAPABILITIES_COMMAND = "qmp_capabilities" |
|
366 |
_MESSAGE_END_TOKEN = "\r\n" |
|
351 |
class MonitorSocket(object): |
|
367 | 352 |
_SOCKET_TIMEOUT = 5 |
368 | 353 |
|
369 | 354 |
def __init__(self, monitor_filename): |
370 |
"""Instantiates the QmpConnection object.
|
|
355 |
"""Instantiates the MonitorSocket object.
|
|
371 | 356 |
|
372 | 357 |
@type monitor_filename: string |
373 | 358 |
@param monitor_filename: the filename of the UNIX raw socket on which the |
374 |
QMP monitor is listening
|
|
359 |
monitor (QMP or simple one) is listening
|
|
375 | 360 |
|
376 | 361 |
""" |
377 | 362 |
self.monitor_filename = monitor_filename |
... | ... | |
380 | 365 |
# in a reasonable amount of time |
381 | 366 |
self.sock.settimeout(self._SOCKET_TIMEOUT) |
382 | 367 |
self._connected = False |
383 |
self._buf = "" |
|
384 | 368 |
|
385 | 369 |
def _check_socket(self): |
386 | 370 |
sock_stat = None |
... | ... | |
388 | 372 |
sock_stat = os.stat(self.monitor_filename) |
389 | 373 |
except EnvironmentError, err: |
390 | 374 |
if err.errno == errno.ENOENT: |
391 |
raise errors.HypervisorError("No qmp socket found")
|
|
375 |
raise errors.HypervisorError("No monitor socket found")
|
|
392 | 376 |
else: |
393 |
raise errors.HypervisorError("Error checking qmp socket: %s",
|
|
377 |
raise errors.HypervisorError("Error checking monitor socket: %s",
|
|
394 | 378 |
utils.ErrnoOrStr(err)) |
395 | 379 |
if not stat.S_ISSOCK(sock_stat.st_mode): |
396 |
raise errors.HypervisorError("Qmp socket is not a socket")
|
|
380 |
raise errors.HypervisorError("Monitor socket is not a socket")
|
|
397 | 381 |
|
398 | 382 |
def _check_connection(self): |
399 | 383 |
"""Make sure that the connection is established. |
400 | 384 |
|
401 | 385 |
""" |
402 | 386 |
if not self._connected: |
403 |
raise errors.ProgrammerError("To use a QmpConnection you need to first"
|
|
387 |
raise errors.ProgrammerError("To use a MonitorSocket you need to first"
|
|
404 | 388 |
" invoke connect() on it") |
405 | 389 |
|
406 | 390 |
def connect(self): |
407 |
"""Connects to the QMP monitor.
|
|
391 |
"""Connects to the monitor. |
|
408 | 392 |
|
409 |
Connects to the UNIX socket and makes sure that we can actually send and |
|
410 |
receive data to the kvm instance via QMP. |
|
393 |
Connects to the UNIX socket |
|
411 | 394 |
|
412 | 395 |
@raise errors.HypervisorError: when there are communication errors |
413 |
@raise errors.ProgrammerError: when there are data serialization errors |
|
414 | 396 |
|
415 | 397 |
""" |
416 | 398 |
if self._connected: |
... | ... | |
425 | 407 |
raise errors.HypervisorError("Can't connect to qmp socket") |
426 | 408 |
self._connected = True |
427 | 409 |
|
410 |
def close(self): |
|
411 |
"""Closes the socket |
|
412 |
|
|
413 |
It cannot be used after this call. |
|
414 |
|
|
415 |
""" |
|
416 |
self.sock.close() |
|
417 |
|
|
418 |
|
|
419 |
class QmpConnection(MonitorSocket): |
|
420 |
"""Connection to the QEMU Monitor using the QEMU Monitor Protocol (QMP). |
|
421 |
|
|
422 |
""" |
|
423 |
_FIRST_MESSAGE_KEY = "QMP" |
|
424 |
_EVENT_KEY = "event" |
|
425 |
_ERROR_KEY = "error" |
|
426 |
_RETURN_KEY = RETURN_KEY = "return" |
|
427 |
_ACTUAL_KEY = ACTUAL_KEY = "actual" |
|
428 |
_ERROR_CLASS_KEY = "class" |
|
429 |
_ERROR_DATA_KEY = "data" |
|
430 |
_ERROR_DESC_KEY = "desc" |
|
431 |
_EXECUTE_KEY = "execute" |
|
432 |
_ARGUMENTS_KEY = "arguments" |
|
433 |
_CAPABILITIES_COMMAND = "qmp_capabilities" |
|
434 |
_MESSAGE_END_TOKEN = "\r\n" |
|
435 |
|
|
436 |
def __init__(self, monitor_filename): |
|
437 |
super(QmpConnection, self).__init__(monitor_filename) |
|
438 |
self._buf = "" |
|
439 |
|
|
440 |
def connect(self): |
|
441 |
"""Connects to the QMP monitor. |
|
442 |
|
|
443 |
Connects to the UNIX socket and makes sure that we can actually send and |
|
444 |
receive data to the kvm instance via QMP. |
|
445 |
|
|
446 |
@raise errors.HypervisorError: when there are communication errors |
|
447 |
@raise errors.ProgrammerError: when there are data serialization errors |
|
448 |
|
|
449 |
""" |
|
450 |
super(QmpConnection, self).connect() |
|
428 | 451 |
# Check if we receive a correct greeting message from the server |
429 | 452 |
# (As per the QEMU Protocol Specification 0.1 - section 2.2) |
430 | 453 |
greeting = self._Recv() |
Also available in: Unified diff