示例#1
0
    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()
示例#2
0
    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)
示例#3
0
	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)
示例#4
0
	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)
示例#5
0
	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()
示例#6
0
	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()
示例#7
0
    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()
示例#8
0
    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()
示例#9
0
    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()