Beispiel #1
0
    def is_host_compatible_with_base(self, base: str) -> bool:
        """Determines if the host is compatible with the GLIBC of the base.

        The system should warn early on when building using a host that does
        not match the intended base, this mechanism here enables additional
        logic when that is ignored to determine built projects will actually
        run.

        :param str base: the base core snap to search for linker.
        :returns: True if there are no GLIBC incompatibilities with the chosen
                  build host, else it returns False.
        :rtype: bool
        """
        try:
            codename = os_release.OsRelease().version_codename()
        except errors.OsReleaseCodenameError:
            return False

        logger.debug("Running on {!r}".format(codename))

        build_host_for_base = _HOST_CODENAME_FOR_BASE.get(base)
        if build_host_for_base is None:
            return False

        compatible_hosts = _HOST_COMPATIBILITY.get(build_host_for_base, [])

        return codename in compatible_hosts
Beispiel #2
0
def annotate_snapcraft(data, parts_dir: str):
    manifest = OrderedDict()  # type: Dict[str, Any]
    manifest["snapcraft-version"] = snapcraft._get_version()

    release = os_release.OsRelease()
    with contextlib.suppress(errors.OsReleaseIdError):
        manifest["snapcraft-os-release-id"] = release.id()
    with contextlib.suppress(errors.OsReleaseVersionIdError):
        manifest["snapcraft-os-release-version-id"] = release.version_id()

    for k, v in data.items():
        manifest[k] = v
    image_info = os.environ.get("SNAPCRAFT_IMAGE_INFO")
    if image_info:
        try:
            image_info_dict = json.loads(image_info)
        except json.decoder.JSONDecodeError as exception:
            raise errors.InvalidContainerImageInfoError(
                image_info) from exception
        manifest["image-info"] = image_info_dict
    for field in ("build-packages", "build-snaps"):
        manifest[field] = get_global_state().assets.get(field, [])
    for part in data["parts"]:
        state_dir = os.path.join(parts_dir, part, "state")
        pull_state = get_state(state_dir, steps.PULL)
        manifest["parts"][part]["build-packages"] = pull_state.assets.get(
            "build-packages", [])
        manifest["parts"][part]["stage-packages"] = pull_state.assets.get(
            "stage-packages", [])
        source_details = pull_state.assets.get("source-details", {})
        if source_details:
            manifest["parts"][part].update(source_details)
        build_state = get_state(state_dir, steps.BUILD)
        manifest["parts"][part].update(build_state.assets)
    return manifest
Beispiel #3
0
    def _setUp(self):
        super()._setUp()

        with open('os-release', 'w') as release_file:
            print(dedent("""\
                NAME="Ubuntu"
                VERSION="16.04.3 LTS (Xenial Xerus)"
                ID_LIKE=debian
                PRETTY_NAME="Ubuntu 16.04.3 LTS"
                HOME_URL="http://www.ubuntu.com/"
                SUPPORT_URL="http://help.ubuntu.com/"
                BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
                UBUNTU_CODENAME=xenial"""), file=release_file)
            if self._id is not None:
                print('ID={}'.format(self._id), file=release_file)
            if self._version_id is not None:
                print('VERSION_ID="{}"'.format(self._version_id),
                      file=release_file)
            if self._version_codename is not None:
                print('VERSION_CODENAME={}'.format(self._version_codename),
                      file=release_file)

        release = os_release.OsRelease(os_release_file='os-release')

        def _create_os_release(*args, **kwargs):
            return release

        patcher = mock.patch(
            'snapcraft.internal.os_release.OsRelease',
            wraps=_create_os_release)
        patcher.start()
        self.addCleanup(patcher.stop)
Beispiel #4
0
    def setUp(self):
        super().setUp()

        with open('os-release', 'w') as f:
            f.write(
                dedent("""\
                NAME="Ubuntu"
                VERSION="16.04.3 LTS (Xenial Xerus)"
                ID=ubuntu
                ID_LIKE=debian
                PRETTY_NAME="Ubuntu 16.04.3 LTS"
                VERSION_ID="16.04"
                HOME_URL="http://www.ubuntu.com/"
                SUPPORT_URL="http://help.ubuntu.com/"
                BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
                UBUNTU_CODENAME=xenial
            """))
        release = os_release.OsRelease(os_release_file='os-release')

        def _create_os_release(*args, **kwargs):
            return release

        patcher = mock.patch('snapcraft.internal.os_release.OsRelease',
                             wraps=_create_os_release)
        self.os_release_mock = patcher.start()
        self.addCleanup(patcher.stop)
