ansible-test - Add `--prime-containers` option.

Resolves https://github.com/ansible/ansible/issues/75320

The option `--prime-containers` was chosen over `--docker-pull-only` to match the recently added `--prime-venvs` option for sanity tests.
It would also fit well with a future `--prime-requirements` option for pre-installing requirements for unit and integration tests.
pull/75773/head
Matt Clay 3 years ago
parent 28a094c5de
commit e3fd9b0769

@ -0,0 +1,2 @@
minor_changes:
- ansible-test - Added a ``--prime-containers`` option to support downloading containers without running tests.

@ -42,6 +42,10 @@ from .cli import (
parse_args,
)
from .provisioning import (
PrimeContainers,
)
def main():
"""Main program function."""
@ -64,6 +68,8 @@ def main():
try:
args.func(config)
except PrimeContainers:
pass
except ListTargets as ex:
# save target_names for use once we exit the exception handler
target_names = ex.target_names

@ -385,6 +385,7 @@ def add_global_docker(
docker_no_pull=False,
docker_network=None,
docker_terminate=None,
prime_containers=False,
)
return
@ -410,6 +411,12 @@ def add_global_docker(
help='terminate the container: %(choices)s (default: %(default)s)',
)
parser.add_argument(
'--prime-containers',
action='store_true',
help='download containers without running tests',
)
def add_environment_docker(
exclusive_parser, # type: argparse.ArgumentParser

@ -151,7 +151,10 @@ def cloud_init(args, targets): # type: (IntegrationConfig, t.Tuple[IntegrationT
results = {}
for provider in get_cloud_providers(args, targets):
for provider in get_cloud_providers(args, targets): # type: CloudProvider
if args.prime_containers and not provider.uses_docker:
continue
args.metadata.cloud_config[provider.platform] = {}
start_time = time.time()

@ -91,7 +91,7 @@ class CsCloudProvider(CloudProvider):
self.port,
]
run_support_container(
descriptor = run_support_container(
self.args,
self.platform,
self.image,
@ -101,6 +101,9 @@ class CsCloudProvider(CloudProvider):
cleanup=CleanupMode.YES,
)
if not descriptor:
return
# apply work-around for OverlayFS issue
# https://github.com/docker/for-linux/issues/72#issuecomment-319904698
docker_exec(self.args, self.DOCKER_SIMULATOR_NAME, ['find', '/var/lib/mysql', '-type', 'f', '-exec', 'touch', '{}', ';'])

@ -115,6 +115,9 @@ class GalaxyProvider(CloudProvider):
allow_existing=True,
)
if not descriptor:
return
if not descriptor.running:
pulp_id = descriptor.container_id

@ -68,6 +68,9 @@ class HttptesterProvider(CloudProvider):
},
)
if not descriptor:
return
# Read the password from the container environment.
# This allows the tests to work when re-using an existing container.
# The password is marked as sensitive, since it may differ from the one we generated.

@ -69,7 +69,7 @@ class OpenShiftCloudProvider(CloudProvider):
cmd = ['start', 'master', '--listen', 'https://0.0.0.0:%d' % port]
run_support_container(
descriptor = run_support_container(
self.args,
self.platform,
self.image,
@ -80,6 +80,9 @@ class OpenShiftCloudProvider(CloudProvider):
cmd=cmd,
)
if not descriptor:
return
if self.args.explain:
config = '# Unknown'
else:

@ -106,6 +106,8 @@ class EnvironmentConfig(CommonConfig):
self.remote_stage = args.remote_stage # type: t.Optional[str]
self.remote_terminate = args.remote_terminate # type: t.Optional[TerminateMode]
self.prime_containers = args.prime_containers # type: bool
self.requirements = args.requirements # type: bool
self.delegate_args = [] # type: t.List[str]

@ -113,11 +113,15 @@ def run_support_container(
env=None, # type: t.Optional[t.Dict[str, str]]
options=None, # type: t.Optional[t.List[str]]
publish_ports=True, # type: bool
): # type: (...) -> ContainerDescriptor
): # type: (...) -> t.Optional[ContainerDescriptor]
"""
Start a container used to support tests, but not run them.
Containers created this way will be accessible from tests.
"""
if args.prime_containers:
docker_pull(args, image)
return None
# SSH is required for publishing ports, as well as modifying the hosts file.
# Initializing the SSH key here makes sure it is available for use after delegation.
SshKey(args)

@ -349,6 +349,9 @@ class DockerProfile(ControllerHostProfile[DockerConfig], SshTargetHostProfile[Do
cleanup=CleanupMode.NO,
)
if not container:
return
self.container_name = container.name
def setup(self): # type: () -> None

@ -30,6 +30,7 @@ from .thread import (
from .host_profiles import (
ControllerHostProfile,
DockerProfile,
HostProfile,
SshConnection,
SshTargetHostProfile,
@ -44,6 +45,10 @@ THostProfile = t.TypeVar('THostProfile', bound=HostProfile)
TEnvironmentConfig = t.TypeVar('TEnvironmentConfig', bound=EnvironmentConfig)
class PrimeContainers(ApplicationError):
"""Exception raised to end execution early after priming containers."""
@dataclasses.dataclass(frozen=True)
class HostState:
"""State of hosts and profiles to be passed to ansible-test during delegation."""
@ -109,6 +114,13 @@ def prepare_profiles(
target_profiles=[create_host_profile(args, target, False) for target in args.targets],
)
if args.prime_containers:
for host_profile in host_state.profiles:
if isinstance(host_profile, DockerProfile):
host_profile.provision()
raise PrimeContainers()
atexit.register(functools.partial(cleanup_profiles, host_state))
def provision(profile): # type: (HostProfile) -> None

Loading…
Cancel
Save