Пример #1
0
    def reset(self,
              name: str,
              force: bool = False,
              skip_host_plugins: bool = False):
        """ Reset package to defaults version

        Args:
            name: SONiC Package name.
            force: Force the installation.
            skip_host_plugins: Skip host plugins installation.
        Raises:
            PackageManagerError
        """

        with failure_ignore(force):
            if not self.is_installed(name):
                raise PackageManagerError(f'{name} is not installed')

        package = self.get_installed_package(name)
        default_reference = package.entry.default_reference
        if default_reference is None:
            raise PackageManagerError(
                f'package {name} has no default reference')

        package_ref = PackageReference(name, default_reference)
        source = self.get_package_source(package_ref=package_ref)
        self.upgrade_from_source(source,
                                 force=force,
                                 allow_downgrade=True,
                                 skip_host_plugins=skip_host_plugins)
Пример #2
0
def changelog(ctx,
              package_expr,
              from_repository,
              from_tarball):
    """ Show package changelog. """

    manager: PackageManager = ctx.obj

    try:
        source = manager.get_package_source(package_expr,
                                            from_repository,
                                            from_tarball)
        package = source.get_package()
        changelog = package.manifest['package']['changelog']

        if not changelog:
            raise PackageManagerError(f'No changelog for package {package.name}')

        for version, entry in changelog.items():
            author = entry.get('author') or 'N/A'
            email = entry.get('email') or 'N/A'
            changes = entry.get('changes') or []
            date = entry.get('date') or 'N/A'
            click.secho(f'{version}:\n', fg='green', bold=True)
            for line in changes:
                click.secho(f'    {BULLET_UC} {line}', bold=True)
            click.secho(f'\n        {author} '
                        f'({email}) {date}', fg='green', bold=True)
            click.secho('')

    except Exception as err:
        exit_cli(f'Failed to print package changelog: {err}', fg='red')
Пример #3
0
 def wrapped_function(*args, **kwargs):
     sig = signature(func)
     unsupported_opts = [opt for opt in kwargs if opt not in sig.parameters]
     if unsupported_opts:
         raise PackageManagerError(
             f'Unsupported options {unsupported_opts} for {func.__name__}')
     return func(*args, **kwargs)
Пример #4
0
 def _get_cli_plugin_path(cls, package: Package, command):
     pkg_loader = pkgutil.get_loader(f'{command}.plugins')
     if pkg_loader is None:
         raise PackageManagerError(
             f'Failed to get plugins path for {command} CLI')
     plugins_pkg_path = os.path.dirname(pkg_loader.path)
     return os.path.join(plugins_pkg_path,
                         cls._get_cli_plugin_name(package))
Пример #5
0
    def get_package_source(self,
                           package_expression: Optional[str] = None,
                           repository_reference: Optional[str] = None,
                           tarboll_path: Optional[str] = None,
                           package_ref: Optional[PackageReference] = None):
        """ Returns PackageSource object based on input source.

        Args:
             package_expression: SONiC Package expression string
             repository_reference: Install from REPO[:TAG][@DIGEST]
             tarboll_path: Install from image tarball
             package_ref: Package reference object
        Returns:
            SONiC Package object.
         Raises:
             ValueError if no source specified.
        """

        if package_expression:
            ref = parse_reference_expression(package_expression)
            return self.get_package_source(package_ref=ref)
        elif repository_reference:
            repo_ref = utils.DockerReference.parse(repository_reference)
            repository = repo_ref['name']
            reference = repo_ref['tag'] or repo_ref['digest']
            reference = reference or 'latest'
            return RegistrySource(repository, reference, self.database,
                                  self.docker, self.metadata_resolver)
        elif tarboll_path:
            return TarballSource(tarboll_path, self.database, self.docker,
                                 self.metadata_resolver)
        elif package_ref:
            package_entry = self.database.get_package(package_ref.name)

            # Determine the reference if not specified.
            # If package is installed assume the installed
            # one is requested, otherwise look for default
            # reference defined for this package. In case package
            # does not have a default reference raise an error.
            if package_ref.reference is None:
                if package_entry.installed:
                    return LocalSource(package_entry, self.database,
                                       self.docker, self.metadata_resolver)
                if package_entry.default_reference is not None:
                    package_ref.reference = package_entry.default_reference
                else:
                    raise PackageManagerError(
                        'No default reference tag. '
                        'Please specify the version or tag explicitly')

            return RegistrySource(package_entry.repository,
                                  package_ref.reference, self.database,
                                  self.docker, self.metadata_resolver)
        else:
            raise ValueError('No package source provided')
Пример #6
0
    def remove_package(self, name: str):
        """ Removes package entry from database.

        Args:
            name: repository name.
        Raises:
            PackageNotFoundError: Raises when package with the given name does not exist
                                  in the database.
        """

        pkg = self.get_package(name)

        if pkg.built_in:
            raise PackageManagerError(
                f'Package {name} is built-in, cannot remove it')

        if pkg.installed:
            raise PackageManagerError(
                f'Package {name} is installed, uninstall it first')

        self._database.pop(name)
Пример #7
0
def package_constraint_to_reference(constraint: PackageConstraint) -> PackageReference:
    package_name, version_constraint = constraint.name, constraint.constraint
    # Allow only specific version for now.
    # Later we can improve package manager to support
    # installing packages using expressions like 'package>1.0.0'
    if version_constraint == VersionRange():  # empty range means any version
        return PackageReference(package_name, None)
    if not isinstance(version_constraint, Version):
        raise PackageManagerError(f'Can only install specific version. '
                                  f'Use only following expression "{package_name}=<version>" '
                                  f'to install specific version')
    return PackageReference(package_name, version_to_tag(version_constraint))
Пример #8
0
def get_cli_plugin_directory(command: str) -> str:
    """ Returns a plugins package directory for command group.

    Args:
        command: SONiC command: "show"/"config"/"clear".
    Returns:
        Path to plugins package directory.
    """

    pkg_loader = pkgutil.get_loader(f'{command}.plugins')
    if pkg_loader is None:
        raise PackageManagerError(
            f'Failed to get plugins path for {command} CLI')
    plugins_pkg_path = os.path.dirname(pkg_loader.path)
    return plugins_pkg_path
Пример #9
0
def package_constraint_to_reference(
        constraint: PackageConstraint) -> PackageReference:
    package_name, version_constraint = constraint.name, constraint.constraint
    # Allow only specific version for now.
    # Later we can improve package manager to support
    # installing packages using expressions like 'package>1.0.0'
    if version_constraint.expression == '*':
        return PackageReference(package_name, None)
    if not version_constraint.is_exact():
        raise PackageManagerError(
            f'Can only install specific version. '
            f'Use only following expression "{package_name}=<version>" '
            f'to install specific version')
    version = version_constraint.get_exact_version()
    return PackageReference(package_name, version_to_tag(version))
Пример #10
0
def validate_package_cli_can_be_skipped(package: Package, skip: bool):
    """ Checks whether package CLI installation can be skipped.

    Args:
        package: Package to validate
        skip: Whether to skip installing CLI

    Raises:
        PackageManagerError

    """

    if package.manifest['cli']['mandatory'] and skip:
        raise PackageManagerError(f'CLI is mandatory for package {package.name} '
                                  f'but it was requested to be not installed')
    elif skip:
        log.warning(f'Package {package.name} CLI plugin will not be installed')