Beispiel #5
0
    def _collected_sources_list(self):
        if self._use_geoip or self._sources_list:
            release = os_release.OsRelease()
            return _format_sources_list(
                self._sources_list, deb_arch=self._deb_arch,
                use_geoip=self._use_geoip, release=release.version_codename())

        return _get_local_sources_list()
Beispiel #6
0
def get_user_agent(platform: str = sys.platform) -> str:
    arch = project.Project().deb_arch
    testing = "(testing) " if _is_ci_env() else ""

    if platform == "linux":
        os_platform = _get_linux_release(os_release.OsRelease())
    else:
        os_platform = platform.title()

    return f"snapcraft/{snapcraft.__version__} {testing}{os_platform} ({arch})"
Beispiel #7
0
 def get_required_package_repositories(cls) -> List[PackageRepository]:
     codename = os_release.OsRelease().version_codename()
     return [
         PackageRepositoryApt(
             formats=["deb"],
             components=["main"],
             key_id="C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654",
             url="http://packages.ros.org/ros2/ubuntu",
             suites=[codename],
         )
     ]
Beispiel #8
0
    def test_no_version_codename_or_version_id(self):
        release = os_release.OsRelease(os_release_file=self._write_os_release(
            dedent("""\
                NAME="Ubuntu"
                ID=ubuntu
                ID_LIKE=debian
                PRETTY_NAME="Ubuntu 16.04.3 LTS"
            """)))

        self.assertRaises(errors.OsReleaseCodenameError,
                          release.version_codename)
Beispiel #9
0
    def test_no_version_id(self):
        release = os_release.OsRelease(os_release_file=self._write_os_release(
            dedent("""\
                NAME="Arch Linux"
                ID=arch
                PRETTY_NAME="Arch Linux"
                ID_LIKE=archlinux
                VERSION_CODENAME="bar"
            """)))

        self.assertRaises(errors.OsReleaseVersionIdError, release.version_id)
Beispiel #10
0
    def test_no_name(self):
        release = os_release.OsRelease(os_release_file=self._write_os_release(
            dedent("""\
                ID=arch
                PRETTY_NAME="Arch Linux"
                ID_LIKE=archlinux
                VERSION_ID="foo"
                VERSION_CODENAME="bar"
            """)))

        self.assertRaises(errors.OsReleaseNameError, release.name)
Beispiel #11
0
    def _wrap(func: Callable[..., None]) -> Callable[..., None]:
        release = os_release.OsRelease()
        actual_codename = None
        with contextlib.suppress(errors.OsReleaseCodenameError):
            actual_codename = release.version_codename()

        @functools.wraps(func)
        @skipUnless(actual_codename == codename, message)
        def _skip_test(*args: Any, **kwargs: Any) -> None:
            func(*args, **kwargs)

        return _skip_test
Beispiel #12
0
def _patchelf_install_required(project_options) -> bool:
    is_xenial = False
    with contextlib.suppress(os_release.errors.OsReleaseCodenameError):
        release_codename = os_release.OsRelease().version_codename()
        is_xenial = release_codename == 'xenial'

    is_snap = common.is_snap()
    is_environment = os.getenv('SNAPCRAFT_NO_PATCHELF')
    is_arch_missing_xenial = project_options.deb_arch in ('armhf', 's390x')

    return not (is_snap or is_environment or
                (is_arch_missing_xenial and is_xenial))
Beispiel #13
0
    def install_ppa(cls, ppa: str) -> bool:
        owner, name = apt_ppa.split_ppa_parts(ppa=ppa)
        codename = os_release.OsRelease().version_codename()

        return any([
            cls.install_sources(
                components=["main"],
                formats=["deb"],
                name=f"ppa-{owner}_{name}",
                suites=[codename],
                url=f"http://ppa.launchpad.net/{owner}/{name}/ubuntu",
            ),
        ])
