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