def exports(self, package_name, required_version=None): """ Tests if the given package is exported by this bundle :param package_name: The name of a package :param required_version: The required version/range of this package :return: True if the package is exported by this bundle """ if package_name not in self.all_exports: return False version = Version(self.all_exports[package_name].get('version')) return version.matches(required_version)
def __init__(self, jar_file, manifest): """ Sets up the bundle details :param jar_file: Path to the JAR file (can be empty, but shouldn't) :param manifest: The parsed Manifest of the JAR file (mandatory) :raise ValueError: Invalid manifest argument """ # Validate parameters if not manifest: raise ValueError("Manifest can't be None") # Extract information from the manifest self._manifest = manifest name = self._manifest.get('Bundle-SymbolicName', '').split(';', 2)[0] version = Version(self._manifest.get('Bundle-Version')) # Configure the Artifact Artifact.__init__(self, "java", name, version, jar_file) # Store Package information self.all_exports = \ self._manifest.extract_packages_list('Export-Package') self.all_imports = \ self._manifest.extract_packages_list('Import-Package') self.all_require = \ self._manifest.extract_packages_list('Require-Bundle')
def imports(self, other_bundle): """ Tests if this bundle should imports the given one :return: True if this bundle imports the other one through Require-Bundle or Import-Package """ if other_bundle.name in self.all_require: # Bundle referenced with a Require-Bundle requirement = self.all_require[other_bundle.name] if other_bundle.version.matches(requirement.get('version')): # The given bundle matches our requirements return True # Try with the packages for package in self.all_imports: if package in other_bundle.all_exports: # Get the required version requirement = self.all_imports[package].get('version') # Parse the provided version provided = other_bundle.all_exports[package].get('version') if Version(provided).matches(requirement): return True return False
def load_cache(self): """ Loads the cache from system file to memory """ use_cache = os.environ.get('COHORTE_USE_CACHE') if use_cache and use_cache.lower() == "true": try: with open('cache.js') as input_file: cache = json.load(input_file) if cache: _logger.info("loading repository from cache...") # load modules for module in cache["modules"]: name = module["name"] version = Version(module["version"]) filename = module["filename"] module_bean = Module(name, version, [], filename) self.__add_module(module_bean, self._modules) for directory in cache["directories"]: self._directory_package[directory["dir_name"]] \ = directory["pkg_name"] return True except (IOError, ValueError): # Error reading/parsing cache file return False # No cache return False
def get_exported_packages(self): """ Retrieves a Name -> Version dictionary of the exported packages :return: A Name -> Version dictionary """ return ((name, Version(attributes.get('version'))) for name, attributes in self.all_exports.items())
def _install_bundles(self, bundles): """ Installs & starts the requested bundles, if necessary :param bundles: A list of (name, version) tuples """ # Convert to dictionaries, for easier filtering pre_installed = { bundle.get_symbolic_name(): Version(bundle.get_version()) for bundle in self._context.get_bundles() } to_install = {name: Version(version) for name, version in bundles} for name, installed_version in pre_installed.items(): try: # Check the version of the bundle indicated by components version = to_install[name] if installed_version < version: _logger.warning("Using an older version of %s", name) # No need to install it del to_install[name] except KeyError: # Bundle not used here pass # Install missing bundles new_installed = [] for name in to_install: try: new_installed.append(self._context.install_bundle(name)) _logger.info("Isolate Composer installed bundle %s", name) except pelix.constants.BundleException as ex: _logger.error("Error installing bundle %s: %s", name, ex) # Start installed bundles for bundle in new_installed: try: bundle.start() except pelix.constants.BundleException as ex: _logger.error("Error starting bundle %s: %s", bundle.get_symbolic_name(), ex)
def resolve_installation(self, bundles, system_artifacts=None, system_packages=None): """ Returns all the bundles that must be installed in order to have the given bundles resolved. To simplify the work, the OSGi framework should be the first one in the list. :param bundles: A list of bundles to be resolved :param system_packages: Packages considered available by the framework :return: A tuple: (bundles, dependencies, missing artifacts, missing packages) :raise ValueError: One of the given bundles is unknown """ # Name -> Bundle for this resolution local_bundles = {} # Name -> (Version, Bundle) local_packages = {} # Bundle -> [Bundles] dependencies = {} # Missing elements missing_bundles = set() missing_packages = set() # Consider system packages already installed if system_packages: for name in system_packages: self.__add_package(local_packages, name, Version(None), SYSTEM_BUNDLE) # Consider system bundles already installed if system_artifacts: for artifact in system_artifacts: if isinstance(artifact, Bundle): # Got a bundle self.__add_bundle(artifact, local_bundles, local_packages) elif isinstance(artifact, Artifact): # Got an artifact bundle = self.get_artifact(artifact.name, artifact.version, artifact.file) if bundle: self.__add_bundle(bundle, local_bundles, local_packages) else: _logger.warning("Unknown system bundle: %s", artifact) else: _logger.warning("Unhandled system artifact: %s", artifact) # Resolution loop to_install = [self.get_artifact(name) for name in bundles] i = 0 while i < len(to_install): # Loop control bundle = to_install[i] i += 1 if bundle is None: # Ignore None bundle (system bundle) continue # Add the current bundle self.__add_bundle(bundle, local_bundles, local_packages) dependencies[bundle] = [] # Resolve Require-Bundle for required in bundle.all_require: # Get the required version required_version = bundle.all_require[required].get('version') # Find the bundle registry = None provider = None for registry in (local_bundles, self._bundles): try: provider = self.get_artifact(required, required_version, None, registry) # Found one break except ValueError: # Try next pass else: # No provider found missing_bundles.add(required) continue if provider is SYSTEM_BUNDLE: # Nothing to do with system bundles continue # Store the bundle we found dependencies[bundle].append(provider) if registry is self._bundles: # The provider was found in the global registry, store it self.__add_bundle(provider, local_bundles, local_packages) # The new bundle will be resolved later if provider not in to_install: # We'll have to resolve it to_install.append(provider) # Resolve Import-Package for imported in bundle.all_imports: # Get the required version pkg_version = bundle.all_imports[imported].get('version') # Self-import ? if bundle.exports(imported, pkg_version): # Nothing to do for this package continue # Work only if necessary provider = self.get_package(imported, pkg_version, local_bundles, local_packages) if provider: # Found the package in the resolved bundles if provider is not SYSTEM_BUNDLE: dependencies[bundle].append(provider) else: # Find it provider = self.get_package(imported, pkg_version, self._bundles, self._packages) if not provider: # Missing missing_packages.add(imported) elif provider is not SYSTEM_BUNDLE: # Store the bundle self.__add_bundle(provider, local_bundles, local_packages) # Store the dependency dependencies[bundle].append(provider) if provider not in to_install: # We'll have to resolve it to_install.append(provider) return to_install, dependencies, missing_bundles, missing_packages