1 # Copyright 2010-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
10 from itertools import chain
19 from textwrap import wrap
25 portage.proxy.lazyimport.lazyimport(globals(),
26 'portage.package.ebuild.config:check_config_instance',
27 'portage.package.ebuild.digestcheck:digestcheck',
28 'portage.package.ebuild.digestgen:digestgen',
29 'portage.package.ebuild.fetch:fetch',
30 'portage.package.ebuild._ipc.QueryCommand:QueryCommand',
31 'portage.dep._slot_operator:evaluate_slot_operator_equal_deps',
32 'portage.package.ebuild._spawn_nofetch:spawn_nofetch',
33 'portage.util._desktop_entry:validate_desktop_entry',
34 'portage.util._async.SchedulerInterface:SchedulerInterface',
35 'portage.util._eventloop.EventLoop:EventLoop',
36 'portage.util._eventloop.global_event_loop:global_event_loop',
37 'portage.util.ExtractKernelVersion:ExtractKernelVersion'
40 from portage import auxdbkeys, bsd_chflags, \
41 eapi_is_supported, merge, os, selinux, shutil, \
42 unmerge, _encodings, _os_merge, \
43 _shell_quote, _unicode_decode, _unicode_encode
44 from portage.const import EBUILD_SH_ENV_FILE, EBUILD_SH_ENV_DIR, \
45 EBUILD_SH_BINARY, INVALID_ENV_FILE, MISC_SH_BINARY
46 from portage.data import portage_gid, portage_uid, secpass, \
48 from portage.dbapi.porttree import _parse_uri_map
49 from portage.dep import Atom, check_required_use, \
50 human_readable_required_use, paren_enclose, use_reduce
51 from portage.eapi import eapi_exports_KV, eapi_exports_merge_type, \
52 eapi_exports_replace_vars, eapi_exports_REPOSITORY, \
53 eapi_has_required_use, eapi_has_src_prepare_and_src_configure, \
54 eapi_has_pkg_pretend, _get_eapi_attrs
55 from portage.elog import elog_process, _preload_elog_modules
56 from portage.elog.messages import eerror, eqawarn
57 from portage.exception import DigestException, FileNotFound, \
58 IncorrectParameter, InvalidDependString, PermissionDenied, \
59 UnsupportedAPIException
60 from portage.localization import _
61 from portage.output import colormap
62 from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
63 from portage.util import apply_recursive_permissions, \
64 apply_secpass_permissions, noiselimit, normalize_path, \
65 writemsg, writemsg_stdout, write_atomic
66 from portage.util.lafilefixer import rewrite_lafile
67 from portage.versions import _pkgsplit
68 from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
69 from _emerge.EbuildBuildDir import EbuildBuildDir
70 from _emerge.EbuildPhase import EbuildPhase
71 from _emerge.EbuildSpawnProcess import EbuildSpawnProcess
72 from _emerge.Package import Package
73 from _emerge.RootConfig import RootConfig
75 _unsandboxed_phases = frozenset([
76 "clean", "cleanrm", "config",
77 "help", "info", "postinst",
78 "preinst", "pretend", "postrm",
83 "config": "pkg_config",
85 "nofetch": "pkg_nofetch",
86 "unpack": "src_unpack",
87 "prepare": "src_prepare",
88 "configure": "src_configure",
89 "compile": "src_compile",
91 "install": "src_install",
92 "preinst": "pkg_preinst",
93 "postinst": "pkg_postinst",
95 "postrm": "pkg_postrm",
97 "pretend": "pkg_pretend",
100 _vdb_use_conditional_keys = Package._dep_keys + \
101 ('LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',)
103 def _doebuild_spawn(phase, settings, actionmap=None, **kwargs):
105 All proper ebuild phases which execute ebuild.sh are spawned
106 via this function. No exceptions.
109 if phase in _unsandboxed_phases:
110 kwargs['free'] = True
112 if phase == 'depend':
113 kwargs['droppriv'] = 'userpriv' in settings.features
114 # It's not necessary to close_fds for this phase, since
115 # it should not spawn any daemons, and close_fds is
116 # best avoided since it can interact badly with some
117 # garbage collectors (see _setup_pipes docstring).
118 kwargs['close_fds'] = False
120 if actionmap is not None and phase in actionmap:
121 kwargs.update(actionmap[phase]["args"])
122 cmd = actionmap[phase]["cmd"] % phase
124 if phase == 'cleanrm':
125 ebuild_sh_arg = 'clean'
127 ebuild_sh_arg = phase
129 cmd = "%s %s" % (_shell_quote(
130 os.path.join(settings["PORTAGE_BIN_PATH"],
131 os.path.basename(EBUILD_SH_BINARY))),
134 settings['EBUILD_PHASE'] = phase
136 return spawn(cmd, settings, **kwargs)
138 settings.pop('EBUILD_PHASE', None)
140 def _spawn_phase(phase, settings, actionmap=None, **kwargs):
141 if kwargs.get('returnpid'):
142 return _doebuild_spawn(phase, settings, actionmap=actionmap, **kwargs)
144 ebuild_phase = EbuildPhase(actionmap=actionmap, background=False,
145 phase=phase, scheduler=SchedulerInterface(portage._internal_caller and
146 global_event_loop() or EventLoop(main=False)),
150 return ebuild_phase.returncode
152 def _doebuild_path(settings, eapi=None):
154 Generate the PATH variable.
157 # Note: PORTAGE_BIN_PATH may differ from the global constant
158 # when portage is reinstalling itself.
159 portage_bin_path = settings["PORTAGE_BIN_PATH"]
160 eprefix = settings["EPREFIX"]
161 prerootpath = [x for x in settings.get("PREROOTPATH", "").split(":") if x]
162 rootpath = [x for x in settings.get("ROOTPATH", "").split(":") if x]
166 prefixes.append(eprefix)
171 if eprefix and uid != 0 and "fakeroot" not in settings.features:
172 path.append(os.path.join(portage_bin_path,
173 "ebuild-helpers", "unprivileged"))
175 if settings.get("USERLAND", "GNU") != "GNU":
176 path.append(os.path.join(portage_bin_path, "ebuild-helpers", "bsd"))
178 path.append(os.path.join(portage_bin_path, "ebuild-helpers"))
179 path.extend(prerootpath)
181 for prefix in prefixes:
182 for x in ("usr/local/sbin", "usr/local/bin", "usr/sbin", "usr/bin", "sbin", "bin"):
183 path.append(os.path.join(prefix, x))
185 path.extend(rootpath)
186 settings["PATH"] = ":".join(path)
188 def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
189 debug=False, use_cache=None, db=None):
191 Create and store environment variable in the config instance
192 that's passed in as the "settings" parameter. This will raise
193 UnsupportedAPIException if the given ebuild has an unsupported
194 EAPI. All EAPI dependent code comes last, so that essential
195 variables like PORTAGE_BUILDDIR are still initialized even in
196 cases when UnsupportedAPIException needs to be raised, which
197 can be useful when uninstalling a package that has corrupt
199 The myroot and use_cache parameters are unused.
205 raise TypeError("settings argument is required")
208 raise TypeError("db argument is required")
210 mysettings = settings
212 ebuild_path = os.path.abspath(myebuild)
213 pkg_dir = os.path.dirname(ebuild_path)
214 mytree = os.path.dirname(os.path.dirname(pkg_dir))
215 mypv = os.path.basename(ebuild_path)[:-7]
216 mysplit = _pkgsplit(mypv, eapi=mysettings.configdict["pkg"].get("EAPI"))
218 raise IncorrectParameter(
219 _("Invalid ebuild path: '%s'") % myebuild)
221 if mysettings.mycpv is not None and \
222 mysettings.configdict["pkg"].get("PF") == mypv and \
223 "CATEGORY" in mysettings.configdict["pkg"]:
224 # Assume that PF is enough to assume that we've got
225 # the correct CATEGORY, though this is not really
226 # a solid assumption since it's possible (though
227 # unlikely) that two packages in different
228 # categories have the same PF. Callers should call
229 # setcpv or create a clean clone of a locked config
230 # instance in order to ensure that this assumption
231 # does not fail like in bug #408817.
232 cat = mysettings.configdict["pkg"]["CATEGORY"]
233 mycpv = mysettings.mycpv
234 elif os.path.basename(pkg_dir) in (mysplit[0], mypv):
235 # portdbapi or vardbapi
236 cat = os.path.basename(os.path.dirname(pkg_dir))
237 mycpv = cat + "/" + mypv
239 raise AssertionError("unable to determine CATEGORY")
241 # Make a backup of PORTAGE_TMPDIR prior to calling config.reset()
242 # so that the caller can override it.
243 tmpdir = mysettings["PORTAGE_TMPDIR"]
246 if mycpv != mysettings.mycpv:
247 # Don't pass in mydbapi here since the resulting aux_get
248 # call would lead to infinite 'depend' phase recursion.
249 mysettings.setcpv(mycpv)
251 # If EAPI isn't in configdict["pkg"], it means that setcpv()
252 # hasn't been called with the mydb argument, so we have to
253 # call it here (portage code always calls setcpv properly,
254 # but api consumers might not).
255 if mycpv != mysettings.mycpv or \
256 "EAPI" not in mysettings.configdict["pkg"]:
257 # Reload env.d variables and reset any previous settings.
260 mysettings.setcpv(mycpv, mydb=mydbapi)
262 # config.reset() might have reverted a change made by the caller,
263 # so restore it to its original value. Sandbox needs canonical
264 # paths, so realpath it.
265 mysettings["PORTAGE_TMPDIR"] = os.path.realpath(tmpdir)
267 mysettings.pop("EBUILD_PHASE", None) # remove from backupenv
268 mysettings["EBUILD_PHASE"] = mydo
270 # Set requested Python interpreter for Portage helpers.
271 mysettings['PORTAGE_PYTHON'] = portage._python_interpreter
273 # This is used by assert_sigpipe_ok() that's used by the ebuild
274 # unpack() helper. SIGPIPE is typically 13, but its better not
276 mysettings['PORTAGE_SIGPIPE_STATUS'] = str(128 + signal.SIGPIPE)
278 # We are disabling user-specific bashrc files.
279 mysettings["BASH_ENV"] = INVALID_ENV_FILE
281 if debug: # Otherwise it overrides emerge's settings.
282 # We have no other way to set debug... debug can't be passed in
283 # due to how it's coded... Don't overwrite this so we can use it.
284 mysettings["PORTAGE_DEBUG"] = "1"
286 mysettings["EBUILD"] = ebuild_path
287 mysettings["O"] = pkg_dir
288 mysettings.configdict["pkg"]["CATEGORY"] = cat
289 mysettings["FILESDIR"] = pkg_dir+"/files"
290 mysettings["PF"] = mypv
292 if hasattr(mydbapi, 'repositories'):
293 repo = mydbapi.repositories.get_repo_for_location(mytree)
294 mysettings['PORTDIR'] = repo.eclass_db.porttrees[0]
295 mysettings['PORTDIR_OVERLAY'] = ' '.join(repo.eclass_db.porttrees[1:])
296 mysettings.configdict["pkg"]["PORTAGE_REPO_NAME"] = repo.name
298 mysettings["PORTDIR"] = os.path.realpath(mysettings["PORTDIR"])
299 mysettings["DISTDIR"] = os.path.realpath(mysettings["DISTDIR"])
300 mysettings["RPMDIR"] = os.path.realpath(mysettings["RPMDIR"])
302 mysettings["ECLASSDIR"] = mysettings["PORTDIR"]+"/eclass"
303 mysettings["SANDBOX_LOG"] = mycpv.replace("/", "_-_")
305 mysettings["PROFILE_PATHS"] = "\n".join(mysettings.profiles)
306 mysettings["P"] = mysplit[0]+"-"+mysplit[1]
307 mysettings["PN"] = mysplit[0]
308 mysettings["PV"] = mysplit[1]
309 mysettings["PR"] = mysplit[2]
312 mysettings["PORTAGE_QUIET"] = "1"
314 if mysplit[2] == "r0":
315 mysettings["PVR"]=mysplit[1]
317 mysettings["PVR"]=mysplit[1]+"-"+mysplit[2]
319 # All temporary directories should be subdirectories of
320 # $PORTAGE_TMPDIR/portage, since it's common for /tmp and /var/tmp
321 # to be mounted with the "noexec" option (see bug #346899).
322 mysettings["BUILD_PREFIX"] = mysettings["PORTAGE_TMPDIR"]+"/portage"
323 mysettings["PKG_TMPDIR"] = mysettings["BUILD_PREFIX"]+"/._unmerge_"
325 # Package {pre,post}inst and {pre,post}rm may overlap, so they must have separate
326 # locations in order to prevent interference.
327 if mydo in ("unmerge", "prerm", "postrm", "cleanrm"):
328 mysettings["PORTAGE_BUILDDIR"] = os.path.join(
329 mysettings["PKG_TMPDIR"],
330 mysettings["CATEGORY"], mysettings["PF"])
332 mysettings["PORTAGE_BUILDDIR"] = os.path.join(
333 mysettings["BUILD_PREFIX"],
334 mysettings["CATEGORY"], mysettings["PF"])
336 mysettings["HOME"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "homedir")
337 mysettings["WORKDIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "work")
338 mysettings["D"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "image") + os.sep
339 mysettings["T"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "temp")
341 # Prefix forward compatability
342 eprefix_lstrip = mysettings["EPREFIX"].lstrip(os.sep)
343 mysettings["ED"] = os.path.join(
344 mysettings["D"], eprefix_lstrip).rstrip(os.sep) + os.sep
346 mysettings["PORTAGE_BASHRC"] = os.path.join(
347 mysettings["PORTAGE_CONFIGROOT"], EBUILD_SH_ENV_FILE)
348 mysettings["PM_EBUILD_HOOK_DIR"] = os.path.join(
349 mysettings["PORTAGE_CONFIGROOT"], EBUILD_SH_ENV_DIR)
351 # Allow color.map to control colors associated with einfo, ewarn, etc...
352 mysettings["PORTAGE_COLORMAP"] = colormap()
354 if "COLUMNS" not in mysettings:
355 # Set COLUMNS, in order to prevent unnecessary stty calls
356 # inside the set_colors function of isolated-functions.sh.
357 # We cache the result in os.environ, in order to avoid
358 # multiple stty calls in cases when get_term_size() falls
359 # back to stty due to a missing or broken curses module.
360 columns = os.environ.get("COLUMNS")
362 rows, columns = portage.output.get_term_size()
364 # Force a sane value for COLUMNS, so that tools
365 # like ls don't complain (see bug #394091).
367 columns = str(columns)
368 os.environ["COLUMNS"] = columns
369 mysettings["COLUMNS"] = columns
371 # EAPI is always known here, even for the "depend" phase, because
372 # EbuildMetadataPhase gets it from _parse_eapi_ebuild_head().
373 eapi = mysettings.configdict['pkg']['EAPI']
374 _doebuild_path(mysettings, eapi=eapi)
376 # All EAPI dependent code comes last, so that essential variables like
377 # PATH and PORTAGE_BUILDDIR are still initialized even in cases when
378 # UnsupportedAPIException needs to be raised, which can be useful
379 # when uninstalling a package that has corrupt EAPI metadata.
380 if not eapi_is_supported(eapi):
381 raise UnsupportedAPIException(mycpv, eapi)
383 if eapi_exports_REPOSITORY(eapi) and "PORTAGE_REPO_NAME" in mysettings.configdict["pkg"]:
384 mysettings.configdict["pkg"]["REPOSITORY"] = mysettings.configdict["pkg"]["PORTAGE_REPO_NAME"]
387 if hasattr(mydbapi, "getFetchMap") and \
388 ("A" not in mysettings.configdict["pkg"] or \
389 "AA" not in mysettings.configdict["pkg"]):
390 src_uri, = mydbapi.aux_get(mysettings.mycpv,
391 ["SRC_URI"], mytree=mytree)
396 use = frozenset(mysettings["PORTAGE_USE"].split())
398 uri_map = _parse_uri_map(mysettings.mycpv, metadata, use=use)
399 except InvalidDependString:
400 mysettings.configdict["pkg"]["A"] = ""
402 mysettings.configdict["pkg"]["A"] = " ".join(uri_map)
405 uri_map = _parse_uri_map(mysettings.mycpv, metadata)
406 except InvalidDependString:
407 mysettings.configdict["pkg"]["AA"] = ""
409 mysettings.configdict["pkg"]["AA"] = " ".join(uri_map)
411 ccache = "ccache" in mysettings.features
412 distcc = "distcc" in mysettings.features
414 # Use default ABI libdir in accordance with bug #355283.
416 default_abi = mysettings.get("DEFAULT_ABI")
418 libdir = mysettings.get("LIBDIR_" + default_abi)
423 mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
424 "usr", libdir, "distcc", "bin") + ":" + mysettings["PATH"]
427 mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
428 "usr", libdir, "ccache", "bin") + ":" + mysettings["PATH"]
430 if not eapi_exports_KV(eapi):
431 # Discard KV for EAPIs that don't support it. Cached KV is restored
432 # from the backupenv whenever config.reset() is called.
433 mysettings.pop('KV', None)
434 elif 'KV' not in mysettings and \
435 mydo in ('compile', 'config', 'configure', 'info',
436 'install', 'nofetch', 'postinst', 'postrm', 'preinst',
437 'prepare', 'prerm', 'setup', 'test', 'unpack'):
438 mykv, err1 = ExtractKernelVersion(
439 os.path.join(mysettings['EROOT'], "usr/src/linux"))
441 # Regular source tree
442 mysettings["KV"] = mykv
444 mysettings["KV"] = ""
445 mysettings.backup_changes("KV")
447 _doebuild_manifest_cache = None
448 _doebuild_broken_ebuilds = set()
449 _doebuild_broken_manifests = set()
450 _doebuild_commands_without_builddir = (
451 'clean', 'cleanrm', 'depend', 'digest',
452 'fetch', 'fetchall', 'help', 'manifest'
455 def doebuild(myebuild, mydo, _unused=None, settings=None, debug=0, listonly=0,
456 fetchonly=0, cleanup=0, dbkey=None, use_cache=1, fetchall=0, tree=None,
457 mydbapi=None, vartree=None, prev_mtimes=None,
458 fd_pipes=None, returnpid=False):
460 Wrapper function that invokes specific ebuild phases through the spawning
463 @param myebuild: name of the ebuild to invoke the phase on (CPV)
464 @type myebuild: String
465 @param mydo: Phase to run
467 @param _unused: Deprecated (use settings["ROOT"] instead)
468 @type _unused: String
469 @param settings: Portage Configuration
470 @type settings: instance of portage.config
471 @param debug: Turns on various debug information (eg, debug for spawn)
473 @param listonly: Used to wrap fetch(); passed such that fetch only lists files required.
474 @type listonly: Boolean
475 @param fetchonly: Used to wrap fetch(); passed such that files are only fetched (no other actions)
476 @type fetchonly: Boolean
477 @param cleanup: Passed to prepare_build_dirs (TODO: what does it do?)
478 @type cleanup: Boolean
479 @param dbkey: A file path where metadata generated by the 'depend' phase
482 @param use_cache: Enables the cache
483 @type use_cache: Boolean
484 @param fetchall: Used to wrap fetch(), fetches all URIs (even ones invalid due to USE conditionals)
485 @type fetchall: Boolean
486 @param tree: Which tree to use ('vartree','porttree','bintree', etc..), defaults to 'porttree'
488 @param mydbapi: a dbapi instance to pass to various functions; this should be a portdbapi instance.
489 @type mydbapi: portdbapi instance
490 @param vartree: A instance of vartree; used for aux_get calls, defaults to db[myroot]['vartree']
491 @type vartree: vartree instance
492 @param prev_mtimes: A dict of { filename:mtime } keys used by merge() to do config_protection
493 @type prev_mtimes: dictionary
494 @param fd_pipes: A dict of mapping for pipes, { '0': stdin, '1': stdout }
496 @type fd_pipes: Dictionary
497 @param returnpid: Return a list of process IDs for a successful spawn, or
498 an integer value if spawn is unsuccessful. NOTE: This requires the
499 caller clean up all returned PIDs.
500 @type returnpid: Boolean
506 Most errors have an accompanying error message.
508 listonly and fetchonly are only really necessary for operations involving 'fetch'
509 prev_mtimes are only necessary for merge operations.
510 Other variables may not be strictly required, many have defaults that are set inside of doebuild.
515 raise TypeError("settings parameter is required")
516 mysettings = settings
517 myroot = settings['EROOT']
519 if _unused is not None and _unused != mysettings['EROOT']:
520 warnings.warn("The third parameter of the "
521 "portage.doebuild() is now unused. Use "
522 "settings['ROOT'] instead.",
523 DeprecationWarning, stacklevel=2)
526 writemsg("Warning: tree not specified to doebuild\n")
529 # chunked out deps for each phase, so that ebuild binary can use it
530 # to collapse targets down.
533 "setup": ["pretend"],
535 "prepare": ["unpack"],
536 "configure": ["prepare"],
537 "compile":["configure"],
541 "package":["install"],
542 "merge" :["install"],
546 mydbapi = portage.db[myroot][tree].dbapi
548 if vartree is None and mydo in ("merge", "qmerge", "unmerge"):
549 vartree = portage.db[myroot]["vartree"]
551 features = mysettings.features
553 clean_phases = ("clean", "cleanrm")
554 validcommands = ["help","clean","prerm","postrm","cleanrm","preinst","postinst",
555 "config", "info", "setup", "depend", "pretend",
556 "fetch", "fetchall", "digest",
557 "unpack", "prepare", "configure", "compile", "test",
558 "install", "rpm", "qmerge", "merge",
559 "package","unmerge", "manifest"]
561 if mydo not in validcommands:
563 writemsg("!!! doebuild: '%s' is not one of the following valid commands:" % mydo,
565 for vcount in range(len(validcommands)):
567 writemsg("\n!!! ", noiselevel=-1)
568 writemsg(validcommands[vcount].ljust(11), noiselevel=-1)
569 writemsg("\n", noiselevel=-1)
572 if returnpid and mydo != 'depend':
573 warnings.warn("portage.doebuild() called " + \
574 "with returnpid parameter enabled. This usage will " + \
575 "not be supported in the future.",
576 DeprecationWarning, stacklevel=2)
578 if mydo == "fetchall":
582 parallel_fetchonly = mydo in ("fetch", "fetchall") and \
583 "PORTAGE_PARALLEL_FETCHONLY" in mysettings
585 if mydo not in clean_phases and not os.path.exists(myebuild):
586 writemsg("!!! doebuild: %s not found for %s\n" % (myebuild, mydo),
590 global _doebuild_manifest_cache
591 pkgdir = os.path.dirname(myebuild)
592 manifest_path = os.path.join(pkgdir, "Manifest")
593 if tree == "porttree":
594 repo_config = mysettings.repositories.get_repo_for_location(
595 os.path.dirname(os.path.dirname(pkgdir)))
600 if "strict" in features and \
601 "digest" not in features and \
602 tree == "porttree" and \
603 not repo_config.thin_manifest and \
604 mydo not in ("digest", "manifest", "help") and \
605 not portage._doebuild_manifest_exempt_depend and \
606 not (repo_config.allow_missing_manifest and not os.path.exists(manifest_path)):
607 # Always verify the ebuild checksums before executing it.
608 global _doebuild_broken_ebuilds
610 if myebuild in _doebuild_broken_ebuilds:
613 # Avoid checking the same Manifest several times in a row during a
614 # regen with an empty cache.
615 if _doebuild_manifest_cache is None or \
616 _doebuild_manifest_cache.getFullname() != manifest_path:
617 _doebuild_manifest_cache = None
618 if not os.path.exists(manifest_path):
619 out = portage.output.EOutput()
620 out.eerror(_("Manifest not found for '%s'") % (myebuild,))
621 _doebuild_broken_ebuilds.add(myebuild)
623 mf = repo_config.load_manifest(pkgdir, mysettings["DISTDIR"])
626 mf = _doebuild_manifest_cache
629 mf.checkFileHashes("EBUILD", os.path.basename(myebuild))
631 if not (mf.allow_missing and
632 os.path.basename(myebuild) not in mf.fhashdict["EBUILD"]):
633 out = portage.output.EOutput()
634 out.eerror(_("Missing digest for '%s'") % (myebuild,))
635 _doebuild_broken_ebuilds.add(myebuild)
638 out = portage.output.EOutput()
639 out.eerror(_("A file listed in the Manifest "
640 "could not be found: '%s'") % (myebuild,))
641 _doebuild_broken_ebuilds.add(myebuild)
643 except DigestException as e:
644 out = portage.output.EOutput()
645 out.eerror(_("Digest verification failed:"))
646 out.eerror("%s" % e.value[0])
647 out.eerror(_("Reason: %s") % e.value[1])
648 out.eerror(_("Got: %s") % e.value[2])
649 out.eerror(_("Expected: %s") % e.value[3])
650 _doebuild_broken_ebuilds.add(myebuild)
653 if mf.getFullname() in _doebuild_broken_manifests:
656 if mf is not _doebuild_manifest_cache and not mf.allow_missing:
658 # Make sure that all of the ebuilds are
659 # actually listed in the Manifest.
660 for f in os.listdir(pkgdir):
662 if f[-7:] == '.ebuild':
664 if pf is not None and not mf.hasFile("EBUILD", f):
665 f = os.path.join(pkgdir, f)
666 if f not in _doebuild_broken_ebuilds:
667 out = portage.output.EOutput()
668 out.eerror(_("A file is not listed in the "
669 "Manifest: '%s'") % (f,))
670 _doebuild_broken_manifests.add(manifest_path)
673 # We cache it only after all above checks succeed.
674 _doebuild_manifest_cache = mf
682 if mydo in ("digest", "manifest", "help"):
683 # Temporarily exempt the depend phase from manifest checks, in case
684 # aux_get calls trigger cache generation.
685 portage._doebuild_manifest_exempt_depend += 1
687 # If we don't need much space and we don't need a constant location,
688 # we can temporarily override PORTAGE_TMPDIR with a random temp dir
689 # so that there's no need for locking and it can be used even if the
690 # user isn't in the portage group.
691 if mydo in ("info",):
692 tmpdir = tempfile.mkdtemp()
693 tmpdir_orig = mysettings["PORTAGE_TMPDIR"]
694 mysettings["PORTAGE_TMPDIR"] = tmpdir
696 doebuild_environment(myebuild, mydo, myroot, mysettings, debug,
699 if mydo in clean_phases:
701 if not returnpid and \
702 'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
703 builddir_lock = EbuildBuildDir(
704 scheduler=(portage._internal_caller and
705 global_event_loop() or EventLoop(main=False)),
709 return _spawn_phase(mydo, mysettings,
710 fd_pipes=fd_pipes, returnpid=returnpid)
712 if builddir_lock is not None:
713 builddir_lock.unlock()
715 # get possible slot information from the deps file
717 writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2)
719 return _spawn_phase(mydo, mysettings,
720 fd_pipes=fd_pipes, returnpid=returnpid)
721 elif isinstance(dbkey, dict):
722 warnings.warn("portage.doebuild() called " + \
723 "with dict dbkey argument. This usage will " + \
724 "not be supported in the future.",
725 DeprecationWarning, stacklevel=2)
726 mysettings["dbkey"] = ""
729 0:portage._get_stdin().fileno(),
730 1:sys.__stdout__.fileno(),
731 2:sys.__stderr__.fileno(),
733 mypids = _spawn_phase(mydo, mysettings, returnpid=True,
735 os.close(pw) # belongs exclusively to the child process now
736 f = os.fdopen(pr, 'rb', 0)
737 for k, v in zip(auxdbkeys,
738 (_unicode_decode(line).rstrip('\n') for line in f)):
741 retval = os.waitpid(mypids[0], 0)[1]
742 portage.process.spawned_pids.remove(mypids[0])
743 # If it got a signal, return the signal that was sent, but
744 # shift in order to distinguish it from a return value. (just
745 # like portage.process.spawn() would do).
747 retval = (retval & 0xff) << 8
749 # Otherwise, return its exit code.
751 if retval == os.EX_OK and len(dbkey) != len(auxdbkeys):
752 # Don't trust bash's returncode if the
753 # number of lines is incorrect.
757 mysettings["dbkey"] = dbkey
759 mysettings["dbkey"] = \
760 os.path.join(mysettings.depcachedir, "aux_db_key_temp")
762 return _spawn_phase(mydo, mysettings,
763 fd_pipes=fd_pipes, returnpid=returnpid)
765 # Validate dependency metadata here to ensure that ebuilds with invalid
766 # data are never installed via the ebuild command. Don't bother when
767 # returnpid == True since there's no need to do this every time emerge
769 if tree == "porttree":
770 rval = _validate_deps(mysettings, myroot, mydo, mydbapi)
775 # FEATURES=noauto only makes sense for porttree, and we don't want
776 # it to trigger redundant sourcing of the ebuild for API consumers
777 # that are using binary packages
778 if "noauto" in mysettings.features:
779 mysettings.features.discard("noauto")
781 # The info phase is special because it uses mkdtemp so and
782 # user (not necessarily in the portage group) can run it.
783 if mydo not in ('info',) and \
784 mydo not in _doebuild_commands_without_builddir:
785 rval = _check_temp_dir(mysettings)
789 if mydo == "unmerge":
790 return unmerge(mysettings["CATEGORY"],
791 mysettings["PF"], myroot, mysettings, vartree=vartree)
793 phases_to_run = set()
794 if "noauto" in mysettings.features or \
795 mydo not in actionmap_deps:
796 phases_to_run.add(mydo)
800 x = phase_stack.pop()
801 if x in phases_to_run:
804 phase_stack.extend(actionmap_deps.get(x, []))
807 alist = set(mysettings.configdict["pkg"].get("A", "").split())
810 if tree != "porttree":
812 elif "unpack" not in phases_to_run:
813 unpacked = os.path.exists(os.path.join(
814 mysettings["PORTAGE_BUILDDIR"], ".unpacked"))
817 workdir_st = os.stat(mysettings["WORKDIR"])
822 if not os.path.exists(os.path.join(
823 mysettings["PORTAGE_BUILDDIR"], ".unpacked")):
825 ">>> Not marked as unpacked; recreating WORKDIR...\n"))
829 writemsg_stdout(">>> Checking %s's mtime...\n" % x)
831 x_st = os.stat(os.path.join(
832 mysettings["DISTDIR"], x))
834 # file not fetched yet
837 if x_st is None or x_st.st_mtime > workdir_st.st_mtime:
838 writemsg_stdout(_(">>> Timestamp of "
839 "%s has changed; recreating WORKDIR...\n") % x)
844 if builddir_lock is None and \
845 'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
846 builddir_lock = EbuildBuildDir(
847 scheduler=(portage._internal_caller and
848 global_event_loop() or EventLoop(main=False)),
852 _spawn_phase("clean", mysettings)
854 if builddir_lock is not None:
855 builddir_lock.unlock()
858 writemsg_stdout(_(">>> WORKDIR is up-to-date, keeping...\n"))
861 # Build directory creation isn't required for any of these.
862 # In the fetch phase, the directory is needed only for RESTRICT=fetch
863 # in order to satisfy the sane $PWD requirement (from bug #239560)
864 # when pkg_nofetch is spawned.
865 have_build_dirs = False
866 if not parallel_fetchonly and \
867 mydo not in ('digest', 'fetch', 'help', 'manifest'):
868 if not returnpid and \
869 'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
870 builddir_lock = EbuildBuildDir(
871 scheduler=(portage._internal_caller and
872 global_event_loop() or EventLoop(main=False)),
875 mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
878 have_build_dirs = True
880 # emerge handles logging externally
882 # PORTAGE_LOG_FILE is set by the
883 # above prepare_build_dirs() call.
884 logfile = mysettings.get("PORTAGE_LOG_FILE")
887 rval = _prepare_env_file(mysettings)
891 if eapi_exports_merge_type(mysettings["EAPI"]) and \
892 "MERGE_TYPE" not in mysettings.configdict["pkg"]:
893 if tree == "porttree":
894 mysettings.configdict["pkg"]["EMERGE_FROM"] = "ebuild"
895 mysettings.configdict["pkg"]["MERGE_TYPE"] = "source"
896 elif tree == "bintree":
897 mysettings.configdict["pkg"]["EMERGE_FROM"] = "binary"
898 mysettings.configdict["pkg"]["MERGE_TYPE"] = "binary"
900 # NOTE: It's not possible to set REPLACED_BY_VERSION for prerm
901 # and postrm here, since we don't necessarily know what
902 # versions are being installed. This could be a problem
903 # for API consumers if they don't use dblink.treewalk()
904 # to execute prerm and postrm.
905 if eapi_exports_replace_vars(mysettings["EAPI"]) and \
906 (mydo in ("postinst", "preinst", "pretend", "setup") or \
907 ("noauto" not in features and not returnpid and \
908 (mydo in actionmap_deps or mydo in ("merge", "package", "qmerge")))):
910 writemsg("Warning: vartree not given to doebuild. " + \
911 "Cannot set REPLACING_VERSIONS in pkg_{pretend,setup}\n")
913 vardb = vartree.dbapi
914 cpv = mysettings.mycpv
915 cpv_slot = "%s%s%s" % \
916 (cpv.cp, portage.dep._slot_separator, cpv.slot)
917 mysettings["REPLACING_VERSIONS"] = " ".join(
918 set(portage.versions.cpv_getversion(match) \
919 for match in vardb.match(cpv_slot) + \
920 vardb.match('='+cpv)))
922 # if any of these are being called, handle them -- running them out of
923 # the sandbox -- and stop now.
924 if mydo in ("config", "help", "info", "postinst",
925 "preinst", "pretend", "postrm", "prerm"):
926 if mydo in ("preinst", "postinst"):
927 env_file = os.path.join(os.path.dirname(mysettings["EBUILD"]),
929 if os.path.isfile(env_file):
930 mysettings["PORTAGE_UPDATE_ENV"] = env_file
932 return _spawn_phase(mydo, mysettings,
933 fd_pipes=fd_pipes, logfile=logfile, returnpid=returnpid)
935 mysettings.pop("PORTAGE_UPDATE_ENV", None)
937 mycpv = "/".join((mysettings["CATEGORY"], mysettings["PF"]))
939 # Only try and fetch the files if we are going to need them ...
940 # otherwise, if user has FEATURES=noauto and they run `ebuild clean
941 # unpack compile install`, we will try and fetch 4 times :/
942 need_distfiles = tree == "porttree" and not unpacked and \
943 (mydo in ("fetch", "unpack") or \
944 mydo not in ("digest", "manifest") and "noauto" not in features)
947 src_uri, = mydbapi.aux_get(mysettings.mycpv,
948 ["SRC_URI"], mytree=os.path.dirname(os.path.dirname(
949 os.path.dirname(myebuild))))
951 "EAPI" : mysettings["EAPI"],
954 use = frozenset(mysettings["PORTAGE_USE"].split())
956 alist = _parse_uri_map(mysettings.mycpv, metadata, use=use)
957 aalist = _parse_uri_map(mysettings.mycpv, metadata)
958 except InvalidDependString as e:
959 writemsg("!!! %s\n" % str(e), noiselevel=-1)
960 writemsg(_("!!! Invalid SRC_URI for '%s'.\n") % mycpv,
965 if "mirror" in features or fetchall:
972 dist_digests = mf.getTypeDigests("DIST")
973 if not fetch(fetchme, mysettings, listonly=listonly,
974 fetchonly=fetchonly, allow_missing_digests=True,
975 digests=dist_digests):
976 spawn_nofetch(mydbapi, myebuild, settings=mysettings)
978 # The convention for listonly mode is to report
979 # success in any case, even though fetch() may
980 # return unsuccessfully in order to trigger the
986 # Files are already checked inside fetch(),
987 # so do not check them again.
990 # The unpack phase is marked as complete, so it
991 # would be wasteful to check distfiles again.
996 if mydo == "fetch" and listonly:
1000 if mydo == "manifest":
1002 _doebuild_manifest_cache = None
1003 return not digestgen(mysettings=mysettings, myportdb=mydbapi)
1004 elif mydo == "digest":
1006 _doebuild_manifest_cache = None
1007 return not digestgen(mysettings=mysettings, myportdb=mydbapi)
1008 elif mydo != 'fetch' and \
1009 "digest" in mysettings.features:
1010 # Don't do this when called by emerge or when called just
1011 # for fetch (especially parallel-fetch) since it's not needed
1012 # and it can interfere with parallel tasks.
1014 _doebuild_manifest_cache = None
1015 digestgen(mysettings=mysettings, myportdb=mydbapi)
1016 except PermissionDenied as e:
1017 writemsg(_("!!! Permission Denied: %s\n") % (e,), noiselevel=-1)
1018 if mydo in ("digest", "manifest"):
1021 # See above comment about fetching only when needed
1022 if tree == 'porttree' and \
1023 not digestcheck(checkme, mysettings, "strict" in features, mf=mf):
1029 # remove PORTAGE_ACTUAL_DISTDIR once cvs/svn is supported via SRC_URI
1030 if tree == 'porttree' and \
1031 ((mydo != "setup" and "noauto" not in features) \
1032 or mydo in ("install", "unpack")):
1033 _prepare_fake_distdir(mysettings, alist)
1035 #initial dep checks complete; time to process main commands
1036 actionmap = _spawn_actionmap(mysettings)
1038 # merge the deps in so we have again a 'full' actionmap
1039 # be glad when this can die.
1041 if len(actionmap_deps.get(x, [])):
1042 actionmap[x]["dep"] = ' '.join(actionmap_deps[x])
1044 if mydo in actionmap:
1046 if mydo == "package":
1047 # Make sure the package directory exists before executing
1048 # this phase. This can raise PermissionDenied if
1049 # the current user doesn't have write access to $PKGDIR.
1050 if hasattr(portage, 'db'):
1051 bintree = portage.db[mysettings['EROOT']]['bintree']
1052 mysettings["PORTAGE_BINPKG_TMPFILE"] = \
1053 bintree.getname(mysettings.mycpv) + \
1054 ".%s" % (os.getpid(),)
1055 bintree._ensure_dir(os.path.dirname(
1056 mysettings["PORTAGE_BINPKG_TMPFILE"]))
1058 parent_dir = os.path.join(mysettings["PKGDIR"],
1059 mysettings["CATEGORY"])
1060 portage.util.ensure_dirs(parent_dir)
1061 if not os.access(parent_dir, os.W_OK):
1062 raise PermissionDenied(
1063 "access('%s', os.W_OK)" % parent_dir)
1064 retval = spawnebuild(mydo,
1065 actionmap, mysettings, debug, logfile=logfile,
1066 fd_pipes=fd_pipes, returnpid=returnpid)
1068 if retval == os.EX_OK:
1069 if mydo == "package" and bintree is not None:
1070 bintree.inject(mysettings.mycpv,
1071 filename=mysettings["PORTAGE_BINPKG_TMPFILE"])
1073 if "PORTAGE_BINPKG_TMPFILE" in mysettings:
1075 os.unlink(mysettings["PORTAGE_BINPKG_TMPFILE"])
1079 elif mydo=="qmerge":
1080 # check to ensure install was run. this *only* pops up when users
1081 # forget it and are using ebuild
1082 if not os.path.exists(
1083 os.path.join(mysettings["PORTAGE_BUILDDIR"], ".installed")):
1084 writemsg(_("!!! mydo=qmerge, but the install phase has not been run\n"),
1087 # qmerge is a special phase that implies noclean.
1088 if "noclean" not in mysettings.features:
1089 mysettings.features.add("noclean")
1090 _handle_self_update(mysettings, vartree.dbapi)
1091 #qmerge is specifically not supposed to do a runtime dep check
1093 mysettings["CATEGORY"], mysettings["PF"], mysettings["D"],
1094 os.path.join(mysettings["PORTAGE_BUILDDIR"], "build-info"),
1095 myroot, mysettings, myebuild=mysettings["EBUILD"], mytree=tree,
1096 mydbapi=mydbapi, vartree=vartree, prev_mtimes=prev_mtimes)
1098 retval = spawnebuild("install", actionmap, mysettings, debug,
1099 alwaysdep=1, logfile=logfile, fd_pipes=fd_pipes,
1100 returnpid=returnpid)
1101 if retval != os.EX_OK:
1102 # The merge phase handles this already. Callers don't know how
1103 # far this function got, so we have to call elog_process() here
1104 # so that it's only called once.
1105 elog_process(mysettings.mycpv, mysettings)
1106 if retval == os.EX_OK:
1107 _handle_self_update(mysettings, vartree.dbapi)
1108 retval = merge(mysettings["CATEGORY"], mysettings["PF"],
1109 mysettings["D"], os.path.join(mysettings["PORTAGE_BUILDDIR"],
1110 "build-info"), myroot, mysettings,
1111 myebuild=mysettings["EBUILD"], mytree=tree, mydbapi=mydbapi,
1112 vartree=vartree, prev_mtimes=prev_mtimes)
1114 writemsg_stdout(_("!!! Unknown mydo: %s\n") % mydo, noiselevel=-1)
1121 if builddir_lock is not None:
1122 builddir_lock.unlock()
1124 mysettings["PORTAGE_TMPDIR"] = tmpdir_orig
1125 shutil.rmtree(tmpdir)
1127 mysettings.pop("REPLACING_VERSIONS", None)
1129 # Make sure that DISTDIR is restored to it's normal value before we return!
1130 if "PORTAGE_ACTUAL_DISTDIR" in mysettings:
1131 mysettings["DISTDIR"] = mysettings["PORTAGE_ACTUAL_DISTDIR"]
1132 del mysettings["PORTAGE_ACTUAL_DISTDIR"]
1134 if logfile and not returnpid:
1136 if os.stat(logfile).st_size == 0:
1141 if mydo in ("digest", "manifest", "help"):
1142 # If necessary, depend phase has been triggered by aux_get calls
1143 # and the exemption is no longer needed.
1144 portage._doebuild_manifest_exempt_depend -= 1
1146 def _check_temp_dir(settings):
1147 if "PORTAGE_TMPDIR" not in settings or \
1148 not os.path.isdir(settings["PORTAGE_TMPDIR"]):
1149 writemsg(_("The directory specified in your "
1150 "PORTAGE_TMPDIR variable, '%s',\n"
1151 "does not exist. Please create this directory or "
1152 "correct your PORTAGE_TMPDIR setting.\n") % \
1153 settings.get("PORTAGE_TMPDIR", ""), noiselevel=-1)
1156 # as some people use a separate PORTAGE_TMPDIR mount
1157 # we prefer that as the checks below would otherwise be pointless
1159 tmpdir = os.path.realpath(settings["PORTAGE_TMPDIR"])
1160 if os.path.exists(os.path.join(tmpdir, "portage")):
1161 checkdir = os.path.realpath(os.path.join(tmpdir, "portage"))
1162 if ("sandbox" in settings.features or
1163 "usersandox" in settings.features) and \
1164 not checkdir.startswith(tmpdir + os.sep):
1165 msg = _("The 'portage' subdirectory of the directory "
1166 "referenced by the PORTAGE_TMPDIR variable appears to be "
1167 "a symlink. In order to avoid sandbox violations (see bug "
1168 "#378379), you must adjust PORTAGE_TMPDIR instead of using "
1169 "the symlink located at '%s'. A suitable PORTAGE_TMPDIR "
1170 "setting would be '%s'.") % \
1171 (os.path.join(tmpdir, "portage"), checkdir)
1175 lines.extend(wrap(msg, 72))
1179 line = "!!! %s" % (line,)
1180 writemsg("%s\n" % (line,), noiselevel=-1)
1185 if not os.access(checkdir, os.W_OK):
1186 writemsg(_("%s is not writable.\n"
1187 "Likely cause is that you've mounted it as readonly.\n") % checkdir,
1191 with tempfile.NamedTemporaryFile(prefix="exectest-", dir=checkdir) as fd:
1192 os.chmod(fd.name, 0o755)
1193 if not os.access(fd.name, os.X_OK):
1194 writemsg(_("Can not execute files in %s\n"
1195 "Likely cause is that you've mounted it with one of the\n"
1196 "following mount options: 'noexec', 'user', 'users'\n\n"
1197 "Please make sure that portage can execute files in this directory.\n") % checkdir,
1203 def _prepare_env_file(settings):
1205 Extract environment.bz2 if it exists, but only if the destination
1206 environment file doesn't already exist. There are lots of possible
1207 states when doebuild() calls this function, and we want to avoid
1208 clobbering an existing environment file.
1211 env_extractor = BinpkgEnvExtractor(background=False,
1212 scheduler=(portage._internal_caller and
1213 global_event_loop() or EventLoop(main=False)),
1216 if env_extractor.dest_env_exists():
1217 # There are lots of possible states when doebuild()
1218 # calls this function, and we want to avoid
1219 # clobbering an existing environment file.
1222 if not env_extractor.saved_env_exists():
1223 # If the environment.bz2 doesn't exist, then ebuild.sh will
1224 # source the ebuild as a fallback.
1227 env_extractor.start()
1228 env_extractor.wait()
1229 return env_extractor.returncode
1231 def _prepare_fake_distdir(settings, alist):
1232 orig_distdir = settings["DISTDIR"]
1233 settings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir
1234 edpath = settings["DISTDIR"] = \
1235 os.path.join(settings["PORTAGE_BUILDDIR"], "distdir")
1236 portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0o755)
1238 # Remove any unexpected files or directories.
1239 for x in os.listdir(edpath):
1240 symlink_path = os.path.join(edpath, x)
1241 st = os.lstat(symlink_path)
1242 if x in alist and stat.S_ISLNK(st.st_mode):
1244 if stat.S_ISDIR(st.st_mode):
1245 shutil.rmtree(symlink_path)
1247 os.unlink(symlink_path)
1249 # Check for existing symlinks and recreate if necessary.
1251 symlink_path = os.path.join(edpath, x)
1252 target = os.path.join(orig_distdir, x)
1254 link_target = os.readlink(symlink_path)
1256 os.symlink(target, symlink_path)
1258 if link_target != target:
1259 os.unlink(symlink_path)
1260 os.symlink(target, symlink_path)
1262 def _spawn_actionmap(settings):
1263 features = settings.features
1264 restrict = settings["PORTAGE_RESTRICT"].split()
1265 nosandbox = (("userpriv" in features) and \
1266 ("usersandbox" not in features) and \
1267 "userpriv" not in restrict and \
1268 "nouserpriv" not in restrict)
1269 if nosandbox and ("userpriv" not in features or \
1270 "userpriv" in restrict or \
1271 "nouserpriv" in restrict):
1272 nosandbox = ("sandbox" not in features and \
1273 "usersandbox" not in features)
1275 if not portage.process.sandbox_capable:
1278 sesandbox = settings.selinux_enabled() and \
1279 "sesandbox" in features
1281 droppriv = "userpriv" in features and \
1282 "userpriv" not in restrict and \
1285 fakeroot = "fakeroot" in features
1287 portage_bin_path = settings["PORTAGE_BIN_PATH"]
1288 ebuild_sh_binary = os.path.join(portage_bin_path,
1289 os.path.basename(EBUILD_SH_BINARY))
1290 misc_sh_binary = os.path.join(portage_bin_path,
1291 os.path.basename(MISC_SH_BINARY))
1292 ebuild_sh = _shell_quote(ebuild_sh_binary) + " %s"
1293 misc_sh = _shell_quote(misc_sh_binary) + " __dyn_%s"
1295 # args are for the to spawn function
1297 "pretend": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0, "fakeroot":0}},
1298 "setup": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0, "fakeroot":0}},
1299 "unpack": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":0, "sesandbox":sesandbox, "fakeroot":0}},
1300 "prepare": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":0, "sesandbox":sesandbox, "fakeroot":0}},
1301 "configure":{"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
1302 "compile": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
1303 "test": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
1304 "install": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox, "fakeroot":fakeroot}},
1305 "rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}},
1306 "package": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}},
1311 def _validate_deps(mysettings, myroot, mydo, mydbapi):
1313 invalid_dep_exempt_phases = \
1314 set(["clean", "cleanrm", "help", "prerm", "postrm"])
1315 all_keys = set(Package.metadata_keys)
1316 all_keys.add("SRC_URI")
1317 all_keys = tuple(all_keys)
1318 metadata = dict(zip(all_keys,
1319 mydbapi.aux_get(mysettings.mycpv, all_keys,
1320 myrepo=mysettings.get("PORTAGE_REPO_NAME"))))
1322 class FakeTree(object):
1323 def __init__(self, mydb):
1326 root_config = RootConfig(mysettings, {"porttree":FakeTree(mydbapi)}, None)
1328 pkg = Package(built=False, cpv=mysettings.mycpv,
1329 metadata=metadata, root_config=root_config,
1334 for k, v in pkg.invalid.items():
1336 msgs.append(" %s\n" % (msg,))
1339 portage.util.writemsg_level(_("Error(s) in metadata for '%s':\n") % \
1340 (mysettings.mycpv,), level=logging.ERROR, noiselevel=-1)
1342 portage.util.writemsg_level(x,
1343 level=logging.ERROR, noiselevel=-1)
1344 if mydo not in invalid_dep_exempt_phases:
1347 if not pkg.built and \
1348 mydo not in ("digest", "help", "manifest") and \
1349 pkg._metadata["REQUIRED_USE"] and \
1350 eapi_has_required_use(pkg.eapi):
1351 result = check_required_use(pkg._metadata["REQUIRED_USE"],
1352 pkg.use.enabled, pkg.iuse.is_valid_flag, eapi=pkg.eapi)
1354 reduced_noise = result.tounicode()
1355 writemsg("\n %s\n" % _("The following REQUIRED_USE flag" + \
1356 " constraints are unsatisfied:"), noiselevel=-1)
1357 writemsg(" %s\n" % reduced_noise,
1359 normalized_required_use = \
1360 " ".join(pkg._metadata["REQUIRED_USE"].split())
1361 if reduced_noise != normalized_required_use:
1362 writemsg("\n %s\n" % _("The above constraints " + \
1363 "are a subset of the following complete expression:"),
1365 writemsg(" %s\n" % \
1366 human_readable_required_use(normalized_required_use),
1368 writemsg("\n", noiselevel=-1)
1373 # XXX This would be to replace getstatusoutput completely.
1374 # XXX Issue: cannot block execution. Deadlock condition.
1375 def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords):
1377 Spawn a subprocess with extra portage-specific options.
1380 Sandbox: Sandbox means the spawned process will be limited in its ability t
1381 read and write files (normally this means it is restricted to ${D}/)
1382 SElinux Sandbox: Enables sandboxing on SElinux
1383 Reduced Privileges: Drops privilages such that the process runs as portage:portage
1386 Notes: os.system cannot be used because it messes with signal handling. Instead we
1387 use the portage.process spawn* family of functions.
1389 This function waits for the process to terminate.
1391 @param mystring: Command to run
1392 @type mystring: String
1393 @param mysettings: Either a Dict of Key,Value pairs or an instance of portage.config
1394 @type mysettings: Dictionary or config instance
1395 @param debug: Ignored
1396 @type debug: Boolean
1397 @param free: Enable sandboxing for this process
1399 @param droppriv: Drop to portage:portage when running this command
1400 @type droppriv: Boolean
1401 @param sesandbox: Enable SELinux Sandboxing (toggles a context switch)
1402 @type sesandbox: Boolean
1403 @param fakeroot: Run this command with faked root privileges
1404 @type fakeroot: Boolean
1405 @param keywords: Extra options encoded as a dict, to be passed to spawn
1406 @type keywords: Dictionary
1409 1. The return code of the spawned process.
1412 check_config_instance(mysettings)
1414 fd_pipes = keywords.get("fd_pipes")
1415 if fd_pipes is None:
1417 0:portage._get_stdin().fileno(),
1418 1:sys.__stdout__.fileno(),
1419 2:sys.__stderr__.fileno(),
1421 # In some cases the above print statements don't flush stdout, so
1422 # it needs to be flushed before allowing a child process to use it
1423 # so that output always shows in the correct order.
1424 stdout_filenos = (sys.__stdout__.fileno(), sys.__stderr__.fileno())
1425 for fd in fd_pipes.values():
1426 if fd in stdout_filenos:
1427 sys.__stdout__.flush()
1428 sys.__stderr__.flush()
1431 features = mysettings.features
1432 # TODO: Enable fakeroot to be used together with droppriv. The
1433 # fake ownership/permissions will have to be converted to real
1434 # permissions in the merge phase.
1435 fakeroot = fakeroot and uid != 0 and portage.process.fakeroot_capable
1436 portage_build_uid = os.getuid()
1437 portage_build_gid = os.getgid()
1438 if uid == 0 and portage_uid and portage_gid and hasattr(os, "setgroups"):
1443 "groups": userpriv_groups,
1446 if "userpriv" in features and "userpriv" not in mysettings["PORTAGE_RESTRICT"].split() and secpass >= 2:
1447 portage_build_uid = portage_uid
1448 portage_build_gid = portage_gid
1449 mysettings["PORTAGE_BUILD_USER"] = pwd.getpwuid(portage_build_uid).pw_name
1450 mysettings["PORTAGE_BUILD_GROUP"] = grp.getgrgid(portage_build_gid).gr_name
1453 free=((droppriv and "usersandbox" not in features) or \
1454 (not droppriv and "sandbox" not in features and \
1455 "usersandbox" not in features and not fakeroot))
1457 if not free and not (fakeroot or portage.process.sandbox_capable):
1460 if mysettings.mycpv is not None:
1461 keywords["opt_name"] = "[%s]" % mysettings.mycpv
1463 keywords["opt_name"] = "[%s/%s]" % \
1464 (mysettings.get("CATEGORY",""), mysettings.get("PF",""))
1466 if free or "SANDBOX_ACTIVE" in os.environ:
1467 keywords["opt_name"] += " bash"
1468 spawn_func = portage.process.spawn_bash
1470 keywords["opt_name"] += " fakeroot"
1471 keywords["fakeroot_state"] = os.path.join(mysettings["T"], "fakeroot.state")
1472 spawn_func = portage.process.spawn_fakeroot
1474 keywords["opt_name"] += " sandbox"
1475 spawn_func = portage.process.spawn_sandbox
1478 spawn_func = selinux.spawn_wrapper(spawn_func,
1479 mysettings["PORTAGE_SANDBOX_T"])
1481 if keywords.get("returnpid"):
1482 return spawn_func(mystring, env=mysettings.environ(), **keywords)
1484 proc = EbuildSpawnProcess(
1485 background=False, args=mystring,
1486 scheduler=SchedulerInterface(portage._internal_caller and
1487 global_event_loop() or EventLoop(main=False)),
1488 spawn_func=spawn_func,
1489 settings=mysettings, **keywords)
1494 return proc.returncode
1496 # parse actionmap to spawn ebuild with the appropriate args
1497 def spawnebuild(mydo, actionmap, mysettings, debug, alwaysdep=0,
1498 logfile=None, fd_pipes=None, returnpid=False):
1501 warnings.warn("portage.spawnebuild() called " + \
1502 "with returnpid parameter enabled. This usage will " + \
1503 "not be supported in the future.",
1504 DeprecationWarning, stacklevel=2)
1506 if not returnpid and \
1507 (alwaysdep or "noauto" not in mysettings.features):
1508 # process dependency first
1509 if "dep" in actionmap[mydo]:
1510 retval = spawnebuild(actionmap[mydo]["dep"], actionmap,
1511 mysettings, debug, alwaysdep=alwaysdep, logfile=logfile,
1512 fd_pipes=fd_pipes, returnpid=returnpid)
1516 eapi = mysettings["EAPI"]
1518 if mydo in ("configure", "prepare") and not eapi_has_src_prepare_and_src_configure(eapi):
1521 if mydo == "pretend" and not eapi_has_pkg_pretend(eapi):
1524 if not (mydo == "install" and "noauto" in mysettings.features):
1525 check_file = os.path.join(
1526 mysettings["PORTAGE_BUILDDIR"], ".%sed" % mydo.rstrip('e'))
1527 if os.path.exists(check_file):
1528 writemsg_stdout(_(">>> It appears that "
1529 "'%(action)s' has already executed for '%(pkg)s'; skipping.\n") %
1530 {"action":mydo, "pkg":mysettings["PF"]})
1531 writemsg_stdout(_(">>> Remove '%(file)s' to force %(action)s.\n") %
1532 {"file":check_file, "action":mydo})
1535 return _spawn_phase(mydo, mysettings,
1536 actionmap=actionmap, logfile=logfile,
1537 fd_pipes=fd_pipes, returnpid=returnpid)
1539 _post_phase_cmds = {
1543 "install_symlink_html_docs",
1548 "preinst_selinux_labels",
1549 "preinst_suid_scan",
1553 def _post_phase_userpriv_perms(mysettings):
1554 if "userpriv" in mysettings.features and secpass >= 2:
1555 """ Privileged phases may have left files that need to be made
1556 writable to a less privileged user."""
1557 apply_recursive_permissions(mysettings["T"],
1558 uid=portage_uid, gid=portage_gid, dirmode=0o70, dirmask=0,
1559 filemode=0o60, filemask=0)
1561 def _check_build_log(mysettings, out=None):
1563 Search the content of $PORTAGE_LOG_FILE if it exists
1564 and generate the following QA Notices when appropriate:
1566 * Automake "maintainer mode"
1568 * Unrecognized configure options
1570 logfile = mysettings.get("PORTAGE_LOG_FILE")
1574 f = open(_unicode_encode(logfile, encoding=_encodings['fs'],
1575 errors='strict'), mode='rb')
1576 except EnvironmentError:
1580 if logfile.endswith('.gz'):
1582 f = gzip.GzipFile(filename='', mode='rb', fileobj=f)
1584 am_maintainer_mode = []
1585 bash_command_not_found = []
1586 bash_command_not_found_re = re.compile(
1587 r'(.*): line (\d*): (.*): command not found$')
1588 command_not_found_exclude_re = re.compile(r'/configure: line ')
1589 helper_missing_file = []
1590 helper_missing_file_re = re.compile(
1591 r'^!!! (do|new).*: .* does not exist$')
1593 configure_opts_warn = []
1594 configure_opts_warn_re = re.compile(
1595 r'^configure: WARNING: [Uu]nrecognized options: (.*)')
1597 qa_configure_opts = ""
1599 with io.open(_unicode_encode(os.path.join(
1600 mysettings["PORTAGE_BUILDDIR"],
1601 "build-info", "QA_CONFIGURE_OPTIONS"),
1602 encoding=_encodings['fs'], errors='strict'),
1603 mode='r', encoding=_encodings['repo.content'],
1604 errors='replace') as qa_configure_opts_f:
1605 qa_configure_opts = qa_configure_opts_f.read()
1606 except IOError as e:
1607 if e.errno not in (errno.ENOENT, errno.ESTALE):
1610 qa_configure_opts = qa_configure_opts.split()
1611 if qa_configure_opts:
1612 if len(qa_configure_opts) > 1:
1613 qa_configure_opts = "|".join("(%s)" % x for x in qa_configure_opts)
1614 qa_configure_opts = "^(%s)$" % qa_configure_opts
1616 qa_configure_opts = "^%s$" % qa_configure_opts[0]
1617 qa_configure_opts = re.compile(qa_configure_opts)
1619 qa_am_maintainer_mode = []
1621 with io.open(_unicode_encode(os.path.join(
1622 mysettings["PORTAGE_BUILDDIR"],
1623 "build-info", "QA_AM_MAINTAINER_MODE"),
1624 encoding=_encodings['fs'], errors='strict'),
1625 mode='r', encoding=_encodings['repo.content'],
1626 errors='replace') as qa_am_maintainer_mode_f:
1627 qa_am_maintainer_mode = [x for x in
1628 qa_am_maintainer_mode_f.read().splitlines() if x]
1629 except IOError as e:
1630 if e.errno not in (errno.ENOENT, errno.ESTALE):
1633 if qa_am_maintainer_mode:
1634 if len(qa_am_maintainer_mode) > 1:
1635 qa_am_maintainer_mode = \
1636 "|".join("(%s)" % x for x in qa_am_maintainer_mode)
1637 qa_am_maintainer_mode = "^(%s)$" % qa_am_maintainer_mode
1639 qa_am_maintainer_mode = "^%s$" % qa_am_maintainer_mode[0]
1640 qa_am_maintainer_mode = re.compile(qa_am_maintainer_mode)
1642 # Exclude output from dev-libs/yaz-3.0.47 which looks like this:
1645 # Automake: ${SHELL} /var/tmp/portage/dev-libs/yaz-3.0.47/work/yaz-3.0.47/config/missing --run automake-1.10
1646 am_maintainer_mode_re = re.compile(r'/missing --run ')
1647 am_maintainer_mode_exclude_re = \
1648 re.compile(r'(/missing --run (autoheader|autotest|help2man|makeinfo)|^\s*Automake:\s)')
1650 make_jobserver_re = \
1651 re.compile(r'g?make\[\d+\]: warning: jobserver unavailable:')
1656 eerror(line, phase="install", key=mysettings.mycpv, out=out)
1660 line = _unicode_decode(line)
1661 if am_maintainer_mode_re.search(line) is not None and \
1662 am_maintainer_mode_exclude_re.search(line) is None and \
1663 (not qa_am_maintainer_mode or
1664 qa_am_maintainer_mode.search(line) is None):
1665 am_maintainer_mode.append(line.rstrip("\n"))
1667 if bash_command_not_found_re.match(line) is not None and \
1668 command_not_found_exclude_re.search(line) is None:
1669 bash_command_not_found.append(line.rstrip("\n"))
1671 if helper_missing_file_re.match(line) is not None:
1672 helper_missing_file.append(line.rstrip("\n"))
1674 m = configure_opts_warn_re.match(line)
1676 for x in m.group(1).split(", "):
1677 if not qa_configure_opts or qa_configure_opts.match(x) is None:
1678 configure_opts_warn.append(x)
1680 if make_jobserver_re.match(line) is not None:
1681 make_jobserver.append(line.rstrip("\n"))
1683 except zlib.error as e:
1684 _eerror(["portage encountered a zlib error: '%s'" % (e,),
1685 "while reading the log file: '%s'" % logfile])
1689 def _eqawarn(lines):
1691 eqawarn(line, phase="install", key=mysettings.mycpv, out=out)
1694 if am_maintainer_mode:
1695 msg = [_("QA Notice: Automake \"maintainer mode\" detected:")]
1697 msg.extend("\t" + line for line in am_maintainer_mode)
1700 "If you patch Makefile.am, "
1701 "configure.in, or configure.ac then you "
1702 "should use autotools.eclass and "
1703 "eautomake or eautoreconf. Exceptions "
1704 "are limited to system packages "
1705 "for which it is impossible to run "
1706 "autotools during stage building. "
1707 "See http://www.gentoo.org/p"
1708 "roj/en/qa/autofailure.xml for more information."),
1712 if bash_command_not_found:
1713 msg = [_("QA Notice: command not found:")]
1715 msg.extend("\t" + line for line in bash_command_not_found)
1718 if helper_missing_file:
1719 msg = [_("QA Notice: file does not exist:")]
1721 msg.extend("\t" + line[4:] for line in helper_missing_file)
1724 if configure_opts_warn:
1725 msg = [_("QA Notice: Unrecognized configure options:")]
1727 msg.extend("\t%s" % x for x in configure_opts_warn)
1731 msg = [_("QA Notice: make jobserver unavailable:")]
1733 msg.extend("\t" + line for line in make_jobserver)
1737 if f_real is not None:
1740 def _post_src_install_write_metadata(settings):
1742 It's possible that the ebuild has changed the
1743 CHOST variable, so revert it to the initial
1744 setting. Also, revert IUSE in case it's corrupted
1745 due to local environment settings like in bug #386829.
1748 eapi_attrs = _get_eapi_attrs(settings.configdict['pkg']['EAPI'])
1750 build_info_dir = os.path.join(settings['PORTAGE_BUILDDIR'], 'build-info')
1752 metadata_keys = ['IUSE']
1753 if eapi_attrs.iuse_effective:
1754 metadata_keys.append('IUSE_EFFECTIVE')
1756 for k in metadata_keys:
1757 v = settings.configdict['pkg'].get(k)
1759 write_atomic(os.path.join(build_info_dir, k), v + '\n')
1761 # The following variables are irrelevant for virtual packages.
1762 if settings.get('CATEGORY') != 'virtual':
1764 for k in ('CHOST',):
1767 write_atomic(os.path.join(build_info_dir, k), v + '\n')
1769 with io.open(_unicode_encode(os.path.join(build_info_dir,
1770 'BUILD_TIME'), encoding=_encodings['fs'], errors='strict'),
1771 mode='w', encoding=_encodings['repo.content'],
1772 errors='strict') as f:
1773 f.write(_unicode_decode("%.0f\n" % (time.time(),)))
1775 use = frozenset(settings['PORTAGE_USE'].split())
1776 for k in _vdb_use_conditional_keys:
1777 v = settings.configdict['pkg'].get(k)
1778 filename = os.path.join(build_info_dir, k)
1786 if k.endswith('DEPEND'):
1787 if eapi_attrs.slot_operator:
1793 v = use_reduce(v, uselist=use, token_class=token_class)
1794 v = paren_enclose(v)
1801 with io.open(_unicode_encode(os.path.join(build_info_dir,
1802 k), encoding=_encodings['fs'], errors='strict'),
1803 mode='w', encoding=_encodings['repo.content'],
1804 errors='strict') as f:
1805 f.write(_unicode_decode(v + '\n'))
1807 if eapi_attrs.slot_operator:
1808 deps = evaluate_slot_operator_equal_deps(settings, use, QueryCommand.get_db())
1809 for k, v in deps.items():
1810 filename = os.path.join(build_info_dir, k)
1817 with io.open(_unicode_encode(os.path.join(build_info_dir,
1818 k), encoding=_encodings['fs'], errors='strict'),
1819 mode='w', encoding=_encodings['repo.content'],
1820 errors='strict') as f:
1821 f.write(_unicode_decode(v + '\n'))
1823 def _preinst_bsdflags(mysettings):
1825 # Save all the file flags for restoration later.
1826 os.system("mtree -c -p %s -k flags > %s" % \
1827 (_shell_quote(mysettings["D"]),
1828 _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))
1830 # Remove all the file flags to avoid EPERM errors.
1831 os.system("chflags -R noschg,nouchg,nosappnd,nouappnd %s" % \
1832 (_shell_quote(mysettings["D"]),))
1833 os.system("chflags -R nosunlnk,nouunlnk %s 2>/dev/null" % \
1834 (_shell_quote(mysettings["D"]),))
1837 def _postinst_bsdflags(mysettings):
1839 # Restore all of the flags saved above.
1840 os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \
1841 (_shell_quote(mysettings["ROOT"]),
1842 _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))
1844 def _post_src_install_uid_fix(mysettings, out):
1846 Files in $D with user and group bits that match the "portage"
1847 user or group are automatically mapped to PORTAGE_INST_UID and
1848 PORTAGE_INST_GID if necessary. The chown system call may clear
1849 S_ISUID and S_ISGID bits, so those bits are restored if
1855 inst_uid = int(mysettings["PORTAGE_INST_UID"])
1856 inst_gid = int(mysettings["PORTAGE_INST_GID"])
1858 _preinst_bsdflags(mysettings)
1860 destdir = mysettings["D"]
1861 ed_len = len(mysettings["ED"])
1863 desktop_file_validate = \
1864 portage.process.find_binary("desktop-file-validate") is not None
1865 xdg_dirs = mysettings.get('XDG_DATA_DIRS', '/usr/share').split(':')
1866 xdg_dirs = tuple(os.path.join(i, "applications") + os.sep
1867 for i in xdg_dirs if i)
1869 qa_desktop_file = ""
1871 with io.open(_unicode_encode(os.path.join(
1872 mysettings["PORTAGE_BUILDDIR"],
1873 "build-info", "QA_DESKTOP_FILE"),
1874 encoding=_encodings['fs'], errors='strict'),
1875 mode='r', encoding=_encodings['repo.content'],
1876 errors='replace') as f:
1877 qa_desktop_file = f.read()
1878 except IOError as e:
1879 if e.errno not in (errno.ENOENT, errno.ESTALE):
1882 qa_desktop_file = qa_desktop_file.split()
1884 if len(qa_desktop_file) > 1:
1885 qa_desktop_file = "|".join("(%s)" % x for x in qa_desktop_file)
1886 qa_desktop_file = "^(%s)$" % qa_desktop_file
1888 qa_desktop_file = "^%s$" % qa_desktop_file[0]
1889 qa_desktop_file = re.compile(qa_desktop_file)
1893 unicode_error = False
1895 counted_inodes = set()
1896 fixlafiles_announced = False
1897 fixlafiles = "fixlafiles" in mysettings.features
1898 desktopfile_errors = []
1900 for parent, dirs, files in os.walk(destdir):
1902 parent = _unicode_decode(parent,
1903 encoding=_encodings['merge'], errors='strict')
1904 except UnicodeDecodeError:
1905 new_parent = _unicode_decode(parent,
1906 encoding=_encodings['merge'], errors='replace')
1907 new_parent = _unicode_encode(new_parent,
1908 encoding='ascii', errors='backslashreplace')
1909 new_parent = _unicode_decode(new_parent,
1910 encoding=_encodings['merge'], errors='replace')
1911 os.rename(parent, new_parent)
1912 unicode_error = True
1913 unicode_errors.append(new_parent[ed_len:])
1916 for fname in chain(dirs, files):
1918 fname = _unicode_decode(fname,
1919 encoding=_encodings['merge'], errors='strict')
1920 except UnicodeDecodeError:
1921 fpath = _os.path.join(
1922 parent.encode(_encodings['merge']), fname)
1923 new_fname = _unicode_decode(fname,
1924 encoding=_encodings['merge'], errors='replace')
1925 new_fname = _unicode_encode(new_fname,
1926 encoding='ascii', errors='backslashreplace')
1927 new_fname = _unicode_decode(new_fname,
1928 encoding=_encodings['merge'], errors='replace')
1929 new_fpath = os.path.join(parent, new_fname)
1930 os.rename(fpath, new_fpath)
1931 unicode_error = True
1932 unicode_errors.append(new_fpath[ed_len:])
1936 fpath = os.path.join(parent, fname)
1938 fpath_relative = fpath[ed_len - 1:]
1939 if desktop_file_validate and fname.endswith(".desktop") and \
1940 os.path.isfile(fpath) and \
1941 fpath_relative.startswith(xdg_dirs) and \
1942 not (qa_desktop_file and qa_desktop_file.match(fpath_relative.strip(os.sep)) is not None):
1944 desktop_validate = validate_desktop_entry(fpath)
1945 if desktop_validate:
1946 desktopfile_errors.extend(desktop_validate)
1949 fname.endswith(".la") and os.path.isfile(fpath):
1950 f = open(_unicode_encode(fpath,
1951 encoding=_encodings['merge'], errors='strict'),
1953 has_lafile_header = b'.la - a libtool library file' \
1959 needs_update, new_contents = rewrite_lafile(contents)
1960 except portage.exception.InvalidData as e:
1961 needs_update = False
1962 if not fixlafiles_announced:
1963 fixlafiles_announced = True
1964 writemsg("Fixing .la files\n", fd=out)
1966 # Suppress warnings if the file does not have the
1967 # expected header (bug #340725). Even if the header is
1968 # missing, we still call rewrite_lafile() since some
1969 # valid libtool archives may not have the header.
1970 msg = " %s is not a valid libtool archive, skipping\n" % fpath[len(destdir):]
1971 qa_msg = "QA Notice: invalid .la file found: %s, %s" % (fpath[len(destdir):], e)
1972 if has_lafile_header:
1973 writemsg(msg, fd=out)
1974 eqawarn(qa_msg, key=mysettings.mycpv, out=out)
1977 if not fixlafiles_announced:
1978 fixlafiles_announced = True
1979 writemsg("Fixing .la files\n", fd=out)
1980 writemsg(" %s\n" % fpath[len(destdir):], fd=out)
1981 # write_atomic succeeds even in some cases in which
1982 # a normal write might fail due to file permission
1983 # settings on some operating systems such as HP-UX
1984 write_atomic(_unicode_encode(fpath,
1985 encoding=_encodings['merge'], errors='strict'),
1986 new_contents, mode='wb')
1988 mystat = os.lstat(fpath)
1989 if stat.S_ISREG(mystat.st_mode) and \
1990 mystat.st_ino not in counted_inodes:
1991 counted_inodes.add(mystat.st_ino)
1992 size += mystat.st_size
1993 if mystat.st_uid != portage_uid and \
1994 mystat.st_gid != portage_gid:
1998 if mystat.st_uid == portage_uid:
2000 if mystat.st_gid == portage_gid:
2002 apply_secpass_permissions(
2003 _unicode_encode(fpath, encoding=_encodings['merge']),
2004 uid=myuid, gid=mygid,
2005 mode=mystat.st_mode, stat_cached=mystat,
2011 if not unicode_error:
2014 if desktopfile_errors:
2015 for l in _merge_desktopfile_error(desktopfile_errors):
2016 l = l.replace(mysettings["ED"], '/')
2017 eqawarn(l, phase='install', key=mysettings.mycpv, out=out)
2020 for l in _merge_unicode_error(unicode_errors):
2021 eqawarn(l, phase='install', key=mysettings.mycpv, out=out)
2023 build_info_dir = os.path.join(mysettings['PORTAGE_BUILDDIR'],
2026 f = io.open(_unicode_encode(os.path.join(build_info_dir,
2027 'SIZE'), encoding=_encodings['fs'], errors='strict'),
2028 mode='w', encoding=_encodings['repo.content'],
2030 f.write(_unicode_decode(str(size) + '\n'))
2033 _reapply_bsdflags_to_image(mysettings)
2035 def _reapply_bsdflags_to_image(mysettings):
2037 Reapply flags saved and removed by _preinst_bsdflags.
2040 os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \
2041 (_shell_quote(mysettings["D"]),
2042 _shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))
2044 def _post_src_install_soname_symlinks(mysettings, out):
2046 Check that libraries in $D have corresponding soname symlinks.
2047 If symlinks are missing then create them and trigger a QA Notice.
2048 This requires $PORTAGE_BUILDDIR/build-info/NEEDED.ELF.2 for
2052 image_dir = mysettings["D"]
2053 needed_filename = os.path.join(mysettings["PORTAGE_BUILDDIR"],
2054 "build-info", "NEEDED.ELF.2")
2058 f = io.open(_unicode_encode(needed_filename,
2059 encoding=_encodings['fs'], errors='strict'),
2060 mode='r', encoding=_encodings['repo.content'],
2062 lines = f.readlines()
2063 except IOError as e:
2064 if e.errno not in (errno.ENOENT, errno.ESTALE):
2074 f = io.open(_unicode_encode(os.path.join(
2075 mysettings["PORTAGE_BUILDDIR"],
2076 "build-info", "QA_SONAME_NO_SYMLINK"),
2077 encoding=_encodings['fs'], errors='strict'),
2078 mode='r', encoding=_encodings['repo.content'],
2080 qa_no_symlink = f.read()
2081 except IOError as e:
2082 if e.errno not in (errno.ENOENT, errno.ESTALE):
2088 qa_no_symlink = qa_no_symlink.split()
2090 if len(qa_no_symlink) > 1:
2091 qa_no_symlink = "|".join("(%s)" % x for x in qa_no_symlink)
2092 qa_no_symlink = "^(%s)$" % qa_no_symlink
2094 qa_no_symlink = "^%s$" % qa_no_symlink[0]
2095 qa_no_symlink = re.compile(qa_no_symlink)
2097 libpaths = set(portage.util.getlibpaths(
2098 mysettings["ROOT"], env=mysettings))
2099 libpath_inodes = set()
2100 for libpath in libpaths:
2101 libdir = os.path.join(mysettings["ROOT"], libpath.lstrip(os.sep))
2107 libpath_inodes.add((s.st_dev, s.st_ino))
2109 is_libdir_cache = {}
2111 def is_libdir(obj_parent):
2113 return is_libdir_cache[obj_parent]
2118 if obj_parent in libpaths:
2121 parent_path = os.path.join(mysettings["ROOT"],
2122 obj_parent.lstrip(os.sep))
2124 s = os.stat(parent_path)
2128 if (s.st_dev, s.st_ino) in libpath_inodes:
2131 is_libdir_cache[obj_parent] = rval
2134 missing_symlinks = []
2136 # Parse NEEDED.ELF.2 like LinkageMapELF.rebuild() does.
2141 fields = l.split(";")
2143 portage.util.writemsg_level(_("\nWrong number of fields " \
2144 "in %s: %s\n\n") % (needed_filename, l),
2145 level=logging.ERROR, noiselevel=-1)
2148 obj, soname = fields[1:3]
2151 if not is_libdir(os.path.dirname(obj)):
2153 if qa_no_symlink and qa_no_symlink.match(obj.strip(os.sep)) is not None:
2156 obj_file_path = os.path.join(image_dir, obj.lstrip(os.sep))
2157 sym_file_path = os.path.join(os.path.dirname(obj_file_path), soname)
2159 os.lstat(sym_file_path)
2160 except OSError as e:
2161 if e.errno not in (errno.ENOENT, errno.ESTALE):
2166 missing_symlinks.append((obj, soname))
2168 if not missing_symlinks:
2171 qa_msg = ["QA Notice: Missing soname symlink(s):"]
2173 qa_msg.extend("\t%s -> %s" % (os.path.join(
2174 os.path.dirname(obj).lstrip(os.sep), soname),
2175 os.path.basename(obj))
2176 for obj, soname in missing_symlinks)
2179 eqawarn(line, key=mysettings.mycpv, out=out)
2181 def _merge_desktopfile_error(errors):
2184 msg = _("QA Notice: This package installs one or more .desktop files "
2185 "that do not pass validation.")
2186 lines.extend(wrap(msg, 72))
2190 lines.extend("\t" + x for x in errors)
2195 def _merge_unicode_error(errors):
2198 msg = _("QA Notice: This package installs one or more file names "
2199 "containing characters that are not encoded with the UTF-8 encoding.")
2200 lines.extend(wrap(msg, 72))
2204 lines.extend("\t" + x for x in errors)
2209 def _prepare_self_update(settings):
2211 Call this when portage is updating itself, in order to create
2212 temporary copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH, since
2213 the new versions may be incompatible. An atexit hook will
2214 automatically clean up the temporary copies.
2217 # sanity check: ensure that that this routine only runs once
2218 if portage._bin_path != portage.const.PORTAGE_BIN_PATH:
2221 # Load lazily referenced portage submodules into memory,
2222 # so imports won't fail during portage upgrade/downgrade.
2223 _preload_elog_modules(settings)
2224 portage.proxy.lazyimport._preload_portage_submodules()
2226 # Make the temp directory inside $PORTAGE_TMPDIR/portage, since
2227 # it's common for /tmp and /var/tmp to be mounted with the
2228 # "noexec" option (see bug #346899).
2229 build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage")
2230 portage.util.ensure_dirs(build_prefix)
2231 base_path_tmp = tempfile.mkdtemp(
2232 "", "._portage_reinstall_.", build_prefix)
2233 portage.process.atexit_register(shutil.rmtree, base_path_tmp)
2235 orig_bin_path = portage._bin_path
2236 portage._bin_path = os.path.join(base_path_tmp, "bin")
2237 shutil.copytree(orig_bin_path, portage._bin_path, symlinks=True)
2239 orig_pym_path = portage._pym_path
2240 portage._pym_path = os.path.join(base_path_tmp, "pym")
2241 shutil.copytree(orig_pym_path, portage._pym_path, symlinks=True)
2243 for dir_path in (base_path_tmp, portage._bin_path, portage._pym_path):
2244 os.chmod(dir_path, 0o755)
2246 def _handle_self_update(settings, vardb):
2247 cpv = settings.mycpv
2248 if settings["ROOT"] == "/" and \
2249 portage.dep.match_from_list(
2250 portage.const.PORTAGE_PACKAGE_ATOM, [cpv]):
2251 _prepare_self_update(settings)