示例#1
0
    def __init__(
        self,
        all_parts: Dict[str, Any],
        *,
        work_dir: pathlib.Path,
        project_dir: pathlib.Path,
        project_name: str,
        ignore_local_sources: List[str],
    ):
        self._all_parts = all_parts.copy()
        self._project_dir = project_dir

        # set the cache dir for parts package management
        cache_dir = BaseDirectory.save_cache_path("charmcraft")

        try:
            self._lcm = LifecycleManager(
                {"parts": all_parts},
                application_name="charmcraft",
                work_dir=work_dir,
                cache_dir=cache_dir,
                ignore_local_sources=ignore_local_sources,
                project_name=project_name,
            )
        except PartsError as err:
            raise CraftError(f"Error bootstrapping lifecycle manager: {err}") from err
示例#2
0
def _do_clean(lf: craft_parts.LifecycleManager, options: argparse.Namespace) -> None:
    if options.plan_only:
        raise ValueError("Clean operations cannot be planned.")

    if not options.parts:
        print("Clean all parts.")

    lf.clean(None, options.parts)
    if _LAYER_DIR.is_dir():
        shutil.rmtree(_LAYER_DIR)
示例#3
0
    def __init__(
        self,
        all_parts: Dict[str, Any],
        *,
        work_dir: pathlib.Path,
        ignore_local_sources: List[str],
    ):
        self._all_parts = all_parts.copy()

        # set the cache dir for parts package management
        cache_dir = BaseDirectory.save_cache_path("charmcraft")

        try:
            self._lcm = LifecycleManager(
                {"parts": all_parts},
                application_name="charmcraft",
                work_dir=work_dir,
                cache_dir=cache_dir,
                ignore_local_sources=ignore_local_sources,
            )
            self._lcm.refresh_packages_list()
        except PartsError as err:
            raise CommandError(err)
示例#4
0
def _do_step(lf: craft_parts.LifecycleManager, options: argparse.Namespace) -> None:
    target_step = _parse_step(options.command) if options.command else Step.PRIME
    part_names = vars(options).get("parts", [])

    if options.update:
        lf.update()

    actions = lf.plan(target_step, part_names)

    if options.plan_only:
        printed = False
        for a in actions:
            if a.type != ActionType.SKIP:
                print(_action_message(a))
                printed = True
        if not printed:
            print("No actions to execute.")
        sys.exit()

    with lf.execution_context() as ctx:
        for a in actions:
            if a.type != ActionType.SKIP:
                print(f"Execute: {_action_message(a)}")
                ctx.execute(a)
示例#5
0
class PartsLifecycle:
    """Create and manage the parts lifecycle."""
    def __init__(
        self,
        all_parts: Dict[str, Any],
        *,
        work_dir: pathlib.Path,
        ignore_local_sources: List[str],
    ):
        self._all_parts = all_parts.copy()

        # set the cache dir for parts package management
        cache_dir = BaseDirectory.save_cache_path("charmcraft")

        try:
            self._lcm = LifecycleManager(
                {"parts": all_parts},
                application_name="charmcraft",
                work_dir=work_dir,
                cache_dir=cache_dir,
                ignore_local_sources=ignore_local_sources,
            )
            self._lcm.refresh_packages_list()
        except PartsError as err:
            raise CommandError(err)

    @property
    def prime_dir(self) -> pathlib.Path:
        """Return the parts prime directory path."""
        return self._lcm.project_info.prime_dir

    def run(self, target_step: Step) -> None:
        """Run the parts lifecycle.

        :param target_step: The final step to execute.
        """
        try:
            # invalidate build if packing a charm and entrypoint changed
            if "charm" in self._all_parts:
                charm_part = self._all_parts["charm"]
                entrypoint = os.path.normpath(charm_part["charm-entrypoint"])
                dis_entrypoint = os.path.normpath(
                    _get_dispatch_entrypoint(self.prime_dir))
                if entrypoint != dis_entrypoint:
                    self._lcm.clean(Step.BUILD, part_names=["charm"])
                    self._lcm.reload_state()

            actions = self._lcm.plan(target_step)
            logger.debug("Parts actions: %s", actions)
            with self._lcm.action_executor() as aex:
                aex.execute(actions)
        except RuntimeError as err:
            raise RuntimeError(
                f"Parts processing internal error: {err}") from err
        except OSError as err:
            msg = err.strerror
            if err.filename:
                msg = f"{err.filename}: {msg}"
            raise CommandError(f"Parts processing error: {msg}") from err
        except Exception as err:
            raise CommandError(f"Parts processing error: {err}") from err
示例#6
0
class PartsLifecycle:
    """Create and manage the parts lifecycle.

    :param all_parts: A dictionary containing the parts defined in the project.
    :param work_dir: The working directory for parts processing.
    :param project_dir: The directory containing the charm project.
    :param ignore_local_sources: A list of local source patterns to be ignored.
    :param name: Charm name as defined in ``metadata.yaml``.
    """

    def __init__(
        self,
        all_parts: Dict[str, Any],
        *,
        work_dir: pathlib.Path,
        project_dir: pathlib.Path,
        project_name: str,
        ignore_local_sources: List[str],
    ):
        self._all_parts = all_parts.copy()
        self._project_dir = project_dir

        # set the cache dir for parts package management
        cache_dir = BaseDirectory.save_cache_path("charmcraft")

        try:
            self._lcm = LifecycleManager(
                {"parts": all_parts},
                application_name="charmcraft",
                work_dir=work_dir,
                cache_dir=cache_dir,
                ignore_local_sources=ignore_local_sources,
                project_name=project_name,
            )
        except PartsError as err:
            raise CraftError(f"Error bootstrapping lifecycle manager: {err}") from err

    @property
    def prime_dir(self) -> pathlib.Path:
        """Return the parts prime directory path."""
        return self._lcm.project_info.prime_dir

    def run(self, target_step: Step) -> None:
        """Run the parts lifecycle.

        :param target_step: The final step to execute.

        :raises CraftError: On error during lifecycle ops.
        :raises RuntimeError: On unexpected error.
        """
        previous_dir = os.getcwd()
        try:
            os.chdir(self._project_dir)

            # invalidate build if packing a charm and entrypoint changed
            if "charm" in self._all_parts:
                charm_part = self._all_parts["charm"]
                if charm_part.get("plugin") == "charm":
                    entrypoint = os.path.normpath(charm_part["charm-entrypoint"])
                    dis_entrypoint = os.path.normpath(_get_dispatch_entrypoint(self.prime_dir))
                    if entrypoint != dis_entrypoint:
                        self._lcm.clean(Step.BUILD, part_names=["charm"])
                        self._lcm.reload_state()

            emit.trace(f"Executing parts lifecycle in {str(self._project_dir)!r}")
            actions = self._lcm.plan(target_step)
            emit.trace(f"Parts actions: {actions}")
            with self._lcm.action_executor() as aex:
                for action in actions:
                    emit.progress(f"Running step {action.step.name} for part {action.part_name!r}")
                    with emit.open_stream("Execute action") as stream:
                        aex.execute([action], stdout=stream, stderr=stream)
        except RuntimeError as err:
            raise RuntimeError(f"Parts processing internal error: {err}") from err
        except OSError as err:
            msg = err.strerror
            if err.filename:
                msg = f"{err.filename}: {msg}"
            raise CraftError(f"Parts processing error: {msg}") from err
        except Exception as err:
            raise CraftError(f"Parts processing error: {err}") from err
        finally:
            os.chdir(previous_dir)