Beispiel #1
0
    def _setup_snapcraft(*, executor: Executor) -> None:
        """Install Snapcraft in target environment.

        On Linux, the default behavior is to inject the host snap into the target
        environment.

        On other platforms, the Snapcraft snap is installed from the Snap Store.

        When installing the snap from the Store, we check if the user specifies a
        channel, using SNAPCRAFT_INSTALL_SNAP_CHANNEL=<channel>.  If unspecified,
        we use the "stable" channel on the default track.

        On Linux, the user may specify this environment variable to force Snapcraft
        to install the snap from the Store rather than inject the host snap.

        :raises BaseConfigurationError: on error.
        """
        # Requirement for apt gpg and version:git
        executor.execute_run(
            ["apt-get", "install", "-y", "gnupg", "dirmngr", "git"],
            capture_output=True,
            check=True,
        )

        snap_channel = utils.get_managed_environment_snap_channel()
        if snap_channel is None and sys.platform != "linux":
            snap_channel = "stable"

        # Snaps that are already installed won't be reinstalled.
        # See https://github.com/canonical/craft-providers/issues/91

        if snap_channel:
            try:
                snap_installer.install_from_store(
                    executor=executor,
                    snap_name="snapcraft",
                    channel=snap_channel,
                    classic=True,
                )
            except snap_installer.SnapInstallationError as error:
                raise bases.BaseConfigurationError(
                    "Failed to install snapcraft snap from store channel "
                    f"{snap_channel!r} into target environment."
                ) from error
        else:
            try:
                snap_installer.inject_from_host(
                    executor=executor, snap_name="snapcraft", classic=True
                )
            except snap_installer.SnapInstallationError as error:
                raise bases.BaseConfigurationError(
                    "Failed to inject host snapcraft snap into target environment."
                ) from error
Beispiel #2
0
    def setup(
        self,
        *,
        executor: Executor,
        retry_wait: float = 0.25,
        timeout: Optional[float] = None,
    ) -> None:
        """Prepare base instance for use by the application.

        In addition to the guarantees provided by buildd:

            - charmcraft installed

            - python3 pip and setuptools installed

        :param executor: Executor for target container.
        :param retry_wait: Duration to sleep() between status checks (if
            required).
        :param timeout: Timeout in seconds.

        :raises BaseCompatibilityError: if instance is incompatible.
        :raises BaseConfigurationError: on other unexpected error.
        """
        super().setup(executor=executor, retry_wait=retry_wait, timeout=timeout)

        try:
            # XXX Claudio 2021-07-22: craft-parts uses sudo, install it until
            # we adjust it to detect if changing to superuser is needed.
            executor.execute_run(
                [
                    "apt-get",
                    "install",
                    "-y",
                    "sudo",
                ],
                check=True,
                capture_output=True,
            )
        except subprocess.CalledProcessError as error:
            raise bases.BaseConfigurationError(
                brief="Failed to install the required dependencies.",
            ) from error

        try:
            snap_installer.inject_from_host(
                executor=executor, snap_name="charmcraft", classic=True
            )
        except snap_installer.SnapInstallationError as error:
            raise bases.BaseConfigurationError(
                brief="Failed to inject host Charmcraft snap into target environment.",
            ) from error
Beispiel #3
0
    def _setup_charmcraft(self, *, executor: Executor) -> None:
        """Install Charmcraft in target environment.

        On Linux, the default behavior is to inject the host snap into the target
        environment.

        On other platforms, the Charmcraft snap is installed from the Snap Store.

        When installing the snap from the Store, we check if the user specifies a
        channel, using CHARMCRAFT_INSTALL_SNAP_CHANNEL=<channel>.  If unspecified,
        we use the "stable" channel on the default track.

        On Linux, the user may specify this environment variable to force Charmcraft
        to install the snap from the Store rather than inject the host snap.

        :raises BaseConfigurationError: on error.
        """
        snap_channel = get_managed_environment_snap_channel()
        if snap_channel is None and sys.platform != "linux":
            snap_channel = "stable"

        if snap_channel:
            try:
                snap_installer.install_from_store(executor=executor,
                                                  snap_name="charmcraft",
                                                  channel=snap_channel,
                                                  classic=True)
            except snap_installer.SnapInstallationError as error:
                raise bases.BaseConfigurationError(
                    brief="Failed to install Charmcraft snap from store channel "
                    f"{snap_channel!r} into target environment.", ) from error
        else:
            try:
                snap_installer.inject_from_host(executor=executor,
                                                snap_name="charmcraft",
                                                classic=True)
            except snap_installer.SnapInstallationError as error:
                raise bases.BaseConfigurationError(
                    brief=
                    "Failed to inject host Charmcraft snap into target environment.",
                ) from error
Beispiel #4
0
def test_launched_environment_launch_base_configuration_error(
        mock_buildd_base_configuration, mock_multipass_launch, tmp_path):
    error = bases.BaseConfigurationError(brief="fail")
    mock_multipass_launch.side_effect = error
    base = Base(name="ubuntu", channel="20.04", architectures=["host-arch"])
    provider = providers.MultipassProvider()

    with pytest.raises(CommandError, match="fail") as exc_info:
        with provider.launched_environment(
                charm_name="test-charm",
                project_path=tmp_path,
                base=base,
                bases_index=1,
                build_on_index=2,
        ):
            pass

    assert exc_info.value.__cause__ is error