mirror of https://github.com/ansible/ansible.git
Reorganize more ansible-test code. (#74611)
* Split out shell command. * Relocate ansible-test integration code.pull/74612/head
parent
065fc3ca17
commit
e6d7aecbe4
@ -0,0 +1,2 @@
|
|||||||
|
minor_changes:
|
||||||
|
- ansible-test - Reorganize integration test implementation by command.
|
@ -0,0 +1,2 @@
|
|||||||
|
minor_changes:
|
||||||
|
- ansible-test - Split out shell command implementation.
|
@ -0,0 +1,246 @@
|
|||||||
|
"""Network integration testing."""
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import textwrap
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from ... import types as t
|
||||||
|
|
||||||
|
from ...thread import (
|
||||||
|
WrappedThread,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...core_ci import (
|
||||||
|
AnsibleCoreCI,
|
||||||
|
SshKey,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...manage_ci import (
|
||||||
|
ManageNetworkCI,
|
||||||
|
get_network_settings,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...io import (
|
||||||
|
write_text_file,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...util import (
|
||||||
|
ApplicationError,
|
||||||
|
display,
|
||||||
|
ANSIBLE_TEST_CONFIG_ROOT,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...util_common import (
|
||||||
|
get_python_path,
|
||||||
|
handle_layout_messages,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...target import (
|
||||||
|
IntegrationTarget,
|
||||||
|
walk_network_integration_targets,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...config import (
|
||||||
|
NetworkIntegrationConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
command_integration_filter,
|
||||||
|
command_integration_filtered,
|
||||||
|
get_inventory_relative_path,
|
||||||
|
check_inventory,
|
||||||
|
delegate_inventory,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...data import (
|
||||||
|
data_context,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def command_network_integration(args):
|
||||||
|
"""
|
||||||
|
:type args: NetworkIntegrationConfig
|
||||||
|
"""
|
||||||
|
handle_layout_messages(data_context().content.integration_messages)
|
||||||
|
|
||||||
|
inventory_relative_path = get_inventory_relative_path(args)
|
||||||
|
template_path = os.path.join(ANSIBLE_TEST_CONFIG_ROOT, os.path.basename(inventory_relative_path)) + '.template'
|
||||||
|
|
||||||
|
if args.inventory:
|
||||||
|
inventory_path = os.path.join(data_context().content.root, data_context().content.integration_path, args.inventory)
|
||||||
|
else:
|
||||||
|
inventory_path = os.path.join(data_context().content.root, inventory_relative_path)
|
||||||
|
|
||||||
|
if args.no_temp_workdir:
|
||||||
|
# temporary solution to keep DCI tests working
|
||||||
|
inventory_exists = os.path.exists(inventory_path)
|
||||||
|
else:
|
||||||
|
inventory_exists = os.path.isfile(inventory_path)
|
||||||
|
|
||||||
|
if not args.explain and not args.platform and not inventory_exists:
|
||||||
|
raise ApplicationError(
|
||||||
|
'Inventory not found: %s\n'
|
||||||
|
'Use --inventory to specify the inventory path.\n'
|
||||||
|
'Use --platform to provision resources and generate an inventory file.\n'
|
||||||
|
'See also inventory template: %s' % (inventory_path, template_path)
|
||||||
|
)
|
||||||
|
|
||||||
|
check_inventory(args, inventory_path)
|
||||||
|
delegate_inventory(args, inventory_path)
|
||||||
|
|
||||||
|
all_targets = tuple(walk_network_integration_targets(include_hidden=True))
|
||||||
|
internal_targets = command_integration_filter(args, all_targets, init_callback=network_init)
|
||||||
|
instances = [] # type: t.List[WrappedThread]
|
||||||
|
|
||||||
|
if args.platform:
|
||||||
|
get_python_path(args, args.python_executable) # initialize before starting threads
|
||||||
|
|
||||||
|
configs = dict((config['platform_version'], config) for config in args.metadata.instance_config)
|
||||||
|
|
||||||
|
for platform_version in args.platform:
|
||||||
|
platform, version = platform_version.split('/', 1)
|
||||||
|
config = configs.get(platform_version)
|
||||||
|
|
||||||
|
if not config:
|
||||||
|
continue
|
||||||
|
|
||||||
|
instance = WrappedThread(functools.partial(network_run, args, platform, version, config))
|
||||||
|
instance.daemon = True
|
||||||
|
instance.start()
|
||||||
|
instances.append(instance)
|
||||||
|
|
||||||
|
while any(instance.is_alive() for instance in instances):
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
remotes = [instance.wait_for_result() for instance in instances]
|
||||||
|
inventory = network_inventory(args, remotes)
|
||||||
|
|
||||||
|
display.info('>>> Inventory: %s\n%s' % (inventory_path, inventory.strip()), verbosity=3)
|
||||||
|
|
||||||
|
if not args.explain:
|
||||||
|
write_text_file(inventory_path, inventory)
|
||||||
|
|
||||||
|
success = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
command_integration_filtered(args, internal_targets, all_targets, inventory_path)
|
||||||
|
success = True
|
||||||
|
finally:
|
||||||
|
if args.remote_terminate == 'always' or (args.remote_terminate == 'success' and success):
|
||||||
|
for instance in instances:
|
||||||
|
instance.result.stop()
|
||||||
|
|
||||||
|
|
||||||
|
def network_init(args, internal_targets): # type: (NetworkIntegrationConfig, t.Tuple[IntegrationTarget, ...]) -> None
|
||||||
|
"""Initialize platforms for network integration tests."""
|
||||||
|
if not args.platform:
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.metadata.instance_config is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
platform_targets = set(a for target in internal_targets for a in target.aliases if a.startswith('network/'))
|
||||||
|
|
||||||
|
instances = [] # type: t.List[WrappedThread]
|
||||||
|
|
||||||
|
# generate an ssh key (if needed) up front once, instead of for each instance
|
||||||
|
SshKey(args)
|
||||||
|
|
||||||
|
for platform_version in args.platform:
|
||||||
|
platform, version = platform_version.split('/', 1)
|
||||||
|
platform_target = 'network/%s/' % platform
|
||||||
|
|
||||||
|
if platform_target not in platform_targets:
|
||||||
|
display.warning('Skipping "%s" because selected tests do not target the "%s" platform.' % (
|
||||||
|
platform_version, platform))
|
||||||
|
continue
|
||||||
|
|
||||||
|
instance = WrappedThread(functools.partial(network_start, args, platform, version))
|
||||||
|
instance.daemon = True
|
||||||
|
instance.start()
|
||||||
|
instances.append(instance)
|
||||||
|
|
||||||
|
while any(instance.is_alive() for instance in instances):
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
args.metadata.instance_config = [instance.wait_for_result() for instance in instances]
|
||||||
|
|
||||||
|
|
||||||
|
def network_start(args, platform, version):
|
||||||
|
"""
|
||||||
|
:type args: NetworkIntegrationConfig
|
||||||
|
:type platform: str
|
||||||
|
:type version: str
|
||||||
|
:rtype: AnsibleCoreCI
|
||||||
|
"""
|
||||||
|
core_ci = AnsibleCoreCI(args, platform, version, stage=args.remote_stage, provider=args.remote_provider)
|
||||||
|
core_ci.start()
|
||||||
|
|
||||||
|
return core_ci.save()
|
||||||
|
|
||||||
|
|
||||||
|
def network_run(args, platform, version, config):
|
||||||
|
"""
|
||||||
|
:type args: NetworkIntegrationConfig
|
||||||
|
:type platform: str
|
||||||
|
:type version: str
|
||||||
|
:type config: dict[str, str]
|
||||||
|
:rtype: AnsibleCoreCI
|
||||||
|
"""
|
||||||
|
core_ci = AnsibleCoreCI(args, platform, version, stage=args.remote_stage, provider=args.remote_provider, load=False)
|
||||||
|
core_ci.load(config)
|
||||||
|
core_ci.wait()
|
||||||
|
|
||||||
|
manage = ManageNetworkCI(args, core_ci)
|
||||||
|
manage.wait()
|
||||||
|
|
||||||
|
return core_ci
|
||||||
|
|
||||||
|
|
||||||
|
def network_inventory(args, remotes):
|
||||||
|
"""
|
||||||
|
:type args: NetworkIntegrationConfig
|
||||||
|
:type remotes: list[AnsibleCoreCI]
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
groups = dict([(remote.platform, []) for remote in remotes])
|
||||||
|
net = []
|
||||||
|
|
||||||
|
for remote in remotes:
|
||||||
|
options = dict(
|
||||||
|
ansible_host=remote.connection.hostname,
|
||||||
|
ansible_user=remote.connection.username,
|
||||||
|
ansible_ssh_private_key_file=os.path.abspath(remote.ssh_key.key),
|
||||||
|
)
|
||||||
|
|
||||||
|
settings = get_network_settings(args, remote.platform, remote.version)
|
||||||
|
|
||||||
|
options.update(settings.inventory_vars)
|
||||||
|
|
||||||
|
groups[remote.platform].append(
|
||||||
|
'%s %s' % (
|
||||||
|
remote.name.replace('.', '-'),
|
||||||
|
' '.join('%s="%s"' % (k, options[k]) for k in sorted(options)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
net.append(remote.platform)
|
||||||
|
|
||||||
|
groups['net:children'] = net
|
||||||
|
|
||||||
|
template = ''
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
hosts = '\n'.join(groups[group])
|
||||||
|
|
||||||
|
template += textwrap.dedent("""
|
||||||
|
[%s]
|
||||||
|
%s
|
||||||
|
""") % (group, hosts)
|
||||||
|
|
||||||
|
inventory = template
|
||||||
|
|
||||||
|
return inventory
|
@ -0,0 +1,57 @@
|
|||||||
|
"""POSIX integration testing."""
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ... import types as t
|
||||||
|
|
||||||
|
from ...util import (
|
||||||
|
ANSIBLE_TEST_DATA_ROOT,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...util_common import (
|
||||||
|
handle_layout_messages,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...containers import (
|
||||||
|
SshConnectionDetail,
|
||||||
|
create_container_hooks,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...target import (
|
||||||
|
walk_posix_integration_targets,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...config import (
|
||||||
|
PosixIntegrationConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
command_integration_filter,
|
||||||
|
command_integration_filtered,
|
||||||
|
get_inventory_relative_path,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...data import (
|
||||||
|
data_context,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def command_posix_integration(args):
|
||||||
|
"""
|
||||||
|
:type args: PosixIntegrationConfig
|
||||||
|
"""
|
||||||
|
handle_layout_messages(data_context().content.integration_messages)
|
||||||
|
|
||||||
|
inventory_relative_path = get_inventory_relative_path(args)
|
||||||
|
inventory_path = os.path.join(ANSIBLE_TEST_DATA_ROOT, os.path.basename(inventory_relative_path))
|
||||||
|
|
||||||
|
all_targets = tuple(walk_posix_integration_targets(include_hidden=True))
|
||||||
|
internal_targets = command_integration_filter(args, all_targets)
|
||||||
|
|
||||||
|
managed_connections = None # type: t.Optional[t.List[SshConnectionDetail]]
|
||||||
|
|
||||||
|
pre_target, post_target = create_container_hooks(args, managed_connections)
|
||||||
|
|
||||||
|
command_integration_filtered(args, internal_targets, all_targets, inventory_path, pre_target=pre_target, post_target=post_target)
|
@ -0,0 +1,310 @@
|
|||||||
|
"""Windows integration testing."""
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import textwrap
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from ... import types as t
|
||||||
|
|
||||||
|
from ...thread import (
|
||||||
|
WrappedThread,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...core_ci import (
|
||||||
|
AnsibleCoreCI,
|
||||||
|
SshKey,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...manage_ci import (
|
||||||
|
ManageWindowsCI,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...io import (
|
||||||
|
write_text_file,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...util import (
|
||||||
|
ApplicationError,
|
||||||
|
display,
|
||||||
|
ANSIBLE_TEST_CONFIG_ROOT,
|
||||||
|
tempdir,
|
||||||
|
open_zipfile,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...util_common import (
|
||||||
|
get_python_path,
|
||||||
|
ResultType,
|
||||||
|
handle_layout_messages,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...containers import (
|
||||||
|
SshConnectionDetail,
|
||||||
|
create_container_hooks,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...ansible_util import (
|
||||||
|
run_playbook,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...target import (
|
||||||
|
IntegrationTarget,
|
||||||
|
walk_windows_integration_targets,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...config import (
|
||||||
|
WindowsIntegrationConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
command_integration_filter,
|
||||||
|
command_integration_filtered,
|
||||||
|
get_inventory_relative_path,
|
||||||
|
check_inventory,
|
||||||
|
delegate_inventory,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...data import (
|
||||||
|
data_context,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...executor import (
|
||||||
|
parse_inventory,
|
||||||
|
get_hosts,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def command_windows_integration(args):
|
||||||
|
"""
|
||||||
|
:type args: WindowsIntegrationConfig
|
||||||
|
"""
|
||||||
|
handle_layout_messages(data_context().content.integration_messages)
|
||||||
|
|
||||||
|
inventory_relative_path = get_inventory_relative_path(args)
|
||||||
|
template_path = os.path.join(ANSIBLE_TEST_CONFIG_ROOT, os.path.basename(inventory_relative_path)) + '.template'
|
||||||
|
|
||||||
|
if args.inventory:
|
||||||
|
inventory_path = os.path.join(data_context().content.root, data_context().content.integration_path, args.inventory)
|
||||||
|
else:
|
||||||
|
inventory_path = os.path.join(data_context().content.root, inventory_relative_path)
|
||||||
|
|
||||||
|
if not args.explain and not args.windows and not os.path.isfile(inventory_path):
|
||||||
|
raise ApplicationError(
|
||||||
|
'Inventory not found: %s\n'
|
||||||
|
'Use --inventory to specify the inventory path.\n'
|
||||||
|
'Use --windows to provision resources and generate an inventory file.\n'
|
||||||
|
'See also inventory template: %s' % (inventory_path, template_path)
|
||||||
|
)
|
||||||
|
|
||||||
|
check_inventory(args, inventory_path)
|
||||||
|
delegate_inventory(args, inventory_path)
|
||||||
|
|
||||||
|
all_targets = tuple(walk_windows_integration_targets(include_hidden=True))
|
||||||
|
internal_targets = command_integration_filter(args, all_targets, init_callback=windows_init)
|
||||||
|
instances = [] # type: t.List[WrappedThread]
|
||||||
|
managed_connections = [] # type: t.List[SshConnectionDetail]
|
||||||
|
|
||||||
|
if args.windows:
|
||||||
|
get_python_path(args, args.python_executable) # initialize before starting threads
|
||||||
|
|
||||||
|
configs = dict((config['platform_version'], config) for config in args.metadata.instance_config)
|
||||||
|
|
||||||
|
for version in args.windows:
|
||||||
|
config = configs['windows/%s' % version]
|
||||||
|
|
||||||
|
instance = WrappedThread(functools.partial(windows_run, args, version, config))
|
||||||
|
instance.daemon = True
|
||||||
|
instance.start()
|
||||||
|
instances.append(instance)
|
||||||
|
|
||||||
|
while any(instance.is_alive() for instance in instances):
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
remotes = [instance.wait_for_result() for instance in instances]
|
||||||
|
inventory = windows_inventory(remotes)
|
||||||
|
|
||||||
|
display.info('>>> Inventory: %s\n%s' % (inventory_path, inventory.strip()), verbosity=3)
|
||||||
|
|
||||||
|
if not args.explain:
|
||||||
|
write_text_file(inventory_path, inventory)
|
||||||
|
|
||||||
|
for core_ci in remotes:
|
||||||
|
ssh_con = core_ci.connection
|
||||||
|
ssh = SshConnectionDetail(core_ci.name, ssh_con.hostname, 22, ssh_con.username, core_ci.ssh_key.key, shell_type='powershell')
|
||||||
|
managed_connections.append(ssh)
|
||||||
|
elif args.explain:
|
||||||
|
identity_file = SshKey(args).key
|
||||||
|
|
||||||
|
# mock connection details to prevent tracebacks in explain mode
|
||||||
|
managed_connections = [SshConnectionDetail(
|
||||||
|
name='windows',
|
||||||
|
host='windows',
|
||||||
|
port=22,
|
||||||
|
user='administrator',
|
||||||
|
identity_file=identity_file,
|
||||||
|
shell_type='powershell',
|
||||||
|
)]
|
||||||
|
else:
|
||||||
|
inventory = parse_inventory(args, inventory_path)
|
||||||
|
hosts = get_hosts(inventory, 'windows')
|
||||||
|
identity_file = SshKey(args).key
|
||||||
|
|
||||||
|
managed_connections = [SshConnectionDetail(
|
||||||
|
name=name,
|
||||||
|
host=config['ansible_host'],
|
||||||
|
port=22,
|
||||||
|
user=config['ansible_user'],
|
||||||
|
identity_file=identity_file,
|
||||||
|
shell_type='powershell',
|
||||||
|
) for name, config in hosts.items()]
|
||||||
|
|
||||||
|
if managed_connections:
|
||||||
|
display.info('Generated SSH connection details from inventory:\n%s' % (
|
||||||
|
'\n'.join('%s %s@%s:%d' % (ssh.name, ssh.user, ssh.host, ssh.port) for ssh in managed_connections)), verbosity=1)
|
||||||
|
|
||||||
|
pre_target, post_target = create_container_hooks(args, managed_connections)
|
||||||
|
|
||||||
|
remote_temp_path = None
|
||||||
|
|
||||||
|
if args.coverage and not args.coverage_check:
|
||||||
|
# Create the remote directory that is writable by everyone. Use Ansible to talk to the remote host.
|
||||||
|
remote_temp_path = 'C:\\ansible_test_coverage_%s' % time.time()
|
||||||
|
playbook_vars = {'remote_temp_path': remote_temp_path}
|
||||||
|
run_playbook(args, inventory_path, 'windows_coverage_setup.yml', playbook_vars)
|
||||||
|
|
||||||
|
success = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
command_integration_filtered(args, internal_targets, all_targets, inventory_path, pre_target=pre_target,
|
||||||
|
post_target=post_target, remote_temp_path=remote_temp_path)
|
||||||
|
success = True
|
||||||
|
finally:
|
||||||
|
if remote_temp_path:
|
||||||
|
# Zip up the coverage files that were generated and fetch it back to localhost.
|
||||||
|
with tempdir() as local_temp_path:
|
||||||
|
playbook_vars = {'remote_temp_path': remote_temp_path, 'local_temp_path': local_temp_path}
|
||||||
|
run_playbook(args, inventory_path, 'windows_coverage_teardown.yml', playbook_vars)
|
||||||
|
|
||||||
|
for filename in os.listdir(local_temp_path):
|
||||||
|
with open_zipfile(os.path.join(local_temp_path, filename)) as coverage_zip:
|
||||||
|
coverage_zip.extractall(ResultType.COVERAGE.path)
|
||||||
|
|
||||||
|
if args.remote_terminate == 'always' or (args.remote_terminate == 'success' and success):
|
||||||
|
for instance in instances:
|
||||||
|
instance.result.stop()
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
def windows_init(args, internal_targets): # pylint: disable=locally-disabled, unused-argument
|
||||||
|
"""
|
||||||
|
:type args: WindowsIntegrationConfig
|
||||||
|
:type internal_targets: tuple[IntegrationTarget]
|
||||||
|
"""
|
||||||
|
# generate an ssh key (if needed) up front once, instead of for each instance
|
||||||
|
SshKey(args)
|
||||||
|
|
||||||
|
if not args.windows:
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.metadata.instance_config is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
instances = [] # type: t.List[WrappedThread]
|
||||||
|
|
||||||
|
for version in args.windows:
|
||||||
|
instance = WrappedThread(functools.partial(windows_start, args, version))
|
||||||
|
instance.daemon = True
|
||||||
|
instance.start()
|
||||||
|
instances.append(instance)
|
||||||
|
|
||||||
|
while any(instance.is_alive() for instance in instances):
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
args.metadata.instance_config = [instance.wait_for_result() for instance in instances]
|
||||||
|
|
||||||
|
|
||||||
|
def windows_start(args, version):
|
||||||
|
"""
|
||||||
|
:type args: WindowsIntegrationConfig
|
||||||
|
:type version: str
|
||||||
|
:rtype: AnsibleCoreCI
|
||||||
|
"""
|
||||||
|
core_ci = AnsibleCoreCI(args, 'windows', version, stage=args.remote_stage, provider=args.remote_provider)
|
||||||
|
core_ci.start()
|
||||||
|
|
||||||
|
return core_ci.save()
|
||||||
|
|
||||||
|
|
||||||
|
def windows_run(args, version, config):
|
||||||
|
"""
|
||||||
|
:type args: WindowsIntegrationConfig
|
||||||
|
:type version: str
|
||||||
|
:type config: dict[str, str]
|
||||||
|
:rtype: AnsibleCoreCI
|
||||||
|
"""
|
||||||
|
core_ci = AnsibleCoreCI(args, 'windows', version, stage=args.remote_stage, provider=args.remote_provider, load=False)
|
||||||
|
core_ci.load(config)
|
||||||
|
core_ci.wait()
|
||||||
|
|
||||||
|
manage = ManageWindowsCI(core_ci)
|
||||||
|
manage.wait()
|
||||||
|
|
||||||
|
return core_ci
|
||||||
|
|
||||||
|
|
||||||
|
def windows_inventory(remotes):
|
||||||
|
"""
|
||||||
|
:type remotes: list[AnsibleCoreCI]
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
hosts = []
|
||||||
|
|
||||||
|
for remote in remotes:
|
||||||
|
options = dict(
|
||||||
|
ansible_host=remote.connection.hostname,
|
||||||
|
ansible_user=remote.connection.username,
|
||||||
|
ansible_password=remote.connection.password,
|
||||||
|
ansible_port=remote.connection.port,
|
||||||
|
)
|
||||||
|
|
||||||
|
# used for the connection_windows_ssh test target
|
||||||
|
if remote.ssh_key:
|
||||||
|
options["ansible_ssh_private_key_file"] = os.path.abspath(remote.ssh_key.key)
|
||||||
|
|
||||||
|
if remote.name == 'windows-2016':
|
||||||
|
options.update(
|
||||||
|
# force 2016 to use NTLM + HTTP message encryption
|
||||||
|
ansible_connection='winrm',
|
||||||
|
ansible_winrm_server_cert_validation='ignore',
|
||||||
|
ansible_winrm_transport='ntlm',
|
||||||
|
ansible_winrm_scheme='http',
|
||||||
|
ansible_port='5985',
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
options.update(
|
||||||
|
ansible_connection='winrm',
|
||||||
|
ansible_winrm_server_cert_validation='ignore',
|
||||||
|
)
|
||||||
|
|
||||||
|
hosts.append(
|
||||||
|
'%s %s' % (
|
||||||
|
remote.name.replace('/', '_'),
|
||||||
|
' '.join('%s="%s"' % (k, options[k]) for k in sorted(options)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
template = """
|
||||||
|
[windows]
|
||||||
|
%s
|
||||||
|
|
||||||
|
# support winrm binary module tests (temporary solution)
|
||||||
|
[testhost:children]
|
||||||
|
windows
|
||||||
|
"""
|
||||||
|
|
||||||
|
template = textwrap.dedent(template)
|
||||||
|
inventory = template % ('\n'.join(hosts))
|
||||||
|
|
||||||
|
return inventory
|
@ -0,0 +1,30 @@
|
|||||||
|
"""Open a shell prompt inside an ansible-test environment."""
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from ...util_common import (
|
||||||
|
run_command,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...config import (
|
||||||
|
ShellConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ...executor import (
|
||||||
|
Delegate,
|
||||||
|
create_shell_command,
|
||||||
|
install_command_requirements,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def command_shell(args):
|
||||||
|
"""
|
||||||
|
:type args: ShellConfig
|
||||||
|
"""
|
||||||
|
if args.delegate:
|
||||||
|
raise Delegate()
|
||||||
|
|
||||||
|
install_command_requirements(args)
|
||||||
|
|
||||||
|
cmd = create_shell_command(['bash', '-i'])
|
||||||
|
run_command(args, cmd)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue