Exemplo n.º 1
0
    def test_architecture_options(
        self,
        monkeypatch,
        machine,
        architecture,
        expected_arch_triplet,
        expected_deb_arch,
        expected_kernel_arch,
        expected_core_dynamic_linker,
    ):
        monkeypatch.setattr(platform, "architecture", lambda: architecture)
        monkeypatch.setattr(platform, "machine", lambda: machine)

        options = snapcraft_legacy.ProjectOptions()

        assert options.arch_triplet == expected_arch_triplet
        assert options.deb_arch == expected_deb_arch
        assert options.kernel_arch == expected_kernel_arch

        # The core dynamic linker is correct.  Guard against stray absolute
        # paths, as they cause os.path.join to discard the previous
        # argument.
        monkeypatch.setattr(os.path, "lexists", lambda x: True)
        monkeypatch.setattr(os.path, "islink", lambda x: False)
        expected_linker_path = os.path.join(
            common.get_installed_snap_path("core18"),
            expected_core_dynamic_linker)
        assert options.get_core_dynamic_linker(
            "core18") == expected_linker_path
Exemplo n.º 2
0
    def get_provider_content_directories(self) -> Set[str]:
        """Get provider content directories from installed snaps."""
        provider_dirs: Set[str] = set()

        for plug in self.get_content_plugs():
            # Get matching slot provider for plug.
            provider = plug.provider
            if not provider:
                continue

            provider_path = common.get_installed_snap_path(provider)
            yaml_path = os.path.join(provider_path, "meta", "snap.yaml")

            if not os.path.exists(yaml_path):
                continue

            snap = Snap.from_file(yaml_path)
            for slot in snap.get_content_slots():
                slot_installed_path = common.get_installed_snap_path(provider)
                provider_dirs |= slot.get_content_dirs(
                    installed_path=slot_installed_path)

        return provider_dirs
Exemplo n.º 3
0
    def get_core_dynamic_linker(self, base: str, expand: bool = True) -> str:
        """Returns the dynamic linker used for the targeted core.

        :param str base: the base core snap to search for linker.
        :param bool expand: expand the linker to the actual linker if True,
                            else the main entry point to the linker for the
                            projects architecture.
        :return: the absolute path to the linker
        :rtype: str
        :raises snapcraft_legacy.internal.errors.SnapcraftMissingLinkerInBaseError:
            if the linker cannot be found in the base.
        :raises snapcraft_legacy.internal.errors.SnapcraftEnvironmentError:
            if a loop is found while resolving the real path to the linker.
        """
        core_path = common.get_installed_snap_path(base)
        dynamic_linker_path = os.path.join(
            core_path,
            self.__machine_info.get("core-dynamic-linker",
                                    "lib/ld-linux.so.2"),
        )

        # return immediately if we do not need to expand
        if not expand:
            return dynamic_linker_path

        # We can't use os.path.realpath because any absolute symlinks
        # have to be interpreted relative to core_path, not the real
        # root.
        seen_paths = set()  # type: Set[str]
        while True:
            if dynamic_linker_path in seen_paths:
                raise errors.SnapcraftEnvironmentError(
                    "found symlink loop resolving dynamic linker path")

            seen_paths.add(dynamic_linker_path)
            if not os.path.lexists(dynamic_linker_path):
                raise errors.SnapcraftMissingLinkerInBaseError(
                    base=base, linker_path=dynamic_linker_path)
            if not os.path.islink(dynamic_linker_path):
                return dynamic_linker_path

            link_contents = os.readlink(dynamic_linker_path)
            if os.path.isabs(link_contents):
                dynamic_linker_path = os.path.join(core_path,
                                                   link_contents.lstrip("/"))
            else:
                dynamic_linker_path = os.path.join(
                    os.path.dirname(dynamic_linker_path), link_contents)
Exemplo n.º 4
0
    def build(self):
        super().build()
        self.run(
            ["shards", "build", "--without-development"] +
            self.options.crystal_build_options,
            self.builddir,
        )

        output_bin = os.path.join(self.builddir, "bin")
        if not os.path.exists(output_bin):
            raise errors.SnapcraftEnvironmentError(
                "No binaries were built. Ensure the shards.yaml contains valid targets."
            )

        install_bin_path = os.path.join(self.installdir, "bin")

        bin_paths = (os.path.join(output_bin, b)
                     for b in os.listdir(output_bin))
        elf_files = (elf.ElfFile(path=b) for b in bin_paths
                     if elf.ElfFile.is_elf(b))

        os.makedirs(install_bin_path, exist_ok=True)

        for elf_file in elf_files:
            shutil.copy2(
                elf_file.path,
                os.path.join(install_bin_path,
                             os.path.basename(elf_file.path)),
            )

            elf_dependencies_path = elf_file.load_dependencies(
                root_path=self.installdir,
                core_base_path=common.get_installed_snap_path(
                    self.project._get_build_base()),
                arch_triplet=self.project.arch_triplet,
                content_dirs=self.project._get_provider_content_dirs(),
            )
            for elf_dependency_path in elf_dependencies_path:
                lib_install_path = os.path.join(self.installdir,
                                                elf_dependency_path[1:])
                os.makedirs(os.path.dirname(lib_install_path), exist_ok=True)
                if not os.path.exists(lib_install_path):
                    file_utils.link_or_copy(elf_dependency_path,
                                            lib_install_path,
                                            follow_symlinks=True)
Exemplo n.º 5
0
def stage_runtime_dependencies(
    part_src: str,
    part_install: str,
    part_build: str,
    arch_triplet: str,
    content_dirs: str,
):
    build_path = os.path.join(part_build, "bin")
    install_path = os.path.join(part_install, "bin")

    if not os.path.exists(build_path):
        raise errors.SnapcraftEnvironmentError(
            "No binaries were built. Ensure the shards.yaml contains valid targets."
        )

    bin_paths = (os.path.join(build_path, b) for b in os.listdir(build_path))
    elf_files = (elf.ElfFile(path=b) for b in bin_paths if elf.ElfFile.is_elf(b))
    os.makedirs(install_path, exist_ok=True)

    # convert colon-delimited paths into a set
    if content_dirs == "":
        content_dirs_set = set()
    else:
        content_dirs_set = set(content_dirs.split(":"))

    for elf_file in elf_files:
        shutil.copy2(
            elf_file.path, os.path.join(install_path, os.path.basename(elf_file.path)),
        )

        elf_dependencies_path = elf_file.load_dependencies(
            root_path=part_install,
            core_base_path=common.get_installed_snap_path("core20"),
            arch_triplet=arch_triplet,
            content_dirs=content_dirs_set,
        )

        for elf_dependency_path in elf_dependencies_path:
            lib_install_path = os.path.join(part_install, elf_dependency_path[1:])
            os.makedirs(os.path.dirname(lib_install_path), exist_ok=True)
            if not os.path.exists(lib_install_path):
                file_utils.link_or_copy(
                    elf_dependency_path, lib_install_path, follow_symlinks=True
                )