Merge "Allow to specify a per-image SSH connection timeout"

This commit is contained in:
Zuul 2020-10-29 02:16:06 +00:00 committed by Gerrit Code Review
commit 5fa0d03c26
7 changed files with 42 additions and 21 deletions

View File

@ -58,7 +58,12 @@ def get_images_options():
cfg.StrOpt('username',
help="Default " + name + " username"),
cfg.StrOpt('password',
help="Default " + name + " password")])]
help="Default " + name + " password"),
cfg.FloatOpt('connection_timeout',
default=None,
help=("Default " + name +
" SSH connection timeout (seconds)")), ]
)]
return options

View File

@ -36,6 +36,7 @@ class CentosImageFixture(glance.URLGlanceImageFixture):
container_format = CONF.tobiko.centos.container_format or "bare"
username = CONF.tobiko.centos.username or 'centos'
password = CONF.tobiko.centos.password
connection_timeout = CONF.tobiko.centos.connection_timeout or 400.
class CentosFlavorStackFixture(_nova.FlavorStackFixture):

View File

@ -38,6 +38,7 @@ class CirrosImageFixture(glance.URLGlanceImageFixture):
disk_format = CONF.tobiko.cirros.disk_format or "qcow2"
username = CONF.tobiko.cirros.username or 'cirros'
password = CONF.tobiko.cirros.password or 'gocubsgo'
connection_timeout = CONF.tobiko.cirros.connection_timeout or 200.
class CirrosFlavorStackFixture(_nova.FlavorStackFixture):

View File

@ -114,6 +114,10 @@ class ServerStackFixture(heat.HeatStackFixture):
"""password used to login to a Nova server instance"""
return self.image_fixture.password
@property
def connection_timeout(self):
return self.image_fixture.connection_timeout
# Stack used to create flavor for Nova server instance
flavor_stack = None
@ -146,10 +150,11 @@ class ServerStackFixture(heat.HeatStackFixture):
return bool(self.floating_network)
@property
def ssh_client(self):
def ssh_client(self) -> ssh.SSHClientFixture:
return ssh.ssh_client(host=self.ip_address,
username=self.username,
password=self.password)
password=self.password,
connection_timeout=self.connection_timeout)
@property
def ssh_command(self):
@ -283,7 +288,7 @@ class ServerStackFixture(heat.HeatStackFixture):
class PeerServerStackFixture(ServerStackFixture):
"""Server witch networking access requires passing by a peer Nova server
"""Server witch networking access requires passing by another Nova server
"""
has_floating_ip = False
@ -296,6 +301,7 @@ class PeerServerStackFixture(ServerStackFixture):
return ssh.ssh_client(host=self.ip_address,
username=self.username,
password=self.password,
connection_timeout=self.connection_timeout,
proxy_jump=self.peer_stack.ssh_client)
@property

View File

@ -33,6 +33,7 @@ class UbuntuImageFixture(glance.URLGlanceImageFixture):
container_format = CONF.tobiko.ubuntu.container_format or "bare"
username = CONF.tobiko.ubuntu.username or 'ubuntu'
password = CONF.tobiko.ubuntu.password
connection_timeout = CONF.tobiko.ubuntu.connection_timeout or 300.
class UbuntuFlavorStackFixture(_nova.FlavorStackFixture):

View File

@ -39,8 +39,8 @@ class RebootHostTimeoutError(RebootHostError):
message = "host {hostname!r} not rebooted after {timeout!s} seconds"
def reboot_host(ssh_client, wait: bool = True, timeout: tobiko.Seconds = None,
method=soft_reset_method):
def reboot_host(ssh_client: ssh.SSHClientFixture, wait: bool = True,
timeout: tobiko.Seconds = None, method=soft_reset_method):
reboot = RebootHostOperation(ssh_client=ssh_client, wait=wait,
timeout=timeout, method=method)
return tobiko.setup_fixture(reboot)
@ -58,6 +58,8 @@ class RebootHostOperation(tobiko.Operation):
@property
def ssh_client(self) -> ssh.SSHClientFixture:
if self._ssh_client is None:
raise ValueError(f"SSH client for object '{self}' is None")
return self._ssh_client
def __init__(self,
@ -66,8 +68,7 @@ class RebootHostOperation(tobiko.Operation):
timeout: tobiko.Seconds = None,
method=soft_reset_method):
super(RebootHostOperation, self).__init__()
if ssh_client is not None:
self._ssh_client = ssh_client
self._ssh_client = ssh_client
tobiko.check_valid_type(self.ssh_client, ssh.SSHClientFixture)
self.wait = bool(wait)
self.timeout = tobiko.to_seconds(timeout)

View File

@ -452,7 +452,8 @@ class SSHClientManager(object):
def get_client(self, host, hostname=None, username=None, port=None,
proxy_jump=None, host_config=None, config_files=None,
proxy_client=None, **connect_parameters):
proxy_client=None, **connect_parameters) -> \
SSHClientFixture:
if isinstance(host, netaddr.IPAddress):
host = str(host)
@ -468,17 +469,22 @@ class SSHClientManager(object):
username = username or global_host_config.username
host_key = hostname, port, username, proxy_jump
client = self.clients.get(host_key, UNDEFINED_CLIENT)
if client is UNDEFINED_CLIENT:
# Put a placeholder client to avoid infinite recursive lookup
self.clients[host_key] = None
proxy_client = proxy_client or self.get_proxy_client(
host=host, proxy_jump=proxy_jump, config_files=config_files)
self.clients[host_key] = client = SSHClientFixture(
host=host, hostname=hostname, port=port, username=username,
proxy_client=proxy_client, host_config=host_config,
**connect_parameters)
return client
existing_client = self.clients.get(host_key)
if isinstance(existing_client, SSHClientFixture):
return existing_client
# Put a placeholder to avoid infinite recursive lookup
if existing_client is UNDEFINED_CLIENT:
raise RuntimeError('Recursive SSH proxy client definition')
self.clients[host_key] = UNDEFINED_CLIENT
proxy_client = proxy_client or self.get_proxy_client(
host=host, proxy_jump=proxy_jump, config_files=config_files)
self.clients[host_key] = new_client = SSHClientFixture(
host=host, hostname=hostname, port=port, username=username,
proxy_client=proxy_client, host_config=host_config,
**connect_parameters)
return new_client
def get_proxy_client(self, host=None, proxy_jump=None, host_config=None,
config_files=None):
@ -495,7 +501,7 @@ CLIENTS = SSHClientManager()
def ssh_client(host, port=None, username=None, proxy_jump=None,
host_config=None, config_files=None, manager=None,
**connect_parameters):
**connect_parameters) -> SSHClientFixture:
manager = manager or CLIENTS
return manager.get_client(host=host, port=port, username=username,
proxy_jump=proxy_jump, host_config=host_config,