ansible-test: async deployment w/ vcenter provider (#59984)

ansible-test: async deployment w/ vcenter provider

So far, `ansible-test`'s vcenter provider was trigger by a blocking POST
call. Since the depoyment take a lot of time (> 8m), we decided to use
an async call instead and poll the API server until the deployment
is ready.
pull/61405/head
Gonéri Le Bouder 5 years ago committed by GitHub
parent e8586114ad
commit e7a9d71ac0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -61,9 +61,6 @@ class VcenterProvider(CloudProvider):
self.vmware_test_platform = os.environ.get('VMWARE_TEST_PLATFORM', '') self.vmware_test_platform = os.environ.get('VMWARE_TEST_PLATFORM', '')
self.aci = None self.aci = None
self.insecure = False self.insecure = False
self.endpoint = ''
self.hostname = ''
self.port = 443
self.proxy = None self.proxy = None
def filter(self, targets, exclude): def filter(self, targets, exclude):
@ -105,11 +102,11 @@ class VcenterProvider(CloudProvider):
self._set_cloud_config('vmware_test_platform', self.vmware_test_platform) self._set_cloud_config('vmware_test_platform', self.vmware_test_platform)
if self.vmware_test_platform == 'govcsim': if self.vmware_test_platform == 'govcsim':
self._setup_dynamic_simulator() self._setup_dynamic_simulator()
elif self.vmware_test_platform == 'worldstream':
self._setup_dynamic_baremetal()
elif self._use_static_config(): elif self._use_static_config():
self._set_cloud_config('vmware_test_platform', 'static') self._set_cloud_config('vmware_test_platform', 'static')
self._setup_static() self._setup_static()
elif self.vmware_test_platform == 'worldstream':
self._setup_dynamic_baremetal()
else: else:
self._setup_dynamic_simulator() self._setup_dynamic_simulator()
@ -200,10 +197,12 @@ class VcenterProvider(CloudProvider):
aci = self._create_ansible_core_ci() aci = self._create_ansible_core_ci()
if not self.args.explain: if not self.args.explain:
response = aci.start()
self.aci = aci self.aci = aci
aci.start()
aci.wait(iterations=160)
config = self._populate_config_template(config, response) data = aci.get().response_json.get('data')
config = self._populate_config_template(config, data)
self._write_config(config) self._write_config(config)
def _create_ansible_core_ci(self): def _create_ansible_core_ci(self):
@ -221,9 +220,6 @@ class VcenterProvider(CloudProvider):
'vmware_proxy_port': '8080'}) 'vmware_proxy_port': '8080'})
parser.read(self.config_static_path) parser.read(self.config_static_path)
self.endpoint = parser.get('DEFAULT', 'vcenter_hostname')
self.port = parser.get('DEFAULT', 'vcenter_port')
if parser.get('DEFAULT', 'vmware_validate_certs').lower() in ('no', 'false'): if parser.get('DEFAULT', 'vmware_validate_certs').lower() in ('no', 'false'):
self.insecure = True self.insecure = True
proxy_host = parser.get('DEFAULT', 'vmware_proxy_host') proxy_host = parser.get('DEFAULT', 'vmware_proxy_host')
@ -231,29 +227,6 @@ class VcenterProvider(CloudProvider):
if proxy_host and proxy_port: if proxy_host and proxy_port:
self.proxy = 'http://%s:%d' % (proxy_host, proxy_port) self.proxy = 'http://%s:%d' % (proxy_host, proxy_port)
self._wait_for_service()
def _wait_for_service(self):
"""Wait for the vCenter service endpoint to accept connections."""
if self.args.explain:
return
client = HttpClient(self.args, always=True, insecure=self.insecure, proxy=self.proxy)
endpoint = 'https://%s:%s' % (self.endpoint, self.port)
for i in range(1, 30):
display.info('Waiting for vCenter service: %s' % endpoint, verbosity=1)
try:
client.get(endpoint)
return
except SubprocessError:
pass
time.sleep(10)
raise ApplicationError('Timeout waiting for vCenter service.')
class VcenterEnvironment(CloudEnvironment): class VcenterEnvironment(CloudEnvironment):
"""VMware vcenter/esx environment plugin. Updates integration test environment after delegation.""" """VMware vcenter/esx environment plugin. Updates integration test environment after delegation."""

@ -306,16 +306,22 @@ class AnsibleCoreCI:
) )
else: else:
response_json = response.json() response_json = response.json()
status = response_json['status'] status = response_json['status']
con = response_json['connection'] con = response_json.get('connection')
if con:
self.connection = InstanceConnection( self.connection = InstanceConnection(
running=status == 'running', running=status == 'running',
hostname=con['hostname'], hostname=con['hostname'],
port=int(con.get('port', self.port)), port=int(con.get('port', self.port)),
username=con['username'], username=con['username'],
password=con.get('password'), password=con.get('password'),
response_json=response_json,
)
else: # 'vcenter' resp does not have a 'connection' key
self.connection = InstanceConnection(
running=status == 'running',
response_json=response_json,
) )
if self.connection.password: if self.connection.password:
@ -329,9 +335,9 @@ class AnsibleCoreCI:
return self.connection return self.connection
def wait(self): def wait(self, iterations=90): # type: (t.Optional[int]) -> None
"""Wait for the instance to become ready.""" """Wait for the instance to become ready."""
for _iteration in range(1, 90): for _iteration in range(1, iterations):
if self.get().running: if self.get().running:
return return
time.sleep(10) time.sleep(10)
@ -597,19 +603,20 @@ class SshKey:
class InstanceConnection: class InstanceConnection:
"""Container for remote instance status and connection details.""" """Container for remote instance status and connection details."""
def __init__(self, running, hostname, port, username, password): def __init__(self,
""" running, # type: bool
:type running: bool hostname=None, # type: t.Optional[str]
:type hostname: str port=None, # type: t.Optional[int]
:type port: int username=None, # type: t.Optional[str]
:type username: str password=None, # type: t.Optional[str]
:type password: str | None response_json=None, # type: t.Optional[t.Dict[str, t.Any]]
""" ): # type: (...) -> None
self.running = running self.running = running
self.hostname = hostname self.hostname = hostname
self.port = port self.port = port
self.username = username self.username = username
self.password = password self.password = password
self.response_json = response_json or {}
def __str__(self): def __str__(self):
if self.password: if self.password:

Loading…
Cancel
Save