1 |
commit: d3f704a425a50b5cfa997a25866929b30f1b7d0f |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Nov 17 23:10:13 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Nov 17 23:10:13 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=d3f704a4 |
7 |
|
8 |
Skip the "resume after portage update" routine. |
9 |
|
10 |
Instead, finish the whole job using a copy of the currently running |
11 |
instance. This allows us to avoid the complexities of emerge --resume, |
12 |
such as the differences in option handling between different portage |
13 |
versions, as reported in bug #390819. |
14 |
|
15 |
--- |
16 |
pym/_emerge/Scheduler.py | 143 +++++++++----------------------- |
17 |
pym/_emerge/depgraph.py | 2 - |
18 |
pym/_emerge/resolver/output.py | 21 ----- |
19 |
pym/_emerge/resolver/output_helpers.py | 1 - |
20 |
pym/portage/dbapi/_MergeProcess.py | 58 ------------- |
21 |
pym/portage/package/ebuild/config.py | 17 +++-- |
22 |
pym/portage/package/ebuild/doebuild.py | 44 ++++++++++- |
23 |
7 files changed, 92 insertions(+), 194 deletions(-) |
24 |
|
25 |
diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py |
26 |
index 3b53a37..393eeb6 100644 |
27 |
--- a/pym/_emerge/Scheduler.py |
28 |
+++ b/pym/_emerge/Scheduler.py |
29 |
@@ -29,7 +29,8 @@ from portage._sets.base import InternalPackageSet |
30 |
from portage.util import ensure_dirs, writemsg, writemsg_level |
31 |
from portage.package.ebuild.digestcheck import digestcheck |
32 |
from portage.package.ebuild.digestgen import digestgen |
33 |
-from portage.package.ebuild.doebuild import _check_temp_dir |
34 |
+from portage.package.ebuild.doebuild import (_check_temp_dir, |
35 |
+ _prepare_self_update) |
36 |
from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs |
37 |
|
38 |
import _emerge |
39 |
@@ -75,12 +76,9 @@ class Scheduler(PollScheduler): |
40 |
frozenset(["--pretend", |
41 |
"--fetchonly", "--fetch-all-uri"]) |
42 |
|
43 |
- _opts_no_restart = frozenset(["--buildpkgonly", |
44 |
+ _opts_no_self_reinstall = frozenset(["--buildpkgonly", |
45 |
"--fetchonly", "--fetch-all-uri", "--pretend"]) |
46 |
|
47 |
- _bad_resume_opts = set(["--ask", "--changelog", |
48 |
- "--resume", "--skipfirst"]) |
49 |
- |
50 |
class _iface_class(SlotObject): |
51 |
__slots__ = ("fetch", |
52 |
"output", "register", "schedule", |
53 |
@@ -289,6 +287,38 @@ class Scheduler(PollScheduler): |
54 |
self._running_portage = self._pkg(cpv, "installed", |
55 |
self._running_root, installed=True) |
56 |
|
57 |
+ def _handle_self_update(self): |
58 |
+ """ |
59 |
+ If portage is updating itself, create temporary |
60 |
+ copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH in order |
61 |
+ to avoid relying on the new versions which may be |
62 |
+ incompatible. Register an atexit hook to clean up the |
63 |
+ temporary directories. Pre-load elog modules here since |
64 |
+ we won't be able to later if they get unmerged (happens |
65 |
+ when namespace changes). |
66 |
+ """ |
67 |
+ |
68 |
+ if self._opts_no_self_reinstall.intersection(self.myopts): |
69 |
+ return |
70 |
+ |
71 |
+ for x in self._mergelist: |
72 |
+ if not isinstance(x, Package): |
73 |
+ continue |
74 |
+ if x.operation != "merge": |
75 |
+ continue |
76 |
+ if x.root != self._running_root.root: |
77 |
+ continue |
78 |
+ if not portage.dep.match_from_list( |
79 |
+ portage.const.PORTAGE_PACKAGE_ATOM, [x]): |
80 |
+ continue |
81 |
+ if self._running_portage is None or \ |
82 |
+ self._running_portage.cpv != x.cpv or \ |
83 |
+ '9999' in x.cpv or \ |
84 |
+ 'git' in x.inherited or \ |
85 |
+ 'git-2' in x.inherited: |
86 |
+ _prepare_self_update(self.settings) |
87 |
+ break |
88 |
+ |
89 |
def _terminate_tasks(self): |
90 |
self._status_display.quiet = True |
91 |
while self._running_tasks: |
92 |
@@ -785,100 +815,6 @@ class Scheduler(PollScheduler): |
93 |
|
94 |
return prefetcher |
95 |
|
96 |
- def _is_restart_scheduled(self): |
97 |
- """ |
98 |
- Check if the merge list contains a replacement |
99 |
- for the current running instance, that will result |
100 |
- in restart after merge. |
101 |
- @rtype: bool |
102 |
- @returns: True if a restart is scheduled, False otherwise. |
103 |
- """ |
104 |
- if self._opts_no_restart.intersection(self.myopts): |
105 |
- return False |
106 |
- |
107 |
- mergelist = self._mergelist |
108 |
- |
109 |
- for i, pkg in enumerate(mergelist): |
110 |
- if self._is_restart_necessary(pkg) and \ |
111 |
- i != len(mergelist) - 1: |
112 |
- return True |
113 |
- |
114 |
- return False |
115 |
- |
116 |
- def _is_restart_necessary(self, pkg): |
117 |
- """ |
118 |
- @return: True if merging the given package |
119 |
- requires restart, False otherwise. |
120 |
- """ |
121 |
- |
122 |
- # Figure out if we need a restart. |
123 |
- if pkg.root == self._running_root.root and \ |
124 |
- portage.match_from_list( |
125 |
- portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): |
126 |
- if self._running_portage is None: |
127 |
- return True |
128 |
- elif pkg.cpv != self._running_portage.cpv or \ |
129 |
- '9999' in pkg.cpv or \ |
130 |
- 'git' in pkg.inherited or \ |
131 |
- 'git-2' in pkg.inherited: |
132 |
- return True |
133 |
- return False |
134 |
- |
135 |
- def _restart_if_necessary(self, pkg): |
136 |
- """ |
137 |
- Use execv() to restart emerge. This happens |
138 |
- if portage upgrades itself and there are |
139 |
- remaining packages in the list. |
140 |
- """ |
141 |
- |
142 |
- if self._opts_no_restart.intersection(self.myopts): |
143 |
- return |
144 |
- |
145 |
- if not self._is_restart_necessary(pkg): |
146 |
- return |
147 |
- |
148 |
- if pkg == self._mergelist[-1]: |
149 |
- return |
150 |
- |
151 |
- self._main_loop_cleanup() |
152 |
- |
153 |
- logger = self._logger |
154 |
- pkg_count = self._pkg_count |
155 |
- mtimedb = self._mtimedb |
156 |
- bad_resume_opts = self._bad_resume_opts |
157 |
- |
158 |
- logger.log(" ::: completed emerge (%s of %s) %s to %s" % \ |
159 |
- (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)) |
160 |
- |
161 |
- logger.log(" *** RESTARTING " + \ |
162 |
- "emerge via exec() after change of " + \ |
163 |
- "portage version.") |
164 |
- |
165 |
- mtimedb["resume"]["mergelist"].remove(list(pkg)) |
166 |
- mtimedb.commit() |
167 |
- portage.run_exitfuncs() |
168 |
- # Don't trust sys.argv[0] here because eselect-python may modify it. |
169 |
- emerge_binary = os.path.join(portage.const.PORTAGE_BIN_PATH, 'emerge') |
170 |
- mynewargv = [emerge_binary, "--resume"] |
171 |
- resume_opts = self.myopts.copy() |
172 |
- # For automatic resume, we need to prevent |
173 |
- # any of bad_resume_opts from leaking in |
174 |
- # via EMERGE_DEFAULT_OPTS. |
175 |
- resume_opts["--ignore-default-opts"] = True |
176 |
- for myopt, myarg in resume_opts.items(): |
177 |
- if myopt not in bad_resume_opts: |
178 |
- if myarg is True: |
179 |
- mynewargv.append(myopt) |
180 |
- elif isinstance(myarg, list): |
181 |
- # arguments like --exclude that use 'append' action |
182 |
- for x in myarg: |
183 |
- mynewargv.append("%s=%s" % (myopt, x)) |
184 |
- else: |
185 |
- mynewargv.append("%s=%s" % (myopt, myarg)) |
186 |
- # priority only needs to be adjusted on the first run |
187 |
- os.environ["PORTAGE_NICENESS"] = "0" |
188 |
- os.execv(mynewargv[0], mynewargv) |
189 |
- |
190 |
def _run_pkg_pretend(self): |
191 |
""" |
192 |
Since pkg_pretend output may be important, this method sends all |
193 |
@@ -1034,6 +970,8 @@ class Scheduler(PollScheduler): |
194 |
except self._unknown_internal_error: |
195 |
return 1 |
196 |
|
197 |
+ self._handle_self_update() |
198 |
+ |
199 |
for root in self.trees: |
200 |
root_config = self.trees[root]["root_config"] |
201 |
|
202 |
@@ -1379,8 +1317,6 @@ class Scheduler(PollScheduler): |
203 |
if pkg.installed: |
204 |
return |
205 |
|
206 |
- self._restart_if_necessary(pkg) |
207 |
- |
208 |
# Call mtimedb.commit() after each merge so that |
209 |
# --resume still works after being interrupted |
210 |
# by reboot, sigkill or similar. |
211 |
@@ -1585,10 +1521,7 @@ class Scheduler(PollScheduler): |
212 |
|
213 |
def _main_loop(self): |
214 |
|
215 |
- # Only allow 1 job max if a restart is scheduled |
216 |
- # due to portage update. |
217 |
- if self._is_restart_scheduled() or \ |
218 |
- self._opts_no_background.intersection(self.myopts): |
219 |
+ if self._opts_no_background.intersection(self.myopts): |
220 |
self._set_max_jobs(1) |
221 |
|
222 |
while self._schedule(): |
223 |
|
224 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
225 |
index fda335f..65fe1fd 100644 |
226 |
--- a/pym/_emerge/depgraph.py |
227 |
+++ b/pym/_emerge/depgraph.py |
228 |
@@ -100,8 +100,6 @@ class _frozen_depgraph_config(object): |
229 |
self.edebug = 1 |
230 |
self.spinner = spinner |
231 |
self._running_root = trees[trees._running_eroot]["root_config"] |
232 |
- self._opts_no_restart = frozenset(["--buildpkgonly", |
233 |
- "--fetchonly", "--fetch-all-uri", "--pretend"]) |
234 |
self.pkgsettings = {} |
235 |
self.trees = {} |
236 |
self._trees_orig = trees |
237 |
|
238 |
diff --git a/pym/_emerge/resolver/output.py b/pym/_emerge/resolver/output.py |
239 |
index eed3019..6f1c76c 100644 |
240 |
--- a/pym/_emerge/resolver/output.py |
241 |
+++ b/pym/_emerge/resolver/output.py |
242 |
@@ -865,27 +865,6 @@ class Display(object): |
243 |
continue |
244 |
self.print_msg.append((myprint, self.verboseadd, self.repoadd)) |
245 |
|
246 |
- if not self.conf.tree_display \ |
247 |
- and not self.conf.no_restart \ |
248 |
- and pkg.root == self.conf.running_root.root \ |
249 |
- and match_from_list(PORTAGE_PACKAGE_ATOM, [pkg]) \ |
250 |
- and not self.conf.quiet: |
251 |
- |
252 |
- if not self.vardb.cpv_exists(pkg.cpv) or \ |
253 |
- '9999' in pkg.cpv or \ |
254 |
- 'git' in pkg.inherited or \ |
255 |
- 'git-2' in pkg.inherited: |
256 |
- if mylist_index < len(mylist) - 1: |
257 |
- self.print_msg.append( |
258 |
- colorize( |
259 |
- "WARN", "*** Portage will stop merging " |
260 |
- "at this point and reload itself," |
261 |
- ) |
262 |
- ) |
263 |
- self.print_msg.append( |
264 |
- colorize("WARN", " then resume the merge.") |
265 |
- ) |
266 |
- |
267 |
show_repos = repoadd_set and repoadd_set != set(["0"]) |
268 |
|
269 |
# now finally print out the messages |
270 |
|
271 |
diff --git a/pym/_emerge/resolver/output_helpers.py b/pym/_emerge/resolver/output_helpers.py |
272 |
index b3cdbc4..dd26534 100644 |
273 |
--- a/pym/_emerge/resolver/output_helpers.py |
274 |
+++ b/pym/_emerge/resolver/output_helpers.py |
275 |
@@ -198,7 +198,6 @@ class _DisplayConfig(object): |
276 |
self.print_use_string = self.verbosity != 1 or "--verbose" in frozen_config.myopts |
277 |
self.changelog = "--changelog" in frozen_config.myopts |
278 |
self.edebug = frozen_config.edebug |
279 |
- self.no_restart = frozen_config._opts_no_restart.intersection(frozen_config.myopts) |
280 |
self.unordered_display = "--unordered-display" in frozen_config.myopts |
281 |
|
282 |
mywidth = 130 |
283 |
|
284 |
diff --git a/pym/portage/dbapi/_MergeProcess.py b/pym/portage/dbapi/_MergeProcess.py |
285 |
index 34ed031..c9b6288 100644 |
286 |
--- a/pym/portage/dbapi/_MergeProcess.py |
287 |
+++ b/pym/portage/dbapi/_MergeProcess.py |
288 |
@@ -2,20 +2,14 @@ |
289 |
# Distributed under the terms of the GNU General Public License v2 |
290 |
|
291 |
import io |
292 |
-import shutil |
293 |
import signal |
294 |
-import tempfile |
295 |
import traceback |
296 |
|
297 |
import errno |
298 |
import fcntl |
299 |
import portage |
300 |
from portage import os, _unicode_decode |
301 |
-from portage.const import PORTAGE_PACKAGE_ATOM |
302 |
-from portage.dep import match_from_list |
303 |
import portage.elog.messages |
304 |
-from portage.elog import _preload_elog_modules |
305 |
-from portage.util import ensure_dirs |
306 |
from _emerge.PollConstants import PollConstants |
307 |
from _emerge.SpawnProcess import SpawnProcess |
308 |
|
309 |
@@ -46,8 +40,6 @@ class MergeProcess(SpawnProcess): |
310 |
settings.reset() |
311 |
settings.setcpv(cpv, mydb=self.mydbapi) |
312 |
|
313 |
- if not self.unmerge: |
314 |
- self._handle_self_reinstall() |
315 |
super(MergeProcess, self)._start() |
316 |
|
317 |
def _lock_vdb(self): |
318 |
@@ -69,56 +61,6 @@ class MergeProcess(SpawnProcess): |
319 |
self.vartree.dbapi.unlock() |
320 |
self._locked_vdb = False |
321 |
|
322 |
- def _handle_self_reinstall(self): |
323 |
- """ |
324 |
- If portage is reinstalling itself, create temporary |
325 |
- copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH in order |
326 |
- to avoid relying on the new versions which may be |
327 |
- incompatible. Register an atexit hook to clean up the |
328 |
- temporary directories. Pre-load elog modules here since |
329 |
- we won't be able to later if they get unmerged (happens |
330 |
- when namespace changes). |
331 |
- """ |
332 |
- |
333 |
- settings = self.settings |
334 |
- cpv = settings.mycpv |
335 |
- reinstall_self = False |
336 |
- if self.settings["ROOT"] == "/" and \ |
337 |
- match_from_list(PORTAGE_PACKAGE_ATOM, [cpv]): |
338 |
- inherited = frozenset(self.settings.get('INHERITED', '').split()) |
339 |
- if not self.vartree.dbapi.cpv_exists(cpv) or \ |
340 |
- '9999' in cpv or \ |
341 |
- 'git' in inherited or \ |
342 |
- 'git-2' in inherited: |
343 |
- reinstall_self = True |
344 |
- |
345 |
- if reinstall_self: |
346 |
- # Load lazily referenced portage submodules into memory, |
347 |
- # so imports won't fail during portage upgrade/downgrade. |
348 |
- _preload_elog_modules(self.settings) |
349 |
- portage.proxy.lazyimport._preload_portage_submodules() |
350 |
- |
351 |
- # Make the temp directory inside $PORTAGE_TMPDIR/portage, since |
352 |
- # it's common for /tmp and /var/tmp to be mounted with the |
353 |
- # "noexec" option (see bug #346899). |
354 |
- build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage") |
355 |
- ensure_dirs(build_prefix) |
356 |
- base_path_tmp = tempfile.mkdtemp( |
357 |
- "", "._portage_reinstall_.", build_prefix) |
358 |
- portage.process.atexit_register(shutil.rmtree, base_path_tmp) |
359 |
- dir_perms = 0o755 |
360 |
- for subdir in "bin", "pym": |
361 |
- var_name = "PORTAGE_%s_PATH" % subdir.upper() |
362 |
- var_orig = settings[var_name] |
363 |
- var_new = os.path.join(base_path_tmp, subdir) |
364 |
- settings[var_name] = var_new |
365 |
- settings.backup_changes(var_name) |
366 |
- shutil.copytree(var_orig, var_new, symlinks=True) |
367 |
- os.chmod(var_new, dir_perms) |
368 |
- portage._bin_path = settings['PORTAGE_BIN_PATH'] |
369 |
- portage._pym_path = settings['PORTAGE_PYM_PATH'] |
370 |
- os.chmod(base_path_tmp, dir_perms) |
371 |
- |
372 |
def _elog_output_handler(self, fd, event): |
373 |
output = None |
374 |
if event & PollConstants.POLLIN: |
375 |
|
376 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
377 |
index 765a4f7..6d5de92 100644 |
378 |
--- a/pym/portage/package/ebuild/config.py |
379 |
+++ b/pym/portage/package/ebuild/config.py |
380 |
@@ -22,7 +22,7 @@ from portage import bsd_chflags, \ |
381 |
load_mod, os, selinux, _unicode_decode |
382 |
from portage.const import CACHE_PATH, \ |
383 |
DEPCACHE_PATH, INCREMENTALS, MAKE_CONF_FILE, \ |
384 |
- MODULES_FILE_PATH, PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, \ |
385 |
+ MODULES_FILE_PATH, \ |
386 |
PRIVATE_PATH, PROFILE_PATH, USER_CONFIG_PATH, \ |
387 |
USER_VIRTUALS_FILE |
388 |
from portage.const import _SANDBOX_COMPAT_LEVEL |
389 |
@@ -722,11 +722,6 @@ class config(object): |
390 |
self["USERLAND"] = "GNU" |
391 |
self.backup_changes("USERLAND") |
392 |
|
393 |
- self["PORTAGE_BIN_PATH"] = PORTAGE_BIN_PATH |
394 |
- self.backup_changes("PORTAGE_BIN_PATH") |
395 |
- self["PORTAGE_PYM_PATH"] = PORTAGE_PYM_PATH |
396 |
- self.backup_changes("PORTAGE_PYM_PATH") |
397 |
- |
398 |
for var in ("PORTAGE_INST_UID", "PORTAGE_INST_GID"): |
399 |
try: |
400 |
self[var] = str(int(self.get(var, "0"))) |
401 |
@@ -2088,6 +2083,14 @@ class config(object): |
402 |
del x[mykey] |
403 |
|
404 |
def __getitem__(self,mykey): |
405 |
+ |
406 |
+ # These ones point to temporary values when |
407 |
+ # portage plans to update itself. |
408 |
+ if mykey == "PORTAGE_BIN_PATH": |
409 |
+ return portage._bin_path |
410 |
+ elif mykey == "PORTAGE_PYM_PATH": |
411 |
+ return portage._pym_path |
412 |
+ |
413 |
for d in self.lookuplist: |
414 |
if mykey in d: |
415 |
return d[mykey] |
416 |
@@ -2133,6 +2136,8 @@ class config(object): |
417 |
|
418 |
def __iter__(self): |
419 |
keys = set() |
420 |
+ keys.add("PORTAGE_BIN_PATH") |
421 |
+ keys.add("PORTAGE_PYM_PATH") |
422 |
for d in self.lookuplist: |
423 |
keys.update(d) |
424 |
return iter(keys) |
425 |
|
426 |
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py |
427 |
index bdfcbcc..49d3e89 100644 |
428 |
--- a/pym/portage/package/ebuild/doebuild.py |
429 |
+++ b/pym/portage/package/ebuild/doebuild.py |
430 |
@@ -44,7 +44,7 @@ from portage.dep import Atom, check_required_use, \ |
431 |
from portage.eapi import eapi_exports_KV, eapi_exports_merge_type, \ |
432 |
eapi_exports_replace_vars, eapi_has_required_use, \ |
433 |
eapi_has_src_prepare_and_src_configure, eapi_has_pkg_pretend |
434 |
-from portage.elog import elog_process |
435 |
+from portage.elog import elog_process, _preload_elog_modules |
436 |
from portage.elog.messages import eerror, eqawarn |
437 |
from portage.exception import DigestException, FileNotFound, \ |
438 |
IncorrectParameter, InvalidDependString, PermissionDenied, \ |
439 |
@@ -1027,6 +1027,7 @@ def doebuild(myebuild, mydo, _unused=None, settings=None, debug=0, listonly=0, |
440 |
# qmerge is a special phase that implies noclean. |
441 |
if "noclean" not in mysettings.features: |
442 |
mysettings.features.add("noclean") |
443 |
+ _handle_self_update(mysettings, vartree.dbapi) |
444 |
#qmerge is specifically not supposed to do a runtime dep check |
445 |
retval = merge( |
446 |
mysettings["CATEGORY"], mysettings["PF"], mysettings["D"], |
447 |
@@ -1043,6 +1044,7 @@ def doebuild(myebuild, mydo, _unused=None, settings=None, debug=0, listonly=0, |
448 |
# so that it's only called once. |
449 |
elog_process(mysettings.mycpv, mysettings) |
450 |
if retval == os.EX_OK: |
451 |
+ _handle_self_update(mysettings, vartree.dbapi) |
452 |
retval = merge(mysettings["CATEGORY"], mysettings["PF"], |
453 |
mysettings["D"], os.path.join(mysettings["PORTAGE_BUILDDIR"], |
454 |
"build-info"), myroot, mysettings, |
455 |
@@ -2013,3 +2015,43 @@ def _merge_unicode_error(errors): |
456 |
lines.append("") |
457 |
|
458 |
return lines |
459 |
+ |
460 |
+def _prepare_self_update(settings): |
461 |
+ # Load lazily referenced portage submodules into memory, |
462 |
+ # so imports won't fail during portage upgrade/downgrade. |
463 |
+ _preload_elog_modules(settings) |
464 |
+ portage.proxy.lazyimport._preload_portage_submodules() |
465 |
+ |
466 |
+ # Make the temp directory inside $PORTAGE_TMPDIR/portage, since |
467 |
+ # it's common for /tmp and /var/tmp to be mounted with the |
468 |
+ # "noexec" option (see bug #346899). |
469 |
+ build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage") |
470 |
+ portage.util.ensure_dirs(build_prefix) |
471 |
+ base_path_tmp = tempfile.mkdtemp( |
472 |
+ "", "._portage_reinstall_.", build_prefix) |
473 |
+ portage.process.atexit_register(shutil.rmtree, base_path_tmp) |
474 |
+ |
475 |
+ orig_bin_path = portage._bin_path |
476 |
+ portage._bin_path = os.path.join(base_path_tmp, "bin") |
477 |
+ shutil.copytree(orig_bin_path, portage._bin_path, symlinks=True) |
478 |
+ |
479 |
+ orig_pym_path = portage._pym_path |
480 |
+ portage._pym_path = os.path.join(base_path_tmp, "pym") |
481 |
+ shutil.copytree(orig_pym_path, portage._pym_path, symlinks=True) |
482 |
+ |
483 |
+ for dir_path in (base_path_tmp, portage._bin_path, portage._pym_path): |
484 |
+ os.chmod(dir_path, 0o755) |
485 |
+ |
486 |
+def _handle_self_update(settings, vardb): |
487 |
+ cpv = settings.mycpv |
488 |
+ if settings["ROOT"] == "/" and \ |
489 |
+ portage.dep.match_from_list( |
490 |
+ portage.const.PORTAGE_PACKAGE_ATOM, [cpv]): |
491 |
+ inherited = frozenset(settings.get('INHERITED', '').split()) |
492 |
+ if not vardb.cpv_exists(cpv) or \ |
493 |
+ '9999' in cpv or \ |
494 |
+ 'git' in inherited or \ |
495 |
+ 'git-2' in inherited: |
496 |
+ _prepare_self_update(settings) |
497 |
+ return True |
498 |
+ return False |