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:
parent
e8586114ad
commit
e7a9d71ac0
2 changed files with 34 additions and 54 deletions
|
@ -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."""
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue