Пример #1
0
    def _is_compatible_version(self, built_by: str) -> bool:
        """Return True if running version is >= built-by version."""

        # We use a bit a of naive string check here.  Re-using Python
        # versioning comparisons cannot be used because we don't follow
        # their spec. Apt version comparison would require running on Linux.
        return snapcraft._get_version() >= built_by
Пример #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
Пример #3
0
    def _check_environment_needs_cleaning(self) -> bool:
        info = self._load_info()
        provider_base = info.get("base")
        built_by = info.get("created-by-snapcraft-version")
        build_base = self.project._get_build_base()

        if provider_base is None or built_by is None:
            self.echoer.warning(
                "Build environment is in unknown state, cleaning first."
            )
            return True
        elif build_base != provider_base:
            self.echoer.warning(
                f"Project base changed from {provider_base!r} to {build_base!r}, cleaning first."
            )
            return True
        elif pkg_resources.parse_version(
            snapcraft._get_version()
        ) < pkg_resources.parse_version(built_by):
            self.echoer.warning(
                f"Build environment was created with newer snapcraft version {built_by!r}, cleaning first."
            )
            return True

        return False
Пример #4
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
Пример #5
0
    def _setup_snapcraft(self) -> None:
        self._save_info(
            data={
                "base": self.project._get_build_base(),
                "created-by-snapcraft-version": snapcraft._get_version(),
            }
        )

        registry_filepath = os.path.join(
            self.provider_project_dir, "snap-registry.yaml"
        )

        # We do not want to inject from the host if not running from the snap
        # or if the provider cannot handle snap mounts.
        # This latter problem should go away when API for retrieving snaps
        # through snapd is generally available.
        if self._get_is_snap_injection_capable():
            inject_from_host = common.is_snap()
        else:
            inject_from_host = False

        snap_injector = SnapInjector(
            registry_filepath=registry_filepath,
            snap_arch=self.project.deb_arch,
            runner=self._run,
            file_pusher=self._push_file,
            inject_from_host=inject_from_host,
        )

        # Note that snap injection order is important.
        # If the build base is core, we do not need to inject snapd.
        # Check for None as this build can be driven from a non snappy enabled
        # system, so we may find ourselves in a situation where the base is not
        # set like on OSX or Windows.
        build_base = self.project._get_build_base()
        if build_base is not None and build_base != "core":
            snap_injector.add(snap_name="snapd")

        # Prevent injecting core18 twice.
        if build_base is not None and build_base != "core18":
            snap_injector.add(snap_name=build_base)

        # Inject snapcraft
        snap_injector.add(snap_name="core18")
        snap_injector.add(snap_name="snapcraft")

        snap_injector.apply()
Пример #6
0
    def _setup_snapcraft(self) -> None:
        self._save_info(
            data={
                "base": self.project._get_build_base(),
                "created-by-snapcraft-version": snapcraft._get_version(),
                "host-project-directory": self.project._project_dir,
            }
        )

        registry_filepath = os.path.join(
            self.provider_project_dir, "snap-registry.yaml"
        )

        # We do not want to inject from the host if not running from the snap
        # or if the provider cannot handle snap mounts.
        # This latter problem should go away when API for retrieving snaps
        # through snapd is generally available.
        if self._get_is_snap_injection_capable():
            inject_from_host = common.is_snap()
        else:
            inject_from_host = False

        snap_injector = SnapInjector(
            registry_filepath=registry_filepath,
            runner=self._run,
            file_pusher=self._push_file,
            inject_from_host=inject_from_host,
        )

        snap_injector.add(snap_name="snapd")

        # Prevent injecting core20 twice (Snapcraft's base).
        build_base = self.project._get_build_base()
        if build_base != "core20":
            snap_injector.add(snap_name=build_base)

        # Inject snapcraft and its base.
        snap_injector.add(snap_name="core20")
        snap_injector.add(snap_name="snapcraft")

        snap_injector.apply()
Пример #7
0
def annotate_snapcraft(data, parts_dir: str, global_state_path: 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

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

    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
Пример #8
0
 def test_version_from_snap(self):
     self.useFixture(fixtures.EnvironmentVariable("SNAP_NAME", "snapcraft"))
     self.useFixture(fixtures.EnvironmentVariable("SNAP_VERSION", "3.14"))
     self.assertThat(snapcraft._get_version(), Equals("3.14"))
Пример #9
0
 def test_version_from_snap(self):
     self.useFixture(fixtures.EnvironmentVariable('SNAP_NAME', 'snapcraft'))
     self.useFixture(fixtures.EnvironmentVariable('SNAP_VERSION', '3.14'))
     self.assertThat(snapcraft._get_version(), Equals('3.14'))
Пример #10
0
 def test_version_from_snap(self):
     self.useFixture(fixtures.EnvironmentVariable(
         'SNAP_NAME', 'snapcraft'))
     self.useFixture(fixtures.EnvironmentVariable(
         'SNAP_VERSION', '3.14'))
     self.assertThat(snapcraft._get_version(), Equals('3.14'))