def test_error(self): soname_cache = elf.SonameCache() raised = self.assertRaises( EnvironmentError, soname_cache.__setitem__, self.key, "/soname.so" ) self.assertThat(str(raised), StartsWith(self.partial_message))
def load_part( self, part_name, plugin_name=None, part_properties=None, project=None, stage_packages_repo=None, base="core18", build_base=None, confinement="strict", snap_type="app", ): if not plugin_name: plugin_name = "nil" properties = {"plugin": plugin_name} if part_properties: properties.update(part_properties) if not project: project = snapcraft.project.Project() project._snap_meta.type = snap_type project._snap_meta.confinement = confinement project._snap_meta.base = base if build_base is not None: project._snap_meta.build_base = build_base validator = _schema.Validator() schema = validator.part_schema definitions_schema = validator.definitions_schema plugin = snapcraft.internal.pluginhandler.load_plugin( part_name=part_name, plugin_name=plugin_name, properties=properties, project=project, part_schema=schema, definitions_schema=definitions_schema, ) if not stage_packages_repo: stage_packages_repo = mock.Mock() grammar_processor = grammar_processing.PartGrammarProcessor( plugin=plugin, properties=properties, project=project, repo=stage_packages_repo, ) return snapcraft.internal.pluginhandler.PluginHandler( plugin=plugin, part_properties=properties, project=project, part_schema=schema, definitions_schema=definitions_schema, grammar_processor=grammar_processor, stage_packages_repo=stage_packages_repo, snap_base_path="/snap/fake-name/current", soname_cache=elf.SonameCache(), )
def handle_glibc_mismatch(*, elf_files: FrozenSet[elf.ElfFile], root_path: str, core_base_path: str, snap_base_path: str, preferred_patchelf_path=None, soname_cache: elf.SonameCache = None) -> None: """Copy over libc6 libraries from the host and patch necessary elf files. If no newer glibc version is detected in elf_files, this function returns. The dynamic linker and related libraries to libc6 are expected to be found in root_path. :param snapcraft.internal.elf.ElfFile elf_files: set of candidate elf files to patch if a newer libc6 is required. :param str root_path: the root path of a snap tree. :param str core_base_path: the path to the base snap. :param str snap_base_path: absolute path to the snap once installed to setup proper rpaths. :param str preferred_patchelf_path: patch the necessary elf_files with this patchelf. """ if soname_cache is None: soname_cache = elf.SonameCache() # We assume the current system will satisfy the GLIBC requirement, # get the current libc6 libraries (which includes the linker) libc6_libraries_list = repo.Repo.get_package_libraries('libc6') # For security reasons, we do not want to automatically pull in # libraries but expect them to be consciously brought in by stage-packages # instead. libc6_libraries_paths = [ os.path.join(root_path, l[1:]) for l in libc6_libraries_list ] dynamic_linker = _get_dynamic_linker(libc6_libraries_paths) # Get the path to the "would be" dynamic linker when this snap is # installed. Strip the root_path from the retrieved dynamic_linker # variables + the leading `/` so that os.path.join can perform the # proper join with snap_base_path. dynamic_linker_path = os.path.join(snap_base_path, dynamic_linker[len(root_path) + 1:]) elf_patcher = elf.Patcher(dynamic_linker=dynamic_linker_path, root_path=root_path, preferred_patchelf_path=preferred_patchelf_path) for elf_file in elf_files: # Search for dependencies again now that the new libc6 is # migrated. elf_file.load_dependencies(root_path=root_path, core_base_path=core_base_path, soname_cache=soname_cache) elf_patcher.patch(elf_file=elf_file)
def __init__(self, *, parts, project, validator): self._soname_cache = elf.SonameCache() self._parts_data = parts.get("parts", {}) self._snap_type = parts.get("type", "app") self._project = project self._validator = validator self.all_parts = [] self._part_names = [] self.after_requests = {} self._process_parts()
def load_part(self, part_name, plugin_name=None, part_properties=None, project_options=None, stage_packages_repo=None, base='core', confinement='strict', snap_type='app'): if not plugin_name: plugin_name = 'nil' properties = {'plugin': plugin_name} if part_properties: properties.update(part_properties) if not project_options: project_options = snapcraft.ProjectOptions() validator = snapcraft.internal.project_loader.Validator() schema = validator.part_schema definitions_schema = validator.definitions_schema plugin = snapcraft.internal.pluginhandler.load_plugin( part_name=part_name, plugin_name=plugin_name, properties=properties, project_options=project_options, part_schema=schema, definitions_schema=definitions_schema) if not stage_packages_repo: stage_packages_repo = mock.Mock() grammar_processor = grammar_processing.PartGrammarProcessor( plugin=plugin, properties=properties, project=project_options, repo=stage_packages_repo) return snapcraft.internal.pluginhandler.PluginHandler( plugin=plugin, part_properties=properties, project_options=project_options, part_schema=schema, definitions_schema=definitions_schema, grammar_processor=grammar_processor, stage_packages_repo=stage_packages_repo, snap_base_path='/snap/fake-name/current', base=base, confinement=confinement, snap_type=snap_type, soname_cache=elf.SonameCache())
def test_get_libraries_with_soname_cache(self): elf_file = self.fake_elf['fake_elf-2.23'] soname_cache = elf.SonameCache() soname_cache['bar.so.2'] = '/lib/bar.so.2' libs = elf_file.load_dependencies( root_path=self.fake_elf.root_path, core_base_path=self.fake_elf.core_base_path, soname_cache=soname_cache) # With no cache this would have returned '/usr/lib/bar.so.2' self.assertThat(libs, Equals(set( [self.fake_elf.root_libraries['foo.so.1'], '/lib/bar.so.2'])))
def __init__(self, *, parts, project, validator, build_snaps, build_tools): self._snap_name = parts["name"] self._base = parts.get("base", "core") self._confinement = parts.get("confinement") self._soname_cache = elf.SonameCache() self._parts_data = parts.get("parts", {}) self._snap_type = parts.get("type", "app") self._project = project self._validator = validator self.build_snaps = build_snaps self.build_tools = build_tools self.all_parts = [] self._part_names = [] self.after_requests = {} self._process_parts()
def __init__(self, *, parts, project_options, validator, build_snaps, build_tools, snapcraft_yaml): self._snap_name = parts['name'] self._confinement = parts['confinement'] self._soname_cache = elf.SonameCache() self._parts_data = parts.get('parts', {}) self._project_options = project_options self._validator = validator self.build_snaps = build_snaps self.build_tools = build_tools self._snapcraft_yaml = snapcraft_yaml self.all_parts = [] self._part_names = [] self.after_requests = {} self._process_parts()
def test_get_libraries_with_soname_cache(self): elf_file = self.fake_elf["fake_elf-2.23"] arch = ("ELFCLASS64", "ELFDATA2LSB", "EM_X86_64") soname_cache = elf.SonameCache() soname_cache[arch, "bar.so.2"] = "/lib/bar.so.2" libs = elf_file.load_dependencies( root_path=self.fake_elf.root_path, core_base_path=self.fake_elf.core_base_path, soname_cache=soname_cache, ) # With no cache this would have returned '/usr/lib/bar.so.2' self.assertThat( libs, Equals(set([self.fake_elf.root_libraries["foo.so.1"], "/lib/bar.so.2"])), )
def test_is_valid_elf_ignores_corrupt_files(self): soname = "libssl.so.1.0.0" soname_path = os.path.join(self.path, soname) library = elf.Library( soname=soname, soname_path=soname_path, search_paths=[self.path], core_base_path="/snap/core/current", arch=("ELFCLASS64", "ELFDATA2LSB", "EM_X86_64"), soname_cache=elf.SonameCache(), ) self.assertThat(library._is_valid_elf(soname_path), Equals(True)) self.useFixture( fixtures.MockPatch( "snapcraft.internal.elf.ElfFile", side_effect=errors.CorruptedElfFileError(path=soname_path, error=RuntimeError()), )) self.assertThat(library._is_valid_elf(soname_path), Equals(False))
def setUp(self): super().setUp() self.arch = ('ELFCLASS64', 'ELFDATA2LSB', 'EM_X86_64') self.soname_cache = elf.SonameCache()
def setUp(self): super().setUp() self.arch = ("ELFCLASS64", "ELFDATA2LSB", "EM_X86_64") self.soname_cache = elf.SonameCache()
def load_part( part_name, plugin_name=None, part_properties=None, project=None, stage_packages_repo=None, snap_name="test-snap", base="core18", build_base=None, confinement="strict", snap_type="app", ): if not plugin_name: plugin_name = "nil" properties = {"plugin": plugin_name} if part_properties: properties.update(part_properties) if "build-environment" not in properties: properties["build-environment"] = list() if not project: project = Project() project._snap_meta.name = snap_name project._snap_meta.version = "1.0" project._snap_meta.grade = "devel" project._snap_meta.type = snap_type project._snap_meta.confinement = confinement project._snap_meta.base = base if build_base is not None: project._snap_meta.build_base = build_base validator = _schema.Validator() schema = validator.part_schema definitions_schema = validator.definitions_schema plugin = pluginhandler.load_plugin( part_name=part_name, plugin_name=plugin_name, properties=properties, project=project, part_schema=schema, definitions_schema=definitions_schema, ) if not stage_packages_repo: stage_packages_repo = mock.Mock() grammar_processor = grammar_processing.PartGrammarProcessor( plugin=plugin, properties=properties, project=project, repo=stage_packages_repo) return pluginhandler.PluginHandler( plugin=plugin, part_properties=properties, project=project, part_schema=schema, definitions_schema=definitions_schema, grammar_processor=grammar_processor, stage_packages_repo=stage_packages_repo, snap_base_path="/snap/fake-name/current", soname_cache=elf.SonameCache(), )
def test_error(self, key, partial_message): soname_cache = elf.SonameCache() with pytest.raises(EnvironmentError) as error: soname_cache.__setitem__(key, "/soname.so") assert str(error).startswith(partial_message)
def setUp(self): super().setUp() self.soname_cache = elf.SonameCache()