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.
This commit is contained in:
Gonéri Le Bouder 2019-08-27 14:56:43 -04:00 committed by GitHub
parent e8586114ad
commit e7a9d71ac0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 54 deletions

View file

@ -61,9 +61,6 @@ class VcenterProvider(CloudProvider):
self.vmware_test_platform = os.environ.get('VMWARE_TEST_PLATFORM', '')
self.aci = None
self.insecure = False
self.endpoint = ''
self.hostname = ''
self.port = 443
self.proxy = None
def filter(self, targets, exclude):
@ -105,11 +102,11 @@ class VcenterProvider(CloudProvider):
self._set_cloud_config('vmware_test_platform', self.vmware_test_platform)
if self.vmware_test_platform == 'govcsim':
self._setup_dynamic_simulator()
elif self.vmware_test_platform == 'worldstream':
self._setup_dynamic_baremetal()
elif self._use_static_config():
self._set_cloud_config('vmware_test_platform', 'static')
self._setup_static()
elif self.vmware_test_platform == 'worldstream':
self._setup_dynamic_baremetal()
else:
self._setup_dynamic_simulator()
@ -200,10 +197,12 @@ class VcenterProvider(CloudProvider):
aci = self._create_ansible_core_ci()
if not self.args.explain:
response = aci.start()
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)
def _create_ansible_core_ci(self):
@ -221,9 +220,6 @@ class VcenterProvider(CloudProvider):
'vmware_proxy_port': '8080'})
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'):
self.insecure = True
proxy_host = parser.get('DEFAULT', 'vmware_proxy_host')
@ -231,29 +227,6 @@ class VcenterProvider(CloudProvider):
if proxy_host and 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):
"""VMware vcenter/esx environment plugin. Updates integration test environment after delegation."""

View file

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