def test_flatpak_create_oci_no_source(workflow): workflow.user_params['flatpak'] = True setup_flatpak_composes(workflow) (flexmock(FlatpakUtil).should_receive( 'get_flatpak_source_info').and_return(None)) runner = PostBuildPluginsRunner(workflow, [{ 'name': FlatpakCreateOciPlugin.key, 'args': {} }]) msg = "flatpak_create_dockerfile must be run before flatpak_create_oci" with pytest.raises(PluginFailedException, match=msg): runner.run()
def test_flatpak_update_dockerfile(tmpdir, docker_tasker, config_name, worker, breakage): config = CONFIGS[config_name] container_yaml = config['container_yaml'] workflow = mock_workflow(tmpdir, container_yaml) assert get_flatpak_compose_info(workflow) is None assert get_flatpak_source_info(workflow) is None if breakage == 'branch_mismatch': config = deepcopy(config) base_module = config['modules'][config['base_module']] base_module['metadata'] = base_module['metadata'].replace( 'branch: f28', 'branch: MISMATCH') expected_exception = "Mismatch for 'branch'" elif breakage == 'no_compose': config = deepcopy(config) config['odcs_composes'] = [] expected_exception = "Can't find main module" else: assert breakage is None expected_exception = None mock_koji_session(config) set_flatpak_source_spec(workflow, config['source_spec']) args = {} if worker: # composes resolved in the parent, compose IDs passed in mock_odcs_session(workflow, config) args['compose_ids'] = [c['id'] for c in config['odcs_composes']] else: # composes run by resolve_composes plugin setup_flatpak_composes(workflow, config) secrets_path = os.path.join(str(tmpdir), "secret") os.mkdir(secrets_path) with open(os.path.join(secrets_path, "token"), "w") as f: f.write("green_eggs_and_ham") workflow.plugin_workspace[ReactorConfigPlugin.key] = {} workflow.plugin_workspace[ReactorConfigPlugin.key][WORKSPACE_CONF_KEY] =\ ReactorConfig({'version': 1, 'odcs': {'api_url': ODCS_URL, 'auth': {'openidc_dir': secrets_path}, 'signing_intents': [ { 'name': 'unsigned', 'keys': [], }, { 'name': 'release', 'keys': ['R123', 'R234'], }, { 'name': 'beta', 'keys': ['R123', 'B456', 'B457'], }, ], 'default_signing_intent': 'unsigned'}, 'koji': {'auth': {}, 'hub_url': 'https://koji.example.com/hub'}}) runner = PreBuildPluginsRunner( docker_tasker, workflow, [{ 'name': FlatpakUpdateDockerfilePlugin.key, 'args': args }]) if expected_exception: with pytest.raises(PluginFailedException) as ex: runner.run() assert expected_exception in str(ex.value) else: runner.run() assert os.path.exists(workflow.builder.df_path) with open(workflow.builder.df_path) as f: df = f.read() m = re.search(r'module enable\s*(.*?)\s*$', df, re.MULTILINE) assert m enabled_modules = sorted(m.group(1).split()) if config_name == 'app': assert enabled_modules == ['eog:f28', 'flatpak-runtime:f28'] else: assert enabled_modules == ['flatpak-runtime:f28'] includepkgs_path = os.path.join(workflow.builder.df_dir, 'atomic-reactor-includepkgs') assert os.path.exists(includepkgs_path) with open(includepkgs_path) as f: includepkgs = f.read() assert 'librsvg2' in includepkgs if config_name == 'app': assert 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64' in includepkgs assert os.path.exists( os.path.join(workflow.builder.df_dir, 'cleanup.sh')) compose_info = get_flatpak_compose_info(workflow) assert compose_info.source_spec == config['source_spec'] if config_name == 'app': assert compose_info.main_module.name == 'eog' assert compose_info.main_module.stream == 'f28' assert compose_info.main_module.version == '20170629213428' assert (compose_info.main_module.mmd.get_summary("C") == 'Eye of GNOME Application Module') assert compose_info.main_module.rpms == [ 'eog-0:3.28.3-1.module_2123+73a9ef6f.src.rpm', 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64.rpm', 'eog-0:3.28.3-1.module_2123+73a9ef6f.ppc64le.rpm', ] source_info = get_flatpak_source_info(workflow) assert source_info.base_module.name == config['base_module']
def test_flatpak_update_dockerfile(workflow, build_dir, config_name, breakage): config = CONFIGS[config_name] container_yaml = config['container_yaml'] workflow = mock_workflow(workflow, build_dir, container_yaml) if breakage == 'branch_mismatch': config = deepcopy(config) base_module = config['modules'][config['base_module']] base_module['metadata'] = base_module['metadata'].replace( 'branch: f28', 'branch: MISMATCH') expected_exception = "Mismatch for 'branch'" elif breakage == 'no_compose': config = deepcopy(config) config['odcs_composes'] = [] expected_exception = "Can't find main module" else: assert breakage is None expected_exception = None mock_koji_session(config) # composes run by resolve_composes plugin setup_flatpak_composes(workflow, config) secrets_path = build_dir / "secret" secrets_path.mkdir() secrets_path.joinpath("token").write_text("green_eggs_and_ham", "utf-8") rcm = { 'version': 1, 'odcs': { 'api_url': ODCS_URL, 'auth': { 'openidc_dir': secrets_path }, 'signing_intents': [ { 'name': 'unsigned', 'keys': [], }, { 'name': 'release', 'keys': ['R123', 'R234'], }, { 'name': 'beta', 'keys': ['R123', 'B456', 'B457'], }, ], 'default_signing_intent': 'unsigned' }, 'koji': { 'auth': {}, 'hub_url': 'https://koji.example.com/hub' } } runner = (MockEnv(workflow).for_plugin( FlatpakUpdateDockerfilePlugin.key).set_reactor_config( rcm).create_runner()) if expected_exception: with pytest.raises(PluginFailedException) as ex: runner.run() assert expected_exception in str(ex.value) else: runner.run() assert os.path.exists(workflow.build_dir.any_platform.dockerfile_path) df = workflow.build_dir.any_platform.dockerfile.content m = re.search(r'module enable\s*(.*?)\s*$', df, re.MULTILINE) assert m enabled_modules = sorted(m.group(1).split()) if config_name == 'app': assert enabled_modules == ['eog:f28', 'flatpak-runtime:f28'] else: assert enabled_modules == ['flatpak-runtime:f28'] includepkgs_path = os.path.join(workflow.build_dir.any_platform.path, 'atomic-reactor-includepkgs') assert os.path.exists(includepkgs_path) with open(includepkgs_path) as f: includepkgs = f.read() assert 'librsvg2' in includepkgs if config_name == 'app': assert 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64' in includepkgs assert os.path.exists( os.path.join(workflow.build_dir.any_platform.path, 'cleanup.sh')) resolve_comp_result = workflow.data.plugins_results.get( PLUGIN_RESOLVE_COMPOSES_KEY) flatpak_util = FlatpakUtil(workflow_config=workflow.conf, source_config=workflow.source.config, composes=resolve_comp_result['composes']) compose_info = flatpak_util.get_flatpak_compose_info() assert compose_info.source_spec == config['source_spec'] if config_name == 'app': assert compose_info.main_module.name == 'eog' assert compose_info.main_module.stream == 'f28' assert compose_info.main_module.version == '20170629213428' assert (compose_info.main_module.mmd.get_summary("C") == 'Eye of GNOME Application Module') assert compose_info.main_module.rpms == [ 'eog-0:3.28.3-1.module_2123+73a9ef6f.src.rpm', 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64.rpm', 'eog-0:3.28.3-1.module_2123+73a9ef6f.ppc64le.rpm', ] source_info = flatpak_util.get_flatpak_source_info() assert source_info.base_module.name == config['base_module']
def test_flatpak_create_oci(workflow, config_name, flatpak_metadata, breakage): # Check that we actually have flatpak available have_flatpak = False try: output = subprocess.check_output(['flatpak', '--version'], universal_newlines=True) m = re.search(r'(\d+)\.(\d+)\.(\d+)', output) if m and (int(m.group(1)), int(m.group(2)), int( m.group(3))) >= (0, 9, 7): have_flatpak = True except (subprocess.CalledProcessError, OSError): pytest.skip(msg='flatpak not available') if not have_flatpak: return # Check if we have skopeo try: subprocess.check_output(['skopeo', '--version']) except (subprocess.CalledProcessError, OSError): pytest.skip(msg='skopeo not available') config = CONFIGS[config_name] platforms = ['x86_64', 'aarch64', 's390x', 'ppc64le'] workflow.user_params['flatpak'] = True write_docker_file(config, workflow.source.path) workflow.build_dir.init_build_dirs(platforms, workflow.source) mock_extract_filesystem_call = functools.partial(mock_extract_filesystem, config) (flexmock(ImageUtil).should_receive( 'extract_filesystem_layer').replace_with(mock_extract_filesystem_call)) make_and_store_reactor_config_map(workflow, flatpak_metadata) if breakage == 'no_runtime': # Copy the parts of the config we are going to change config = dict(config) config['modules'] = dict(config['modules']) config['modules']['eog'] = dict(config['modules']['eog']) module_config = config['modules']['eog'] mmd = Modulemd.ModuleStream.read_string(module_config['metadata'], strict=True) mmd.clear_dependencies() mmd.add_dependencies(Modulemd.Dependencies()) mmd_index = Modulemd.ModuleIndex.new() mmd_index.add_module_stream(mmd) module_config['metadata'] = mmd_index.dump_to_string() expected_exception = 'Failed to identify runtime module' else: assert breakage is None expected_exception = None runner = PostBuildPluginsRunner(workflow, [{ 'name': FlatpakCreateOciPlugin.key, 'args': {} }]) setup_flatpak_composes(workflow) source = setup_flatpak_source_info(config) (flexmock(FlatpakUtil).should_receive( 'get_flatpak_source_info').and_return(source)) if expected_exception: with pytest.raises(PluginFailedException) as ex: runner.run() assert expected_exception in str(ex.value) else: builder = FlatpakBuilder(source, workflow.build_dir.any_platform.path, 'var/tmp/flatpak-build', parse_manifest=parse_rpm_output, flatpak_metadata=FLATPAK_METADATA_ANNOTATIONS) with NamedTemporaryFile(dir=workflow.build_dir.any_platform.path) as f: f.write( config['filesystem_contents']['/var/tmp/flatpak-build.rpm_qf']) f.flush() expected_components = builder.get_components(f.name) results = runner.run() x86_64_results = results[FlatpakCreateOciPlugin.key][platforms[0]] dir_metadata = x86_64_results['metadata'] components = x86_64_results['components'] assert components == expected_components assert dir_metadata['type'] == IMAGE_TYPE_OCI # Check that the correct labels and annotations were written labels, annotations = load_labels_and_annotations(dir_metadata) if config_name == 'app': assert labels['name'] == 'eog' assert labels['com.redhat.component'] == 'eog' assert labels['version'] == 'f28' assert labels['release'] == '20170629213428' elif config_name == 'runtime': # runtime assert labels['name'] == 'flatpak-runtime' assert labels[ 'com.redhat.component'] == 'flatpak-runtime-container' assert labels['version'] == 'f28' assert labels['release'] == '20170701152209' else: assert labels['name'] == 'flatpak-sdk' assert labels['com.redhat.component'] == 'flatpak-sdk-container' assert labels['version'] == 'f28' assert labels['release'] == '20170701152209' if flatpak_metadata == 'annotations': assert annotations.get( 'org.flatpak.ref') == config['expected_ref_name'] assert 'org.flatpak.ref' not in labels elif flatpak_metadata == 'labels': assert 'org.flatpak.ref' not in annotations assert labels.get('org.flatpak.ref') == config['expected_ref_name'] elif flatpak_metadata == 'both': assert annotations.get( 'org.flatpak.ref') == config['expected_ref_name'] assert labels.get('org.flatpak.ref') == config['expected_ref_name'] # Check that the expected files ended up in the flatpak # Flatpak versions before 1.6 require annotations to be present, and Flatpak # versions 1.6 and later require labels to be present. Skip the remaining # checks unless we have both annotations and labels. if flatpak_metadata != 'both': return inspector = DefaultInspector(str(workflow.build_dir.any_platform.path), dir_metadata) files = inspector.list_files() assert sorted(files) == config['expected_contents'] metadata_lines = inspector.cat_file('/metadata').split('\n') assert any( re.match(r'runtime=org.fedoraproject.Platform/.*/f28$', line) for line in metadata_lines) assert any( re.match(r'sdk=org.fedoraproject.Sdk/.*/f28$', line) for line in metadata_lines) if config_name == 'app': # Check that the desktop file was rewritten output = inspector.cat_file( '/export/share/applications/org.gnome.eog.desktop') lines = output.split('\n') assert 'Icon=org.gnome.eog' in lines assert 'name=org.gnome.eog' in metadata_lines assert 'tags=Viewer' in metadata_lines assert 'command=eog2' in metadata_lines elif config_name == 'runtime': # runtime # Check that permissions have been normalized assert inspector.get_file_perms('/files/etc/shadow') == '-00644' assert inspector.get_file_perms('/files/bin/mount') == '-00755' assert inspector.get_file_perms('/files/share/foo') == 'd00755' assert 'name=org.fedoraproject.Platform' in metadata_lines else: # SDK assert 'name=org.fedoraproject.Sdk' in metadata_lines