1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Package Manager Client Dependency handling Interface}.
10
11 """
12 from __future__ import with_statement
13 from entropy.misc import Lifo
14 from entropy.const import *
15 from entropy.exceptions import *
16 from entropy.output import bold, darkgreen, darkred, blue, red
17 from entropy.i18n import _
18
20
22
23 if dbconn == None:
24 dbconn = self.clientDbconn
25
26 installed_packages = dbconn.listAllIdpackages()
27
28 pdepend_id = etpConst['spm']['pdepend_id']
29 deps_not_matched = set()
30
31 length = len(installed_packages)
32 count = 0
33 for idpackage in installed_packages:
34 count += 1
35
36 if (count%150 == 0) or (count == length) or (count == 1):
37 atom = dbconn.retrieveAtom(idpackage)
38 self.updateProgress(
39 darkgreen(_("Checking %s") % (bold(atom),)),
40 importance = 0,
41 type = "info",
42 back = True,
43 count = (count,length),
44 header = darkred(" @@ ")
45 )
46
47 xdeps = dbconn.retrieveDependencies(idpackage,
48 exclude_deptypes = (pdepend_id,))
49 needed_deps = [(x,dbconn.atomMatch(x),) for x in xdeps]
50 deps_not_matched |= set([x for x,(y,z,) in needed_deps if y == -1])
51
52 return deps_not_matched
53
69
71
72 packageInformation = {}
73 versionInformation = {}
74
75
76 tbz2repos = [x for x in results if x.endswith(etpConst['packagesext'])]
77 if tbz2repos:
78 del tbz2repos
79 newrepos = results.copy()
80 for x in newrepos:
81 if x.endswith(etpConst['packagesext']):
82 continue
83 del results[x]
84
85 version_duplicates = set()
86 versions = set()
87 for repo in results:
88 packageInformation[repo] = {}
89 if extended_results:
90 version = results[repo][1]
91 packageInformation[repo]['versiontag'] = results[repo][2]
92 packageInformation[repo]['revision'] = results[repo][3]
93 else:
94 dbconn = self.__atom_match_open_db(repo, server_inst)
95 packageInformation[repo]['versiontag'] = dbconn.retrieveVersionTag(results[repo])
96 packageInformation[repo]['revision'] = dbconn.retrieveRevision(results[repo])
97 version = dbconn.retrieveVersion(results[repo])
98 packageInformation[repo]['version'] = version
99 versionInformation[version] = repo
100 if version in versions:
101 version_duplicates.add(version)
102 versions.add(version)
103
104 newerVersion = self.entropyTools.get_newer_version(list(versions))[0]
105
106 if (not version_duplicates) or (newerVersion not in version_duplicates):
107 reponame = versionInformation.get(newerVersion)
108 return (results[reponame],reponame)
109
110
111
112
113 conflictingEntries = {}
114 tags_duplicates = set()
115 tags = set()
116 tagsInfo = {}
117 for repo in packageInformation:
118 if packageInformation[repo]['version'] != newerVersion:
119 continue
120 conflictingEntries[repo] = {}
121 versiontag = packageInformation[repo]['versiontag']
122 if versiontag in tags:
123 tags_duplicates.add(versiontag)
124 tags.add(versiontag)
125 tagsInfo[versiontag] = repo
126 conflictingEntries[repo]['versiontag'] = versiontag
127 conflictingEntries[repo]['revision'] = packageInformation[repo]['revision']
128
129
130 newerTag = sorted(list(tags), reverse = True)[0]
131 if newerTag not in tags_duplicates:
132 reponame = tagsInfo.get(newerTag)
133 return (results[reponame],reponame)
134
135
136
137
138 conflictingRevisions = {}
139 revisions = set()
140 revisions_duplicates = set()
141 revisionInfo = {}
142 for repo in conflictingEntries:
143 if conflictingEntries[repo]['versiontag'] == newerTag:
144 conflictingRevisions[repo] = {}
145 versionrev = conflictingEntries[repo]['revision']
146 if versionrev in revisions:
147 revisions_duplicates.add(versionrev)
148 revisions.add(versionrev)
149 revisionInfo[versionrev] = repo
150 conflictingRevisions[repo]['revision'] = versionrev
151
152 newerRevision = max(revisions)
153 if newerRevision not in revisions_duplicates:
154 reponame = revisionInfo.get(newerRevision)
155 return (results[reponame],reponame)
156
157
158
159
160 for reponame in valid_repos:
161 if reponame in conflictingRevisions:
162 return (results[reponame],reponame)
163
165
166 data, rc = cached_obj
167 if rc == 1: return cached_obj
168
169 if multiRepo or multiMatch:
170 matches = data
171 if extendedResults:
172
173 matches = [(x[0][0],x[1],) for x in data]
174 for m_id, m_repo in matches:
175 m_db = self.__atom_match_open_db(m_repo, server_inst)
176 if not m_db.isIdpackageAvailable(m_id):
177 return None
178 else:
179 m_id, m_repo = cached_obj
180 if extendedResults:
181
182 m_id, m_repo = cached_obj[0][0],cached_obj[1]
183 m_db = self.__atom_match_open_db(m_repo, server_inst)
184 if not m_db.isIdpackageAvailable(m_id):
185 return None
186
187 return cached_obj
188
190 if server_inst != None:
191 dbconn = server_inst.open_server_repository(just_reading = True,
192 repo = repoid, do_treeupdates = False)
193 else:
194 dbconn = self.open_repository(repoid)
195 return dbconn
196
197 - def atom_match(self, atom, caseSensitive = True, matchSlot = None,
198 matchTag = None, packagesFilter = True,
199 multiMatch = False, multiRepo = False, matchRevision = None,
200 matchRepo = None, server_repos = [], serverInstance = None,
201 extendedResults = False, useCache = True):
202
203
204
205 atom, repos = self.entropyTools.dep_get_match_in_repos(atom)
206 if (matchRepo == None) and (repos != None):
207 matchRepo = repos
208
209 u_hash = ""
210 k_ms = "//"
211 k_mt = "@#@"
212 k_mr = "-1"
213 if isinstance(matchRepo,(list,tuple,set,)):
214 u_hash = hash(frozenset(matchRepo))
215 if isinstance(matchSlot,basestring):
216 k_ms = matchSlot
217 if isinstance(matchTag,basestring):
218 k_mt = matchTag
219 if isinstance(matchRevision,basestring):
220 k_mr = matchRevision
221
222 c_hash = "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s" % (
223 atom,k_ms,k_mt,hash(packagesFilter),
224 hash(frozenset(self.validRepositories)),
225 hash(frozenset(self.SystemSettings['repositories']['available'])),
226 hash(multiMatch),hash(multiRepo),hash(caseSensitive),
227 k_mr,hash(extendedResults),
228 u_hash,
229 )
230 c_hash = "%s%s" % (self.atomMatchCacheKey,hash(c_hash),)
231
232 if self.xcache and useCache:
233 cached = self.Cacher.pop(c_hash)
234 if cached != None:
235 try:
236 cached = self.__validate_atom_match_cache(cached, multiMatch, extendedResults, multiRepo, serverInstance)
237 except (TypeError,ValueError,IndexError,KeyError,):
238 cached = None
239 if cached != None:
240 return cached
241
242 if server_repos:
243 if not serverInstance:
244 t = _("server_repos needs serverInstance")
245 raise IncorrectParameter("IncorrectParameter: %s" % (t,))
246 valid_repos = server_repos[:]
247 else:
248 valid_repos = self.validRepositories
249 if matchRepo and (type(matchRepo) in (list,tuple,set)):
250 valid_repos = list(matchRepo)
251
252 repoResults = {}
253 for repo in valid_repos:
254
255
256 dbconn = self.__atom_match_open_db(repo, serverInstance)
257 use_cache = useCache
258 while 1:
259 try:
260 query_data, query_rc = dbconn.atomMatch(
261 atom,
262 caseSensitive = caseSensitive,
263 matchSlot = matchSlot,
264 matchTag = matchTag,
265 packagesFilter = packagesFilter,
266 matchRevision = matchRevision,
267 extendedResults = extendedResults,
268 useCache = use_cache
269 )
270 if query_rc == 0:
271
272 if extendedResults:
273 repoResults[repo] = (query_data[0],query_data[2],query_data[3],query_data[4])
274 else:
275 repoResults[repo] = query_data
276 except TypeError:
277 if not use_cache:
278 raise
279 use_cache = False
280 continue
281 except dbconn.dbapi2.OperationalError:
282
283 break
284 break
285
286 dbpkginfo = (-1,1)
287 if extendedResults:
288 dbpkginfo = ((-1,None,None,None),1)
289
290 if multiRepo and repoResults:
291
292 data = set()
293 for repoid in repoResults:
294 data.add((repoResults[repoid],repoid))
295 dbpkginfo = (data,0)
296
297 elif len(repoResults) == 1:
298
299 repo = repoResults.keys()[0]
300 dbpkginfo = (repoResults[repo],repo)
301
302 elif len(repoResults) > 1:
303
304
305 mypkginfo = self.__handle_multi_repo_matches(repoResults, extendedResults, valid_repos, serverInstance)
306 if mypkginfo != None: dbpkginfo = mypkginfo
307
308
309 if multiMatch:
310
311 if dbpkginfo[1] == 1:
312 dbpkginfo = (set(), 1)
313 else:
314 if multiRepo:
315 data = set()
316 for q_id,q_repo in dbpkginfo[0]:
317 dbconn = self.__atom_match_open_db(q_repo, serverInstance)
318 query_data, query_rc = dbconn.atomMatch(
319 atom,
320 caseSensitive = caseSensitive,
321 matchSlot = matchSlot,
322 matchTag = matchTag,
323 packagesFilter = packagesFilter,
324 multiMatch = True,
325 extendedResults = extendedResults
326 )
327 if extendedResults:
328 for item in query_data:
329 data.add(((item[0],item[2],item[3],item[4]),q_repo))
330 else:
331 for x in query_data: data.add((x,q_repo))
332 dbpkginfo = (data,0)
333 else:
334 dbconn = self.__atom_match_open_db(dbpkginfo[1], serverInstance)
335 query_data, query_rc = dbconn.atomMatch(
336 atom,
337 caseSensitive = caseSensitive,
338 matchSlot = matchSlot,
339 matchTag = matchTag,
340 packagesFilter = packagesFilter,
341 multiMatch = True,
342 extendedResults = extendedResults
343 )
344 if extendedResults:
345 dbpkginfo = (set([((x[0],x[2],x[3],x[4]),dbpkginfo[1]) for x in query_data]),0)
346 else:
347 dbpkginfo = (set([(x,dbpkginfo[1]) for x in query_data]),0)
348
349 if self.xcache and useCache:
350 self.Cacher.push(c_hash,dbpkginfo)
351
352 return dbpkginfo
353
354
356 new_packages = []
357
358 for pkg_id in range(len(packages)):
359 package = packages[pkg_id]
360
361
362 if package.startswith(etpConst['packagesetprefix']):
363 set_pkgs = sorted(list(self.package_set_expand(package, raise_exceptions = False)))
364 new_packages.extend([x for x in set_pkgs if x not in packages])
365 else:
366 new_packages.append(package)
367
368 return new_packages
369
371
372 max_recursion_level = 50
373 recursion_level = 0
374
375 def do_expand(myset, recursion_level, max_recursion_level):
376 recursion_level += 1
377 if recursion_level > max_recursion_level:
378 raise InvalidPackageSet('InvalidPackageSet: corrupted, too many recursions: %s' % (myset,))
379 set_data, set_rc = self.package_set_match(myset[len(etpConst['packagesetprefix']):])
380 if not set_rc:
381 raise InvalidPackageSet('InvalidPackageSet: not found: %s' % (myset,))
382 (set_from, package_set, mydata,) = set_data
383
384 mypkgs = set()
385 for fset in mydata:
386 if fset.startswith(etpConst['packagesetprefix']):
387 mypkgs |= do_expand(fset, recursion_level, max_recursion_level)
388 else:
389 mypkgs.add(fset)
390
391 return mypkgs
392
393 if not package_set.startswith(etpConst['packagesetprefix']):
394 package_set = "%s%s" % (etpConst['packagesetprefix'],package_set,)
395
396 try:
397 mylist = do_expand(package_set, recursion_level, max_recursion_level)
398 except InvalidPackageSet:
399 if raise_exceptions: raise
400 mylist = set()
401
402 return mylist
403
404 - def package_set_list(self, server_repos = [], serverInstance = None, matchRepo = None):
405 return self.package_set_match('', matchRepo = matchRepo, server_repos = server_repos, serverInstance = serverInstance, search = True)[0]
406
407 - def package_set_search(self, package_set, server_repos = [], serverInstance = None, matchRepo = None):
408
409 if package_set == '*': package_set = ''
410 return self.package_set_match(package_set, matchRepo = matchRepo, server_repos = server_repos, serverInstance = serverInstance, search = True)[0]
411
418
419 - def package_set_match(self, package_set, multiMatch = False,
420 matchRepo = None, server_repos = [], serverInstance = None,
421 search = False):
422
423
424
425 package_set, repos = self.entropyTools.dep_get_match_in_repos(
426 package_set)
427 if (matchRepo == None) and (repos != None):
428 matchRepo = repos
429
430 if server_repos:
431 if not serverInstance:
432 t = _("server_repos needs serverInstance")
433 raise IncorrectParameter("IncorrectParameter: %s" % (t,))
434 valid_repos = server_repos[:]
435 else:
436 valid_repos = self.validRepositories
437
438 if matchRepo and (type(matchRepo) in (list,tuple,set)):
439 valid_repos = list(matchRepo)
440
441
442 if search: multiMatch = True
443
444 set_data = []
445
446 while 1:
447
448
449 if not server_repos:
450 sys_pkgsets = self.SystemSettings['system_package_sets']
451 if search:
452 mysets = [x for x in sys_pkgsets.keys() if \
453 (x.find(package_set) != -1)]
454 for myset in mysets:
455 mydata = sys_pkgsets.get(myset)
456 set_data.append((etpConst['userpackagesetsid'],
457 unicode(myset), mydata.copy(),))
458 else:
459 mydata = sys_pkgsets.get(package_set)
460 if mydata is not None:
461 set_data.append((etpConst['userpackagesetsid'],
462 unicode(package_set), mydata,))
463 if not multiMatch:
464 break
465
466 for repoid in valid_repos:
467 dbconn = self.__package_set_match_open_db(repoid,
468 serverInstance)
469 if search:
470 mysets = dbconn.searchSets(package_set)
471 for myset in mysets:
472 mydata = dbconn.retrievePackageSet(myset)
473 set_data.append((repoid, myset, mydata.copy(),))
474 else:
475 mydata = dbconn.retrievePackageSet(package_set)
476 if mydata:
477 set_data.append((repoid, package_set, mydata,))
478 if not multiMatch:
479 break
480
481 break
482
483 if not set_data:
484 return (),False
485
486 if multiMatch:
487 return set_data,True
488
489 return set_data.pop(0),True
490
492
493 if self.xcache:
494 c_data = sorted(dependencies)
495 client_checksum = self.clientDbconn.checksum()
496 c_hash = hash("%s|%s|%s" % (c_data,deep_deps,client_checksum,))
497 c_hash = "%s%s" % (etpCache['filter_satisfied_deps'],c_hash,)
498 cached = self.Cacher.pop(c_hash)
499 if cached != None: return cached
500
501 const_debug_write(__name__,
502 "get_unsatisfied_dependencies (not cached, deep: %s) for => %s" % (
503 deep_deps, dependencies,))
504
505 if not isinstance(depcache,dict):
506 depcache = {}
507
508
509
510 satisfied_kw = '__%s__satisfied_ids' % (__name__,)
511 satisfied_data = self.SystemSettings.get(satisfied_kw)
512 if satisfied_data is None:
513 satisfied_list = self.SystemSettings['satisfied']
514 tmp_satisfied_data = set()
515 for atom in satisfied_list:
516 matches, m_res = self.atom_match(atom, multiMatch = True,
517 packagesFilter = False, multiRepo = True)
518 if m_res == 0:
519 tmp_satisfied_data |= matches
520 satisfied_data = tmp_satisfied_data
521 self.SystemSettings[satisfied_kw] = satisfied_data
522
523 cdb_am = self.clientDbconn.atomMatch
524 am = self.atom_match
525 open_repo = self.open_repository
526 intf_error = self.dbapi2.InterfaceError
527 cdb_getversioning = self.clientDbconn.getVersioningData
528 etp_cmp = self.entropyTools.entropy_compare_versions
529 etp_get_rev = self.entropyTools.dep_get_entropy_revision
530
531 def fm_dep(dependency):
532
533 cached = depcache.get(dependency)
534 if cached != None:
535 const_debug_write(__name__,
536 "get_unsatisfied_dependencies control cached for => %s" % (
537 dependency,))
538 const_debug_write(__name__, "...")
539 return cached
540
541
542 if dependency.startswith("!"):
543 idpackage,rc = cdb_am(dependency[1:])
544 if idpackage != -1:
545 depcache[dependency] = dependency
546 const_debug_write(__name__,
547 "get_unsatisfied_dependencies conflict not found on system for => %s" % (
548 dependency,))
549 const_debug_write(__name__, "...")
550 return dependency
551 depcache[dependency] = 0
552 const_debug_write(__name__, "...")
553 return 0
554
555 c_ids, c_rc = cdb_am(dependency, multiMatch = True)
556 if c_rc != 0:
557 depcache[dependency] = dependency
558 const_debug_write(__name__,
559 "get_unsatisfied_dependencies not satisfied on system for => %s" % (
560 dependency,))
561 const_debug_write(__name__, "...")
562 return dependency
563
564 r_id, r_repo = am(dependency)
565 if r_id == -1:
566 depcache[dependency] = dependency
567 const_debug_write(__name__,
568 "get_unsatisfied_dependencies repository match not found for => %s" % (
569 dependency,))
570 const_debug_write(__name__, "...")
571 return dependency
572
573
574
575 if (r_id, r_repo,) in satisfied_data:
576 return 0
577
578 dbconn = open_repo(r_repo)
579 try:
580 repo_pkgver, repo_pkgtag, repo_pkgrev = dbconn.getVersioningData(r_id)
581 except (intf_error,TypeError,):
582
583 const_debug_write(__name__,
584 "get_unsatisfied_dependencies repository entry broken for match => %s" % (
585 (r_id, r_repo),))
586 const_debug_write(__name__, "...")
587 return dependency
588
589 client_data = set()
590 for c_id in c_ids:
591 try:
592 installedVer, installedTag, installedRev = cdb_getversioning(c_id)
593 except TypeError:
594 installedVer = "0"
595 installedTag = ''
596 installedRev = 0
597 client_data.add((installedVer, installedTag, installedRev,))
598
599
600
601 do_deep = deep_deps
602 if not do_deep:
603 string_rev = etp_get_rev(dependency)
604 if string_rev == -1:
605 do_deep = True
606
607
608
609 for installedVer, installedTag, installedRev in client_data:
610 vcmp = etp_cmp((repo_pkgver,repo_pkgtag,repo_pkgrev,),
611 (installedVer,installedTag,installedRev,))
612 if vcmp == 0:
613 const_debug_write(__name__,
614 "get_unsatisfied_dependencies SATISFIED equals (not cached, deep: %s) => %s" % (
615 deep_deps, dependency,))
616 depcache[dependency] = 0
617 const_debug_write(__name__, "...")
618 return 0
619 ver_tag_repo = (repo_pkgver, repo_pkgtag,)
620 ver_tag_inst = (installedVer, installedTag,)
621 rev_match = repo_pkgrev != installedRev
622
623 if not do_deep and (ver_tag_repo == ver_tag_inst) and rev_match:
624
625 depcache[dependency] = 0
626 const_debug_write(__name__,
627 "get_unsatisfied_dependencies SATISFIED w/o rev (not cached, deep: %s) => %s" % (
628 deep_deps, dependency,))
629 const_debug_write(__name__, "...")
630 return 0
631
632
633 const_debug_write(__name__,
634 "get_unsatisfied_dependencies NOT SATISFIED (not cached, deep: %s) => %s" % (
635 deep_deps, dependency,))
636
637 depcache[dependency] = dependency
638 const_debug_write(__name__, "...")
639 return dependency
640
641 unsatisfied = map(fm_dep,dependencies)
642 unsatisfied = set([x for x in unsatisfied if x != 0])
643
644 if self.xcache:
645 self.Cacher.push(c_hash,unsatisfied)
646
647 return unsatisfied
648
650
651 if not isinstance(matchfilter,set):
652 matchfilter = set()
653
654 maskedtree = {}
655 mybuffer = Lifo()
656 depcache = set()
657 treelevel = -1
658
659 match_id, match_repo = match
660
661 mydbconn = self.open_repository(match_repo)
662 myatom = mydbconn.retrieveAtom(match_id)
663 idpackage, idreason = mydbconn.idpackageValidator(match_id)
664 if idpackage == -1:
665 treelevel += 1
666 if atoms:
667 mydict = {myatom: idreason,}
668 else:
669 mydict = {match: idreason,}
670 if flat:
671 maskedtree.update(mydict)
672 else:
673 maskedtree[treelevel] = mydict
674
675 mydeps = mydbconn.retrieveDependencies(match_id)
676 for mydep in mydeps: mybuffer.push(mydep)
677 try:
678 mydep = mybuffer.pop()
679 except ValueError:
680 mydep = None
681
682 open_db = self.open_repository
683 am = self.atom_match
684 while mydep:
685
686 if mydep in depcache:
687 try:
688 mydep = mybuffer.pop()
689 except ValueError:
690 break
691 continue
692 depcache.add(mydep)
693
694 idpackage, repoid = am(mydep)
695 if (idpackage, repoid) in matchfilter:
696 try:
697 mydep = mybuffer.pop()
698 except ValueError:
699 break
700 continue
701
702 if idpackage != -1:
703
704
705 matchfilter.add((idpackage, repoid))
706
707
708 if idpackage == -1:
709 idpackage, repoid = am(mydep, packagesFilter = False)
710 if idpackage != -1:
711 treelevel += 1
712 if not maskedtree.has_key(treelevel) and not flat:
713 maskedtree[treelevel] = {}
714 dbconn = open_db(repoid)
715 vidpackage, idreason = dbconn.idpackageValidator(idpackage)
716 if atoms:
717 mydict = {dbconn.retrieveAtom(idpackage): idreason}
718 else:
719 mydict = {(idpackage,repoid): idreason}
720 if flat: maskedtree.update(mydict)
721 else: maskedtree[treelevel].update(mydict)
722
723
724 if idpackage != -1:
725 matchfilter.add((idpackage, repoid))
726 dbconn = open_db(repoid)
727 owndeps = dbconn.retrieveDependencies(idpackage)
728 for owndep in owndeps:
729 mybuffer.push(owndep)
730
731 try:
732 mydep = mybuffer.pop()
733 except ValueError:
734 break
735
736 return maskedtree
737
738
739 - def generate_dependency_tree(self,
740 matched_atom, empty_deps = False, deep_deps = False, matchfilter = None,
741 flat = False, filter_unsat_cache = None, treecache = None, keyslotcache = None):
742
743 if not isinstance(matchfilter,set):
744 matchfilter = set()
745 if not isinstance(filter_unsat_cache,dict):
746 filter_unsat_cache = {}
747 if not isinstance(treecache,set):
748 treecache = set()
749 if not isinstance(keyslotcache,set):
750 keyslotcache = set()
751
752 mydbconn = self.open_repository(matched_atom[1])
753 myatom = mydbconn.retrieveAtom(matched_atom[0])
754
755
756
757 deps_not_found = set()
758 conflicts = set()
759
760 mydep = (1,myatom)
761 mybuffer = Lifo()
762 deptree = set()
763 if matched_atom not in matchfilter:
764 deptree.add((1,matched_atom))
765
766 virgin = True
767 open_repo = self.open_repository
768 atom_match = self.atom_match
769 cdb_atom_match = self.clientDbconn.atomMatch
770 lookup_conflict_replacement = self._lookup_conflict_replacement
771 lookup_library_breakages = self._lookup_library_breakages
772 lookup_inverse_dependencies = self._lookup_inverse_dependencies
773 get_unsatisfied_deps = self.get_unsatisfied_dependencies
774
775 def my_dep_filter(x):
776 if x in treecache: return False
777 if tuple(x.split(":")) in keyslotcache: return False
778 return True
779
780 while mydep:
781
782 const_debug_write(__name__,
783 "generate_dependency_tree analyzing => %s" % (
784 mydep,))
785
786 dep_level, dep_atom = mydep
787
788
789 if dep_atom in treecache:
790 const_debug_write(__name__,
791 "generate_dependency_tree already in treecache => %s" % (
792 dep_atom,))
793 try:
794 mydep = mybuffer.pop()
795 except ValueError:
796 const_debug_write(__name__, "---empty--")
797 break
798 const_debug_write(__name__, "---")
799 continue
800 treecache.add(dep_atom)
801
802 if dep_atom is None:
803 const_debug_write(__name__,
804 "generate_dependency_tree broken entry in DB => %s" % (
805 mydep,))
806 try:
807 mydep = mybuffer.pop()
808 except ValueError:
809 const_debug_write(__name__, "---empty2--")
810 break
811 const_debug_write(__name__, "---")
812 continue
813
814
815 if dep_atom[0] == "!":
816 c_idpackage, xst = cdb_atom_match(dep_atom[1:])
817 if c_idpackage != -1:
818 myreplacement = lookup_conflict_replacement(dep_atom[1:],
819 c_idpackage, deep_deps = deep_deps)
820
821 const_debug_write(__name__,
822 "generate_dependency_tree conflict replacement => %s" % (
823 myreplacement,))
824
825 if (myreplacement != None) and (myreplacement not in treecache):
826 mybuffer.push((dep_level+1,myreplacement))
827 else:
828 conflicts.add(c_idpackage)
829 try:
830 mydep = mybuffer.pop()
831 except ValueError:
832 const_debug_write(__name__, "---empty3---")
833 break
834 const_debug_write(__name__, "---")
835 continue
836
837
838 if virgin:
839
840 virgin = False
841 m_idpackage, m_repo = matched_atom
842 dbconn = open_repo(m_repo)
843 myidpackage, idreason = dbconn.idpackageValidator(m_idpackage)
844
845 const_debug_write(__name__,
846 "generate_dependency_tree virgin match masked? => %s - %s" % (
847 myidpackage, idreason,))
848
849 if myidpackage == -1:
850 m_idpackage = -1
851
852 else:
853 m_idpackage, m_repo = atom_match(dep_atom)
854 const_debug_write(__name__,
855 "generate_dependency_tree matching %s => (%s, %s)" % (
856 dep_atom, m_idpackage, m_repo,))
857
858 if m_idpackage == -1:
859
860 const_debug_write(__name__,
861 "generate_dependency_tree dep not found => %s" % (
862 dep_atom,))
863
864 deps_not_found.add(dep_atom)
865 try:
866 mydep = mybuffer.pop()
867 except ValueError:
868 const_debug_write(__name__, "---empty3---")
869 break
870 const_debug_write(__name__, "---")
871 continue
872
873
874 matchdb = open_repo(m_repo)
875 matchatom = matchdb.retrieveAtom(m_idpackage)
876 matchkey, matchslot = matchdb.retrieveKeySlot(m_idpackage)
877
878 const_debug_write(__name__,
879 "generate_dependency_tree idpackage %s => %s - %s:%s" % (
880 m_idpackage, matchatom, matchkey, matchslot))
881
882 if (dep_atom != matchatom) and (matchatom in treecache):
883 try:
884 mydep = mybuffer.pop()
885 except ValueError:
886 const_debug_write(__name__, "---empty4---")
887 break
888 const_debug_write(__name__,
889 "generate_dependency_tree matchatom %s already in cache" % (
890 matchatom,))
891 const_debug_write(__name__, "---")
892 continue
893
894 treecache.add(matchatom)
895
896 const_debug_write(__name__,
897 "generate_dependency_tree check if key + slot cache => %s" % (
898 (matchslot, matchkey),))
899
900
901 if (matchslot, matchkey) in keyslotcache:
902 try:
903 mydep = mybuffer.pop()
904 except ValueError:
905 const_debug_write(__name__, "---empty5---")
906 break
907 const_debug_write(__name__, "---")
908 continue
909 else:
910 keyslotcache.add((matchslot, matchkey))
911
912 const_debug_write(__name__,
913 "generate_dependency_tree not in key + slot cache => %s" % (
914 (matchslot, matchkey),))
915
916 match = (m_idpackage, m_repo,)
917
918 if match in matchfilter:
919 try:
920 mydep = mybuffer.pop()
921 except ValueError:
922 const_debug_write(__name__, "---empty6---")
923 break
924 const_debug_write(__name__, "---")
925 continue
926
927 const_debug_write(__name__,
928 "generate_dependency_tree match NOT already analyzed => %s" % (
929 match,))
930
931
932 matchfilter.add(match)
933 treedepth = dep_level+1
934 deptree.add((dep_level,match))
935
936
937 cm_idpackage, cm_result = cdb_atom_match(matchkey,
938 matchSlot = matchslot)
939 if cm_idpackage != -1:
940
941 broken_atoms = lookup_library_breakages(match,
942 (cm_idpackage, cm_result,), deep_deps = deep_deps)
943 const_debug_write(__name__,
944 "generate_dependency_tree lib broken atoms for %s => %s" % (
945 matchkey+":"+matchslot, broken_atoms,))
946
947 inverse_deps = lookup_inverse_dependencies(match,
948 (cm_idpackage, cm_result,))
949 const_debug_write(__name__,
950 "generate_dependency_tree inverse deps for %s => %s" % (
951 matchkey+":"+matchslot, inverse_deps,))
952
953 if inverse_deps:
954 deptree.remove((dep_level,match))
955 for ikey,islot in inverse_deps:
956 iks_str = '%s:%s' % (ikey,islot,)
957 if ((ikey,islot) not in keyslotcache) and (iks_str not in treecache):
958 mybuffer.push((dep_level,iks_str))
959 keyslotcache.add((ikey,islot))
960 deptree.add((treedepth,match))
961 treedepth += 1
962
963 for x in broken_atoms:
964 if (tuple(x.split(":")) not in keyslotcache) and (x not in treecache):
965 mybuffer.push((treedepth,x))
966
967 m_deplist = matchdb.retrieveDependenciesList(m_idpackage)
968
969 const_debug_write(__name__,
970 "generate_dependency_tree dependency list for %s => %s" % (
971 m_idpackage, m_deplist,))
972
973 myundeps = filter(my_dep_filter, m_deplist)
974
975 const_debug_write(__name__,
976 "generate_dependency_tree filtered dependency list => %s" % (
977 myundeps,))
978
979 if not empty_deps:
980
981 m_unsat_deplist = get_unsatisfied_deps(myundeps, deep_deps,
982 depcache = filter_unsat_cache)
983
984 const_debug_write(__name__,
985 "generate_dependency_tree unsatisfied dependencies (deep: %s) => %s" % (
986 deep_deps, m_unsat_deplist,))
987
988 myundeps = filter(my_dep_filter, m_unsat_deplist)
989
990 const_debug_write(__name__,
991 "generate_dependency_tree filtered UNSATISFIED dependencies => %s" % (
992 myundeps,))
993
994
995 if myundeps:
996
997 post_deps = [x for x in \
998 matchdb.retrievePostDependencies(m_idpackage) if x \
999 in myundeps]
1000
1001 const_debug_write(__name__,
1002 "generate_dependency_tree POST dependencies => %s" % (
1003 post_deps,))
1004
1005 if post_deps:
1006
1007
1008
1009 myundeps = [x for x in myundeps if x not in post_deps]
1010
1011 const_debug_write(__name__,
1012 "generate_dependency_tree POST dependencies ADDED => %s" % (
1013 myundeps,))
1014
1015 for x in post_deps:
1016 mybuffer.push((-1, x))
1017
1018 for x in myundeps:
1019 mybuffer.push((treedepth, x))
1020
1021 try:
1022 mydep = mybuffer.pop()
1023 except ValueError:
1024 const_debug_write(__name__, "---empty7---")
1025 break
1026 const_debug_write(__name__, "---")
1027
1028 if deps_not_found:
1029 return list(deps_not_found), -2
1030
1031 if flat:
1032 return [x[1] for x in deptree], 0
1033
1034 newdeptree = {}
1035 for key, item in deptree:
1036 if key >= 0:
1037
1038 key += 1
1039 obj = newdeptree.setdefault(key, set())
1040 obj.add(item)
1041
1042 newdeptree[0] = conflicts
1043
1044 return newdeptree,0
1045
1046
1048
1049 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1050 data = client_settings['repositories']['system_mask']
1051
1052 if not data:
1053 return []
1054 mydata = []
1055 cached_items = set()
1056 for atom in data:
1057 mymatch = self.atom_match(atom)
1058 if mymatch[0] == -1:
1059 continue
1060 if mymatch in cached_items:
1061 continue
1062 if mymatch not in mydata:
1063
1064 myaction = self.get_package_action(mymatch)
1065
1066 if myaction == 1: mydata.append(mymatch)
1067 cached_items.add(mymatch)
1068 return mydata
1069
1071 if self.entropyTools.isjustname(conflict_atom):
1072 return None
1073 conflict_match = self.atom_match(conflict_atom)
1074 mykey, myslot = self.clientDbconn.retrieveKeySlot(client_idpackage)
1075 new_match = self.atom_match(mykey, matchSlot = myslot)
1076 if (conflict_match == new_match) or (new_match[1] == 1):
1077 return None
1078 action = self.get_package_action(new_match)
1079 if (action == 0) and (not deep_deps):
1080 return None
1081 return "%s:%s" % (mykey,myslot,)
1082
1084
1085 cmpstat = self.get_package_action(match)
1086 if cmpstat == 0: return set()
1087
1088 keyslots = set()
1089 mydepends = self.clientDbconn.retrieveReverseDependencies(clientmatch[0])
1090 am = self.atom_match
1091 cdb_rdeps = self.clientDbconn.retrieveDependencies
1092 cdb_rks = self.clientDbconn.retrieveKeySlot
1093 gpa = self.get_package_action
1094 keyslots_cache = set()
1095 match_cache = {}
1096
1097 for idpackage in mydepends:
1098 try:
1099 key, slot = cdb_rks(idpackage)
1100 except TypeError:
1101 continue
1102 if (key,slot) in keyslots_cache: continue
1103 keyslots_cache.add((key,slot))
1104 if (key,slot) in keyslots: continue
1105
1106 mydeps = cdb_rdeps(idpackage)
1107 found = False
1108 for mydep in mydeps:
1109 mymatch = match_cache.get(mydep, 0)
1110 if mymatch == 0:
1111 mymatch = am(mydep)
1112 match_cache[mydep] = mymatch
1113 if mymatch == match:
1114 found = True
1115 break
1116 if not found:
1117 mymatch = am(key, matchSlot = slot)
1118 if mymatch[0] == -1: continue
1119 cmpstat = gpa(mymatch)
1120 if cmpstat == 0: continue
1121 keyslots.add((key,slot))
1122
1123 return keyslots
1124
1126 repo_needed = match_db.retrieveNeeded(match_idpackage, extended = True, format = True)
1127 client_needed = self.clientDbconn.retrieveNeeded(client_idpackage, extended = True, format = True)
1128 repo_split = [x.split(".so")[0] for x in repo_needed]
1129 client_split = [x.split(".so")[0] for x in client_needed]
1130 client_side = [x for x in client_needed if (x not in repo_needed) and (x.split(".so")[0] in repo_split)]
1131 repo_side = [x for x in repo_needed if (x not in client_needed) and (x.split(".so")[0] in client_split)]
1132 return repo_needed, client_side, repo_side
1133
1135
1136
1137
1138
1139 c_hash = "%s|%s|%s" % (
1140 tuple(match),
1141 deep_deps,
1142 tuple(clientmatch),
1143 )
1144 c_hash = "%s%s" % (etpCache['library_breakage'], hash(c_hash),)
1145 if self.xcache:
1146 cached = self.Cacher.pop(c_hash)
1147 if cached != None: return cached
1148
1149
1150 repo_atoms = set()
1151
1152 client_atoms = set()
1153
1154 matchdb = self.open_repository(match[1])
1155 reponeeded, client_side, repo_side = self.__get_lib_breaks_client_and_repo_side(matchdb,
1156 match[0], clientmatch[0])
1157
1158
1159 client_idpackages = set()
1160 for needed in client_side: client_idpackages |= self.clientDbconn.searchNeeded(needed)
1161
1162 client_keyslots = set()
1163 def mymf(idpackage):
1164 if idpackage == clientmatch[0]:
1165 return 0
1166 ks = self.clientDbconn.retrieveKeySlot(idpackage)
1167 if ks is None:
1168 return 0
1169 return ks
1170 client_keyslots = set([x for x in map(mymf,client_idpackages) if x != 0])
1171
1172
1173 repodata = {}
1174 for needed in repo_side:
1175 repodata[needed] = reponeeded[needed]
1176 del repo_side,reponeeded
1177
1178 repo_dependencies = matchdb.retrieveDependencies(match[0])
1179 matched_deps = set()
1180 matched_repos = set()
1181 for dependency in repo_dependencies:
1182 depmatch = self.atom_match(dependency)
1183 if depmatch[0] == -1:
1184 continue
1185 matched_repos.add(depmatch[1])
1186 matched_deps.add(depmatch)
1187
1188 matched_repos = [x for x in self.SystemSettings['repositories']['order'] \
1189 if x in matched_repos]
1190 found_matches = set()
1191 for needed in repodata:
1192 for myrepo in matched_repos:
1193 mydbc = self.open_repository(myrepo)
1194 solved_needed = mydbc.resolveNeeded(needed,
1195 repodata[needed])
1196 found = False
1197 for idpackage in solved_needed:
1198 x = (idpackage, myrepo)
1199 if x in matched_deps:
1200 found_matches.add(x)
1201 found = True
1202 break
1203 if found:
1204 break
1205
1206 for idpackage,repo in found_matches:
1207 if not deep_deps:
1208 cmpstat = self.get_package_action((idpackage,repo))
1209 if cmpstat == 0:
1210 continue
1211 mydbc = self.open_repository(repo)
1212 repo_atoms.add(mydbc.retrieveAtom(idpackage))
1213
1214 for key, slot in client_keyslots:
1215 idpackage, repo = self.atom_match(key, matchSlot = slot)
1216 if idpackage == -1:
1217 continue
1218 if not deep_deps:
1219 cmpstat = self.get_package_action((idpackage, repo))
1220 if cmpstat == 0:
1221 continue
1222 mydbc = self.open_repository(repo)
1223 client_atoms.add(mydbc.retrieveAtom(idpackage))
1224
1225 client_atoms |= repo_atoms
1226
1227 if self.xcache:
1228 self.Cacher.push(c_hash,client_atoms)
1229
1230 return client_atoms
1231
1232
1234
1235 c_hash = "%s%s" % (
1236 etpCache['dep_tree'],
1237 hash("%s|%s|%s|%s|%s" % (
1238 hash(frozenset(sorted(matched_atoms))),
1239 empty_deps,
1240 deep_deps,
1241 self.clientDbconn.checksum(),
1242
1243
1244 self.SystemSettings['repositories']['branch'],
1245 )),)
1246 if self.xcache:
1247 cached = self.Cacher.pop(c_hash)
1248 if cached != None: return cached
1249
1250 deptree = {}
1251 deptree[0] = set()
1252
1253 atomlen = len(matched_atoms); count = 0
1254 error_generated = 0
1255 error_tree = set()
1256
1257
1258 forced_matches = self._lookup_system_mask_repository_deps()
1259 if forced_matches:
1260 if isinstance(matched_atoms, list):
1261 matched_atoms = forced_matches + [x for x in matched_atoms if x not in forced_matches]
1262 elif isinstance(matched_atoms, set):
1263 matched_atoms |= set(forced_matches)
1264
1265 sort_dep_text = _("Sorting dependencies")
1266 filter_unsat_cache = {}
1267 treecache = set()
1268 keyslotcache = set()
1269 matchfilter = set()
1270 for matched_atom in matched_atoms:
1271 const_debug_write(__name__,
1272 "get_required_packages matched_atom => %s" % (matched_atom,))
1273
1274 if not quiet:
1275 count += 1
1276 if (count%10 == 0) or (count == atomlen) or (count == 1):
1277 self.updateProgress(sort_dep_text, importance = 0, type = "info",
1278 back = True, header = ":: ", footer = " ::",
1279 percent = True, count = (count,atomlen))
1280
1281 if matched_atom in matchfilter: continue
1282 newtree, result = self.generate_dependency_tree(
1283 matched_atom, empty_deps, deep_deps,
1284 matchfilter = matchfilter, filter_unsat_cache = filter_unsat_cache, treecache = treecache,
1285 keyslotcache = keyslotcache
1286 )
1287
1288 const_debug_write(__name__,
1289 "get_required_packages deptree => %s -- %s" % (
1290 newtree, result,))
1291
1292 if result == -2:
1293 error_generated = -2
1294 error_tree |= set(newtree)
1295 elif (result != 0):
1296 return newtree, result
1297 elif newtree:
1298
1299 max_parent_key = max(deptree)
1300 deptree[0] |= newtree.pop(0)
1301 levelcount = 0
1302 for mylevel in sorted(newtree.keys(), reverse = True):
1303 levelcount += 1
1304 deptree[max_parent_key+levelcount] = newtree.get(mylevel)
1305
1306 if error_generated != 0:
1307 return error_tree,error_generated
1308
1309 if self.xcache:
1310 self.Cacher.push(c_hash,(deptree,0))
1311
1312 return deptree,0
1313
1315 remove_depends = set()
1316 for d_idpackage in depends:
1317 mydeps = self.clientDbconn.retrieveDependencies(d_idpackage)
1318 for mydep in mydeps:
1319 matches, rslt = self.clientDbconn.atomMatch(mydep, multiMatch = True)
1320 if rslt == 1: continue
1321 if idpackage in matches and len(matches) > 1:
1322
1323 for mymatch in matches:
1324 if mymatch not in depends and mymatch not in monotree:
1325 remove_depends.add(d_idpackage)
1326 break
1327 depends -= remove_depends
1328 return depends
1329
1330
1332
1333 c_hash = "%s%s" % (
1334 etpCache['depends_tree'],
1335 hash("%s|%s" % (
1336 tuple(sorted(idpackages)),
1337 deep,
1338 ),
1339 ),
1340 )
1341 if self.xcache:
1342 cached = self.Cacher.pop(c_hash)
1343 if cached != None: return cached
1344
1345 dependscache = set()
1346 treeview = set(idpackages)
1347 treelevel = set(idpackages)
1348 tree = {}
1349
1350 treedepth = 0
1351 tree[treedepth] = set(idpackages)
1352 monotree = set(idpackages)
1353
1354
1355 pdepend_id = etpConst['spm']['pdepend_id']
1356
1357 self.clientDbconn.retrieveReverseDependencies(idpackages[0])
1358 count = 0
1359
1360 rem_dep_text = _("Calculating inverse dependencies for")
1361 while 1:
1362 treedepth += 1
1363 tree[treedepth] = set()
1364 for idpackage in treelevel:
1365
1366 count += 1
1367 p_atom = self.clientDbconn.retrieveAtom(idpackage)
1368 self.updateProgress(
1369 blue(rem_dep_text + " %s" % (red(p_atom),)),
1370 importance = 0,
1371 type = "info",
1372 back = True,
1373 header = '|/-\\'[count%4]+" "
1374 )
1375
1376 systempkg = not self.validate_package_removal(idpackage)
1377 if (idpackage in dependscache) or systempkg:
1378 if idpackage in treeview:
1379 treeview.remove(idpackage)
1380 continue
1381
1382
1383 depends = self.clientDbconn.retrieveReverseDependencies(idpackage,
1384 exclude_deptypes = (pdepend_id,))
1385
1386 depends = set([x for x in depends if x not in monotree])
1387 depends = set([x for x in depends if \
1388 self.validate_package_removal(x)])
1389 if depends:
1390 depends = self._filter_depends_multimatched_atoms(
1391 idpackage, depends, monotree)
1392 if depends:
1393 tree[treedepth] |= depends
1394 monotree |= depends
1395 treeview |= depends
1396 elif deep:
1397
1398 mydeps = set()
1399 for x in self.clientDbconn.retrieveDependencies(idpackage):
1400 match = self.clientDbconn.atomMatch(x)
1401 if match[0] != -1:
1402 mydeps.add(match[0])
1403
1404
1405 mydeps = [x for x in mydeps if x not in monotree and not \
1406 (self.clientDbconn.isSystemPackage(x) or \
1407 self.is_installed_idpackage_in_system_mask(x) )]
1408 for x in mydeps:
1409 mydepends = self.clientDbconn.retrieveReverseDependencies(x)
1410 mydepends -= set([y for y in mydepends if y \
1411 not in monotree])
1412 if not mydepends:
1413 tree[treedepth].add(x)
1414 monotree.add(x)
1415 treeview.add(x)
1416
1417 dependscache.add(idpackage)
1418 if idpackage in treeview:
1419 treeview.remove(idpackage)
1420
1421 treelevel = treeview.copy()
1422 if not treelevel:
1423 if not tree[treedepth]:
1424 del tree[treedepth]
1425 break
1426
1427
1428 for count in sorted(tree.keys(), reverse = True):
1429 x = 0
1430 while x < count:
1431 tree[x] -= tree[count]
1432 x += 1
1433
1434 if self.xcache:
1435 self.Cacher.push(c_hash,(tree,0))
1436
1437
1438 return tree,0
1439
1441
1442 c_hash = self.get_available_packages_chash()
1443 if use_cache and self.xcache:
1444 cached = self.get_available_packages_cache(myhash = c_hash)
1445 if cached != None:
1446 return cached
1447
1448 available = []
1449 self.setTotalCycles(len(self.validRepositories))
1450 avail_dep_text = _("Calculating available packages for")
1451 for repo in self.validRepositories:
1452 try:
1453 dbconn = self.open_repository(repo)
1454 dbconn.validateDatabase()
1455 except (RepositoryError, SystemDatabaseError):
1456 self.cycleDone()
1457 continue
1458 try:
1459
1460 idpackages = [x for x in dbconn.listAllIdpackages(
1461 order_by = 'atom') if dbconn.idpackageValidator(x)[0] != -1]
1462 except dbconn.dbapi2.OperationalError:
1463 self.cycleDone()
1464 continue
1465 count = 0
1466 maxlen = len(idpackages)
1467 myavailable = []
1468 do_break = False
1469 for idpackage in idpackages:
1470 if do_break:
1471 break
1472 count += 1
1473 if (count % 10 == 0) or (count == 1) or (count == maxlen):
1474 self.updateProgress(
1475 avail_dep_text + " %s" % (repo,),
1476 importance = 0,
1477 type = "info",
1478 back = True,
1479 header = "::",
1480 count = (count,maxlen),
1481 percent = True,
1482 footer = " ::"
1483 )
1484
1485 try:
1486 key, slot = dbconn.retrieveKeySlot(idpackage)
1487 matches = self.clientDbconn.searchKeySlot(key, slot)
1488 except (self.dbapi2.DatabaseError,self.dbapi2.IntegrityError,self.dbapi2.OperationalError,):
1489 self.cycleDone()
1490 do_break = True
1491 continue
1492 if not matches: myavailable.append((idpackage,repo))
1493 available += myavailable[:]
1494 self.cycleDone()
1495
1496 if self.xcache:
1497 self.Cacher.push("%s%s" % (
1498 etpCache['world_available'], c_hash), available)
1499 return available
1500
1502
1503
1504
1505 in_branch_upgrade = etpConst['etp_in_branch_upgrade_file']
1506 if os.access(in_branch_upgrade, os.R_OK | os.F_OK):
1507 return set(), []
1508
1509 db_digest = self.all_repositories_checksum()
1510 if use_cache and self.xcache:
1511 cached = self.get_critical_updates_cache(db_digest = db_digest)
1512 if cached != None:
1513 return cached
1514
1515 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1516 critical_data = client_settings['repositories']['critical_updates']
1517
1518 atoms = set()
1519 atom_matches = {}
1520 for repoid in critical_data:
1521 for atom in critical_data[repoid]:
1522 match_id, match_repo = self.atom_match(atom)
1523 if match_repo == 1:
1524 continue
1525 atom_matches[atom] = (match_id, match_repo,)
1526 atoms.add(atom)
1527
1528 atoms = self.get_unsatisfied_dependencies(atoms)
1529 matches = [atom_matches.get(atom) for atom in atoms]
1530 data = (atoms, matches)
1531
1532 if self.xcache:
1533 c_hash = self.get_critical_update_cache_hash(db_digest)
1534 self.Cacher.push("%s%s" % (etpCache['critical_update'], c_hash,),
1535 data, async = False)
1536
1537 return data
1538
1539
1542
1543 cl_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1544 misc_settings = cl_settings['misc']
1545 update = []
1546 remove = []
1547 fine = []
1548 spm_fine = []
1549
1550
1551
1552 if misc_settings.get('forcedupdates') and critical_updates:
1553 upd_atoms, upd_matches = self.calculate_critical_updates(
1554 use_cache = use_cache)
1555 if upd_atoms:
1556 return upd_matches, remove, fine, spm_fine
1557
1558 db_digest = self.all_repositories_checksum()
1559 if use_cache and self.xcache:
1560 cached = self.get_world_update_cache(empty_deps = empty_deps,
1561 db_digest = db_digest)
1562 if cached != None:
1563 return cached
1564
1565
1566 ignore_spm_downgrades = misc_settings['ignore_spm_downgrades']
1567
1568
1569 try:
1570 idpackages = self.clientDbconn.listAllIdpackages(order_by = 'atom')
1571 except self.dbapi2.OperationalError:
1572
1573 raise SystemDatabaseError("installed packages database is broken")
1574
1575 maxlen = len(idpackages)
1576 count = 0
1577 mytxt = _("Calculating world packages")
1578 for idpackage in idpackages:
1579
1580 count += 1
1581 if (count%10 == 0) or (count == maxlen) or (count == 1):
1582 self.updateProgress(
1583 mytxt,
1584 importance = 0,
1585 type = "info",
1586 back = True,
1587 header = ":: ",
1588 count = (count,maxlen),
1589 percent = True,
1590 footer = " ::"
1591 )
1592
1593 try:
1594 cl_pkgkey, cl_slot, cl_version, \
1595 cl_tag, cl_revision, \
1596 cl_atom = self.clientDbconn.getStrictData(idpackage)
1597 except TypeError:
1598
1599 continue
1600 use_match_cache = True
1601 do_continue = False
1602 while 1:
1603 try:
1604 match = self.atom_match(
1605 cl_pkgkey,
1606 matchSlot = cl_slot,
1607 extendedResults = True,
1608 useCache = use_match_cache
1609 )
1610 except self.dbapi2.OperationalError:
1611
1612 do_continue = True
1613 break
1614 try:
1615 m_idpackage = match[0][0]
1616 except TypeError:
1617 if not use_match_cache: raise
1618 use_match_cache = False
1619 continue
1620 break
1621 if do_continue: continue
1622
1623
1624
1625
1626 if (m_idpackage != -1):
1627 repoid = match[1]
1628 version = match[0][1]
1629 tag = match[0][2]
1630 revision = match[0][3]
1631 if empty_deps:
1632 if (m_idpackage,repoid) not in update:
1633 update.append((m_idpackage,repoid))
1634 continue
1635 elif (cl_revision != revision):
1636
1637 if cl_revision == 9999 and ignore_spm_downgrades:
1638
1639 fine.append(cl_atom)
1640 if (m_idpackage,repoid) not in update:
1641 spm_fine.append((m_idpackage,repoid))
1642 continue
1643 else:
1644 if (m_idpackage,repoid) not in update:
1645 update.append((m_idpackage,repoid))
1646 continue
1647 elif (cl_version != version):
1648
1649 if (m_idpackage,repoid) not in update:
1650 update.append((m_idpackage,repoid))
1651 continue
1652 elif (cl_tag != tag):
1653
1654 if (m_idpackage,repoid) not in update:
1655 update.append((m_idpackage,repoid))
1656 continue
1657 else:
1658
1659 fine.append(cl_atom)
1660 continue
1661
1662
1663 maskedresults = self.atom_match(cl_pkgkey, matchSlot = cl_slot,
1664 packagesFilter = False)
1665 if maskedresults[0] == -1:
1666 remove.append(idpackage)
1667
1668
1669 matchresults = self.atom_match(cl_pkgkey)
1670 if matchresults[0] != -1:
1671 m_action = self.get_package_action(matchresults)
1672 if m_action > 0 and (matchresults not in update):
1673 update.append(matchresults)
1674
1675 if self.xcache:
1676 c_hash = self.get_world_update_cache_hash(db_digest, empty_deps,
1677 ignore_spm_downgrades)
1678 data = (update, remove, fine, spm_fine,)
1679 self.Cacher.push("%s%s" % (etpCache['world_update'],c_hash,),
1680 data, async = False)
1681
1682 if not update:
1683
1684
1685 br_path = etpConst['etp_in_branch_upgrade_file']
1686 if os.access(br_path, os.W_OK | os.F_OK):
1687 os.remove(br_path)
1688
1689 return update, remove, fine, spm_fine
1690
1692
1693 c_hash = "%s%s" % (etpCache['check_package_update'],
1694 hash("%s%s" % (atom, deep,)
1695 ),
1696 )
1697 if self.xcache:
1698 cached = self.Cacher.pop(c_hash)
1699 if cached != None:
1700 return cached
1701
1702 found = False
1703 match = self.clientDbconn.atomMatch(atom)
1704 matched = None
1705 if match[0] != -1:
1706 myatom = self.clientDbconn.retrieveAtom(match[0])
1707 mytag = self.entropyTools.dep_gettag(myatom)
1708 myatom = self.entropyTools.remove_tag(myatom)
1709 myrev = self.clientDbconn.retrieveRevision(match[0])
1710 pkg_match = "="+myatom+"~"+str(myrev)
1711 if mytag != None:
1712 pkg_match += "#%s" % (mytag,)
1713 pkg_unsatisfied = self.get_unsatisfied_dependencies([pkg_match], deep_deps = deep)
1714 if pkg_unsatisfied:
1715
1716 pkg_key = self.entropyTools.dep_getkey(myatom)
1717 pkg_id, pkg_repo = self.atom_match(pkg_key)
1718 if pkg_id != -1:
1719 found = True
1720 del pkg_unsatisfied
1721 matched = self.atom_match(pkg_match)
1722 del match
1723
1724 if self.xcache:
1725 self.Cacher.push(c_hash,(found, matched))
1726 return found, matched
1727
1729
1730 pkgatom = self.clientDbconn.retrieveAtom(idpackage)
1731 pkgkey = self.entropyTools.dep_getkey(pkgatom)
1732 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1733 mask_installed_keys = client_settings['system_mask']['repos_installed_keys']
1734
1735 if self.is_installed_idpackage_in_system_mask(idpackage):
1736 idpackages = mask_installed_keys.get(pkgkey)
1737 if not idpackages: return False
1738 if len(idpackages) > 1:
1739 return True
1740 return False
1741
1742
1743 system_pkg = self.clientDbconn.isSystemPackage(idpackage)
1744 if not system_pkg: return True
1745
1746 matches, rc = self.clientDbconn.atomMatch(pkgkey, multiMatch = True)
1747 if len(matches) < 2:
1748 return False
1749 return True
1750
1751
1753 queue = []
1754 if not idpackages:
1755 return queue
1756 treeview, status = self.generate_depends_tree(idpackages, deep = deep)
1757 if status == 0:
1758 for x in range(len(treeview))[::-1]: queue.extend(treeview[x])
1759 return queue
1760
1762
1763 install = []
1764 removal = []
1765 treepackages, result = self.get_required_packages(matched_atoms,
1766 empty_deps, deep_deps, quiet = quiet)
1767
1768 if result == -2:
1769 return treepackages,removal,result
1770
1771
1772 removal = treepackages.pop(0, set())
1773 for dep_level in sorted(treepackages):
1774 install.extend(treepackages[dep_level])
1775
1776
1777 if install and removal:
1778 myremmatch = {}
1779 for rm_idpackage in removal:
1780 keyslot = self.clientDbconn.retrieveKeySlot(rm_idpackage)
1781
1782
1783 if keyslot is None:
1784 continue
1785 myremmatch[keyslot] = rm_idpackage
1786
1787 for pkg_id, pkg_repo in install:
1788 dbconn = self.open_repository(pkg_repo)
1789 testtuple = dbconn.retrieveKeySlot(pkg_id)
1790 removal.discard(myremmatch.get(testtuple))
1791
1792 return install, sorted(removal), 0
1793