def resolve(cls, *args): logger.info('Resolving RPM dependencies ...') import yum y = yum.YumBase() y.setCacheDir(tempfile.mkdtemp()) for pkg in args: if pkg.startswith('@'): y.selectGroup(pkg[1:]) else: try: y.install(y.returnPackageByDep(pkg)) except yum.Errors.YumBaseError: msg = 'Package not found: {pkg}'.format(pkg=pkg) raise exceptions.DependencyException(msg) try: y.resolveDeps() except yum.Errors.PackageSackError as e: # Resolution of Issue 154 raise exceptions.DependencyException('Error resolving RPM dependencies: {0}'.\ format(str(e))) logger.debug('Installing/Updating:') to_install = [] for pkg in y.tsInfo.getMembers(): to_install.append(pkg.po.ui_envra) logger.debug(pkg.po.ui_envra) return to_install
def resolve(cls, *args): logger.info('Resolving RPM dependencies with DNF...') import dnf import hawkey base = dnf.Base() base.conf.cachedir = tempfile.mkdtemp() base.conf.substitutions['releasever'] = platform.linux_distribution( )[1] base.read_all_repos() base.fill_sack(load_system_repo=True, load_available_repos=True) for pkg in (str(arg) for arg in args): if pkg.startswith('@'): base.group_install(pkg[1:]) else: try: res = base.sack.query().available().filter( provides=pkg).run() base.install(str(res[0])) except (hawkey.QueryException, IndexError): msg = 'Package not found: {pkg}'.format(pkg=pkg) raise exceptions.DependencyException(msg) try: base.resolve() except dnf.exceptions.Error as e: raise exceptions.DependencyException( 'Error resolving RPM dependencies with DNF: {0}'.format( utils.exc_as_decoded_string(e))) logger.debug('Installing/Updating:') to_install = [] for pkg in base.transaction.install_set: to_install.append(str(pkg)) logger.debug(str(pkg)) return to_install
def _install_dependencies(self): """Install missing dependencies""" for dep_t, dep_l in self.dependencies.items(): if not dep_l: continue pkg_mgr = self.get_package_manager(dep_t) pkg_mgr.works() to_resolve = [] for dep in dep_l: if not pkg_mgr.is_pkg_installed(dep): to_resolve.append(dep) if not to_resolve: # nothing to install, let's move on continue to_install = pkg_mgr.resolve(*to_resolve) confirm = self._ask_to_confirm(pkg_mgr, *to_install) if not confirm: msg = 'List of packages denied by user, exiting.' logger.error(msg) raise exceptions.DependencyException(msg) type(self).install_lock = True logger.info('Installing dependencies, sit back and relax ...') installed = pkg_mgr.install(*to_install) type(self).install_lock = False if not installed: msg = 'Failed to install dependencies, exiting.' logger.error(msg) raise exceptions.DependencyException(msg) else: logger.info('Successfully installed dependencies!')
def resolve(cls, *deps): """ Return all dependencies which will be installed. Like a portage based implementation it just tries to get the best package available according a given spec. """ import paludis logger.info('[paludis] Resolving dependencies ...') env = paludis.EnvironmentFactory.instance.create('') fltr = paludis.Filter.And(paludis.Filter.SupportsInstallAction(), paludis.Filter.NotMasked()) to_install = set() for dep in deps: ds = paludis.parse_user_package_dep_spec(dep, env, paludis.UserPackageDepSpecOptions()) gen = paludis.Generator.Matches(ds, paludis.MatchPackageOptions()) fg = paludis.FilteredGenerator(gen, fltr) s = paludis.Selection.BestVersionOnly(fg) _to_install = set() for pkg in env[s]: _to_install.add(str(pkg)) if _to_install: to_install += _to_install else: msg = 'Package not found: {pkg}'.format(pkg=dep) raise exceptions.DependencyException(msg) cls.throw_package_list(list(to_install))
def resolve(cls, *deps): """ Return all dependencies which will be installed. NOTE Simplified (naive) implementation will show the list of correctly spelled packages to be installed. For example 'firefox' will be resolved to 'www-client/firefox-25.0.1'... TODO ... or maybe version part must be stripped? """ import portage logger.info('[portage] Resolving dependencies ...') porttree = portage.db[portage.root]['porttree'] to_install = set() for dep in deps: res = porttree.dep_bestmatch(dep) logger.debug('{0} resolved to {1}'.format(repr(dep), repr(res))) if res: to_install.add(res) else: msg = 'Package not found or spec is invalid: {pkg}'.format(pkg=dep) raise exceptions.DependencyException(msg) cls.throw_package_list(list(to_install))
def resolve(cls, *args): # TODO: we may need to rewrite this for e.g. suse, which # is rpm based, but doesn't use yum; same for install()/is_available()/can_operate() logger.info('Resolving RPM dependencies ...') import yum y = yum.YumBase() y.setCacheDir(tempfile.mkdtemp()) for pkg in args: if pkg.startswith('@'): y.selectGroup(pkg[1:]) else: try: y.install(y.returnPackageByDep(pkg)) except yum.Errors.YumBaseError: msg = 'Package not found: {pkg}'.format(pkg=pkg) logger.error(msg) raise exceptions.DependencyException(msg) y.resolveDeps() logger.debug('Installing/Updating:') to_install = [] for pkg in y.tsInfo.getMembers(): to_install.append(pkg.po.ui_envra) logger.debug(pkg.po.ui_envra) return to_install
def _install_dependencies(self, ui, debug): """Install missing dependencies""" for dep_t, dep_l in self.dependencies: if not dep_l: continue pkg_mgr = self.get_package_manager(dep_t) pkg_mgr.works() to_resolve = [] for dep in dep_l: if not pkg_mgr.is_pkg_installed(dep): to_resolve.append(dep) if not to_resolve: # nothing to install, let's move on continue to_install = pkg_mgr.resolve(*to_resolve) confirm = self._ask_to_confirm(ui, pkg_mgr, *to_install) if not confirm: msg = 'List of packages denied by user, exiting.' raise exceptions.DependencyException(msg) type(self).install_lock = True # TODO: we should do this more systematically (send signal to cl/gui?) logger.info('Installing dependencies, sit back and relax ...', extra={'event_type': 'dep_installation_start'}) if ui == 'cli' and not debug: # TODO: maybe let every manager to decide when to start event = threading.Event() t = EndlessProgressThread(event) t.start() installed = pkg_mgr.install(*to_install) if ui == 'cli' and not debug: event.set() t.join() if installed: logger.info(' Done.') else: logger.error(' Failed.') type(self).install_lock = False log_extra = {'event_type': 'dep_installation_end'} if not installed: msg = 'Failed to install dependencies, exiting.' logger.error(msg, extra=log_extra) raise exceptions.DependencyException(msg) else: logger.info('Successfully installed dependencies!', extra=log_extra)
def is_pkg_installed(cls, pkg): """Is a package managed by this manager installed?""" import portage # Get access to installed packages DB vartree = portage.db[portage.root]['vartree'] try: r = vartree.dbapi.match(pkg) logger.debug('Checking is installed: {0} -> {1}'.format(pkg, repr(r))) except portage.exception.InvalidAtom: raise exceptions.DependencyException('Invalid dependency specification: {0}'.\ format(pkg)) # TODO Compare package version! return bool(r)
def is_pkg_installed(cls, dep): """Is a package managed by this manager installed?""" import paludis env = paludis.EnvironmentFactory.instance.create('') installed = env.fetch_repository('installed') try: pkg = paludis.parse_user_package_dep_spec(dep, env, paludis.UserPackageDepSpecOptions()) # TODO Compare package version! r = [] for i in installed.package_ids(str(pkg.package), []): r.append(str(i)) logger.debug('Checking is installed: {0} -> {1}'.format(pkg, repr(r))) return r except paludis.BaseException as e: msg = 'Dependency specification is invalid [{0}]: {1}'.format(dep, str(e)) raise exceptions.DependencyException(msg)
def throw_package_list(cls, to_install): assert(isinstance(to_install, list)) _list = ', '.join(to_install) raise exceptions.DependencyException( 'You must install the following packages before run this command: {0}'.format(_list) )