diff --git a/changelogs/fragments/galaxy-ng-26.03.yml b/changelogs/fragments/galaxy-ng-26.03.yml new file mode 100644 index 00000000000..be9c3657dbb --- /dev/null +++ b/changelogs/fragments/galaxy-ng-26.03.yml @@ -0,0 +1,2 @@ +minor_changes: +- ansible-test - update galaxy_ng container to current version deployed to galaxy.ansible.com diff --git a/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py b/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py deleted file mode 100644 index 72fa7706cc3..00000000000 --- a/test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/python - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import annotations - -DOCUMENTATION = """ ---- -module: reset_pulp -short_description: Resets pulp back to the initial state -description: -- See short_description -options: - pulp_api: - description: - - The Pulp API endpoint. - required: yes - type: str - galaxy_ng_server: - description: - - The Galaxy NG API endpoint. - required: yes - type: str - url_username: - description: - - The username to use when authenticating against Pulp. - required: yes - type: str - url_password: - description: - - The password to use when authenticating against Pulp. - required: yes - type: str - repositories: - description: - - A list of pulp repositories to create. - - Galaxy NG expects a repository that matches C(GALAXY_API_DEFAULT_DISTRIBUTION_BASE_PATH) in - C(/etc/pulp/settings.py) or the default of C(published). - required: yes - type: list - elements: str - namespaces: - description: - - A list of namespaces to create for Galaxy NG. - required: yes - type: list - elements: str -author: -- Jordan Borean (@jborean93) -""" - -EXAMPLES = """ -- name: reset pulp content - reset_pulp: - pulp_api: http://galaxy:24817 - galaxy_ng_server: http://galaxy/api/galaxy/ - url_username: username - url_password: password - repository: published - namespaces: - - namespace1 - - namespace2 -""" - -RETURN = """ -# -""" - -import json - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.urls import fetch_url -from ansible.module_utils.common.text.converters import to_text - - -def invoke_api(module, url, method='GET', data=None, status_codes=None): - status_codes = status_codes or [200] - headers = {} - if data: - headers['Content-Type'] = 'application/json' - data = json.dumps(data) - - resp, info = fetch_url(module, url, method=method, data=data, headers=headers) - if info['status'] not in status_codes: - info['url'] = url - module.fail_json(**info) - - data = to_text(resp.read()) - if data: - return json.loads(data) - - -def delete_galaxy_namespace(namespace, module): - """ Deletes the galaxy ng namespace specified. """ - ns_uri = '%sv3/namespaces/%s/' % (module.params['galaxy_ng_server'], namespace) - invoke_api(module, ns_uri, method='DELETE', status_codes=[204]) - - -def delete_pulp_distribution(distribution, module): - """ Deletes the pulp distribution at the URI specified. """ - task_info = invoke_api(module, distribution, method='DELETE', status_codes=[202]) - wait_pulp_task(task_info['task'], module) - - -def delete_pulp_orphans(module): - """ Deletes any orphaned pulp objects. """ - orphan_uri = module.params['galaxy_ng_server'] + 'pulp/api/v3/orphans/' - task_info = invoke_api(module, orphan_uri, method='DELETE', status_codes=[202]) - wait_pulp_task(task_info['task'], module) - - -def delete_pulp_repository(repository, module): - """ Deletes the pulp repository at the URI specified. """ - task_info = invoke_api(module, repository, method='DELETE', status_codes=[202]) - wait_pulp_task(task_info['task'], module) - - -def get_galaxy_namespaces(module): - """ Gets a list of galaxy namespaces. """ - # No pagination has been implemented, shouldn't need unless we ever exceed 100 namespaces. - namespace_uri = module.params['galaxy_ng_server'] + 'v3/namespaces/?limit=100&offset=0' - ns_info = invoke_api(module, namespace_uri) - - return [n['name'] for n in ns_info['data']] - - -def get_pulp_distributions(module, distribution): - """ Gets a list of all the pulp distributions. """ - distro_uri = module.params['galaxy_ng_server'] + 'pulp/api/v3/distributions/ansible/ansible/' - distro_info = invoke_api(module, distro_uri + '?name=' + distribution) - return [module.params['pulp_api'] + r['pulp_href'] for r in distro_info['results']] - - -def get_pulp_repositories(module, repository): - """ Gets a list of all the pulp repositories. """ - repo_uri = module.params['galaxy_ng_server'] + 'pulp/api/v3/repositories/ansible/ansible/' - repo_info = invoke_api(module, repo_uri + '?name=' + repository) - return [module.params['pulp_api'] + r['pulp_href'] for r in repo_info['results']] - - -def get_repo_collections(repository, module): - collections_uri = module.params['galaxy_ng_server'] + 'v3/plugin/ansible/content/' + repository + '/collections/index/' - # status code 500 isn't really expected, an unhandled exception is causing this instead of a 404 - # See https://issues.redhat.com/browse/AAH-2329 - info = invoke_api(module, collections_uri + '?limit=100&offset=0', status_codes=[200, 500]) - if not info: - return [] - return [module.params['pulp_api'] + c['href'] for c in info['data']] - - -def delete_repo_collection(collection, module): - task_info = invoke_api(module, collection, method='DELETE', status_codes=[202]) - wait_pulp_task(task_info['task'], module) - - -def new_galaxy_namespace(name, module): - """ Creates a new namespace in Galaxy NG. """ - ns_uri = module.params['galaxy_ng_server'] + 'v3/namespaces/ ' - data = {'name': name, 'groups': []} - ns_info = invoke_api(module, ns_uri, method='POST', data=data, status_codes=[201]) - - return ns_info['id'] - - -def new_pulp_repository(name, module): - """ Creates a new pulp repository. """ - repo_uri = module.params['galaxy_ng_server'] + 'pulp/api/v3/repositories/ansible/ansible/' - # retain_repo_versions to work around https://issues.redhat.com/browse/AAH-2332 - data = {'name': name, 'retain_repo_versions': '1024'} - repo_info = invoke_api(module, repo_uri, method='POST', data=data, status_codes=[201]) - - return repo_info['pulp_href'] - - -def new_pulp_distribution(name, base_path, repository, module): - """ Creates a new pulp distribution for a repository. """ - distro_uri = module.params['galaxy_ng_server'] + 'pulp/api/v3/distributions/ansible/ansible/' - data = {'name': name, 'base_path': base_path, 'repository': repository} - task_info = invoke_api(module, distro_uri, method='POST', data=data, status_codes=[202]) - task_info = wait_pulp_task(task_info['task'], module) - - return module.params['pulp_api'] + task_info['created_resources'][0] - - -def wait_pulp_task(task, module): - """ Waits for a pulp import task to finish. """ - while True: - task_info = invoke_api(module, module.params['pulp_api'] + task) - if task_info['finished_at'] is not None: - break - - return task_info - - -def main(): - module_args = dict( - pulp_api=dict(type='str', required=True), - galaxy_ng_server=dict(type='str', required=True), - url_username=dict(type='str', required=True), - url_password=dict(type='str', required=True, no_log=True), - repositories=dict(type='list', elements='str', required=True), - namespaces=dict(type='list', elements='str', required=True), - ) - - module = AnsibleModule( - argument_spec=module_args, - supports_check_mode=False - ) - module.params['force_basic_auth'] = True - - # It may be due to the process of cleaning up orphans, but we cannot delete the namespace - # while a collection still exists, so this is just a new safety to nuke all collections - # first - for repository in module.params['repositories']: - [delete_repo_collection(c, module) for c in get_repo_collections(repository, module)] - - for repository in module.params['repositories']: - [delete_pulp_distribution(d, module) for d in get_pulp_distributions(module, repository)] - [delete_pulp_repository(r, module) for r in get_pulp_repositories(module, repository)] - delete_pulp_orphans(module) - [delete_galaxy_namespace(n, module) for n in get_galaxy_namespaces(module)] - - for repository in module.params['repositories']: - repo_href = new_pulp_repository(repository, module) - new_pulp_distribution(repository, repository, repo_href, module) - [new_galaxy_namespace(n, module) for n in module.params['namespaces']] - - module.exit_json(changed=True) - - -if __name__ == '__main__': - main() diff --git a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py b/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py deleted file mode 100644 index 9d94f1c09fb..00000000000 --- a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/python - -# Copyright: (c) 2020, Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import annotations - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = """ ---- -module: setup_collections -short_description: Set up test collections based on the input -description: -- Builds and publishes a whole bunch of collections used for testing in bulk. -options: - server: - description: - - The Galaxy server to upload the collections to. - required: yes - type: str - token: - description: - - The token used to authenticate with the Galaxy server. - required: yes - type: str - collections: - description: - - A list of collection details to use for the build. - required: yes - type: list - elements: dict - options: - namespace: - description: - - The namespace of the collection. - required: yes - type: str - name: - description: - - The name of the collection. - required: yes - type: str - version: - description: - - The version of the collection. - type: str - default: '1.0.0' - dependencies: - description: - - The dependencies of the collection. - type: dict - default: '{}' - use_symlink: - description: - - Create a symlink in the collection. - type: bool - default: False - runtime: - description: - - File content for meta/runtime.yml. - type: str - default: 'requires_ansible: ">=2.9"' -author: -- Jordan Borean (@jborean93) -""" - -EXAMPLES = """ -- name: Build test collections - setup_collections: - path: ~/ansible/collections/ansible_collections - collections: - - namespace: namespace1 - name: name1 - version: 0.0.1 - - namespace: namespace1 - name: name1 - version: 0.0.2 -""" - -RETURN = """ -# -""" - -import datetime -import os -import subprocess -import tarfile -import tempfile -import yaml - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_bytes -from functools import partial -from multiprocessing import dummy as threading -from multiprocessing import TimeoutError, Lock - - -COLLECTIONS_BUILD_AND_PUBLISH_TIMEOUT = 300 -LOCK = Lock() - - -def publish_collection(module, collection): - namespace = collection['namespace'] - name = collection['name'] - version = collection['version'] - dependencies = collection['dependencies'] - use_symlink = collection['use_symlink'] - runtime = collection['runtime'] - - result = {} - collection_dir = os.path.join(module.tmpdir, "%s-%s-%s" % (namespace, name, version)) - b_collection_dir = to_bytes(collection_dir, errors='surrogate_or_strict') - os.mkdir(b_collection_dir) - os.mkdir(os.path.join(b_collection_dir, b'meta')) - - with open(os.path.join(b_collection_dir, b'README.md'), mode='wb') as fd: - fd.write(b"Collection readme") - - galaxy_meta = { - 'namespace': namespace, - 'name': name, - 'version': version, - 'readme': 'README.md', - 'authors': ['Collection author =0.5.0,<1.0.0' - - namespace: parent_dep - name: parent_collection - version: 1.1.0 - dependencies: - child_dep.child_collection: '>=0.9.9,<=1.0.0' - - namespace: parent_dep - name: parent_collection - version: 2.0.0 - dependencies: - child_dep.child_collection: '>=1.0.0' - - namespace: parent_dep2 - name: parent_collection - dependencies: - child_dep.child_collection: '0.5.0' - - namespace: child_dep - name: child_collection - version: 0.4.0 - - namespace: child_dep - name: child_collection - version: 0.5.0 - - namespace: child_dep - name: child_collection - version: 0.9.9 - dependencies: - child_dep.child_dep2: '!=1.2.3' - - namespace: child_dep - name: child_collection - version: 1.0.0 - dependencies: - child_dep.child_dep2: '!=1.2.3' - - namespace: child_dep - name: child_dep2 - version: 1.2.2 - - namespace: child_dep - name: child_dep2 - version: 1.2.3 - - # Dep resolution failure - - namespace: fail_namespace - name: fail_collection - version: 2.1.2 - dependencies: - fail_dep.name: '0.0.5' - fail_dep2.name: '<0.0.5' - - namespace: fail_dep - name: name - version: '0.0.5' - dependencies: - fail_dep2.name: '>0.0.5' - - namespace: fail_dep2 - name: name - - # Symlink tests - - namespace: symlink - name: symlink - use_symlink: yes - - # Caching update tests - - namespace: cache - name: cache - version: 1.0.0 - - # Dep with beta version - - namespace: dep_with_beta - name: parent - dependencies: - namespace1.name1: '*' - - # non-prerelease is published to test that installing - # the pre-release from SCM doesn't accidentally prefer indirect - # dependencies from Galaxy - - namespace: test_prereleases - name: collection2 - version: 1.0.0 - - - namespace: dev_and_stables_ns - name: dev_and_stables_name - version: 1.2.3-dev0 - - namespace: dev_and_stables_ns - name: dev_and_stables_name - version: 1.2.4 - - - namespace: ns_with_wildcard_dep - name: name_with_wildcard_dep - version: 5.6.7-beta.3 - dependencies: - dev_and_stables_ns.dev_and_stables_name: >- - * - - namespace: ns_with_dev_dep - name: name_with_dev_dep - version: 6.7.8 - dependencies: - dev_and_stables_ns.dev_and_stables_name: 1.2.3-dev0 - - - namespace: rc_meta_ns_with_transitive_dev_dep - name: rc_meta_name_with_transitive_dev_dep - version: 2.4.5-rc5 - dependencies: - ns_with_dev_dep.name_with_dev_dep: >- - * - - namespace: meta_ns_with_transitive_wildcard_dep - name: meta_name_with_transitive_wildcard_dep - version: 4.5.6 - dependencies: - ns_with_wildcard_dep.name_with_wildcard_dep: 5.6.7-beta.3 - - - namespace: ns_requires_ansible - name: name_requires_ansible - version: 1.0.0 - runtime: |- - requires_ansible: "<1.1" - - - namespace: ns_requires_ansible - name: dependency - version: 1.0.0 - - - namespace: ns_requires_ansible - name: dependency - version: 2.0.0 - dependencies: - ns_requires_ansible.name_requires_ansible: 1.0.0 - - - namespace: ns_requires_ansible - name: dependency_incompat - version: 1.0.0 - dependencies: - ns_requires_ansible.name_requires_ansible: 1.0.0 - - - namespace: ns_requires_ansible - name: dependency_incompat - version: 2.0.0 - dependencies: - ns_requires_ansible.dependency: 2.0.0 # pinned incompatible version - - - namespace: ns_requires_ansible - name: dependency_incompat - version: 3.0.0 - dependencies: - ns_requires_ansible.name_requires_ansible: 1.0.0 - - - namespace: ns_requires_ansible - name: backtracking_error - version: 1.0.0 - dependencies: - ns_requires_ansible.dependency_incompat: "*" diff --git a/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml b/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml index 8ae15ea5944..70d855f7d7a 100644 --- a/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml +++ b/test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml @@ -2,9 +2,9 @@ # The first task to interact with pulp needs to wait until it responds appropriately. - name: Wait for Pulp API uri: - url: '{{ pulp_api }}/pulp/api/v3/distributions/ansible/ansible/' - user: '{{ pulp_user }}' - password: '{{ pulp_password }}' + url: '{{ galaxy_ng_server }}/pulp/api/v3/repositories/ansible/ansible/' + user: '{{ galaxy_user }}' + password: '{{ galaxy_password }}' force_basic_auth: true register: this until: this is successful @@ -13,13 +13,9 @@ - name: Verify Galaxy NG server uri: - url: "{{ galaxy_ng_server }}" - user: '{{ pulp_user }}' - password: '{{ pulp_password }}' + url: "{{ amanda }}/api/" force_basic_auth: true - name: Verify Pulp server uri: - url: "{{ pulp_server }}" - status_code: - - 404 # endpoint responds without authentication + url: "{{ galaxy_ng_server }}" diff --git a/test/lib/ansible_test/_internal/commands/integration/cloud/galaxy.py b/test/lib/ansible_test/_internal/commands/integration/cloud/galaxy.py index 206efa92f40..51ea000b3f7 100644 --- a/test/lib/ansible_test/_internal/commands/integration/cloud/galaxy.py +++ b/test/lib/ansible_test/_internal/commands/integration/cloud/galaxy.py @@ -10,6 +10,7 @@ from ....config import ( ) from ....docker_util import ( + docker_cp_from, docker_cp_to, docker_exec, ) @@ -33,43 +34,6 @@ from . import ( ) -GALAXY_HOST_NAME = 'galaxy-pulp' -SETTINGS = { - 'PULP_CONTENT_ORIGIN': f'http://{GALAXY_HOST_NAME}', - 'PULP_ANSIBLE_API_HOSTNAME': f'http://{GALAXY_HOST_NAME}', - 'PULP_GALAXY_API_PATH_PREFIX': '/api/galaxy/', - # These paths are unique to the container image which has an nginx location for /pulp/content to route - # requests to the content backend - 'PULP_ANSIBLE_CONTENT_HOSTNAME': f'http://{GALAXY_HOST_NAME}/pulp/content/api/galaxy/v3/artifacts/collections/', - 'PULP_CONTENT_PATH_PREFIX': '/pulp/content/api/galaxy/v3/artifacts/collections/', - 'PULP_GALAXY_AUTHENTICATION_CLASSES': [ - 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.TokenAuthentication', - 'rest_framework.authentication.BasicAuthentication', - 'django.contrib.auth.backends.ModelBackend', - ], - # This should probably be false see https://issues.redhat.com/browse/AAH-2328 - 'PULP_GALAXY_REQUIRE_CONTENT_APPROVAL': 'true', - 'PULP_GALAXY_DEPLOYMENT_MODE': 'standalone', - 'PULP_GALAXY_AUTO_SIGN_COLLECTIONS': 'false', - 'PULP_GALAXY_COLLECTION_SIGNING_SERVICE': 'ansible-default', - 'PULP_RH_ENTITLEMENT_REQUIRED': 'insights', - 'PULP_TOKEN_AUTH_DISABLED': 'false', - 'PULP_TOKEN_SERVER': f'http://{GALAXY_HOST_NAME}/token/', - 'PULP_TOKEN_SIGNATURE_ALGORITHM': 'ES256', - 'PULP_PUBLIC_KEY_PATH': '/src/galaxy_ng/dev/common/container_auth_public_key.pem', - 'PULP_PRIVATE_KEY_PATH': '/src/galaxy_ng/dev/common/container_auth_private_key.pem', - 'PULP_ANALYTICS': 'false', - 'PULP_GALAXY_ENABLE_UNAUTHENTICATED_COLLECTION_ACCESS': 'true', - 'PULP_GALAXY_ENABLE_UNAUTHENTICATED_COLLECTION_DOWNLOAD': 'true', - 'PULP_GALAXY_ENABLE_LEGACY_ROLES': 'true', - 'PULP_GALAXY_FEATURE_FLAGS__execution_environments': 'false', - 'PULP_SOCIAL_AUTH_LOGIN_REDIRECT_URL': '/', - 'PULP_GALAXY_FEATURE_FLAGS__ai_deny_index': 'true', - 'PULP_DEFAULT_ADMIN_PASSWORD': 'password' -} - - GALAXY_IMPORTER = b""" [galaxy-importer] ansible_local_tmp=~/.ansible/tmp @@ -90,49 +54,86 @@ run_flake8=false class GalaxyProvider(CloudProvider): """ - Galaxy plugin. Sets up pulp (ansible-galaxy) servers for tests. - The pulp source itself resides at: https://github.com/pulp/pulp-oci-images + Galaxy plugin. Sets up ansible-galaxy servers for tests. """ def __init__(self, args: IntegrationConfig) -> None: super().__init__(args) - self.image = os.environ.get( - 'ANSIBLE_PULP_CONTAINER', - 'quay.io/pulp/galaxy:4.7.1' - ) - self.uses_docker = True + self.galaxy_image = os.getenv( + 'ANSIBLE_GALAXY_CONTAINER', + 'ghcr.io/ansible/galaxy-ng-test-container:26.03.0' + ) + self.postgres_image = os.getenv( + 'ANSIBLE_POSTGRES_CONTAINER', + 'public.ecr.aws/docker/library/postgres:13' + ) + self.amanda_image = os.getenv( + 'ANSIBLE_AMANDA_CONTAINER', + 'ghcr.io/sivel/amanda@sha256:f704fe6f062b8ada59ae6553a70d2175295d068d56f544875980581b7df9c16d' + ) def setup(self) -> None: """Setup cloud resource before delegation and reg cleanup callback.""" super().setup() - with tempfile.NamedTemporaryFile(mode='w+') as env_fd: - settings = '\n'.join( - f'{key}={value}' for key, value in SETTINGS.items() - ) - env_fd.write(settings) - env_fd.flush() - display.info(f'>>> galaxy_ng Configuration\n{settings}', verbosity=3) - descriptor = run_support_container( + # This container is created separately from the actual galaxy container due to + # needing it created for postgres, but the galaxy container has a dependency on knowing the postgres + # container id + gdata = run_support_container(self.args, self.platform, self.galaxy_image, 'galaxy-data', [0], start=False) + if not gdata: + return + + amanda = run_support_container( + self.args, + self.platform, + self.amanda_image, + 'amanda', + [8001], + aliases=['amanda'], + options=[ + '--volumes-from', gdata.container_id, + ], + cmd=['-port', '8001', '-publish'], + ) + if not amanda: + return + + postgres = run_support_container( + self.args, + self.platform, + self.postgres_image, + 'galaxy-postgres', + [5432], + aliases=['postgres'], + options=[ + '--volumes-from', gdata.container_id, + ], + ) + if not postgres: + return + + with tempfile.TemporaryDirectory() as tmpdir: + docker_cp_from(self.args, gdata.container_id, '/galaxy_ng.env', tmpdir) + galaxy_ng = run_support_container( self.args, self.platform, - self.image, - GALAXY_HOST_NAME, - [ - 80, - ], - aliases=[ - GALAXY_HOST_NAME, - ], + self.galaxy_image, + 'galaxy_ng', + [8000, 24816], + aliases=['galaxy'], start=True, options=[ - '--env-file', env_fd.name, + '--env-file', os.path.join(tmpdir, 'galaxy_ng.env'), + '--add-host', f'postgres:{postgres.details.container_ip}', + ], + cmd=[ + '/bin/sh', '-c', + '(start-api &); (start-content-app &); start-worker;' ], ) - - if not descriptor: + if not galaxy_ng: return injected_files = [ @@ -143,13 +144,14 @@ class GalaxyProvider(CloudProvider): temp_fd.write(content) temp_fd.flush() display.info(f'>>> {friendly_name} Configuration\n{to_text(content)}', verbosity=3) - docker_exec(self.args, descriptor.container_id, ['mkdir', '-p', os.path.dirname(path)], True) - docker_cp_to(self.args, descriptor.container_id, temp_fd.name, path) - docker_exec(self.args, descriptor.container_id, ['chown', 'pulp:pulp', path], True) + docker_exec(self.args, galaxy_ng.container_id, ['mkdir', '-p', os.path.dirname(path)], True, options=['-u', 'root']) + docker_cp_to(self.args, galaxy_ng.container_id, temp_fd.name, path) + docker_exec(self.args, galaxy_ng.container_id, ['chown', 'galaxy:galaxy', path], True, options=['-u', 'root']) - self._set_cloud_config('PULP_HOST', GALAXY_HOST_NAME) - self._set_cloud_config('PULP_USER', 'admin') - self._set_cloud_config('PULP_PASSWORD', 'password') + self._set_cloud_config('GALAXY_HOST', 'galaxy') + self._set_cloud_config('GALAXY_USER', 'admin') + self._set_cloud_config('GALAXY_PASSWORD', 'admin') + self._set_cloud_config('AMANDA_HOST', 'amanda') class GalaxyEnvironment(CloudEnvironment): @@ -157,22 +159,22 @@ class GalaxyEnvironment(CloudEnvironment): def get_environment_config(self) -> CloudEnvironmentConfig: """Return environment configuration for use in the test environment after delegation.""" - pulp_user = str(self._get_cloud_config('PULP_USER')) - pulp_password = str(self._get_cloud_config('PULP_PASSWORD')) - pulp_host = self._get_cloud_config('PULP_HOST') + galaxy_user = str(self._get_cloud_config('GALAXY_USER')) + galaxy_password = str(self._get_cloud_config('GALAXY_PASSWORD')) + galaxy_host = self._get_cloud_config('GALAXY_HOST') + amanda_host = self._get_cloud_config('AMANDA_HOST') return CloudEnvironmentConfig( ansible_vars=dict( - pulp_user=pulp_user, - pulp_password=pulp_password, - pulp_api=f'http://{pulp_host}', - pulp_server=f'http://{pulp_host}/pulp_ansible/galaxy/', - galaxy_ng_server=f'http://{pulp_host}/api/galaxy/', + galaxy_user=galaxy_user, + galaxy_password=galaxy_password, + galaxy_ng_server=f'http://{galaxy_host}:8000/api/galaxy', + amanda=f'http://{amanda_host}:8001', ), env_vars=dict( - PULP_USER=pulp_user, - PULP_PASSWORD=pulp_password, - PULP_SERVER=f'http://{pulp_host}/pulp_ansible/galaxy/api/', - GALAXY_NG_SERVER=f'http://{pulp_host}/api/galaxy/', + GALAXY_USER=galaxy_user, + GALAXY_PASSWORD=galaxy_password, + GALAXY_NG_SERVER=f'http://{galaxy_host}:8000/api/galaxy', + AMANDA=f'http://{amanda_host}:8001', ), ) diff --git a/test/lib/ansible_test/_internal/containers.py b/test/lib/ansible_test/_internal/containers.py index 86508a83bf6..7842bb14d36 100644 --- a/test/lib/ansible_test/_internal/containers.py +++ b/test/lib/ansible_test/_internal/containers.py @@ -451,6 +451,9 @@ def create_container_database(args: EnvironmentConfig) -> ContainerDatabase: managed: dict[str, dict[str, ContainerAccess]] = {} for name, container in support_containers.items(): + if container.details is None: + # data containers will not be started, and will be missing details + continue if container.details.published_ports: if require_docker().command == 'podman': host_ip_func = get_podman_host_ip diff --git a/test/lib/ansible_test/_internal/docker_util.py b/test/lib/ansible_test/_internal/docker_util.py index d6e450ff7e5..566786703d3 100644 --- a/test/lib/ansible_test/_internal/docker_util.py +++ b/test/lib/ansible_test/_internal/docker_util.py @@ -658,15 +658,15 @@ def __docker_pull(args: CommonConfig, image: str) -> None: """Internal implementation for docker_pull. Do not call directly.""" if '@' not in image and ':' not in image: display.info('Skipping pull of image without tag or digest: %s' % image, verbosity=2) - inspect = docker_image_inspect(args, image) - elif inspect := docker_image_inspect(args, image, always=True): + docker_image_inspect(args, image) + elif docker_image_inspect(args, image, always=True): display.info('Skipping pull of existing image: %s' % image, verbosity=2) else: for _iteration in range(1, 10): try: docker_command(args, ['pull', image], capture=False) - if (inspect := docker_image_inspect(args, image)) or args.explain: + if docker_image_inspect(args, image) or args.explain: break display.warning(f'Image "{image}" not found after pull completed. Waiting a few seconds before trying again.') @@ -676,18 +676,17 @@ def __docker_pull(args: CommonConfig, image: str) -> None: else: raise ApplicationError(f'Failed to pull container image "{image}".') - if inspect and inspect.volumes: - display.warning(f'Image "{image}" contains {len(inspect.volumes)} volume(s): {", ".join(sorted(inspect.volumes))}\n' - 'This may result in leaking anonymous volumes. It may also prevent the image from working on some hosts or container engines.\n' - 'The image should be rebuilt without the use of the VOLUME instruction.', - unique=True) - def docker_cp_to(args: CommonConfig, container_id: str, src: str, dst: str) -> None: """Copy a file to the specified container.""" docker_command(args, ['cp', src, '%s:%s' % (container_id, dst)], capture=True) +def docker_cp_from(args: CommonConfig, container_id: str, src: str, dst: str) -> None: + """Copy a file from the specified container.""" + docker_command(args, ['cp', '%s:%s' % (container_id, src), dst], capture=True) + + def docker_create( args: CommonConfig, image: str, @@ -726,7 +725,7 @@ def docker_rm(args: CommonConfig, container_id: str) -> None: # Podman supports `--time` for stop. The `--timeout` option was deprecated in 1.9.0. # Both Docker and Podman support the `-t` option for stop. docker_command(args, ['stop', '-t', '0', container_id], capture=True) - docker_command(args, ['rm', container_id], capture=True) + docker_command(args, ['rm', '-v', container_id], capture=True) except SubprocessError as ex: # Both Podman and Docker report an error if the container does not exist. # The error messages contain the same "no such container" string, differing only in capitalization.