Beispiel #14
0
    def test_no_version_codename(self):
        """Test that version codename can also come from VERSION_ID"""
        release = os_release.OsRelease(os_release_file=self._write_os_release(
            dedent("""\
                NAME="Ubuntu"
                VERSION="14.04.5 LTS, Trusty Tahr"
                ID=ubuntu
                ID_LIKE=debian
                PRETTY_NAME="Ubuntu 14.04.5 LTS"
                VERSION_ID="14.04"
            """)))

        self.assertThat(release.version_codename(), Equals('trusty'))
Beispiel #15
0
def annotate_snapcraft(project: "Project", data: Dict[str,
                                                      Any]) -> Dict[str, Any]:
    manifest = OrderedDict()  # type: Dict[str, Any]
    manifest["snapcraft-version"] = snapcraft._get_version()
    manifest["snapcraft-started-at"] = project._get_start_time().isoformat(
    ) + "Z"

    release = os_release.OsRelease()
    with contextlib.suppress(errors.OsReleaseIdError):
        manifest["snapcraft-os-release-id"] = release.id()
    with contextlib.suppress(errors.OsReleaseVersionIdError):
        manifest["snapcraft-os-release-version-id"] = release.version_id()

    for k, v in data.items():
        manifest[k] = v
    image_info = os.environ.get("SNAPCRAFT_IMAGE_INFO")
    if image_info:
        try:
            image_info_dict = json.loads(image_info)
        except json.decoder.JSONDecodeError as exception:
            raise errors.InvalidContainerImageInfoError(
                image_info) from exception
        manifest["image-info"] = image_info_dict

    global_state = GlobalState.load(
        filepath=project._get_global_state_file_path())
    manifest["build-packages"] = sorted(global_state.get_build_packages())
    manifest["build-snaps"] = sorted(global_state.get_build_snaps())

    for part in data["parts"]:
        state_dir = os.path.join(project.parts_dir, part, "state")
        pull_state = get_state(state_dir, steps.PULL)
        manifest["parts"][part]["build-packages"] = sorted(
            pull_state.assets.get("build-packages", []))
        manifest["parts"][part]["stage-packages"] = sorted(
            pull_state.assets.get("stage-packages", []))
        source_details = pull_state.assets.get("source-details", {})
        if source_details:
            manifest["parts"][part].update(source_details)
        build_state = get_state(state_dir, steps.BUILD)
        manifest["parts"][part].update(build_state.assets)

    # Assemble all primed stage packages into a single list...
    primed_stage_packages: Set[str] = set()
    for part in data["parts"]:
        state_dir = os.path.join(project.parts_dir, part, "state")
        prime_state = get_state(state_dir, steps.PRIME)
        primed_stage_packages |= prime_state.primed_stage_packages
    manifest["primed-stage-packages"] = sorted(primed_stage_packages)

    return manifest
Beispiel #16
0
    def plugin_stage_packages(self):
        release_codename = os_release.OsRelease().version_codename()
        if self.options.python_version == "python2":
            python_base = "python"
        elif self.options.python_version == "python3":
            python_base = "python3"
        else:
            return

        stage_packages = [python_base]
        # In bionic, python3's pip started requiring python-distutils
        # to be installed.
        if python_base == "python3" and release_codename == "bionic":
            stage_packages.append("{}-distutils".format(python_base))
        return stage_packages
Beispiel #17
0
    def plugin_stage_packages(self):
        release_codename = os_release.OsRelease().version_codename()
        if self.options.python_version == 'python2':
            python_base = 'python'
        elif self.options.python_version == 'python3':
            python_base = 'python3'
        else:
            return

        stage_packages = [python_base]
        # In bionic, python3's pip started requiring python-distutils
        # to be installed.
        if python_base == 'python3' and release_codename == 'bionic':
            stage_packages.append('{}-distutils'.format(python_base))
        return stage_packages
Beispiel #18
0
    def test_blank_lines(self):
        release = os_release.OsRelease(os_release_file=self._write_os_release(
            dedent("""\
                NAME="Arch Linux"

                PRETTY_NAME="Arch Linux"
                ID=arch
                ID_LIKE=archlinux
                VERSION_ID="foo"
                VERSION_CODENAME="bar"

            """)))

        self.assertThat(release.id(), Equals('arch'))
        self.assertThat(release.name(), Equals('Arch Linux'))
        self.assertThat(release.version_id(), Equals('foo'))
        self.assertThat(release.version_codename(), Equals('bar'))
