def _buildpkg_exit(self, packager): """ Released build dir lock when there is a failure or when in buildpkgonly mode. Otherwise, the lock will be released when merge() is called. """ if self._default_exit(packager) != os.EX_OK: self._unlock_builddir() self.wait() return if self.opts.buildpkgonly: phase = 'success_hooks' success_hooks = MiscFunctionsProcess(background=self.background, commands=[phase], phase=phase, scheduler=self.scheduler, settings=self.settings) self._start_task(success_hooks, self._buildpkgonly_success_hook_exit) return # Continue holding the builddir lock until # after the package has been installed. self._current_task = None self.returncode = packager.returncode self.wait()
def _start(self): if isinstance(self.commands, list): cmds = [({}, self.commands)] else: cmds = list(self.commands) if 'selinux' not in self.settings.features: cmds = [(kwargs, commands) for kwargs, commands in cmds if not kwargs.get('selinux_only')] tasks = TaskSequence() for kwargs, commands in cmds: # Select args intended for MiscFunctionsProcess. kwargs = dict((k, v) for k, v in kwargs.items() if k in ('ld_preload_sandbox', )) tasks.add( MiscFunctionsProcess(background=self.background, commands=commands, fd_pipes=self.fd_pipes, logfile=self.logfile, phase=self.phase, scheduler=self.scheduler, settings=self.settings, **kwargs)) self._start_task(tasks, self._commands_exit)
def _die_hooks(self): self.returncode = None phase = 'die_hooks' die_hooks = MiscFunctionsProcess(background=self.background, commands=[phase], phase=phase, pkg=self.pkg, scheduler=self.scheduler, settings=self.settings) self._start_task(die_hooks, self._die_hooks_exit)
def _die_hooks(self): self.returncode = None phase = 'die_hooks' die_hooks = MiscFunctionsProcess(background=self.background, commands=[phase], phase=phase, logfile=self._get_log_path(), fd_pipes=self.fd_pipes, scheduler=self.scheduler, settings=self.settings) self._start_task(die_hooks, self._die_hooks_exit)
def testDoebuildSpawn(self): playground = ResolverPlayground() try: settings = config(clone=playground.settings) cpv = 'sys-apps/portage-2.1' metadata = { 'EAPI' : '2', 'INHERITED' : 'python eutils', 'IUSE' : 'build doc epydoc python3 selinux', 'LICENSE' : 'GPL-2', 'PROVIDE' : 'virtual/portage', 'RDEPEND' : '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT' : '0', } root_config = playground.trees[playground.root]['root_config'] pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['T'] = os.path.join( settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb') task_scheduler = TaskScheduler() for phase in ('_internal_test',): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=task_scheduler.sched_iface, settings=settings) task_scheduler.add(ebuild_phase) task_scheduler.run() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=task_scheduler.sched_iface, settings=settings) task_scheduler.add(ebuild_phase) task_scheduler.run() self.assertEqual(ebuild_phase.returncode, os.EX_OK) finally: playground.cleanup()
def _ebuild_exit(self, ebuild_process): if self.phase == "install": out = portage.StringIO() log_path = self.settings.get("PORTAGE_LOG_FILE") log_file = None if log_path is not None: log_file = codecs.open(_unicode_encode(log_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='replace') try: _check_build_log(self.settings, out=out) msg = _unicode_decode(out.getvalue(), encoding=_encodings['content'], errors='replace') if msg: if not self.background: writemsg_stdout(msg, noiselevel=-1) if log_file is not None: log_file.write(msg) finally: if log_file is not None: log_file.close() if self._default_exit(ebuild_process) != os.EX_OK: self._die_hooks() return settings = self.settings if self.phase == "install": out = None log_path = self.settings.get("PORTAGE_LOG_FILE") log_file = None if self.background and log_path is not None: log_file = codecs.open(_unicode_encode(log_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='replace') out = log_file _post_src_install_chost_fix(settings) _post_src_install_uid_fix(settings, out=out) if log_file is not None: log_file.close() post_phase_cmds = _post_phase_cmds.get(self.phase) if post_phase_cmds is not None: post_phase = MiscFunctionsProcess(background=self.background, commands=post_phase_cmds, phase=self.phase, pkg=self.pkg, scheduler=self.scheduler, settings=settings) self._start_task(post_phase, self._post_phase_exit) return self.returncode = ebuild_process.returncode self._current_task = None self.wait()
def _ebuild_exit(self, ebuild_process): if self._ebuild_lock is not None: self._ebuild_lock.unlock() self._ebuild_lock = None fail = False if self._default_exit(ebuild_process) != os.EX_OK: if self.phase == "test" and \ "test-fail-continue" in self.settings.features: # mark test phase as complete (bug #452030) try: open( _unicode_encode(os.path.join( self.settings["PORTAGE_BUILDDIR"], ".tested"), encoding=_encodings['fs'], errors='strict'), 'wb').close() except OSError: pass else: fail = True if not fail: self.returncode = None logfile = self._get_log_path() if self.phase == "install": out = io.StringIO() _check_build_log(self.settings, out=out) msg = out.getvalue() self.scheduler.output(msg, log_path=logfile) if fail: self._die_hooks() return settings = self.settings _post_phase_userpriv_perms(settings) if self.phase == "unpack": # Bump WORKDIR timestamp, in case tar gave it a timestamp # that will interfere with distfiles / WORKDIR timestamp # comparisons as reported in bug #332217. Also, fix # ownership since tar can change that too. os.utime(settings["WORKDIR"], None) _prepare_workdir(settings) elif self.phase == "install": out = io.StringIO() _post_src_install_write_metadata(settings) _post_src_install_uid_fix(settings, out) msg = out.getvalue() if msg: self.scheduler.output(msg, log_path=logfile) elif self.phase == "preinst": _preinst_bsdflags(settings) elif self.phase == "postinst": _postinst_bsdflags(settings) post_phase_cmds = _post_phase_cmds.get(self.phase) if post_phase_cmds is not None: if logfile is not None and self.phase in ("install", ): # Log to a temporary file, since the code we are running # reads PORTAGE_LOG_FILE for QA checks, and we want to # avoid annoying "gzip: unexpected end of file" messages # when FEATURES=compress-build-logs is enabled. fd, logfile = tempfile.mkstemp() os.close(fd) post_phase = MiscFunctionsProcess(background=self.background, commands=post_phase_cmds, fd_pipes=self.fd_pipes, logfile=logfile, phase=self.phase, scheduler=self.scheduler, settings=settings) self._start_task(post_phase, self._post_phase_exit) return # this point is not reachable if there was a failure and # we returned for die_hooks above, so returncode must # indicate success (especially if ebuild_process.returncode # is unsuccessful and test-fail-continue came into play) self.returncode = os.EX_OK self._current_task = None self.wait()
def testDoebuildSpawn(self): ebuild_body = textwrap.dedent(""" pkg_nofetch() { : ; } """) ebuilds = { "sys-apps/portage-2.1": { "EAPI": "2", "IUSE": "build doc epydoc python3 selinux", "KEYWORDS": "x86", "LICENSE": "GPL-2", "RDEPEND": ">=app-shells/bash-3.2_p17 >=dev-lang/python-2.6", "SLOT": "0", "MISC_CONTENT": ebuild_body, } } playground = ResolverPlayground(ebuilds=ebuilds) try: root_config = playground.trees[playground.eroot]["root_config"] portdb = root_config.trees["porttree"].dbapi settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = os.environ[ "__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = "sys-apps/portage-2.1" metadata = dict( zip(Package.metadata_keys, portdb.aux_get(cpv, Package.metadata_keys))) pkg = Package( built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name="ebuild", ) settings.setcpv(pkg) settings["PORTAGE_PYTHON"] = _python_interpreter settings["PORTAGE_BUILDDIR"] = os.path.join( settings["PORTAGE_TMPDIR"], cpv) settings["PYTHONDONTWRITEBYTECODE"] = os.environ.get( "PYTHONDONTWRITEBYTECODE", "") settings["HOME"] = os.path.join(settings["PORTAGE_BUILDDIR"], "homedir") settings["T"] = os.path.join(settings["PORTAGE_BUILDDIR"], "temp") for x in ("PORTAGE_BUILDDIR", "HOME", "T"): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings["T"], "environment"), "wb").close() scheduler = SchedulerInterface(global_event_loop()) for phase in ("_internal_test", ): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn( "%s %s" % ( _shell_quote( os.path.join( settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY), )), phase, ), settings, free=1, ) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase( background=False, phase=phase, scheduler=scheduler, settings=settings, ) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess( background=False, commands=["success_hooks"], scheduler=scheduler, settings=settings, ) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) spawn_nofetch(portdb, portdb.findname(cpv), settings=settings) finally: playground.cleanup()
def _ebuild_exit(self, ebuild_process): fail = False if self._default_exit(ebuild_process) != os.EX_OK: if self.phase == "test" and \ "test-fail-continue" in self.settings.features: pass else: fail = True if not fail: self.returncode = None if self.phase == "install": out = portage.StringIO() _check_build_log(self.settings, out=out) msg = _unicode_decode(out.getvalue(), encoding=_encodings['content'], errors='replace') self.scheduler.output( msg, log_path=self.settings.get("PORTAGE_LOG_FILE")) if fail: self._die_hooks() return settings = self.settings _post_phase_userpriv_perms(settings) if self.phase == "install": out = portage.StringIO() _post_src_install_chost_fix(settings) _post_src_install_uid_fix(settings, out) msg = _unicode_decode(out.getvalue(), encoding=_encodings['content'], errors='replace') if msg: self.scheduler.output( msg, log_path=self.settings.get("PORTAGE_LOG_FILE")) post_phase_cmds = _post_phase_cmds.get(self.phase) if post_phase_cmds is not None: logfile = settings.get("PORTAGE_LOG_FILE") if logfile is not None and self.phase in ("install", ): # Log to a temporary file, since the code we are running # reads PORTAGE_LOG_FILE for QA checks, and we want to # avoid annoying "gzip: unexpected end of file" messages # when FEATURES=compress-build-logs is enabled. fd, logfile = tempfile.mkstemp() os.close(fd) post_phase = MiscFunctionsProcess(background=self.background, commands=post_phase_cmds, logfile=logfile, phase=self.phase, scheduler=self.scheduler, settings=settings) self._start_task(post_phase, self._post_phase_exit) return # this point is not reachable if there was a failure and # we returned for die_hooks above, so returncode must # indicate success (especially if ebuild_process.returncode # is unsuccessful and test-fail-continue came into play) self.returncode = os.EX_OK self._current_task = None self.wait()
def testDoebuildSpawn(self): ebuild_body = textwrap.dedent(""" pkg_nofetch() { : ; } """) ebuilds = { 'sys-apps/portage-2.1': { 'EAPI': '2', 'IUSE': 'build doc epydoc python3 selinux', 'KEYWORDS': 'x86', 'LICENSE': 'GPL-2', 'RDEPEND': '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6', 'SLOT': '0', "MISC_CONTENT": ebuild_body, } } playground = ResolverPlayground(ebuilds=ebuilds) try: root_config = playground.trees[playground.eroot]['root_config'] portdb = root_config.trees["porttree"].dbapi settings = config(clone=playground.settings) if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS") cpv = 'sys-apps/portage-2.1' metadata = dict( zip(Package.metadata_keys, portdb.aux_get(cpv, Package.metadata_keys))) pkg = Package(built=False, cpv=cpv, installed=False, metadata=metadata, root_config=root_config, type_name='ebuild') settings.setcpv(pkg) settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) settings['T'] = os.path.join(settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): os.makedirs(settings[x]) # Create a fake environment, to pretend as if the ebuild # has been sourced already. open(os.path.join(settings['T'], 'environment'), 'wb').close() scheduler = SchedulerInterface(global_event_loop()) for phase in ('_internal_test', ): # Test EbuildSpawnProcess by calling doebuild.spawn() with # returnpid=False. This case is no longer used by portage # internals since EbuildPhase is used instead and that passes # returnpid=True to doebuild.spawn(). rval = doebuild_spawn("%s %s" % (_shell_quote( os.path.join(settings["PORTAGE_BIN_PATH"], os.path.basename(EBUILD_SH_BINARY))), phase), settings, free=1) self.assertEqual(rval, os.EX_OK) ebuild_phase = EbuildPhase(background=False, phase=phase, scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) ebuild_phase = MiscFunctionsProcess(background=False, commands=['success_hooks'], scheduler=scheduler, settings=settings) ebuild_phase.start() ebuild_phase.wait() self.assertEqual(ebuild_phase.returncode, os.EX_OK) spawn_nofetch(portdb, portdb.findname(cpv), settings=settings) finally: playground.cleanup()