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