Beispiel #19
0
def _get_system_libs() -> FrozenSet[str]:
    global _libraries
    if _libraries:
        return _libraries

    lib_path = None

    release = os_release.OsRelease()
    with contextlib.suppress(errors.OsReleaseVersionIdError):
        lib_path = os.path.join(
            common.get_librariesdir(), release.version_id())

    if not lib_path or not os.path.exists(lib_path):
        logger.debug('Only excluding libc libraries from the release')
        libc6_libs = [os.path.basename(l)
                      for l in repo.Repo.get_package_libraries('libc6')]
        return frozenset(libc6_libs)

    with open(lib_path) as fn:
        _libraries = frozenset(fn.read().split())

    return _libraries
Beispiel #20
0
    def _install_sources_ppa(
            self, *,
            package_repo: package_repository.PackageRepositoryAptPpa) -> bool:
        """Install PPA formatted repository.

        Create a sources list config by:
        - Looking up the codename of the host OS and using it as the "suites"
          entry.
        - Formulate deb URL to point to PPA.
        - Enable only "deb" formats.

        :returns: True if source configuration was changed.
        """
        owner, name = apt_ppa.split_ppa_parts(ppa=package_repo.ppa)
        codename = os_release.OsRelease().version_codename()

        return self._install_sources(
            components=["main"],
            formats=["deb"],
            name=f"ppa-{owner}_{name}",
            suites=[codename],
            url=f"http://ppa.launchpad.net/{owner}/{name}/ubuntu",
        )
Beispiel #21
0
    def setUp(self):
        super().setUp()

        with open('os-release', 'w') as f:
            f.write(dedent("""\
                NAME="Ubuntu"
                VERSION="16.04.3 LTS (Xenial Xerus)"
                ID=ubuntu
                ID_LIKE=debian
                PRETTY_NAME="Ubuntu 16.04.3 LTS"
                VERSION_ID="16.04"
                HOME_URL="http://www.ubuntu.com/"
                SUPPORT_URL="http://help.ubuntu.com/"
                BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
                UBUNTU_CODENAME=xenial
            """))
        release = os_release.OsRelease(os_release_file='os-release')

        def _create_os_release(*args, **kwargs):
            return release

        patcher = mock.patch(
            'snapcraft.internal.os_release.OsRelease',
            wraps=_create_os_release)
        self.os_release_mock = patcher.start()
        self.addCleanup(patcher.stop)

        patcher = mock.patch('snapcraft.internal.common.run_output')
        self.run_output_mock = patcher.start()
        self.addCleanup(patcher.stop)

        lines = [
            'foo.so.1 => /lib/foo.so.1 (0xdead)',
            'bar.so.2 => /usr/lib/bar.so.2 (0xbeef)',
            '/lib/baz.so.2 (0x1234)',
        ]
        self.run_output_mock.return_value = '\t' + '\n\t'.join(lines) + '\n'
Beispiel #22
0
    def setUp(self):
        super().setUp()

        elf._libraries = None

        with open('os-release', 'w') as f:
            f.write(
                dedent("""\
                NAME="Gentoo"
                ID=gentoo
                PRETTY_NAME="Gentoo/Linux"
                HOME_URL="http://www.gentoo.org/"
                SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
                BUG_REPORT_URL="https://bugs.gentoo.org/"
            """))
        release = os_release.OsRelease(os_release_file='os-release')

        def _create_os_release(*args, **kwargs):
            return release

        patcher = mock.patch('snapcraft.internal.os_release.OsRelease',
                             wraps=_create_os_release)
        self.os_release_mock = patcher.start()
        self.addCleanup(patcher.stop)
Beispiel #23
0
def _format_sources_list(sources_list: str):
    release = os_release.OsRelease().version_codename()

    return string.Template(sources_list).substitute({"release": release})
Beispiel #24
0
def _format_sources_list(sources_list: str):
    release = os_release.OsRelease().version_codename()

    return sources_list.replace("$SNAPCRAFT_APT_RELEASE", release)