Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Virt: turn timeout values into definitions

This tries to replace values on timeouts (sometimes repeated over
multiple places) with definitions of them. The approach is to use
those definitions as default values, but still allowing a function
caller to pass a specific timeout.

This way, if a specific timeout need tweaking, it's much simpler
to do so. This tweaking can also be necessary only on a specific
monitor or VM implementation, so we keep them separate.

aexpect.py has not received the same treatment because it is
a library that has broad and general use.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
  • Loading branch information...
commit b638c9c3a5f9fdee07281b1e232832c94d300458 1 parent 216eff1
@clebergnu clebergnu authored
View
6 client/virt/aexpect.py
@@ -898,15 +898,13 @@ def __getinitargs__(self):
return Tail.__getinitargs__(self)
- def read_nonblocking(self, timeout=None):
+ def read_nonblocking(self, timeout=0.1):
"""
Read from child until there is nothing to read for timeout seconds.
@param timeout: Time (seconds) to wait before we give up reading from
- the child process, or None to use the default value.
+ the child process.
"""
- if timeout is None:
- timeout = 0.1
fd = self._get_fd("expect")
data = ""
while True:
View
52 client/virt/kvm_monitor.py
@@ -60,6 +60,9 @@ class Monitor:
Common code for monitor classes.
"""
+ ACQUIRE_LOCK_TIMEOUT = 20
+ DATA_AVAILABLE_TIMEOUT = 0
+
def __init__(self, name, filename):
"""
Initialize the instance.
@@ -110,7 +113,8 @@ def _close_sock(self):
pass
self._socket.close()
- def _acquire_lock(self, timeout=20):
+
+ def _acquire_lock(self, timeout=ACQUIRE_LOCK_TIMEOUT):
end_time = time.time() + timeout
while time.time() < end_time:
if self._lock.acquire(False):
@@ -119,7 +123,7 @@ def _acquire_lock(self, timeout=20):
return False
- def _data_available(self, timeout=0):
+ def _data_available(self, timeout=DATA_AVAILABLE_TIMEOUT):
timeout = max(0, timeout)
try:
return bool(select.select([self._socket], [], [], timeout)[0])
@@ -157,6 +161,9 @@ class HumanMonitor(Monitor):
Wraps "human monitor" commands.
"""
+ PROMPT_TIMEOUT = 20
+ CMD_TIMEOUT = 20
+
def __init__(self, name, filename, suppress_exceptions=False):
"""
Connect to the monitor socket and find the (qemu) prompt.
@@ -176,7 +183,7 @@ def __init__(self, name, filename, suppress_exceptions=False):
self.protocol = "human"
# Find the initial (qemu) prompt
- s, o = self._read_up_to_qemu_prompt(20)
+ s, o = self._read_up_to_qemu_prompt()
if not s:
raise MonitorProtocolError("Could not find (qemu) prompt "
"after connecting to monitor. "
@@ -195,7 +202,7 @@ def __init__(self, name, filename, suppress_exceptions=False):
# Private methods
- def _read_up_to_qemu_prompt(self, timeout=20):
+ def _read_up_to_qemu_prompt(self, timeout=PROMPT_TIMEOUT):
s = ""
end_time = time.time() + timeout
while self._data_available(end_time - time.time()):
@@ -219,7 +226,7 @@ def _send(self, cmd):
@raise MonitorLockError: Raised if the lock cannot be acquired
@raise MonitorSocketError: Raised if a socket error occurs
"""
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to send "
"monitor command '%s'" % cmd)
@@ -236,7 +243,7 @@ def _send(self, cmd):
# Public methods
- def cmd(self, command, timeout=20, debug=True, fd=None):
+ def cmd(self, command, timeout=CMD_TIMEOUT, debug=True, fd=None):
"""
Send command to the monitor.
@@ -252,7 +259,7 @@ def cmd(self, command, timeout=20, debug=True, fd=None):
if debug:
logging.debug("(monitor %s) Sending command '%s'",
self.name, command)
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to send "
"monitor command '%s'" % command)
@@ -313,7 +320,7 @@ def verify_status(self, status):
# cmd().
# - A command wrapper should use self._help_str if it requires information
# about the monitor's capabilities.
- def send_args_cmd(self, cmdlines, timeout=20, convert=True):
+ def send_args_cmd(self, cmdlines, timeout=CMD_TIMEOUT, convert=True):
"""
Send a command with/without parameters and return its output.
Have same effect with cmd function.
@@ -463,6 +470,11 @@ class QMPMonitor(Monitor):
Wraps QMP monitor commands.
"""
+ READ_OBJECTS_TIMEOUT = 5
+ CMD_TIMEOUT = 20
+ RESPONSE_TIMEOUT = 20
+ PROMPT_TIMEOUT = 20
+
def __init__(self, name, filename, suppress_exceptions=False):
"""
Connect to the monitor socket, read the greeting message and issue the
@@ -528,7 +540,7 @@ def _build_cmd(self, cmd, args=None, id=None):
return obj
- def _read_objects(self, timeout=5):
+ def _read_objects(self, timeout=READ_OBJECTS_TIMEOUT):
"""
Read lines from the monitor and try to decode them.
Stop when all available lines have been successfully decoded, or when
@@ -580,7 +592,7 @@ def _send(self, data):
raise MonitorSocketError("Could not send data: %r" % data, e)
- def _get_response(self, id=None, timeout=20):
+ def _get_response(self, id=None, timeout=RESPONSE_TIMEOUT):
"""
Read a response from the QMP monitor.
@@ -600,7 +612,7 @@ def _get_response(self, id=None, timeout=20):
# Public methods
- def cmd(self, cmd, args=None, timeout=20, debug=True):
+ def cmd(self, cmd, args=None, timeout=CMD_TIMEOUT, debug=True):
"""
Send a QMP monitor command and return the response.
@@ -621,7 +633,7 @@ def cmd(self, cmd, args=None, timeout=20, debug=True):
if debug:
logging.debug("(monitor %s) Sending command '%s'",
self.name, cmd)
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to send "
"QMP command '%s'" % cmd)
@@ -653,7 +665,7 @@ def cmd(self, cmd, args=None, timeout=20, debug=True):
self._lock.release()
- def cmd_raw(self, data, timeout=20):
+ def cmd_raw(self, data, timeout=CMD_TIMEOUT):
"""
Send a raw string to the QMP monitor and return the response.
Unlike cmd(), return the raw response dict without performing any
@@ -666,7 +678,7 @@ def cmd_raw(self, data, timeout=20):
@raise MonitorSocketError: Raised if a socket error occurs
@raise MonitorProtocolError: Raised if no response is received
"""
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to send "
"data: %r" % data)
@@ -683,7 +695,7 @@ def cmd_raw(self, data, timeout=20):
self._lock.release()
- def cmd_obj(self, obj, timeout=20):
+ def cmd_obj(self, obj, timeout=CMD_TIMEOUT):
"""
Transform a Python object to JSON, send the resulting string to the QMP
monitor, and return the response.
@@ -697,10 +709,10 @@ def cmd_obj(self, obj, timeout=20):
@raise MonitorSocketError: Raised if a socket error occurs
@raise MonitorProtocolError: Raised if no response is received
"""
- return self.cmd_raw(json.dumps(obj) + "\n")
+ return self.cmd_raw(json.dumps(obj) + "\n", timeout)
- def cmd_qmp(self, cmd, args=None, id=None, timeout=20):
+ def cmd_qmp(self, cmd, args=None, id=None, timeout=CMD_TIMEOUT):
"""
Build a QMP command from the passed arguments, send it to the monitor
and return the response.
@@ -751,7 +763,7 @@ def get_events(self):
@return: A list of events (the objects returned have an "event" key)
@raise MonitorLockError: Raised if the lock cannot be acquired
"""
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to read "
"QMP events")
try:
@@ -779,7 +791,7 @@ def clear_events(self):
@raise MonitorLockError: Raised if the lock cannot be acquired
"""
- if not self._acquire_lock(20):
+ if not self._acquire_lock():
raise MonitorLockError("Could not acquire exclusive lock to clear "
"QMP event list")
self._events = []
@@ -796,7 +808,7 @@ def get_greeting(self):
# Command wrappers
# Note: all of the following functions raise exceptions in a similar manner
# to cmd().
- def send_args_cmd(self, cmdlines, timeout=20, convert=True):
+ def send_args_cmd(self, cmdlines, timeout=CMD_TIMEOUT, convert=True):
"""
Send a command with/without parameters and return its output.
Have same effect with cmd function.
View
32 client/virt/kvm_vm.py
@@ -17,6 +17,17 @@ class VM(virt_vm.BaseVM):
MIGRATION_PROTOS = ['tcp', 'unix', 'exec']
+ #
+ # By default we inherit all timeouts from the base VM class
+ #
+ LOGIN_TIMEOUT = virt_vm.BaseVM.LOGIN_TIMEOUT
+ LOGIN_WAIT_TIMEOUT = virt_vm.BaseVM.LOGIN_WAIT_TIMEOUT
+ COPY_FILES_TIMEOUT = virt_vm.BaseVM.COPY_FILES_TIMEOUT
+ MIGRATE_TIMEOUT = virt_vm.BaseVM.MIGRATE_TIMEOUT
+ REBOOT_TIMEOUT = virt_vm.BaseVM.REBOOT_TIMEOUT
+ CREATE_TIMEOUT = virt_vm.BaseVM.CREATE_TIMEOUT
+ CLOSE_SESSION_TIMEOUT = 30
+
def __init__(self, name, params, root_dir, address_cache, state=None):
"""
Initialize the object and set a few attributes.
@@ -635,8 +646,8 @@ def add_usb(help, usb_id, usb_type, multifunction=False,
@error.context_aware
- def create(self, name=None, params=None, root_dir=None, timeout=5.0,
- migration_mode=None, mac_source=None):
+ def create(self, name=None, params=None, root_dir=None,
+ timeout=CREATE_TIMEOUT, migration_mode=None, mac_source=None):
"""
Start the VM by running a qemu command.
All parameters are optional. If name, params or root_dir are not
@@ -1301,9 +1312,10 @@ def del_nic(self, nic_info, wait=20):
@error.context_aware
- def migrate(self, timeout=3600, protocol="tcp", cancel_delay=None,
- offline=False, stable_check=False, clean=True,
- save_path="/tmp", dest_host="localhost", remote_port=None):
+ def migrate(self, timeout=MIGRATE_TIMEOUT, protocol="tcp",
+ cancel_delay=None, offline=False, stable_check=False,
+ clean=True, save_path="/tmp", dest_host="localhost",
+ remote_port=None):
"""
Migrate the VM.
@@ -1457,7 +1469,8 @@ def wait_for_migration():
@error.context_aware
- def reboot(self, session=None, method="shell", nic_index=0, timeout=240):
+ def reboot(self, session=None, method="shell", nic_index=0,
+ timeout=REBOOT_TIMEOUT):
"""
Reboot the VM and wait for it to come back up by trying to log in until
timeout expires.
@@ -1497,9 +1510,10 @@ def reboot(self, session=None, method="shell", nic_index=0, timeout=240):
raise virt_vm.VMRebootError("Unknown reboot method: %s" % method)
error.context("waiting for guest to go down", logging.info)
- if not virt_utils.wait_for(lambda:
- not session.is_responsive(timeout=30),
- 120, 0, 1):
+ if not virt_utils.wait_for(
+ lambda:
+ not session.is_responsive(timeout=self.CLOSE_SESSION_TIMEOUT),
+ timeout / 2, 0, 1):
raise virt_vm.VMRebootError("Guest refuses to go down")
session.close()
View
6 client/virt/libvirt_monitor.py
@@ -8,6 +8,8 @@ class VirshMonitor:
Wraps "Virsh monitor" commands.
"""
+ LOGIN_TIMEOUT = 10
+
def __init__(self, virsh_exec, name, vmname, password=None,
prompt=None, hostname='localhost', driver=None, username=None,
linesep="\\n"):
@@ -61,7 +63,7 @@ def __getinitargs__(self):
self.hostname, self.driver, self.username)
- def login(self, timeout=10):
+ def login(self, timeout=LOGIN_TIMEOUT):
"""
Log into the hypervisor using required URIs .
@@ -83,7 +85,7 @@ def login(self, timeout=10):
if self.username is not None:
try:
virt_utils._remote_login(session, self.username, self.password,
- self.prompt, self.timeout)
+ self.prompt, timeout)
except aexpect.ShellError:
session.close()
session = None
View
37 client/virt/virt_vm.py
@@ -509,6 +509,17 @@ class BaseVM(object):
#
MIGRATION_PROTOS = ['tcp', ]
+ #
+ # Timeout definition. This is being kept inside the base class so that
+ # sub classes can change the default just for themselves
+ #
+ LOGIN_TIMEOUT = 10
+ LOGIN_WAIT_TIMEOUT = 240
+ COPY_FILES_TIMEOUT = 600
+ MIGRATE_TIMEOUT = 3600
+ REBOOT_TIMEOUT = 240
+ CREATE_TIMEOUT = 5
+
def __init__(self, name, params):
self.name = name
self.params = params
@@ -607,7 +618,7 @@ def get_testlog_filename(self):
@error.context_aware
- def login(self, nic_index=0, timeout=10):
+ def login(self, nic_index=0, timeout=LOGIN_TIMEOUT):
"""
Log into the guest via SSH/Telnet/Netcat.
If timeout expires while waiting for output from the guest (e.g. a
@@ -636,14 +647,15 @@ def login(self, nic_index=0, timeout=10):
return session
- def remote_login(self, nic_index=0, timeout=10):
+ def remote_login(self, nic_index=0, timeout=LOGIN_TIMEOUT):
"""
Alias for login() for backward compatibility.
"""
return self.login(nic_index, timeout)
- def wait_for_login(self, nic_index=0, timeout=240, internal_timeout=10):
+ def wait_for_login(self, nic_index=0, timeout=LOGIN_WAIT_TIMEOUT,
+ internal_timeout=LOGIN_TIMEOUT):
"""
Make multiple attempts to log into the guest via SSH/Telnet/Netcat.
@@ -667,7 +679,7 @@ def wait_for_login(self, nic_index=0, timeout=240, internal_timeout=10):
@error.context_aware
def copy_files_to(self, host_path, guest_path, nic_index=0, verbose=False,
- timeout=600):
+ timeout=COPY_FILES_TIMEOUT):
"""
Transfer files to the remote host(guest).
@@ -694,7 +706,7 @@ def copy_files_to(self, host_path, guest_path, nic_index=0, verbose=False,
@error.context_aware
def copy_files_from(self, guest_path, host_path, nic_index=0,
- verbose=False, timeout=600):
+ verbose=False, timeout=COPY_FILES_TIMEOUT):
"""
Transfer files from the guest.
@@ -720,7 +732,7 @@ def copy_files_from(self, guest_path, host_path, nic_index=0,
@error.context_aware
- def serial_login(self, timeout=10):
+ def serial_login(self, timeout=LOGIN_TIMEOUT):
"""
Log into the guest via the serial console.
If timeout expires while waiting for output from the guest (e.g. a
@@ -747,7 +759,8 @@ def serial_login(self, timeout=10):
return self.serial_console
- def wait_for_serial_login(self, timeout=240, internal_timeout=10):
+ def wait_for_serial_login(self, timeout=LOGIN_WAIT_TIMEOUT,
+ internal_timeout=LOGIN_TIMEOUT):
"""
Make multiple attempts to log into the guest via serial console.
@@ -898,9 +911,10 @@ def destroy(self, gracefully=True, free_mac_addresses=True):
raise NotImplementedError
- def migrate(self, timeout=3600, protocol="tcp", cancel_delay=None,
- offline=False, stable_check=False, clean=True,
- save_path="/tmp", dest_host="localhost", remote_port=None):
+ def migrate(self, timeout=MIGRATE_TIMEOUT, protocol="tcp",
+ cancel_delay=None, offline=False, stable_check=False,
+ clean=True, save_path="/tmp", dest_host="localhost",
+ remote_port=None):
"""
Migrate the VM.
@@ -925,7 +939,8 @@ def migrate(self, timeout=3600, protocol="tcp", cancel_delay=None,
raise NotImplementedError
- def reboot(self, session=None, method="shell", nic_index=0, timeout=240):
+ def reboot(self, session=None, method="shell", nic_index=0,
+ timeout=REBOOT_TIMEOUT):
"""
Reboot the VM and wait for it to come back up by trying to log in until
timeout expires.
Please sign in to comment.
Something went wrong with that request. Please try again.