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 Source Package Manager "Portage" Plugin}.
10
11 """
12 import os
13 import bz2
14 import sys
15 import shutil
16 import tempfile
17 import subprocess
18 from entropy.const import etpConst, etpUi, const_get_stringtype, \
19 const_convert_to_unicode, const_convert_to_rawstring
20 from entropy.exceptions import FileNotFound, SPMError, InvalidDependString, \
21 InvalidData, InvalidAtom
22 from entropy.output import darkred, darkgreen, brown, darkblue, purple, red, \
23 bold, blue
24 from entropy.i18n import _
25 from entropy.core.settings.base import SystemSettings
26 from entropy.misc import LogFile
27 from entropy.spm.plugins.skel import SpmPlugin
28 import entropy.tools
29 from entropy.spm.plugins.interfaces.portage_plugin import xpak
30 from entropy.spm.plugins.interfaces.portage_plugin import xpaktools
33 """
34 Entropy Package categories group representation
35 """
37 dict.__init__(self)
38
39 data = {
40 'office': {
41 'name': _("Office"),
42 'description': _("Applications used in office environments"),
43 'categories': ['app-office', 'app-pda', 'app-mobilephone',
44 'app-cdr', 'app-antivirus', 'app-laptop', 'mail-',
45 ],
46 },
47 'development': {
48 'name': _("Development"),
49 'description': _("Applications or system libraries"),
50 'categories': ['dev-', 'sys-devel'],
51 },
52 'system': {
53 'name': _("System"),
54 'description': _("System applications or libraries"),
55 'categories': ['sys-'],
56 },
57 'games': {
58 'name': _("Games"),
59 'description': _("Games, enjoy your spare time"),
60 'categories': ['games-'],
61 },
62 'gnome': {
63 'name': _("GNOME Desktop"),
64 'description': \
65 _("Applications and libraries for the GNOME Desktop"),
66 'categories': ['gnome-'],
67 },
68 'kde': {
69 'name': _("KDE Desktop"),
70 'description': \
71 _("Applications and libraries for the KDE Desktop"),
72 'categories': ['kde-'],
73 },
74 'xfce': {
75 'name': _("XFCE Desktop"),
76 'description': \
77 _("Applications and libraries for the XFCE Desktop"),
78 'categories': ['xfce-'],
79 },
80 'lxde': {
81 'name': _("LXDE Desktop"),
82 'description': \
83 _("Applications and libraries for the LXDE Desktop"),
84 'categories': ['lxde-'],
85 },
86 'multimedia': {
87 'name': _("Multimedia"),
88 'description': \
89 _("Applications and libraries for Multimedia"),
90 'categories': ['media-'],
91 },
92 'networking': {
93 'name': _("Networking"),
94 'description': \
95 _("Applications and libraries for Networking"),
96 'categories': ['net-', 'www-'],
97 },
98 'science': {
99 'name': _("Science"),
100 'description': \
101 _("Scientific applications and libraries"),
102 'categories': ['sci-'],
103 },
104 'x11': {
105 'name': _("X11"),
106 'description': \
107 _("Applications and libraries for X11"),
108 'categories': ['x11-'],
109 },
110 }
111 self.update(data)
112
149
152
153 builtin_pkg_sets = [
154 "system", "world", "installed", "module-rebuild",
155 "security", "preserved-rebuild", "live-rebuild",
156 "downgrade", "unavailable"
157 ]
158
159 xpak_entries = {
160 'description': "DESCRIPTION",
161 'homepage': "HOMEPAGE",
162 'chost': "CHOST",
163 'category': "CATEGORY",
164 'cflags': "CFLAGS",
165 'cxxflags': "CXXFLAGS",
166 'license': "LICENSE",
167 'src_uri': "SRC_URI",
168 'use': "USE",
169 'iuse': "IUSE",
170 'slot': "SLOT",
171 'provide': "PROVIDE",
172 'depend': "DEPEND",
173 'rdepend': "RDEPEND",
174 'pdepend': "PDEPEND",
175 'needed': "NEEDED",
176 'inherited': "INHERITED",
177 'keywords': "KEYWORDS",
178 'contents': "CONTENTS",
179 'counter': "COUNTER",
180 'defined_phases': "DEFINED_PHASES",
181 'repository': "repository",
182 'pf': "PF",
183 }
184
185 _ebuild_entries = {
186 'ebuild_pkg_tag_var': "ENTROPY_PROJECT_TAG",
187 }
188
189 _cmd_map = {
190 'env_update_cmd': "/usr/sbin/env-update",
191 'ask_cmd': "--ask",
192 'info_cmd': "--info",
193 'remove_cmd': "-C",
194 'nodeps_cmd': "--nodeps",
195 'fetchonly_cmd': "--fetchonly",
196 'buildonly_cmd': "--buildonly",
197 'oneshot_cmd': "--oneshot",
198 'pretend_cmd': "--pretend",
199 'verbose_cmd': "--verbose",
200 'nocolor_cmd': "--color=n",
201 'source_profile_cmd': ["source", "/etc/profile"],
202 'exec_cmd': "/usr/bin/emerge",
203 }
204
205 _package_phases_map = {
206 'setup': 'setup',
207 'preinstall': 'preinst',
208 'postinstall': 'postinst',
209 'preremove': 'prerm',
210 'postremove': 'postrm',
211 'configure': 'config',
212 }
213
214 _config_files_map = {
215 'global_make_conf': "/etc/make.conf",
216 'global_package_keywords': "/etc/portage/package.keywords",
217 'global_package_use': "/etc/portage/package.use",
218 'global_package_mask': "/etc/portage/package.mask",
219 'global_package_unmask': "/etc/portage/package.unmask",
220 'global_make_profile': "/etc/make.profile",
221 }
222
223 PLUGIN_API_VERSION = 3
224
225 SUPPORTED_MATCH_TYPES = [
226 "bestmatch-visible", "cp-list", "list-visible", "match-all",
227 "match-visible", "minimum-all", "minimum-visible"
228 ]
229
230 CACHE = {
231 'vartree': {},
232 'binarytree': {},
233 'config': {},
234 'portagetree': {},
235 }
236
237 IS_DEFAULT = True
238 PLUGIN_NAME = 'portage'
239 ENV_FILE_COMP = "environment.bz2"
240 EBUILD_EXT = ".ebuild"
241 KERNEL_CATEGORY = "sys-kernel"
242
243 sys.path.append("/usr/lib/gentoolkit/pym")
244
246 """Take a dependency structure as returned by paren_reduce or use_reduce
247 and generate an equivalent structure that has no redundant lists."""
249 list.__init__(self)
250 self._zap_parens(src, self)
251
253 if not src:
254 return dest
255 i = iter(src)
256 for x in i:
257 if isinstance(x, const_get_stringtype()):
258 if x == '||':
259 x = self._zap_parens(next(i), [], disjunction=True)
260 if len(x) == 1:
261 dest.append(x[0])
262 else:
263 dest.append("||")
264 dest.append(x)
265 elif x.endswith("?"):
266 dest.append(x)
267 dest.append(self._zap_parens(next(i), []))
268 else:
269 dest.append(x)
270 else:
271 if disjunction:
272 x = self._zap_parens(x, [])
273 if len(x) == 1:
274 dest.append(x[0])
275 else:
276 dest.append(x)
277 else:
278 self._zap_parens(x, dest)
279 return dest
280
282
283 mytxt = _("OutputInterface does not have an updateProgress method")
284 if not hasattr(OutputInterface, 'updateProgress'):
285 raise AttributeError(mytxt)
286 elif not hasattr(OutputInterface.updateProgress, '__call__'):
287 raise AttributeError(mytxt)
288
289
290 self.updateProgress = OutputInterface.updateProgress
291 self.askQuestion = OutputInterface.askQuestion
292
293
294 import portage
295 self.portage = portage
296 self.EAPI = 1
297 try:
298 import portage.const as portage_const
299 except ImportError:
300 import portage_const
301 if hasattr(portage_const, "EAPI"):
302 self.EAPI = portage_const.EAPI
303 self.portage_const = portage_const
304
305 from portage.versions import best
306 self._portage_best = best
307
308 try:
309 import portage.util as portage_util
310 except ImportError:
311 import portage_util
312 self.portage_util = portage_util
313
314 try:
315 import portage.sets as portage_sets
316 self.portage_sets = portage_sets
317 except ImportError:
318 self.portage_sets = None
319
320 try:
321 import glsa
322 self.glsa = glsa
323 except ImportError:
324 self.glsa = None
325
326 self.__entropy_repository_treeupdate_digests = {}
327
328 @staticmethod
330 """
331 Return package groups available metadata (Spm categories are grouped
332 into macro categories called "groups").
333 """
334 return PortagePackageGroups()
335
351
353 """
354 Reimplemented from SpmPlugin class.
355 """
356 if root is None:
357 root = etpConst['systemroot'] + os.path.sep
358 cache_path = self.portage_const.CACHE_PATH.lstrip(os.path.sep)
359 return os.path.join(root, cache_path)
360
366
368 """
369 Reimplemented from SpmPlugin class.
370 """
371 ebuild_path = self.get_package_build_script_path(package)
372 if isinstance(ebuild_path, const_get_stringtype()):
373
374 clog_path = os.path.join(os.path.dirname(ebuild_path), "ChangeLog")
375 if os.access(clog_path, os.R_OK) and os.path.isfile(clog_path):
376 with open(clog_path, "rb") as clog_f:
377 return clog_f.read()
378
380 """
381 Reimplemented from SpmPlugin class.
382 """
383 return self.portage.portdb.findname(package)
384
391
400
410
412 """
413 Reimplemented from SpmPlugin class.
414 """
415 return self._get_portage_config(os.path.sep, os.path.sep).categories
416
433
435 """
436 Reimplemented from SpmPlugin class.
437 """
438 if not self.glsa:
439 return []
440 if security_property not in ['new', 'all', 'affected']:
441 return []
442
443 glsaconfig = self.glsa.checkconfig(
444 self.portage.config(clone=self.portage.settings))
445 completelist = self.glsa.get_glsa_list(
446 glsaconfig["GLSA_DIR"], glsaconfig)
447
448 glsalist = []
449 if security_property == "new":
450
451 checklist = []
452 if os.access(glsaconfig["CHECKFILE"], os.R_OK) and \
453 os.path.isfile(glsaconfig["CHECKFILE"]):
454 with open(glsaconfig["CHECKFILE"], "rb") as check_f:
455 checklist.extend([x.strip() for x in check_f.readlines()])
456 glsalist = [x for x in completelist if x not in checklist]
457
458 elif security_property == "all":
459 glsalist = completelist
460
461 elif security_property == "affected":
462
463
464 for glsa_item in completelist:
465 try:
466 myglsa = self.glsa.Glsa(glsa_item, glsaconfig)
467 except (self.glsa.GlsaTypeException,
468 self.glsa.GlsaFormatException,):
469 continue
470
471 if not myglsa.isVulnerable():
472 continue
473
474 glsalist.append(glsa_item)
475
476 return glsalist
477
523
525 """
526 Reimplemented from SpmPlugin class.
527 """
528 return self.portage.settings[key]
529
531 """
532 Reimplemented from SpmPlugin class.
533 """
534 world_file = self.portage_const.WORLD_FILE
535 if root is None:
536 root = etpConst['systemroot'] + os.path.sep
537 return os.path.join(root, world_file)
538
540 """
541 Reimplemented from SpmPlugin class.
542 """
543 config_protect = self.portage.settings['CONFIG_PROTECT']
544 return [os.path.expandvars(x) for x in config_protect.split()]
545
547 """
548 Reimplemented from SpmPlugin class.
549 """
550 config_protect = self.portage.settings['CONFIG_PROTECT_MASK']
551 return [os.path.expandvars(x) for x in config_protect.split()]
552
554 """
555 Reimplemented from SpmPlugin class.
556 """
557 mirrors = []
558 if mirror_name in self.portage.thirdpartymirrors:
559 mirrors.extend(self.portage.thirdpartymirrors[mirror_name])
560 return mirrors
561
598
600 """
601 Reimplemented from SpmPlugin class.
602 """
603 if match_type is None:
604 match_type = "bestmatch-visible"
605 elif match_type not in PortagePlugin.SUPPORTED_MATCH_TYPES:
606 raise KeyError
607 try:
608 return self.portage.portdb.xmatch(match_type, package)
609 except self.portage.exception.PortageException:
610 raise InvalidAtom(package)
611
613 """
614 Reimplemented from SpmPlugin class.
615 """
616 if root is None:
617 root = etpConst['systemroot'] + os.path.sep
618
619 vartree = self._get_portage_vartree(root = root)
620 try:
621 matches = vartree.dep_match(package) or []
622 except self.portage.exception.InvalidAtom as err:
623 raise InvalidAtom(str(err))
624
625 if match_all:
626 return matches
627 elif matches:
628 return matches[-1]
629 return ''
630
632 """
633 Reimplemented from SpmPlugin class.
634 """
635 pkgcat, pkgname = package.split("/", 1)
636 if not os.path.isdir(file_save_path):
637 os.makedirs(file_save_path)
638 file_save_path += "/" + pkgname + etpConst['packagesext']
639 dbdir = os.path.join(self._get_vdb_path(), pkgcat, pkgname)
640
641 import tarfile
642 import stat
643 trees = self.portage.db["/"]
644 vartree = trees["vartree"]
645 dblnk = self.portage.dblink(pkgcat, pkgname, "/", vartree.settings,
646 treetype="vartree", vartree=vartree)
647 if etpConst['uid'] == 0:
648 dblnk.lockdb()
649 tar = tarfile.open(file_save_path, "w:bz2")
650
651 contents = dblnk.getcontents()
652 paths = sorted(contents.keys())
653
654 for path in paths:
655 try:
656 exist = os.lstat(path)
657 except OSError:
658 continue
659 ftype = contents[path][0]
660 lpath = path
661 arcname = path[1:]
662 if 'dir' == ftype and \
663 not stat.S_ISDIR(exist.st_mode) and \
664 os.path.isdir(lpath):
665 lpath = os.path.realpath(lpath)
666 tarinfo = tar.gettarinfo(lpath, arcname)
667
668 if stat.S_ISREG(exist.st_mode):
669 tarinfo.mode = stat.S_IMODE(exist.st_mode)
670 tarinfo.type = tarfile.REGTYPE
671 f = open(path, "rb")
672 try:
673 tar.addfile(tarinfo, f)
674 finally:
675 f.close()
676 else:
677 tar.addfile(tarinfo)
678
679 tar.close()
680
681
682 tbz2 = xpak.tbz2(file_save_path)
683 tbz2.recompose(dbdir)
684
685 dblnk.unlockdb()
686
687 if os.path.isfile(file_save_path):
688 return file_save_path
689
690 raise SPMError("SPMError: Spm:generate_package %s: %s %s" % (
691 _("error"),
692 file_save_path,
693 _("not found"),
694 )
695 )
696
698
699 kmod_pfx = "/lib/modules"
700 content = [x for x in pkg_data['content'] if x.startswith(kmod_pfx)]
701 content = [x for x in content if x != kmod_pfx]
702 if not content:
703 return
704 content.sort()
705
706 for item in content:
707
708 k_base = os.path.basename(item)
709 if k_base.startswith("."):
710 continue
711
712
713 owners = self.search_paths_owners([item])
714 if not owners:
715 continue
716
717
718
719 pkg_data['versiontag'] = k_base
720
721 owner_data = None
722 for k_atom, k_slot in owners:
723 k_cat, k_name, k_ver, k_rev = entropy.tools.catpkgsplit(k_atom)
724 if k_cat == PortagePlugin.KERNEL_CATEGORY:
725 owner_data = (k_cat, k_name, k_ver, k_rev,)
726 break
727
728
729 if owner_data is None:
730 continue
731
732 k_cat, k_name, k_ver, k_rev = owner_data
733 if k_rev != "r0":
734 k_ver += "-%s" % (k_rev,)
735
736
737 pkg_data['slot'] = k_base
738 kern_dep_key = "=%s~-1" % (k_atom,)
739
740 return kern_dep_key
741
743 defaults = self.portage.settings.getvirtuals()[virtual_key]
744 if defaults:
745 return defaults[0]
746
1016
1018 """
1019 Reimplemented from SpmPlugin class.
1020 """
1021 result = self._unset_package_useflags(package, options)
1022 if not result:
1023 return False
1024 return self._handle_new_useflags(package, options, "")
1025
1027 """
1028 Reimplemented from SpmPlugin class.
1029 """
1030 result = self._unset_package_useflags(package, options)
1031 if not result:
1032 return False
1033 return self._handle_new_useflags(package, options, "-")
1034
1036 """
1037 Reimplemented from SpmPlugin class.
1038 """
1039 matched_atom = self.match_package(package)
1040 if not matched_atom:
1041 return {}
1042 global_useflags = self._get_useflags()
1043 use_force = self._get_useflags_force()
1044 use_mask = self._get_useflags_mask()
1045 package_use_useflags = self._get_package_use_useflags(package)
1046
1047 data = {}
1048 data['use_force'] = use_force.copy()
1049 data['use_mask'] = use_mask.copy()
1050 data['global_use'] = global_useflags.split()
1051
1052 iuse = self.get_package_metadata(package, "IUSE")
1053 if not isinstance(iuse, const_get_stringtype()):
1054 iuse = ''
1055 data['iuse'] = iuse.split()[:]
1056 iuse = set()
1057 for myiuse in data['iuse']:
1058 if myiuse.startswith("+"):
1059 myiuse = myiuse[1:]
1060 iuse.add(myiuse)
1061
1062 use = [f for f in data['global_use'] + \
1063 list(package_use_useflags['enabled']) if (f in iuse) \
1064 and (f not in use_mask) and \
1065 (f not in package_use_useflags['disabled'])]
1066
1067 use_disabled = [f for f in iuse if (f not in data['global_use']) \
1068 and (f not in use_mask) and \
1069 (f not in package_use_useflags['enabled'])]
1070
1071 data['use'] = use[:]
1072 data['use_disabled'] = use_disabled[:]
1073
1074 matched_slot = self.get_package_metadata(matched_atom, "SLOT")
1075 try:
1076 inst_key = "%s:%s" % (
1077 entropy.tools.dep_getkey(package),
1078 matched_slot,
1079 )
1080 installed_atom = self.match_installed_package(inst_key)
1081 except self.portage.exception.PortageException:
1082 installed_atom = ''
1083
1084 if installed_atom:
1085
1086
1087 previous_iuse = self.get_installed_package_metadata(installed_atom,
1088 "IUSE").split()
1089 previous_use = self.get_installed_package_metadata(installed_atom,
1090 "USE").split()
1091
1092 new_previous_iuse = set()
1093 for myuse in previous_iuse:
1094 if myuse.startswith("+"):
1095 myuse = myuse[1:]
1096 new_previous_iuse.add(myuse)
1097 previous_iuse = list(new_previous_iuse)
1098
1099 inst_use = [f for f in previous_iuse if (f in previous_use) and \
1100 (f not in use_mask)]
1101
1102
1103
1104
1105 use_removed = []
1106 for myuse in inst_use:
1107 if myuse not in use:
1108 use_removed.append(myuse)
1109
1110
1111 use_not_avail = []
1112 for myuse in previous_iuse:
1113 if (myuse not in iuse) and (myuse not in use_removed):
1114 use_not_avail.append(myuse)
1115
1116
1117 t_use = []
1118 for myuse in use:
1119 if myuse not in inst_use:
1120 myuse = "+%s*" % (myuse,)
1121 t_use.append(myuse)
1122 use = t_use
1123
1124
1125 t_use_disabled = []
1126 for myuse in use_disabled:
1127 if myuse in inst_use:
1128 if myuse in use_removed+use_not_avail:
1129 continue
1130 myuse = "-%s*" % (myuse,)
1131 else:
1132 myuse = "-%s" % (myuse,)
1133 t_use_disabled.append(myuse)
1134 use_disabled = t_use_disabled
1135
1136 for myuse in use_removed:
1137 use_disabled.append("(-%s*)" % (myuse,))
1138 for myuse in use_not_avail:
1139 use_disabled.append("(-%s)" % (myuse,))
1140 else:
1141 use_disabled = ["-"+x for x in use_disabled]
1142
1143 data['use_string'] = ' '.join(sorted(use)+sorted([x for x in \
1144 use_disabled]))
1145 data['use_string_colored'] = ' '.join(
1146 sorted([darkred(x) for x in use if not x.startswith("+")] + \
1147 [darkgreen(x) for x in use if x.startswith("+")]) + \
1148 sorted([darkblue(x) for x in use_disabled if x.startswith("-")] + \
1149 [brown(x) for x in use_disabled if x.startswith("(") and \
1150 (x.find("*") == -1)] + \
1151 [purple(x) for x in use_disabled if x.startswith("(") and \
1152 (x.find("*") != -1)]
1153 )
1154 )
1155
1156 return data
1157
1159 """
1160 Reimplemented from SpmPlugin class.
1161 """
1162 matched_atom = self.match_installed_package(package, root = root)
1163 if not matched_atom:
1164 return {}
1165
1166 global_use = self.get_installed_package_metadata(matched_atom, "USE",
1167 root = root)
1168 use_mask = self._get_useflags_mask()
1169
1170 data = {}
1171 data['use_mask'] = use_mask.copy()
1172 data['global_use'] = global_use.split()
1173
1174 iuse = self.get_installed_package_metadata(matched_atom, "IUSE",
1175 root = root)
1176 if not isinstance(iuse, const_get_stringtype()):
1177 iuse = ''
1178 data['iuse'] = iuse.split()[:]
1179 iuse = set()
1180 for myiuse in data['iuse']:
1181 if myiuse.startswith("+"):
1182 myiuse = myiuse[1:]
1183 iuse.add(myiuse)
1184
1185 use = [f for f in data['global_use'] if (f in iuse) and \
1186 (f not in use_mask)]
1187 use_disabled = [f for f in iuse if (f not in data['global_use']) and \
1188 (f not in use_mask)]
1189 data['use'] = use[:]
1190 data['use_disabled'] = use_disabled[:]
1191
1192 data['use_string'] = ' '.join(sorted(use)+sorted([x for x in \
1193 use_disabled]))
1194 data['use_string_colored'] = ' '.join(
1195 sorted([darkred(x) for x in use if not x.startswith("+")] + \
1196 [darkgreen(x) for x in use if x.startswith("+")]) + \
1197 sorted([darkblue(x) for x in use_disabled if x.startswith("-")] + \
1198 [brown(x) for x in use_disabled if x.startswith("(") and \
1199 (x.find("*") == -1)] + \
1200 [purple(x) for x in use_disabled if x.startswith("(") and \
1201 (x.find("*") != -1)]
1202 )
1203 )
1204 return data
1205
1206 - def get_installed_package_content(self, package, root = None):
1207 """
1208 Reimplemented from SpmPlugin class.
1209 """
1210 if root is None:
1211 root = etpConst['systemroot'] + os.path.sep
1212 mytree = self._get_portage_vartree(root)
1213
1214 cat, pkgv = package.split("/")
1215 return sorted(self.portage.dblink(cat, pkgv, root,
1216 self.portage.settings).getcontents())
1217
1218 - def get_packages(self, categories = None, filter_reinstalls = True):
1219 """
1220 Reimplemented from SpmPlugin class.
1221 """
1222 if categories is None:
1223 categories = []
1224
1225 root = etpConst['systemroot'] + os.path.sep
1226 mysettings = self._get_portage_config(os.path.sep, root)
1227 portdb = self.portage.portdbapi(mysettings["PORTDIR"],
1228 mysettings = mysettings)
1229
1230 cps = portdb.cp_all()
1231 visibles = set()
1232 for cp in cps:
1233 if categories and cp.split("/")[0] not in categories:
1234 continue
1235
1236
1237 slots = set()
1238 atoms = self.match_package(cp, match_type = "match-visible")
1239 if atoms:
1240 for atom in atoms:
1241 slots.add(portdb.aux_get(atom, ["SLOT"])[0])
1242 for slot in slots:
1243 visibles.add(cp+":"+slot)
1244
1245
1246 available = set()
1247 for visible in visibles:
1248
1249 match = self.match_package(visible)
1250 if not match:
1251 continue
1252
1253 if filter_reinstalls:
1254 installed = self.match_installed_package(visible)
1255 if installed != match:
1256 available.add(match)
1257 else:
1258 available.add(match)
1259
1260 return available
1261
1262 - def compile_packages(self, packages, stdin = None, stdout = None,
1263 stderr = None, environ = None, pid_write_func = None,
1264 pretend = False, verbose = False, fetch_only = False,
1265 build_only = False, no_dependencies = False,
1266 ask = False, coloured_output = False, oneshot = False):
1303
1304 - def remove_packages(self, packages, stdin = None, stdout = None,
1305 stderr = None, environ = None, pid_write_func = None,
1306 pretend = False, verbose = False, no_dependencies = False, ask = False,
1307 coloured_output = False):
1339
1348
1349 - def print_build_environment_info(self, stdin = None, stdout = None,
1350 stderr = None, environ = None, pid_write_func = None,
1351 coloured_output = False):
1352
1353 cmd = [PortagePlugin._cmd_map['exec_cmd'],
1354 PortagePlugin._cmd_map['info_cmd']]
1355 if not coloured_output:
1356 cmd.append(PortagePlugin._cmd_map['nocolor_cmd'])
1357
1358 cmd_string = """\
1359 %s && %s && %s
1360 """ % (PortagePlugin._cmd_map['env_update_cmd'],
1361 PortagePlugin._cmd_map['source_profile_cmd'],
1362 ' '.join(cmd)
1363 )
1364
1365 env = os.environ.copy()
1366 if environ is not None:
1367 env.update(environ)
1368
1369 proc = subprocess.Popen(cmd_string, stdout = stdout, stderr = stderr,
1370 stdin = stdin, env = env, shell = True)
1371 if pid_write_func is not None:
1372 pid_write_func(proc.pid)
1373 return proc.wait()
1374
1376 """
1377 Reimplemented from SpmPlugin class.
1378 """
1379 vartree = self._get_portage_vartree(root = root)
1380 packages = vartree.dbapi.cpv_all()
1381 if not categories:
1382 return packages
1383
1384 def catfilter(pkg):
1385 if pkg.split("/", 1)[0] in categories:
1386 return True
1387 return False
1388
1389 return list(filter(catfilter, packages))
1390
1392 """
1393 Reimplemented from SpmPlugin class.
1394 """
1395 config = self._get_set_config()
1396 if config == None:
1397 return {}
1398
1399 mysets = config.getSets()
1400 if not builtin_sets:
1401 builtin_pkg_sets = [x for x in PortagePlugin.builtin_pkg_sets if \
1402 x in mysets]
1403 for pkg_set in builtin_pkg_sets:
1404 mysets.pop(pkg_set)
1405
1406 return dict((x, y.getAtoms(),) for x, y in list(mysets.items()))
1407
1409 """
1410 Reimplemented from SpmPlugin class.
1411 """
1412 spm_name = entropy.tools.remove_tag(entropy_package_name)
1413 spm_name = entropy.tools.remove_entropy_revision(spm_name)
1414 return spm_name
1415
1417 """
1418 Reimplemented from SpmPlugin class.
1419 """
1420 if root is None:
1421 root = etpConst['systemroot'] + os.path.sep
1422
1423 vartree = self._get_portage_vartree(root)
1424 dbbuild = self.get_installed_package_build_script_path(package,
1425 root = root)
1426
1427 counter_dir = os.path.dirname(dbbuild)
1428 counter_name = PortagePlugin.xpak_entries['counter']
1429 counter_path = os.path.join(counter_dir, counter_name)
1430
1431 if not os.access(counter_dir, os.W_OK):
1432 raise SPMError("SPM package directory not found")
1433
1434 with open(counter_path, "wb") as count_f:
1435 new_counter = vartree.dbapi.counter_tick(root, mycpv = package)
1436 count_f.write(const_convert_to_rawstring(new_counter))
1437 count_f.flush()
1438
1439 return new_counter
1440
1443 """
1444 Reimplemented from SpmPlugin class.
1445 """
1446 counter_path = PortagePlugin.xpak_entries['counter']
1447 entropy_atom = entropy_repository.retrieveAtom(
1448 entropy_repository_package_id)
1449
1450 spm_name = self.convert_from_entropy_package_name(entropy_atom)
1451 build_path = self.get_installed_package_build_script_path(spm_name)
1452 atom_counter_path = os.path.join(os.path.dirname(build_path),
1453 counter_path)
1454
1455 if not (os.access(atom_counter_path, os.R_OK) and \
1456 os.path.isfile(atom_counter_path)):
1457 return None
1458
1459 try:
1460 with open(atom_counter_path, "r") as f:
1461 counter = int(f.readline().strip())
1462 except ValueError:
1463 raise SPMError("invalid Unique Identifier found")
1464 except Exception as e:
1465 raise SPMError("General SPM Error: %s" % (e,))
1466
1467 return counter
1468
1470 """
1471 Reimplemented from SpmPlugin class.
1472 """
1473 if not isinstance(paths, (list, set, frozenset, dict, tuple)):
1474 raise AttributeError("iterable needed")
1475 root = etpConst['systemroot'] + os.path.sep
1476 mytree = self._get_portage_vartree(root)
1477 packages = mytree.dbapi.cpv_all()
1478 matches = {}
1479
1480 for package in packages:
1481 cat, pkgv = package.split("/")
1482 content = self.portage.dblink(cat, pkgv, root,
1483 self.portage.settings).getcontents()
1484
1485 if exact_match:
1486 for filename in paths:
1487 if filename in content:
1488 myslot = self.get_installed_package_metadata(package,
1489 "SLOT")
1490 obj = matches.setdefault((package, myslot,), set())
1491 obj.add(filename)
1492 else:
1493 for filename in paths:
1494 for myfile in content:
1495 if myfile.find(filename) == -1:
1496 continue
1497 myslot = self.get_installed_package_metadata(package,
1498 "SLOT")
1499 obj = matches.setdefault((package, myslot,), set())
1500 obj.add(filename)
1501
1502 return matches
1503
1504 - def _portage_doebuild(self, myebuild, mydo, tree, cpv,
1505 portage_tmpdir = None, licenses = None):
1506
1507
1508
1509
1510
1511
1512
1513 if licenses is None:
1514 licenses = []
1515
1516 oldsystderr = sys.stderr
1517 dev_null = open("/dev/null", "w")
1518 if not etpUi['debug']:
1519 sys.stderr = dev_null
1520
1521
1522
1523 domute = False
1524 if etpUi['mute']:
1525 domute = True
1526 oldsysstdout = sys.stdout
1527 sys.stdout = dev_null
1528
1529 root = etpConst['systemroot'] + os.path.sep
1530
1531
1532 os.environ["SKIP_EQUO_SYNC"] = "1"
1533
1534
1535 myebuilddir = os.path.dirname(myebuild)
1536 keys = self.portage.auxdbkeys
1537 metadata = {}
1538
1539 for key in keys:
1540 mykeypath = os.path.join(myebuilddir, key)
1541 if os.path.isfile(mykeypath) and os.access(mykeypath, os.R_OK):
1542 if sys.hexversion >= 0x3000000:
1543 f = open(mykeypath, "r", encoding = "raw_unicode_escape")
1544 else:
1545 f = open(mykeypath, "rb")
1546 metadata[key] = f.readline().strip()
1547 f.close()
1548
1549
1550
1551
1552 mysettings = self._get_portage_config(os.path.sep, root)
1553 mysettings['EBUILD_PHASE'] = mydo
1554
1555
1556
1557
1558
1559
1560 mysettings['LICENSE'] = str(' '.join(licenses))
1561 if licenses:
1562
1563 mysettings["ACCEPT_LICENSE"] = mysettings['LICENSE']
1564 mysettings.backup_changes("ACCEPT_LICENSE")
1565
1566 mysettings['EAPI'] = "0"
1567 if 'EAPI' in metadata:
1568 mysettings['EAPI'] = metadata['EAPI']
1569
1570
1571 mysettings['ROOT'] = root
1572 mysettings['CD_ROOT'] = "/tmp"
1573
1574 mysettings.backup_changes("EAPI")
1575 mysettings.backup_changes("LICENSE")
1576 mysettings.backup_changes("EBUILD_PHASE")
1577 mysettings.backup_changes("ROOT")
1578 mysettings.backup_changes("CD_ROOT")
1579
1580 try:
1581 mysettings._environ_whitelist = set(mysettings._environ_whitelist)
1582
1583 mysettings._environ_whitelist.add("SKIP_EQUO_SYNC")
1584 mysettings._environ_whitelist.add("ACCEPT_LICENSE")
1585 mysettings._environ_whitelist.add("CD_ROOT")
1586 mysettings._environ_whitelist.add("ROOT")
1587 mysettings._environ_whitelist = frozenset(mysettings._environ_whitelist)
1588 except (AttributeError,):
1589 self.log_message(entropy.tools.get_traceback())
1590
1591 portage_tmpdir_created = False
1592
1593 if portage_tmpdir is None:
1594 portage_tmpdir = entropy.tools.get_random_temp_file()
1595
1596 if portage_tmpdir:
1597 if not os.path.isdir(portage_tmpdir):
1598 os.makedirs(portage_tmpdir)
1599 portage_tmpdir_created = True
1600 mysettings['PORTAGE_TMPDIR'] = str(portage_tmpdir)
1601 mysettings.backup_changes("PORTAGE_TMPDIR")
1602
1603
1604 portdir = os.path.join(portage_tmpdir, "portdir")
1605 portdir_lic = os.path.join(portdir, "licenses")
1606 if not os.path.isdir(portdir):
1607 os.mkdir(portdir)
1608
1609 if not os.path.isdir(portdir_lic):
1610 os.mkdir(portdir_lic)
1611
1612
1613 old_portdir = mysettings["PORTDIR"][:]
1614 mysettings["PORTDIR"] = portdir
1615 mysettings.backup_changes("PORTDIR")
1616
1617
1618
1619
1620 for lic in licenses:
1621 lic_path = os.path.join(portdir_lic, lic)
1622 if os.access(portdir_lic, os.W_OK | os.R_OK):
1623 lic_f = open(lic_path, "wb")
1624 lic_f.close()
1625
1626 cpv = str(cpv)
1627 mydbapi = self.portage.fakedbapi(settings=mysettings)
1628 mydbapi.cpv_inject(cpv, metadata = metadata)
1629 mysettings.setcpv(cpv, mydb = mydbapi)
1630
1631
1632 vartree = self._get_portage_vartree(root = root)
1633
1634 try:
1635 rc = self.portage.doebuild(
1636 myebuild = str(myebuild),
1637 mydo = str(mydo),
1638 myroot = root,
1639 tree = tree,
1640 mysettings = mysettings,
1641 mydbapi = mydbapi,
1642 vartree = vartree,
1643 use_cache = 0
1644 )
1645 except:
1646 self.log_message(entropy.tools.get_traceback())
1647 raise
1648
1649
1650 if domute:
1651 sys.stdout = oldsysstdout
1652
1653 sys.stderr = oldsystderr
1654 dev_null.close()
1655
1656 if portage_tmpdir_created:
1657 shutil.rmtree(portage_tmpdir, True)
1658
1659
1660
1661 mysettings["PORTDIR"] = old_portdir
1662 mysettings.backup_changes("PORTDIR")
1663
1664 del mydbapi
1665 del metadata
1666 del keys
1667 return rc
1668
1669 @staticmethod
1671 return package_metadata['category'] + "/" + \
1672 package_metadata['name'] + "-" + package_metadata['version']
1673
1674 @staticmethod
1679
1681
1682 mydir = os.path.dirname(moved_ebuild)
1683 shutil.rmtree(mydir, True)
1684 mydir = os.path.dirname(mydir)
1685 content = os.listdir(mydir)
1686 while not content:
1687 os.rmdir(mydir)
1688 mydir = os.path.dirname(mydir)
1689 content = os.listdir(mydir)
1690
1692
1693 ebuild_path = os.path.dirname(ebuild)
1694
1695 myroot = os.path.sep
1696 if etpConst['systemroot']:
1697 myroot = etpConst['systemroot'] + os.path.sep
1698
1699
1700 bz2envfile = os.path.join(ebuild_path, PortagePlugin.ENV_FILE_COMP)
1701 if os.path.isfile(bz2envfile) and os.path.isdir(myroot):
1702 envfile = entropy.tools.unpack_bzip2(bz2envfile)
1703 bzf = bz2.BZ2File(bz2envfile, "w")
1704 f = open(envfile, "rb")
1705 line = f.readline()
1706 while line:
1707 if sys.hexversion >= 0x3000000:
1708 if line.startswith(b"ROOT="):
1709 line = b"ROOT=%s\n" % (myroot,)
1710 else:
1711 if line.startswith("ROOT="):
1712 line = "ROOT=%s\n" % (myroot,)
1713 bzf.write(line)
1714 line = f.readline()
1715
1716 f.close()
1717 bzf.close()
1718 os.remove(envfile)
1719
1721
1722 ebuild_dir = os.path.dirname(myebuild)
1723 ebuild_file = os.path.basename(myebuild)
1724 moved_ebuild = None
1725
1726
1727 dest_dir = os.path.join(etpConst['entropyunpackdir'],
1728 "vardb/" + portage_atom)
1729 if os.path.exists(dest_dir):
1730 if os.path.isdir(dest_dir):
1731 shutil.rmtree(dest_dir, True)
1732 elif os.path.isfile(dest_dir) or os.path.islink(dest_dir):
1733 os.remove(dest_dir)
1734
1735 os.makedirs(dest_dir)
1736 items = os.listdir(ebuild_dir)
1737 for item in items:
1738 myfrom = os.path.join(ebuild_dir, item)
1739 myto = os.path.join(dest_dir, item)
1740 shutil.copy2(myfrom, myto)
1741
1742 newmyebuild = os.path.join(dest_dir, ebuild_file)
1743 if os.path.isfile(newmyebuild):
1744 myebuild = newmyebuild
1745 moved_ebuild = myebuild
1746 self._pkg_remove_ebuild_env_setup_hook(myebuild)
1747
1748 return myebuild, moved_ebuild
1749
1750 - def _pkg_setup(self, package_metadata, skip_if_found = False):
1751
1752 package = PortagePlugin._pkg_compose_atom(package_metadata)
1753 env_file = os.path.join(package_metadata['unpackdir'], "portage",
1754 package, "temp/environment")
1755
1756 if os.path.isfile(env_file) and skip_if_found:
1757 return 0
1758
1759
1760
1761
1762
1763
1764
1765 bz2envfile = os.path.join(package_metadata['xpakdir'],
1766 PortagePlugin.ENV_FILE_COMP)
1767
1768 if "linux-info" in package_metadata['eclasses'] and \
1769 os.path.isfile(bz2envfile) and package_metadata['versiontag']:
1770
1771 envfile = entropy.tools.unpack_bzip2(bz2envfile)
1772 bzf = bz2.BZ2File(bz2envfile, "w")
1773 f = open(envfile, "rb")
1774 line = f.readline()
1775 while line:
1776
1777 if sys.hexversion >= 0x3000000:
1778 if line == b"KV_OUT_DIR=/usr/src/linux\n":
1779 line = b"KV_OUT_DIR=/lib/modules/"
1780 line += const_convert_to_rawstring(
1781 package_metadata['versiontag'])
1782 line += "/build\n"
1783 else:
1784 if line == "KV_OUT_DIR=/usr/src/linux\n":
1785 line = "KV_OUT_DIR=/lib/modules/%s/build\n" % (
1786 package_metadata['versiontag'],)
1787 bzf.write(line)
1788 line = f.readline()
1789 f.close()
1790 bzf.close()
1791 os.remove(envfile)
1792
1793 ebuild = PortagePlugin._pkg_compose_xpak_ebuild(package_metadata)
1794 rc = self._portage_doebuild(ebuild, "setup",
1795 "bintree", package, portage_tmpdir = package_metadata['unpackdir'],
1796 licenses = package_metadata.get('accept_license'))
1797
1798 if rc == 1:
1799 self.log_message(
1800 "[POST] ATTENTION Cannot properly run Source Package Manager"
1801 " setup phase for %s Something bad happened." % (package,)
1802 )
1803
1804 return rc
1805
1807
1808 tmp_file = tempfile.mktemp()
1809 stdfile = open(tmp_file, "wb")
1810 oldstderr = sys.stderr
1811 oldstdout = sys.stdout
1812 sys.stderr = stdfile
1813
1814 package = PortagePlugin._pkg_compose_atom(package_metadata)
1815 ebuild = PortagePlugin._pkg_compose_xpak_ebuild(package_metadata)
1816 rc = 0
1817 remove_tmp = True
1818
1819 try:
1820
1821 if not (os.path.isfile(ebuild) and os.access(ebuild, os.R_OK)):
1822 return rc
1823
1824 try:
1825
1826 if not etpUi['debug']:
1827 sys.stdout = stdfile
1828 self._pkg_setup(package_metadata, skip_if_found = True)
1829 if not etpUi['debug']:
1830 sys.stdout = oldstdout
1831
1832 rc = self._portage_doebuild(ebuild, phase, "bintree",
1833 package, portage_tmpdir = package_metadata['unpackdir'],
1834 licenses = package_metadata.get('accept_license'))
1835
1836 if rc != 0:
1837 self.log_message(
1838 "[PRE] ATTENTION Cannot properly run SPM %s"
1839 " phase for %s. Something bad happened." % (
1840 phase, package,)
1841 )
1842
1843 except Exception as e:
1844
1845 stdfile.flush()
1846 sys.stdout = oldstdout
1847 entropy.tools.print_traceback()
1848
1849 self.log_message(
1850 "[PRE] ATTENTION Cannot properly run SPM %s"
1851 " phase for %s. Something bad happened."
1852 " Exception %s [%s]" % (
1853 phase, package, Exception, e,)
1854 )
1855
1856 mytxt = "%s: %s %s." % (
1857 bold(_("QA")),
1858 brown(_("Cannot run Source Package Manager trigger for")),
1859 bold(str(package)),
1860 )
1861 self.updateProgress(
1862 mytxt,
1863 importance = 0,
1864 header = red(" ## ")
1865 )
1866 mytxt = "%s. %s: %s + %s [%s]" % (
1867 brown(_("Please report it")),
1868 bold(_("Attach this")),
1869 darkred(etpConst['spmlogfile']),
1870 darkred(tmp_file),
1871 brown(phase),
1872 )
1873 self.updateProgress(
1874 mytxt,
1875 importance = 0,
1876 header = red(" ## ")
1877 )
1878 remove_tmp = False
1879
1880 return rc
1881
1882 finally:
1883
1884 sys.stderr = oldstderr
1885 sys.stdout = oldstdout
1886 stdfile.flush()
1887 stdfile.close()
1888
1889 if (rc == 0) and remove_tmp:
1890 try:
1891 os.remove(tmp_file)
1892 except OSError:
1893 pass
1894
1896
1897 tmp_file = tempfile.mktemp()
1898 stdfile = open(tmp_file, "wb")
1899 oldstderr = sys.stderr
1900 oldstdout = sys.stdout
1901 sys.stderr = stdfile
1902
1903 rc = 0
1904 remove_tmp = True
1905 moved_ebuild = None
1906 package = PortagePlugin._pkg_compose_atom(package_metadata)
1907 ebuild = self.get_installed_package_build_script_path(package)
1908
1909 try:
1910
1911 if not os.path.isfile(ebuild):
1912 return 0
1913
1914 try:
1915 ebuild, moved_ebuild = self._pkg_remove_setup_ebuild_env(
1916 ebuild, package)
1917
1918 except EOFError as e:
1919 sys.stderr = oldstderr
1920
1921 self.updateProgress(
1922 darkred("!!! Ebuild: pkg_" + phase + "() failed, EOFError: ") + \
1923 str(e) + darkred(" - ignoring"),
1924 importance = 1,
1925 type = "warning",
1926 header = red(" ## ")
1927 )
1928 return 0
1929
1930 except ImportError as e:
1931 sys.stderr = oldstderr
1932
1933 self.updateProgress(
1934 darkred("!!! Ebuild: pkg_" + phase + "() failed, ImportError: ") + \
1935 str(e) + darkred(" - ignoring"),
1936 importance = 1,
1937 type = "warning",
1938 header = red(" ## ")
1939 )
1940 return 0
1941
1942 try:
1943
1944 work_dir = os.path.join(etpConst['entropyunpackdir'], package)
1945
1946 rc = self._portage_doebuild(ebuild, phase, "bintree",
1947 package, portage_tmpdir = work_dir,
1948 licenses = package_metadata.get('accept_license'))
1949
1950 if rc != 1:
1951 self.log_message(
1952 "[PRE] ATTENTION Cannot properly run SPM %s trigger "
1953 "for %s. Something bad happened." % (phase, package,)
1954 )
1955
1956 except Exception as e:
1957
1958 stdfile.flush()
1959 sys.stdout = oldstdout
1960 entropy.tools.print_traceback()
1961
1962 self.log_message(
1963 "[PRE] ATTENTION Cannot properly run SPM %s"
1964 " phase for %s. Something bad happened."
1965 " Exception %s [%s]" % (phase, package, Exception, e,)
1966 )
1967
1968 mytxt = "%s: %s %s." % (
1969 bold(_("QA")),
1970 brown(_("Cannot run Source Package Manager trigger for")),
1971 bold(str(package)),
1972 )
1973 self.updateProgress(
1974 mytxt,
1975 importance = 0,
1976 header = red(" ## ")
1977 )
1978 mytxt = "%s. %s: %s + %s [%s]" % (
1979 brown(_("Please report it")),
1980 bold(_("Attach this")),
1981 darkred(etpConst['spmlogfile']),
1982 darkred(tmp_file),
1983 brown(phase),
1984 )
1985 self.updateProgress(
1986 mytxt,
1987 importance = 0,
1988 header = red(" ## ")
1989 )
1990 remove_tmp = False
1991
1992 if moved_ebuild is not None:
1993 if os.path.isfile(moved_ebuild):
1994 self._pkg_remove_overlayed_ebuild(moved_ebuild)
1995
1996 return rc
1997
1998 finally:
1999
2000 sys.stderr = oldstderr
2001 sys.stdout = oldstdout
2002 stdfile.flush()
2003 stdfile.close()
2004
2005 if (rc == 0) and remove_tmp:
2006 try:
2007 os.remove(tmp_file)
2008 except OSError:
2009 pass
2010
2012 return self._pkg_fooinst(package_metadata, "preinst")
2013
2014 - def _pkg_postinst(self, package_metadata):
2015 return self._pkg_fooinst(package_metadata, "postinst")
2016
2018 return self._pkg_foorm(package_metadata, "prerm")
2019
2020 - def _pkg_postrm(self, package_metadata):
2021 return self._pkg_foorm(package_metadata, "postrm")
2022
2024
2025 package = PortagePlugin._pkg_compose_atom(package_metadata)
2026 ebuild = self.get_installed_package_build_script_path(package)
2027 if not os.path.isfile(ebuild):
2028 return 2
2029
2030 try:
2031
2032 rc = self._portage_doebuild(ebuild, "config", "bintree",
2033 package, licenses = package_metadata.get('accept_license'))
2034
2035 if rc != 0:
2036 return 3
2037
2038 except Exception as err:
2039
2040 entropy.tools.print_traceback()
2041 mytxt = "%s: %s %s." % (
2042 bold(_("QA")),
2043 brown(_("Cannot run SPM configure phase for")),
2044 bold(str(package)),
2045 )
2046 mytxt2 = "%s: %s, %s" % (
2047 bold(_("Error")),
2048 type(Exception),
2049 err,
2050 )
2051 for txt in (mytxt, mytxt2,):
2052 self.updateProgress(
2053 txt,
2054 importance = 0,
2055 header = red(" ## ")
2056 )
2057 return 1
2058
2059 return 0
2060
2074
2076 """
2077 Executes packages regeneration for given atoms.
2078 """
2079 package_paths = set()
2080 runatoms = set()
2081 for myatom in atoms:
2082 mymatch = repo_db.atomMatch(myatom)
2083 if mymatch[0] == -1:
2084 continue
2085 myatom = repo_db.retrieveAtom(mymatch[0])
2086 myatom = entropy.tools.remove_tag(myatom)
2087 runatoms.add(myatom)
2088
2089 for myatom in runatoms:
2090
2091 self.updateProgress(
2092 red("%s: " % (_("repackaging"),) )+blue(myatom),
2093 importance = 1,
2094 type = "warning",
2095 header = blue(" # ")
2096 )
2097 mydest = entropy_server.get_local_store_directory(repo = repo)
2098 try:
2099 mypath = self.generate_package(myatom, mydest)
2100 except:
2101
2102 mypath = os.path.join(mydest,
2103 os.path.basename(myatom) + etpConst['packagesext'])
2104 if os.path.isfile(mypath):
2105 os.remove(mypath)
2106 entropy.tools.print_traceback()
2107 mytxt = "%s: %s: %s, %s." % (
2108 bold(_("WARNING")),
2109 red(_("Cannot complete quickpkg for atom")),
2110 blue(myatom),
2111 _("do it manually"),
2112 )
2113 self.updateProgress(
2114 mytxt,
2115 importance = 1,
2116 type = "warning",
2117 header = darkred(" * ")
2118 )
2119 continue
2120 package_paths.add(mypath)
2121 packages_data = [(x, False,) for x in package_paths]
2122 idpackages = entropy_server.add_packages_to_repository(packages_data,
2123 repo = repo)
2124
2125 if not idpackages:
2126
2127 mytxt = "%s: %s. %s." % (
2128 bold(_("ATTENTION")),
2129 red(_("package files rebuild did not run properly")),
2130 red(_("Please update packages manually")),
2131 )
2132 self.updateProgress(
2133 mytxt,
2134 importance = 1,
2135 type = "warning",
2136 header = darkred(" * ")
2137 )
2138
2139 - def package_names_update(self, entropy_repository, entropy_repository_id,
2140 entropy_server, entropy_branch):
2141
2142
2143 from entropy.server.interfaces.main import ServerEntropyRepositoryPlugin
2144
2145 repo_updates_file = entropy_server.get_local_database_treeupdates_file(
2146 entropy_repository_id)
2147 do_rescan = False
2148
2149 stored_digest = entropy_repository.retrieveRepositoryUpdatesDigest(
2150 entropy_repository_id)
2151 if stored_digest == -1:
2152 do_rescan = True
2153
2154
2155 portage_dirs_digest = "0"
2156 if not do_rescan:
2157
2158 if entropy_repository_id in \
2159 self.__entropy_repository_treeupdate_digests:
2160
2161 portage_dirs_digest = \
2162 self.__entropy_repository_treeupdate_digests.get(
2163 entropy_repository_id)
2164 else:
2165
2166
2167 updates_dir = etpConst['systemroot'] + \
2168 self.get_setting("PORTDIR") + "/profiles/updates"
2169 if os.path.isdir(updates_dir):
2170
2171 mdigest = entropy.tools.md5obj_directory(updates_dir)
2172
2173 if os.path.isfile(repo_updates_file):
2174 f = open(repo_updates_file)
2175 block = f.read(1024)
2176 while block:
2177 mdigest.update(block)
2178 block = f.read(1024)
2179 f.close()
2180 portage_dirs_digest = mdigest.hexdigest()
2181 self.__entropy_repository_treeupdate_digests[entropy_repository_id] = \
2182 portage_dirs_digest
2183
2184 if do_rescan or (str(stored_digest) != str(portage_dirs_digest)):
2185
2186
2187 entropy_repository.readOnly = False
2188
2189 entropy_repository.set_plugin_metadata(
2190 ServerEntropyRepositoryPlugin.PLUGIN_ID, "no_upload", True)
2191
2192
2193 entropy_repository.clearTreeupdatesEntries(entropy_repository_id)
2194
2195 updates_dir = etpConst['systemroot'] + \
2196 self.get_setting("PORTDIR") + "/profiles/updates"
2197 update_files = PortageMetaphor.sort_update_files(
2198 os.listdir(updates_dir))
2199 update_files = [os.path.join(updates_dir, x) for x in update_files]
2200
2201 update_actions = []
2202 for update_file in update_files:
2203 f = open(update_file, "r")
2204 mycontent = f.readlines()
2205 f.close()
2206 lines = [x.strip() for x in mycontent if x.strip()]
2207 update_actions.extend(lines)
2208
2209
2210 if os.path.isfile(repo_updates_file):
2211 f = open(repo_updates_file, "r")
2212 mycontent = f.readlines()
2213 f.close()
2214 lines = [x.strip() for x in mycontent if x.strip() and \
2215 not x.strip().startswith("#")]
2216 update_actions.extend(lines)
2217
2218 update_actions = entropy_repository.filterTreeUpdatesActions(
2219 update_actions)
2220 if update_actions:
2221
2222 mytxt = "%s: %s. %s %s" % (
2223 bold(_("ATTENTION")),
2224 red(_("forcing package updates")),
2225 red(_("Syncing with")),
2226 blue(updates_dir),
2227 )
2228 self.updateProgress(
2229 mytxt,
2230 importance = 1,
2231 type = "info",
2232 header = brown(" * ")
2233 )
2234
2235 if entropy_repository.get_plugins_metadata().get("lock_remote"):
2236 no_upload = entropy_repository.get_plugins_metadata().get(
2237 "no_upload")
2238 entropy_server.do_server_repository_sync_lock(
2239 entropy_repository_id, no_upload)
2240
2241 try:
2242 quickpkg_list = entropy_repository.runTreeUpdatesActions(
2243 update_actions)
2244 except:
2245
2246 entropy_repository.setRepositoryUpdatesDigest(
2247 entropy_repository_id, "-1")
2248 raise
2249
2250 if quickpkg_list:
2251
2252 try:
2253 self.__run_pkg_sync_quickpkg(
2254 entropy_server,
2255 quickpkg_list, entropy_repository,
2256 entropy_repository_id)
2257 except:
2258 entropy.tools.print_traceback()
2259 mytxt = "%s: %s: %s, %s." % (
2260 bold(_("WARNING")),
2261 red(_("Cannot complete quickpkg for atoms")),
2262 blue(str(sorted(quickpkg_list))),
2263 _("do it manually"),
2264 )
2265 self.updateProgress(
2266 mytxt,
2267 importance = 1,
2268 type = "warning",
2269 header = darkred(" * ")
2270 )
2271 entropy_repository.commitChanges()
2272
2273
2274 entropy_repository.addRepositoryUpdatesActions(
2275 entropy_repository_id, update_actions, entropy_branch)
2276
2277
2278 entropy_repository.setRepositoryUpdatesDigest(
2279 entropy_repository_id, portage_dirs_digest)
2280 entropy_repository.commitChanges()
2281
2282 @staticmethod
2288
2289 @staticmethod
2295
2297 """
2298 Reimplemented from SpmPlugin class.
2299 """
2300 portage_phase = PortagePlugin._package_phases_map[phase_name]
2301 phase_calls = {
2302 'setup': self._pkg_setup,
2303 'preinst': self._pkg_preinst,
2304 'postinst': self._pkg_postinst,
2305 'prerm': self._pkg_prerm,
2306 'postrm': self._pkg_postrm,
2307 'config': self._pkg_config,
2308 }
2309 return phase_calls[portage_phase](package_metadata)
2310
2312 """
2313 Reimplemented from SpmPlugin class.
2314 """
2315 atomsfound = set()
2316 spm_package = PortagePlugin._pkg_compose_atom(package_metadata)
2317 key = entropy.tools.dep_getkey(spm_package)
2318 category = key.split("/")[0]
2319
2320 build = self.get_installed_package_build_script_path(spm_package)
2321 pkg_dir = package_metadata.get('unittest_root', '') + \
2322 os.path.dirname(build)
2323 cat_dir = os.path.dirname(pkg_dir)
2324
2325 if os.path.isdir(cat_dir):
2326 my_findings = [os.path.join(category, x) for x in \
2327 os.listdir(cat_dir)]
2328
2329 real_findings = [x for x in my_findings if \
2330 key == entropy.tools.dep_getkey(x)]
2331 atomsfound.update(real_findings)
2332
2333 myslot = package_metadata['slot']
2334 for xatom in atomsfound:
2335
2336 try:
2337 if self.get_installed_package_metadata(xatom, "SLOT") != myslot:
2338 continue
2339 except KeyError:
2340 continue
2341
2342 mybuild = self.get_installed_package_build_script_path(xatom)
2343 remove_path = os.path.dirname(mybuild)
2344 shutil.rmtree(remove_path, True)
2345
2346
2347 xpak_rel_path = etpConst['entropyxpakdatarelativepath']
2348 proposed_xpak_dir = os.path.join(package_metadata['xpakpath'],
2349 xpak_rel_path)
2350
2351 counter = -1
2352 if (package_metadata['xpakstatus'] != None) and \
2353 os.path.isdir(proposed_xpak_dir) or package_metadata['merge_from']:
2354
2355 copypath = proposed_xpak_dir
2356 if package_metadata['merge_from']:
2357 copypath = package_metadata['xpakdir']
2358 if not os.path.isdir(copypath):
2359 return 0
2360
2361 if not os.path.isdir(cat_dir):
2362 os.makedirs(cat_dir, 0o755)
2363 if os.path.isdir(pkg_dir):
2364 shutil.rmtree(pkg_dir)
2365
2366 try:
2367 shutil.copytree(copypath, pkg_dir)
2368 except (IOError,) as e:
2369 mytxt = "%s: %s: %s: %s" % (red(_("QA")),
2370 brown(_("Cannot update Portage database to destination")),
2371 purple(pkg_dir), e,)
2372 self.updateProgress(
2373 mytxt,
2374 importance = 1,
2375 type = "warning",
2376 header = darkred(" ## ")
2377 )
2378
2379
2380
2381 if not package_metadata.get('unittest_root'):
2382 try:
2383 counter = self.assign_uid_to_installed_package(spm_package)
2384 except SPMError as err:
2385 mytxt = "%s: %s [%s]" % (
2386 brown(_("SPM uid update error")), pkg_dir, err,
2387 )
2388 self.updateProgress(
2389 red("QA: ") + mytxt,
2390 importance = 1,
2391 type = "warning",
2392 header = darkred(" ## ")
2393 )
2394 counter = -1
2395
2396 user_inst_source = etpConst['install_sources']['user']
2397 if package_metadata['install_source'] != user_inst_source:
2398
2399 return counter
2400
2401 myslot = package_metadata['slot'][:]
2402 if (package_metadata['versiontag'] == package_metadata['slot']) \
2403 and package_metadata['versiontag']:
2404
2405 myslot = "0"
2406
2407 keyslot = const_convert_to_rawstring(key+":"+myslot)
2408 key = const_convert_to_rawstring(key)
2409 world_file = self.get_user_installed_packages_file()
2410 world_dir = os.path.dirname(world_file)
2411 world_atoms = set()
2412
2413 if os.access(world_file, os.R_OK) and os.path.isfile(world_file):
2414 with open(world_file, "rb") as world_f:
2415 world_atoms |= set((x.strip() for x in world_f.readlines() if \
2416 x.strip()))
2417
2418 try:
2419
2420 if keyslot not in world_atoms and \
2421 os.access(world_dir, os.W_OK) and \
2422 entropy.tools.istextfile(world_file):
2423
2424 world_atoms.discard(key)
2425 world_atoms.add(keyslot)
2426 world_file_tmp = world_file+".entropy_inst"
2427
2428 newline = const_convert_to_rawstring("\n")
2429 with open(world_file_tmp, "wb") as world_f:
2430 for item in sorted(world_atoms):
2431 world_f.write(
2432 const_convert_to_rawstring(item + newline))
2433 world_f.flush()
2434
2435 os.rename(world_file_tmp, world_file)
2436
2437 except (UnicodeDecodeError, UnicodeEncodeError,) as e:
2438
2439 mytxt = "%s: %s" % (
2440 brown(_("Cannot update SPM installed pkgs file")), world_file,
2441 )
2442 self.updateProgress(
2443 red("QA: ") + mytxt + ": " + repr(e),
2444 importance = 1,
2445 type = "warning",
2446 header = darkred(" ## ")
2447 )
2448
2449 return counter
2450
2452 """
2453 Reimplemented from SpmPlugin class.
2454 """
2455 atom = entropy.tools.remove_tag(package_metadata['removeatom'])
2456 remove_build = self.get_installed_package_build_script_path(atom)
2457 remove_path = os.path.dirname(remove_build)
2458 key = entropy.tools.dep_getkey(atom)
2459
2460 others_installed = self.match_installed_package(key, match_all = True)
2461
2462
2463 slot = package_metadata['slot']
2464 tag = package_metadata['versiontag']
2465 if (tag == slot) and tag:
2466 slot = "0"
2467
2468 def do_rm_path_atomic(xpath):
2469 for my_el in os.listdir(xpath):
2470 my_el = os.path.join(xpath, my_el)
2471 try:
2472 os.remove(my_el)
2473 except OSError:
2474 pass
2475 try:
2476 os.rmdir(xpath)
2477 except OSError:
2478 pass
2479
2480 if os.path.isdir(remove_path):
2481 do_rm_path_atomic(remove_path)
2482
2483
2484 category_path = os.path.dirname(remove_path)
2485 if os.path.isdir(category_path):
2486 if not os.listdir(category_path):
2487 try:
2488 os.rmdir(category_path)
2489 except OSError:
2490 pass
2491
2492 if isinstance(others_installed, (list, set, tuple)):
2493
2494 for myatom in others_installed:
2495
2496 if myatom == atom:
2497
2498 continue
2499
2500 try:
2501 myslot = self.get_installed_package_metadata(myatom, "SLOT")
2502 except KeyError:
2503
2504 continue
2505
2506 if myslot != slot:
2507 continue
2508 mybuild = self.get_installed_package_build_script_path(myatom)
2509 mydir = os.path.dirname(mybuild)
2510 if not os.path.isdir(mydir):
2511 continue
2512 do_rm_path_atomic(mydir)
2513
2514 return 0
2515
2516
2517 world_file = self.get_user_installed_packages_file()
2518 world_file_tmp = world_file + ".entropy.tmp"
2519 if os.access(world_file, os.W_OK) and os.path.isfile(world_file):
2520
2521 new = open(world_file_tmp, "wb")
2522 old = open(world_file, "rb")
2523 line = old.readline()
2524 key = const_convert_to_rawstring(key)
2525 keyslot = const_convert_to_rawstring(key+":"+slot)
2526
2527 while line:
2528
2529 if line.find(key) != -1:
2530 line = old.readline()
2531 continue
2532 if line.find(keyslot) != -1:
2533 line = old.readline()
2534 continue
2535 new.write(line)
2536 line = old.readline()
2537
2538 new.flush()
2539 new.close()
2540 old.close()
2541 os.rename(world_file_tmp, world_file)
2542
2543 return 0
2544
2545 @staticmethod
2547 """
2548 Reimplemented from SpmPlugin class.
2549 """
2550 tests = [PortagePlugin._test_environment_bz2]
2551 msg = None
2552 exec_rc = 0
2553 for test in tests:
2554 exec_rc, msg = test(package_path)
2555 if exec_rc != 0:
2556 break
2557 return exec_rc, msg
2558
2559 @staticmethod
2561
2562 tmp_path = tempfile.mkdtemp()
2563 xpaktools.extract_xpak(package_path, tmpdir = tmp_path)
2564 if not os.listdir(tmp_path):
2565 shutil.rmtree(tmp_path)
2566 return 1, "unable to extract xpak metadata"
2567
2568
2569 env_file = os.path.join(tmp_path, PortagePlugin.ENV_FILE_COMP)
2570 if not (os.path.isfile(env_file) and os.access(env_file, os.R_OK)):
2571 shutil.rmtree(tmp_path)
2572 return 2, "unable to locate %s file" % (
2573 PortagePlugin.ENV_FILE_COMP,)
2574
2575
2576 sys_settings = SystemSettings()
2577 srv_plug_id = etpConst['system_settings_plugins_ids']['server_plugin']
2578 try:
2579 qa_langs = sys_settings[srv_plug_id]['server']['qa_langs']
2580 except KeyError:
2581 qa_langs = ["en_US", "C"]
2582
2583 qa_rlangs = [const_convert_to_rawstring("LC_ALL="+x) for x in qa_langs]
2584
2585
2586 bz_f = bz2.BZ2File(env_file, "r")
2587 valid_lc_all = False
2588 lc_found = False
2589 msg = None
2590 lc_all_str = const_convert_to_rawstring("LC_ALL")
2591 found_lang = None
2592 try:
2593 for line in bz_f.readlines():
2594 if not line.startswith(lc_all_str):
2595 continue
2596 lc_found = True
2597 found_lang = line.strip()
2598 for lang in qa_rlangs:
2599 if line.startswith(lang):
2600 valid_lc_all = True
2601 break
2602 finally:
2603 bz_f.close()
2604
2605 env_rc = 0
2606 if lc_found and (not valid_lc_all):
2607 msg = "LC_ALL not set to => %s (but: %s)" % (qa_langs, found_lang,)
2608 env_rc = 1
2609 shutil.rmtree(tmp_path)
2610
2611 return env_rc, msg
2612
2613 @staticmethod
2615
2616
2617 system_make_conf = PortagePlugin._config_files_map['global_make_conf']
2618
2619 avail_data = entropy_client.SystemSettings['repositories']['available']
2620 repo_dbpath = avail_data[repo]['dbpath']
2621 repo_make_conf = os.path.join(repo_dbpath,
2622 os.path.basename(system_make_conf))
2623
2624 if not (os.path.isfile(repo_make_conf) and \
2625 os.access(repo_make_conf, os.R_OK)):
2626 return
2627
2628 make_conf_variables_check = ["CHOST"]
2629
2630 if not os.path.isfile(system_make_conf):
2631 entropy_client.updateProgress(
2632 "%s %s. %s." % (
2633 red(system_make_conf),
2634 blue(_("does not exist")), blue(_("Overwriting")),
2635 ),
2636 importance = 1,
2637 type = "info",
2638 header = blue(" @@ ")
2639 )
2640 if os.path.lexists(system_make_conf):
2641 shutil.move(
2642 system_make_conf,
2643 "%s.backup_%s" % (system_make_conf,
2644 entropy.tools.get_random_number(),)
2645 )
2646 shutil.copy2(repo_make_conf, system_make_conf)
2647
2648 elif os.access(system_make_conf, os.W_OK):
2649
2650 repo_f = open(repo_make_conf, "r")
2651 sys_f = open(system_make_conf, "r")
2652 repo_make_c = [x.strip() for x in repo_f.readlines()]
2653 sys_make_c = [x.strip() for x in sys_f.readlines()]
2654 repo_f.close()
2655 sys_f.close()
2656
2657
2658 repo_data = {}
2659 for setting in make_conf_variables_check:
2660 for line in repo_make_c:
2661 if line.startswith(setting+"="):
2662
2663
2664 repo_data[setting] = line
2665
2666
2667
2668 differences = {}
2669
2670 for setting in repo_data:
2671 for idx in range(len(sys_make_c)):
2672 line = sys_make_c[idx]
2673
2674 if line.startswith(setting+"=") and \
2675 (line != repo_data[setting]):
2676
2677
2678
2679 entropy_client.updateProgress(
2680 "%s: %s %s. %s." % (
2681 red(system_make_conf), bold(repr(setting)),
2682 blue(_("variable differs")), red(_("Updating")),
2683 ),
2684 importance = 1,
2685 type = "info",
2686 header = blue(" @@ ")
2687 )
2688 differences[setting] = repo_data[setting]
2689 line = repo_data[setting]
2690 sys_make_c[idx] = line
2691
2692 if differences:
2693
2694 entropy_client.updateProgress(
2695 "%s: %s." % (
2696 red(system_make_conf),
2697 blue(_("updating critical variables")),
2698 ),
2699 importance = 1,
2700 type = "info",
2701 header = blue(" @@ ")
2702 )
2703
2704 shutil.copy2(system_make_conf,
2705 "%s.entropy_backup" % (system_make_conf,))
2706
2707 entropy_client.updateProgress(
2708 "%s: %s." % (
2709 red(system_make_conf),
2710 darkgreen("writing changes to disk"),
2711 ),
2712 importance = 1,
2713 type = "info",
2714 header = blue(" @@ ")
2715 )
2716
2717 tmp_make_conf = "%s.entropy_write" % (system_make_conf,)
2718 f = open(tmp_make_conf, "w")
2719 for line in sys_make_c:
2720 f.write(line+"\n")
2721 f.flush()
2722 f.close()
2723 shutil.move(tmp_make_conf, system_make_conf)
2724
2725
2726 for var in differences:
2727 try:
2728 myval = '='.join(differences[var].strip().split("=")[1:])
2729 if myval:
2730 if myval[0] in ("'", '"',): myval = myval[1:]
2731 if myval[-1] in ("'", '"',): myval = myval[:-1]
2732 except IndexError:
2733 myval = ''
2734 os.environ[var] = myval
2735
2736 @staticmethod
2738
2739 avail_data = entropy_client.SystemSettings['repositories']['available']
2740 repo_dbpath = avail_data[repo]['dbpath']
2741 profile_link = PortagePlugin._config_files_map['global_make_profile']
2742 profile_link_name = os.path.basename(profile_link)
2743
2744 repo_make_profile = os.path.join(repo_dbpath, profile_link_name)
2745
2746 if not (os.path.isfile(repo_make_profile) and \
2747 os.access(repo_make_profile, os.R_OK)):
2748 return
2749
2750 system_make_profile = \
2751 PortagePlugin._config_files_map['global_make_profile']
2752
2753 f = open(repo_make_profile, "r")
2754 repo_profile_link_data = f.readline().strip()
2755 f.close()
2756 current_profile_link = ''
2757 if os.path.islink(system_make_profile) and \
2758 os.access(system_make_profile, os.R_OK):
2759
2760 current_profile_link = os.readlink(system_make_profile)
2761
2762 if (repo_profile_link_data != current_profile_link) and \
2763 repo_profile_link_data:
2764
2765 entropy_client.updateProgress(
2766 "%s: %s %s. %s." % (
2767 red(system_make_profile), blue("link"),
2768 blue(_("differs")), red(_("Updating")),
2769 ),
2770 importance = 1,
2771 type = "info",
2772 header = blue(" @@ ")
2773 )
2774 merge_sfx = ".entropy_merge"
2775 os.symlink(repo_profile_link_data, system_make_profile+merge_sfx)
2776 if entropy.tools.is_valid_path(system_make_profile+merge_sfx):
2777 os.rename(system_make_profile+merge_sfx, system_make_profile)
2778 else:
2779
2780 entropy_client.updateProgress(
2781 "%s: %s %s. %s." % (
2782 red(system_make_profile), blue("new link"),
2783 blue(_("does not exist")), red(_("Reverting")),
2784 ),
2785 importance = 1,
2786 type = "info",
2787 header = blue(" @@ ")
2788 )
2789 os.remove(system_make_profile+merge_sfx)
2790
2791 @staticmethod
2792 - def entropy_client_post_repository_update_hook(entropy_client,
2793 entropy_repository_id):
2794
2795
2796 if etpConst['uid'] != 0:
2797 entropy_client.updateProgress(
2798 brown(_("Skipping configuration files update, you are not root.")),
2799 importance = 1,
2800 type = "info",
2801 header = blue(" @@ ")
2802 )
2803 return 0
2804
2805 default_repo = \
2806 entropy_client.SystemSettings['repositories']['default_repository']
2807
2808 if default_repo == entropy_repository_id:
2809 PortagePlugin._config_updates_make_conf(entropy_client,
2810 entropy_repository_id)
2811 PortagePlugin._config_updates_make_profile(entropy_client,
2812 entropy_repository_id)
2813
2814 return 0
2815
2816 @staticmethod
2818 """
2819 Reimplemented from SpmPlugin class.
2820 """
2821 package_metadata['xpakpath'] = etpConst['entropyunpackdir'] + \
2822 os.path.sep + package_metadata['download'] + os.path.sep + \
2823 etpConst['entropyxpakrelativepath']
2824
2825 if not package_metadata['merge_from']:
2826
2827 package_metadata['xpakstatus'] = None
2828 package_metadata['xpakdir'] = package_metadata['xpakpath'] + \
2829 os.path.sep + etpConst['entropyxpakdatarelativepath']
2830
2831 else:
2832
2833 package_metadata['xpakstatus'] = True
2834
2835 try:
2836 try:
2837 import portage.const as pc
2838 except ImportError:
2839 import portage_const as pc
2840 portdbdir = pc.VDB_PATH
2841 except ImportError:
2842 portdbdir = 'var/db/pkg'
2843
2844 portdbdir = os.path.join(package_metadata['merge_from'], portdbdir)
2845 portdbdir = os.path.join(portdbdir,
2846 PortagePlugin._pkg_compose_atom(package_metadata))
2847
2848 package_metadata['xpakdir'] = portdbdir
2849
2850 package_metadata['triggers']['install']['xpakdir'] = \
2851 package_metadata['xpakdir']
2852
2853 return 0
2854
2855 @staticmethod
2857 """
2858 Reimplemented from SpmPlugin class.
2859 """
2860
2861 if os.path.isdir(package_metadata['xpakpath']):
2862 shutil.rmtree(package_metadata['xpakpath'], True)
2863
2864
2865 xpak_dir = package_metadata['xpakpath'] + os.path.sep + \
2866 etpConst['entropyxpakdatarelativepath']
2867
2868 os.makedirs(xpak_dir, 0o755)
2869
2870 xpak_path = package_metadata['xpakpath'] + os.path.sep + \
2871 etpConst['entropyxpakfilename']
2872
2873 if not package_metadata['merge_from']:
2874
2875 if package_metadata['smartpackage']:
2876
2877
2878 xdbconn = entropy_client.open_repository(
2879 package_metadata['repository'])
2880 xpakdata = xdbconn.retrieveXpakMetadata(
2881 package_metadata['idpackage'])
2882 if xpakdata:
2883
2884 with open(xpak_path, "wb") as xpak_f:
2885 xpak_f.write(xpakdata)
2886 xpak_f.flush()
2887 package_metadata['xpakstatus'] = \
2888 xpaktools.unpack_xpak(
2889 xpak_path,
2890 xpak_dir
2891 )
2892 else:
2893 package_metadata['xpakstatus'] = None
2894 del xpakdata
2895
2896 else:
2897 package_metadata['xpakstatus'] = xpaktools.extract_xpak(
2898 package_metadata['pkgpath'],
2899 xpak_dir
2900 )
2901
2902 else:
2903
2904 tolink_dir = xpak_dir
2905 if os.path.isdir(tolink_dir):
2906 shutil.rmtree(tolink_dir, True)
2907
2908 os.symlink(package_metadata['xpakdir'], tolink_dir)
2909
2910
2911 portage_cpv = PortagePlugin._pkg_compose_atom(package_metadata)
2912
2913 portage_db_fakedir = os.path.join(
2914 package_metadata['unpackdir'],
2915 "portage/" + portage_cpv
2916 )
2917
2918 os.makedirs(portage_db_fakedir, 0o755)
2919
2920 os.symlink(package_metadata['imagedir'],
2921 os.path.join(portage_db_fakedir, "image"))
2922
2923 return 0
2924
2926 """
2927 Extract Portage package merge log file information.
2928
2929 @param logfile: path to log file
2930 @type logfile: string
2931 @return: content of the log file
2932 @rtype: string
2933 """
2934
2935 logline = False
2936 logoutput = []
2937 f = open(logfile, "r")
2938 reallog = f.readlines()
2939 f.close()
2940
2941 for line in reallog:
2942 if line.startswith("INFO: postinst") or \
2943 line.startswith("LOG: postinst"):
2944 logline = True
2945 continue
2946
2947 elif line.startswith("LOG:"):
2948 logline = False
2949 continue
2950 if (logline) and (line.strip()):
2951
2952 logoutput.append(line.strip())
2953 return logoutput
2954
2956
2957 if root is None:
2958 root = etpConst['systemroot'] + os.path.sep
2959
2960 cached = PortagePlugin.CACHE['vartree'].get(root)
2961 if cached is not None:
2962 return cached
2963
2964 try:
2965 mytree = self.portage.vartree(root=root)
2966 except Exception as e:
2967 raise SPMError("SPMError: %s: %s" % (Exception, e,))
2968 PortagePlugin.CACHE['vartree'][root] = mytree
2969 return mytree
2970
2972
2973 cached = PortagePlugin.CACHE['portagetree'].get(root)
2974 if cached is not None:
2975 return cached
2976
2977 try:
2978 mytree = self.portage.portagetree(root=root)
2979 except Exception as e:
2980 raise SPMError("SPMError: %s: %s" % (Exception, e,))
2981 PortagePlugin.CACHE['portagetree'][root] = mytree
2982 return mytree
2983
2985
2986 cached = PortagePlugin.CACHE['binarytree'].get(root)
2987 if cached is not None:
2988 return cached
2989
2990 pkgdir = root+self.portage.settings['PKGDIR']
2991 try:
2992 mytree = self.portage.binarytree(root, pkgdir)
2993 except Exception as e:
2994 raise SPMError("SPMError: %s: %s" % (Exception, e,))
2995 PortagePlugin.CACHE['binarytree'][root] = mytree
2996 return mytree
2997
2999
3000 if use_cache:
3001 cached = PortagePlugin.CACHE['config'].get((config_root, root))
3002 if cached is not None:
3003 return cached
3004
3005 try:
3006 mysettings = self.portage.config(config_root = config_root,
3007 target_root = root,
3008 config_incrementals = self.portage_const.INCREMENTALS)
3009 except Exception as e:
3010 raise SPMError("SPMError: %s: %s" % (Exception, e,))
3011 if use_cache:
3012 PortagePlugin.CACHE['config'][(config_root, root)] = mysettings
3013
3014 return mysettings
3015
3017 return os.path.join(self.portage_const.USER_CONFIG_PATH, 'package.use')
3018
3020 matched_atom = self.match_package(atom)
3021 if not matched_atom:
3022 return False
3023 use_file = self._get_package_use_file()
3024
3025 if not (os.path.isfile(use_file) and os.access(use_file, os.W_OK)):
3026 return False
3027 f = open(use_file, "rb")
3028 content = [x.strip() for x in f.readlines()]
3029 f.close()
3030
3031 def handle_line(line, useflags):
3032
3033 data = line.split()
3034 if len(data) < 2:
3035 return False, line
3036
3037 myatom = data[0]
3038 if matched_atom != self.match_package(myatom):
3039 return False, line
3040
3041 plus = const_convert_to_rawstring("+")
3042 minus = const_convert_to_rawstring("-")
3043 myatom = const_convert_to_rawstring(myatom)
3044
3045 flags = data[1:]
3046 base_flags = []
3047 added_flags = []
3048 for flag in flags:
3049 myflag = flag
3050 if myflag.startswith(plus):
3051 myflag = myflag[1:]
3052 elif myflag.startswith(minus):
3053 myflag = myflag[1:]
3054 if not myflag:
3055 continue
3056 base_flags.append(myflag)
3057
3058 for useflag in useflags:
3059 if mark+useflag in base_flags:
3060 continue
3061 added_flags.append(mark+useflag)
3062
3063 if sys.hexversion >= 0x3000000:
3064 new_line = myatom + b" " + b" ".join(flags+added_flags)
3065 else:
3066 new_line = myatom + " " + " ".join(flags+added_flags)
3067
3068 return True, new_line
3069
3070
3071 atom_found = False
3072 new_content = []
3073 for line in content:
3074
3075 changed, elaborated_line = handle_line(line, useflags)
3076 if changed: atom_found = True
3077 new_content.append(elaborated_line)
3078
3079 if not atom_found:
3080 if sys.hexversion >= 0x3000000:
3081 myline = atom + b" " + b' '.join([mark+x for x in useflags])
3082 else:
3083 myline = "%s %s" % (atom, ' '.join([mark+x for x in useflags]))
3084 new_content.append(myline)
3085
3086
3087 f = open(use_file+".tmp", "wb")
3088 newline = const_convert_to_rawstring("\n")
3089 for line in new_content:
3090 f.write(line + newline)
3091 f.flush()
3092 f.close()
3093 os.rename(use_file + ".tmp", use_file)
3094 return True
3095
3097 matched_atom = self.match_package(atom)
3098 if not matched_atom:
3099 return False
3100
3101 use_file = self._get_package_use_file()
3102 if not (os.path.isfile(use_file) and os.access(use_file, os.W_OK)):
3103 return False
3104
3105 with open(use_file, "rb") as f:
3106 content = [x.strip() for x in f.readlines()]
3107
3108 new_content = []
3109 for line in content:
3110
3111 data = line.split()
3112 if len(data) < 2:
3113 new_content.append(line)
3114 continue
3115
3116 myatom = data[0]
3117 if matched_atom != self.match_package(myatom):
3118 new_content.append(line)
3119 continue
3120
3121 plus = const_convert_to_rawstring("+")
3122 minus = const_convert_to_rawstring("-")
3123 myatom = const_convert_to_rawstring(myatom)
3124
3125 flags = data[1:]
3126 new_flags = []
3127 for flag in flags:
3128 myflag = flag
3129
3130 if myflag.startswith(plus):
3131 myflag = myflag[1:]
3132 elif myflag.startswith(minus):
3133 myflag = myflag[1:]
3134
3135 if myflag in useflags:
3136 continue
3137 elif not flag:
3138 continue
3139
3140 new_flags.append(flag)
3141
3142 if new_flags:
3143 if sys.hexversion >= 0x3000000:
3144 new_line = myatom + b" " + b" ".join(new_flags)
3145 else:
3146 new_line = myatom + " " + " ".join(new_flags)
3147 new_content.append(new_line)
3148
3149 newline = const_convert_to_rawstring("\n")
3150 with open(use_file+".tmp", "wb") as f:
3151 for line in new_content:
3152 f.write(line + newline)
3153 f.flush()
3154
3155 os.rename(use_file + ".tmp", use_file)
3156 return True
3157
3159
3160 data = {
3161 'enabled': set(),
3162 'disabled': set(),
3163 }
3164
3165 matched_atom = self.match_package(atom)
3166 if not matched_atom:
3167 return data
3168
3169 use_file = self._get_package_use_file()
3170 if not (os.path.isfile(use_file) and os.access(use_file, os.W_OK)):
3171 return data
3172
3173 plus = const_convert_to_rawstring("+")
3174 minus = const_convert_to_rawstring("-")
3175 use_data = self.portage_util.grabdict(use_file)
3176 for myatom in use_data:
3177 mymatch = self.match_package(myatom)
3178 if mymatch != matched_atom:
3179 continue
3180 for flag in use_data[myatom]:
3181 if flag.startswith(minus):
3182 myflag = flag[1:]
3183 data['enabled'].discard(myflag)
3184 data['disabled'].add(myflag)
3185 else:
3186 myflag = flag
3187 if myflag.startswith(plus):
3188 myflag = myflag[1:]
3189 data['disabled'].discard(myflag)
3190 data['enabled'].add(myflag)
3191
3192 return data
3193
3195 return self.portage.settings['USE']
3196
3198 return self.portage.settings.useforce
3199
3201 return self.portage.settings.usemask
3202
3204 use = set()
3205 use_mask = self._get_useflags_mask()
3206 use_force = self._get_useflags_force()
3207 plus = const_convert_to_rawstring("+")
3208 minus = const_convert_to_rawstring("-")
3209 for myiuse in iuse_list:
3210 if myiuse[0] in (plus, minus,):
3211 myiuse = myiuse[1:]
3212 if ((myiuse in use_list) or (myiuse in use_force)) and \
3213 (myiuse not in use_mask):
3214 use.add(myiuse)
3215 return use
3216
3217 - def _calculate_dependencies(self, my_iuse, my_use, my_license, my_depend,
3218 my_rdepend, my_pdepend, my_provide, my_src_uri):
3219
3220 metadata = {
3221 'LICENSE': my_license,
3222 'DEPEND': my_depend,
3223 'PDEPEND': my_pdepend,
3224 'RDEPEND': my_rdepend,
3225 'PROVIDE': my_provide,
3226 'SRC_URI': my_src_uri,
3227 'USE_MASK': sorted(self._get_useflags_mask()),
3228 'USE_FORCE': sorted(self._get_useflags_force()),
3229 }
3230
3231
3232 raw_use = my_use.split()
3233 enabled_use = sorted(self._resolve_enabled_useflags(
3234 my_iuse.split(), raw_use))
3235
3236 metadata['ENABLED_USE'] = enabled_use
3237 use = raw_use + [x for x in metadata['USE_FORCE'] if x not in raw_use]
3238 metadata['USE'] = sorted([const_convert_to_unicode(x) for x in use if \
3239 x not in metadata['USE_MASK']])
3240
3241 for k in "LICENSE", "RDEPEND", "DEPEND", "PDEPEND", "PROVIDE", "SRC_URI":
3242 try:
3243 if k == "SRC_URI":
3244 deps = self._src_uri_paren_reduce(metadata[k])
3245 else:
3246 deps = self._paren_reduce(metadata[k])
3247 deps = self._use_reduce(deps, uselist = raw_use)
3248 deps = self.paren_normalize(deps)
3249 if k == "LICENSE":
3250 deps = self._paren_license_choose(deps)
3251 else:
3252 deps = self._paren_choose(deps)
3253 if k.endswith("DEPEND"):
3254 deps = self._usedeps_reduce(deps, enabled_use)
3255 deps = ' '.join(deps)
3256 except Exception as e:
3257 entropy.tools.print_traceback()
3258 self.updateProgress(
3259 darkred("%s: %s: %s :: %s") % (
3260 _("Error calculating dependencies"),
3261 str(Exception),
3262 k,
3263 e,
3264 ),
3265 importance = 1,
3266 type = "error",
3267 header = red(" !!! ")
3268 )
3269 deps = ''
3270 continue
3271 metadata[k] = deps
3272 return metadata
3273
3275 src_uris = self._paren_reduce(src_uris)
3276 newlist = []
3277 skip_next = False
3278 for src_uri in src_uris:
3279 if skip_next:
3280 skip_next = False
3281 continue
3282 if src_uri == "->":
3283 skip_next = True
3284 continue
3285 newlist.append(src_uri)
3286 return newlist
3287
3289 newlist = []
3290
3291 def strip_use(xuse):
3292 myuse = xuse[:]
3293 if myuse[0] == "!":
3294 myuse = myuse[1:]
3295 if myuse[-1] in ("=", "?",):
3296 myuse = myuse[:-1]
3297 return myuse
3298
3299 for dependency in dependencies:
3300 use_deps = entropy.tools.dep_getusedeps(dependency)
3301 if use_deps:
3302 new_use_deps = []
3303 for use in use_deps:
3304 """
3305 explicitly support only specific types
3306 """
3307 if (use[0] == "!") and (use[-1] not in ("=", "?",)):
3308
3309 continue
3310 elif use[-1] == "=":
3311 if use[0] == "!":
3312
3313 s_use = strip_use(use)
3314 if s_use in enabled_useflags:
3315 new_use_deps.append("-%s" % (s_use,))
3316 else:
3317 new_use_deps.append(s_use)
3318 continue
3319 else:
3320
3321 s_use = strip_use(use)
3322 if s_use in enabled_useflags:
3323 new_use_deps.append(s_use)
3324 else:
3325 new_use_deps.append("-%s" % (s_use,))
3326 continue
3327 elif use[-1] == "?":
3328 if use[0] == "!":
3329
3330 s_use = strip_use(use)
3331 if s_use not in enabled_useflags:
3332 new_use_deps.append("-%s" % (s_use,))
3333 continue
3334 else:
3335
3336 s_use = strip_use(use)
3337 if s_use in enabled_useflags:
3338 new_use_deps.append(s_use)
3339 continue
3340 new_use_deps.append(use)
3341
3342 if new_use_deps:
3343 dependency = "%s[%s]" % (
3344 entropy.tools.remove_usedeps(dependency),
3345 ','.join(new_use_deps),
3346 )
3347 else:
3348 dependency = entropy.tools.remove_usedeps(dependency)
3349
3350 newlist.append(dependency)
3351 return newlist
3352
3354 """
3355
3356 # deps.py -- Portage dependency resolution functions
3357 # Copyright 2003-2004 Gentoo Foundation
3358 # Distributed under the terms of the GNU General Public License v2
3359 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
3360
3361 Take a string and convert all paren enclosed entities into sublists, optionally
3362 futher splitting the list elements by spaces.
3363
3364 Example usage:
3365 >>> paren_reduce('foobar foo ( bar baz )',1)
3366 ['foobar', 'foo', ['bar', 'baz']]
3367 >>> paren_reduce('foobar foo ( bar baz )',0)
3368 ['foobar foo ', [' bar baz ']]
3369
3370 @param mystr: The string to reduce
3371 @type mystr: String
3372 @rtype: Array
3373 @return: The reduced string in an array
3374 """
3375 mylist = []
3376 while mystr:
3377 left_paren = mystr.find("(")
3378 has_left_paren = left_paren != -1
3379 right_paren = mystr.find(")")
3380 has_right_paren = right_paren != -1
3381 if not has_left_paren and not has_right_paren:
3382 freesec = mystr
3383 subsec = None
3384 tail = ""
3385 elif mystr[0] == ")":
3386 return [mylist, mystr[1:]]
3387 elif has_left_paren and not has_right_paren:
3388 raise InvalidDependString(
3389 "InvalidDependString: %s: '%s'" % (_("missing right parenthesis"), mystr,))
3390 elif has_left_paren and left_paren < right_paren:
3391 freesec, subsec = mystr.split("(", 1)
3392 subsec, tail = self._paren_reduce(subsec)
3393 else:
3394 subsec, tail = mystr.split(")", 1)
3395 subsec = self._strip_empty(subsec.split(" "))
3396 return [mylist+subsec, tail]
3397 mystr = tail
3398 if freesec:
3399 mylist = mylist + self._strip_empty(freesec.split(" "))
3400 if subsec is not None:
3401 mylist = mylist + [subsec]
3402 return mylist
3403
3405 """
3406
3407 # deps.py -- Portage dependency resolution functions
3408 # Copyright 2003-2004 Gentoo Foundation
3409 # Distributed under the terms of the GNU General Public License v2
3410 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
3411
3412 Strip all empty elements from an array
3413
3414 @param myarr: The list of elements
3415 @type myarr: List
3416 @rtype: Array
3417 @return: The array with empty elements removed
3418 """
3419 for x in range(len(myarr)-1, -1, -1):
3420 if not myarr[x]:
3421 del myarr[x]
3422 return myarr
3423
3424 - def _use_reduce(self, deparray, uselist = None, masklist = None,
3425 matchall = 0, excludeall = None):
3426 """
3427
3428 # deps.py -- Portage dependency resolution functions
3429 # Copyright 2003-2004 Gentoo Foundation
3430 # Distributed under the terms of the GNU General Public License v2
3431 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
3432
3433 Takes a paren_reduce'd array and reduces the use? conditionals out
3434 leaving an array with subarrays
3435
3436 @param deparray: paren_reduce'd list of deps
3437 @type deparray: List
3438 @param uselist: List of use flags
3439 @type uselist: List
3440 @param masklist: List of masked flags
3441 @type masklist: List
3442 @param matchall: Resolve all conditional deps unconditionally. Used by repoman
3443 @type matchall: Integer
3444 @rtype: List
3445 @return: The use reduced depend array
3446 """
3447
3448 if uselist is None:
3449 uselist = []
3450 if masklist is None:
3451 masklist = []
3452 if excludeall is None:
3453 excludeall = []
3454
3455
3456 for x in range(len(deparray)):
3457 if deparray[x] in ["||", "&&"]:
3458 if len(deparray) - 1 == x or not isinstance(deparray[x+1], list):
3459 mytxt = _("missing atom list in")
3460 raise InvalidDependString(deparray[x]+" "+mytxt+" \""+str(deparray)+"\"")
3461 if deparray and deparray[-1] and deparray[-1][-1] == "?":
3462 mytxt = _("Conditional without target in")
3463 raise InvalidDependString("InvalidDependString: "+mytxt+" \""+str(deparray)+"\"")
3464
3465
3466
3467
3468
3469 _dep_check_strict = False
3470
3471 mydeparray = deparray[:]
3472 rlist = []
3473 while mydeparray:
3474 head = mydeparray.pop(0)
3475
3476 if isinstance(head, list):
3477 additions = self._use_reduce(head, uselist, masklist, matchall, excludeall)
3478 if additions:
3479 rlist.append(additions)
3480 elif rlist and rlist[-1] == "||":
3481
3482
3483 rlist.append([])
3484 else:
3485 if head[-1] == "?":
3486
3487 newdeparray = [head]
3488 while isinstance(newdeparray[-1], const_get_stringtype()) and newdeparray[-1][-1] == "?":
3489 if mydeparray:
3490 newdeparray.append(mydeparray.pop(0))
3491 else:
3492 raise ValueError(_("Conditional with no target"))
3493
3494
3495 warned = 0
3496 if len(newdeparray[-1]) == 0:
3497 mytxt = "%s. (%s)" % (_("Empty target in string"), _("Deprecated"),)
3498 self.updateProgress(
3499 darkred("PortagePlugin._use_reduce(): %s" % (mytxt,)),
3500 importance = 0,
3501 type = "error",
3502 header = bold(" !!! ")
3503 )
3504 warned = 1
3505 if len(newdeparray) != 2:
3506 mytxt = "%s. (%s)" % (_("Nested use flags without parenthesis"), _("Deprecated"),)
3507 self.updateProgress(
3508 darkred("PortagePlugin._use_reduce(): %s" % (mytxt,)),
3509 importance = 0,
3510 type = "error",
3511 header = bold(" !!! ")
3512 )
3513 warned = 1
3514 if warned:
3515 self.updateProgress(
3516 darkred("PortagePlugin._use_reduce(): "+" ".join(map(str, [head]+newdeparray))),
3517 importance = 0,
3518 type = "error",
3519 header = bold(" !!! ")
3520 )
3521
3522
3523 ismatch = True
3524 missing_flag = False
3525 for head in newdeparray[:-1]:
3526 head = head[:-1]
3527 if not head:
3528 missing_flag = True
3529 break
3530 if head.startswith("!"):
3531 head_key = head[1:]
3532 if not head_key:
3533 missing_flag = True
3534 break
3535 if not matchall and head_key in uselist or \
3536 head_key in excludeall:
3537 ismatch = False
3538 break
3539 elif head not in masklist:
3540 if not matchall and head not in uselist:
3541 ismatch = False
3542 break
3543 else:
3544 ismatch = False
3545 if missing_flag:
3546 mytxt = _("Conditional without flag")
3547 raise InvalidDependString(
3548 "InvalidDependString: "+mytxt+": \"" + \
3549 str([head+"?", newdeparray[-1]])+"\"")
3550
3551
3552 if ismatch:
3553 target = newdeparray[-1]
3554 if isinstance(target, list):
3555 additions = self._use_reduce(target, uselist, masklist, matchall, excludeall)
3556 if additions:
3557 rlist.append(additions)
3558 elif not _dep_check_strict:
3559
3560 rlist.append(target)
3561 else:
3562 mytxt = _("Conditional without parenthesis")
3563 raise InvalidDependString(
3564 "InvalidDependString: "+mytxt+": '%s?'" % head)
3565
3566 else:
3567 rlist += [head]
3568 return rlist
3569
3571 newlist = []
3572 do_skip = False
3573 for idx in range(len(dep_list)):
3574
3575 if do_skip:
3576 do_skip = False
3577 continue
3578
3579 item = dep_list[idx]
3580 if item == "||":
3581 next_item = dep_list[idx+1]
3582 if not next_item:
3583 do_skip = True
3584 continue
3585 item = self._dep_or_select(next_item)
3586 if not item:
3587
3588 newlist.append(str(next_item))
3589 else:
3590 newlist += item
3591 do_skip = True
3592 elif isinstance(item, list):
3593 item = self._dep_and_select(item)
3594 newlist += item
3595 else:
3596 newlist.append(item)
3597
3598 return newlist
3599
3601 do_skip = False
3602 newlist = []
3603 for idx in range(len(and_list)):
3604
3605 if do_skip:
3606 do_skip = False
3607 continue
3608
3609 x = and_list[idx]
3610 if x == "||":
3611 x = self._dep_or_select(and_list[idx+1])
3612 do_skip = True
3613 if not x:
3614 x = str(and_list[idx+1])
3615 else:
3616 newlist += x
3617 elif isinstance(x, list):
3618 x = self._dep_and_select(x)
3619 newlist += x
3620 else:
3621 newlist.append(x)
3622
3623
3624 for x in newlist:
3625 match = self.match_installed_package(x)
3626 if not match:
3627 return []
3628
3629 return newlist
3630
3632 do_skip = False
3633 for idx in range(len(or_list)):
3634 if do_skip:
3635 do_skip = False
3636 continue
3637 x = or_list[idx]
3638 if x == "||":
3639 x = self._dep_or_select(or_list[idx+1])
3640 do_skip = True
3641 elif isinstance(x, list):
3642 x = self._dep_and_select(x)
3643 if not x:
3644 continue
3645
3646 return x
3647 else:
3648 x = [x]
3649
3650 for y in x:
3651 match = self.match_installed_package(y)
3652 if match:
3653 return [y]
3654
3655 return []
3656
3658
3659 newlist = set()
3660 for item in dep_list:
3661
3662 if isinstance(item, list):
3663
3664 data = set(self._paren_license_choose(item))
3665 newlist.update(data)
3666 else:
3667 if item not in ["||"]:
3668 newlist.add(item)
3669
3670 return list(newlist)
3671
3673 if root is None:
3674 root = etpConst['systemroot'] + os.path.sep
3675 return os.path.join(root, self.portage_const.VDB_PATH)
3676
3678
3679
3680 setconfigpaths = [os.path.join(self.portage_const.GLOBAL_CONFIG_PATH, etpConst['setsconffilename'])]
3681 setconfigpaths.append(os.path.join(settings["PORTDIR"], etpConst['setsconffilename']))
3682 setconfigpaths += [os.path.join(x, etpConst['setsconffilename']) for x in settings["PORTDIR_OVERLAY"].split()]
3683 setconfigpaths.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
3684 self.portage_const.USER_CONFIG_PATH.lstrip(os.path.sep), etpConst['setsconffilename']))
3685 return self.portage_sets.SetConfig(setconfigpaths, settings, trees)
3686
3688
3689 if self.portage_sets == None:
3690 return
3691 myroot = etpConst['systemroot'] + os.path.sep
3692 return self._load_sets_config(
3693 self.portage.settings,
3694 self.portage.db[myroot]
3695 )
3696
3785
3787
3788 pkg_content = {}
3789 obj_t = const_convert_to_unicode("obj")
3790 sym_t = const_convert_to_unicode("sym")
3791 dir_t = const_convert_to_unicode("dir")
3792
3793 if os.path.isfile(content_file):
3794
3795 with open(content_file, "rb") as f:
3796 content = [const_convert_to_unicode(x) for x in f.readlines()]
3797
3798 outcontent = set()
3799 for line in content:
3800 line = line.strip().split()
3801 try:
3802 datatype = line[0]
3803 datafile = line[1:]
3804 if datatype == obj_t:
3805 datafile = datafile[:-2]
3806 datafile = ' '.join(datafile)
3807 elif datatype == dir_t:
3808 datafile = ' '.join(datafile)
3809 elif datatype == sym_t:
3810 datafile = datafile[:-3]
3811 datafile = ' '.join(datafile)
3812 else:
3813 myexc = "InvalidData: %s %s. %s." % (
3814 datafile,
3815 _("not supported"),
3816 _("Probably Portage API has changed"),
3817 )
3818 raise InvalidData(myexc)
3819 outcontent.add((datafile, datatype))
3820 except:
3821 pass
3822
3823 outcontent = sorted(outcontent)
3824 for datafile, datatype in outcontent:
3825 pkg_content[datafile] = datatype
3826
3827 else:
3828
3829
3830
3831
3832 mytempdir = os.path.join(etpConst['packagestmpdir'],
3833 os.path.basename(package_path) + ".inject")
3834 if os.path.isdir(mytempdir):
3835 shutil.rmtree(mytempdir)
3836 if not os.path.isdir(mytempdir):
3837 os.makedirs(mytempdir)
3838
3839 entropy.tools.uncompress_tar_bz2(package_path, extractPath = mytempdir,
3840 catchEmpty = True)
3841 tmpdir_len = len(mytempdir)
3842 for currentdir, subdirs, files in os.walk(mytempdir):
3843 pkg_content[currentdir[tmpdir_len:]] = dir_t
3844 for item in files:
3845 item = currentdir + "/" + item
3846 if os.path.islink(item):
3847 pkg_content[item[tmpdir_len:]] = sym_t
3848 else:
3849 pkg_content[item[tmpdir_len:]] = obj_t
3850
3851
3852 shutil.rmtree(mytempdir, True)
3853 try:
3854 os.rmdir(mytempdir)
3855 except (OSError,):
3856 pass
3857
3858 return pkg_content
3859
3885
3921
3945
3981
3995
4009