From 99754a2af8b433bd0f037925afed7b1fea25eca8 Mon Sep 17 00:00:00 2001 From: Vladimir Sedmik Date: Fri, 17 Jan 2025 18:00:04 +0100 Subject: [PATCH] [WIP] Extend mixed content export import with consume --- tests/foreman/cli/test_satellitesync.py | 163 +++++++++++++++++++++--- 1 file changed, 145 insertions(+), 18 deletions(-) diff --git a/tests/foreman/cli/test_satellitesync.py b/tests/foreman/cli/test_satellitesync.py index 686761319c..befd4a2f9f 100644 --- a/tests/foreman/cli/test_satellitesync.py +++ b/tests/foreman/cli/test_satellitesync.py @@ -207,28 +207,42 @@ def function_synced_docker_repo(target_sat, function_org, function_product): @pytest.fixture -def function_synced_flatpak_repo(target_sat, function_org, function_product): +def function_synced_flatpak_repos(target_sat, function_org, function_product): fr = target_sat.cli.FlatpakRemote().create( { 'organization-id': function_org.id, - 'url': FLATPAK_REMOTES['Fedora']['url'], + 'url': FLATPAK_REMOTES['RedHat']['url'], 'name': gen_string('alpha'), + 'username': settings.container_repo.registries.redhat.username, + 'token': settings.container_repo.registries.redhat.password, } ) target_sat.cli.FlatpakRemote().scan({'id': fr['id']}) - repos = target_sat.cli.FlatpakRemote().repository_list({'flatpak-remote-id': fr['id']}) - assert len(repos), 'No repositories scanned' - repo_name = 'firefox' - remote_repo = next(r for r in repos if r['name'] == repo_name) - target_sat.cli.FlatpakRemote().repository_mirror( - {'flatpak-remote-id': fr['id'], 'id': remote_repo['id'], 'product-id': function_product.id} - ) - local_repo = target_sat.cli.Repository.list( - {'product-id': function_product.id, 'name': repo_name} - )[0] - target_sat.cli.Repository.update({'id': local_repo['id'], 'download-policy': 'immediate'}) - target_sat.cli.Repository.synchronize({'id': local_repo['id']}) - return target_sat.cli.Repository.info({'id': local_repo['id']}) + scanned_repos = target_sat.cli.FlatpakRemote().repository_list({'flatpak-remote-id': fr['id']}) + assert len(scanned_repos), 'No repositories scanned' + + repo_names = ['rhel9/firefox-flatpak', 'rhel9/flatpak-runtime'] # runtime is dependency + remote_repos = [r for r in scanned_repos if r['name'] in repo_names] + for repo in remote_repos: + target_sat.cli.FlatpakRemote().repository_mirror( + { + 'flatpak-remote-id': fr['id'], + 'id': repo['id'], # or by name + 'product-id': function_product.id, + } + ) + + local_repos = [ + r + for r in target_sat.cli.Repository.list({'product-id': function_product.id}) + if r['name'] in repo_names + ] + # assert set([r['name'] for r in local_repos]) == set(repo_names) + for repo in local_repos: + target_sat.cli.Repository.update({'id': repo['id'], 'download-policy': 'immediate'}) + target_sat.cli.Repository.synchronize({'id': repo['id']}) + + return [target_sat.cli.Repository.info({'id': repo['id']}) for repo in local_repos] @pytest.fixture @@ -1357,21 +1371,25 @@ def test_negative_import_incomplete_archive( ) assert 'content_view not found' in error.value.message, 'The imported CV should be gone' + @pytest.mark.e2e @pytest.mark.tier3 def test_postive_export_import_cv_with_mixed_content_repos( self, complete_export_import_cleanup, target_sat, function_org, + function_product, function_synced_custom_repo, function_synced_file_repo, function_synced_docker_repo, - function_synced_flatpak_repo, + function_synced_flatpak_repos, function_synced_AC_repo, module_import_sat, function_import_org_at_isat, + module_flatpak_contenthost, ): - """Export and import CV with mixed content types in the exportable format. + """Export and import CV with mixed content types in the exportable format, + consume it from the import. :id: ffcdbbc6-f787-4978-80a7-4b44c389bf49 @@ -1382,10 +1400,14 @@ def test_postive_export_import_cv_with_mixed_content_repos( 1. Create CV, add all setup repos and publish. 2. Export CV version contents to a directory. 3. Import the exported CV, check the content. + 4. Register a contenthost using AK. + 5. Configure the contenthost via REX to use import Sat's flatpak index. + 6. Consume the imported content for each content type. :expectedresults: 1. Export succeeds and content is exported. 2. Import succeeds, content is imported and matches the export. + 3. Imported content is consumable at the registered host. :BZ: 1726457 @@ -1400,9 +1422,9 @@ def test_postive_export_import_cv_with_mixed_content_repos( function_synced_custom_repo, function_synced_file_repo, function_synced_docker_repo, - function_synced_flatpak_repo, function_synced_AC_repo, ] + repos.extend(function_synced_flatpak_repos) for repo in repos: target_sat.cli.ContentView.add_repository( { @@ -1483,6 +1505,111 @@ def test_postive_export_import_cv_with_mixed_content_repos( f'"{key}" of the {imp["content-type"]} repo differs: {exp[key]} ≠ {imp[key]}' ) + # Register a content host using AK. + ak = module_import_sat.cli.ActivationKey.create( + { + 'name': gen_string('alpha'), + 'organization-id': function_import_org_at_isat.id, + 'lifecycle-environment': 'Library', + 'content-view': importing_cv['name'], + } + ) + module_import_sat.cli.ActivationKey.content_override( + { + 'id': ak['id'], + 'content-label': '_'.join( + [ + function_import_org_at_isat.name, + function_product.name, + function_synced_custom_repo.name, + ] + ), + 'value': 'true', + } + ) + res = module_flatpak_contenthost.register( + function_import_org_at_isat, None, ak['name'], module_import_sat, force=True + ) + assert res.status == 0, ( + f'Failed to register host: {module_flatpak_contenthost.hostname}\n' + f'StdOut: {res.stdout}\nStdErr: {res.stderr}' + ) + assert module_flatpak_contenthost.subscribed + + # Configure the contenthost via REX to use Satellite's flatpak index. + remote_name = f'ISS-remote-{gen_string("alpha")}' + job = module_import_sat.cli_factory.job_invocation( + { + 'organization': function_import_org_at_isat.name, + 'job-template': 'Set up Flatpak remote on host', + 'inputs': ( + f'Remote Name={remote_name}, ' + f'Flatpak registry URL=https://{module_import_sat.hostname}/pulpcore_registry/, ' # TODO org/CV scoped registry + f'Username={settings.server.admin_username}, ' + f'Password={settings.server.admin_password}' + ), + 'search-query': f"name ~ {module_flatpak_contenthost.hostname}", + } + ) + res = module_import_sat.cli.JobInvocation.info({'id': job.id}) + assert 'succeeded' in res['status'] + + # Consume the imported content for each content type. + # Flatpak + res = module_flatpak_contenthost.execute('flatpak remotes') + assert remote_name in res.stdout + + app_name = 'Firefox' + res = module_flatpak_contenthost.execute('flatpak remote-ls') + assert app_name in res.stdout + + job = module_import_sat.cli_factory.job_invocation( + { + 'organization': function_import_org_at_isat.name, + 'job-template': 'Install Flatpak application on host', + 'inputs': f'Flatpak remote name={remote_name}, Application name={app_name}', + 'search-query': f"name ~ {module_flatpak_contenthost.hostname}", + } + ) + res = module_import_sat.cli.JobInvocation.info({'id': job.id}) + assert 'succeeded' in res['status'] + + # Yum + res = module_flatpak_contenthost.execute('dnf install -y cheetah') + assert res.status == 0 + + # File + repo_url = module_import_sat.get_published_repo_url( + org=function_import_org_at_isat.label, + prod=function_product.label, + repo=function_synced_file_repo.label, + lce='Library', + cv=importing_cv['label'], + ) + res = module_flatpak_contenthost.execute(f'curl {repo_url}test.txt') + assert 'Hello, World!' in res.stdout, 'Expected world-wide greeting' + + # Docker + repo_path = f'{function_import_org_at_isat.label}/library/{importing_cv["label"]}/{function_product.label}/{function_synced_docker_repo.label}'.lower() + res = module_flatpak_contenthost.execute( + f'podman search {module_import_sat.hostname}/{repo_path}' + ) # logged in already since flatpak setup + assert repo_path in res.stdout + res = module_flatpak_contenthost.execute( + f'podman pull {module_import_sat.hostname}/{repo_path}' + ) + assert res.status == 0 + res = module_flatpak_contenthost.execute('podman images') + assert repo_path in res.stdout + + # AC + api_path = f'https://{module_import_sat.hostname}/pulp_ansible/galaxy/{function_import_org_at_isat.label}/Library/custom/{function_product.label}/{function_synced_AC_repo.label}' + res = target_sat.execute( + f'ansible-galaxy collection install -c -f -s {api_path} theforeman.foreman' + ) + assert res.status == 0 + assert 'installed successfully' in res.stdout + @pytest.mark.tier3 def test_postive_export_import_cv_with_mixed_content_syncable( self,