From 9e0cb61ca9db8b9dea6abeb96edc8e8eb052276e Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Sat, 6 Aug 2011 15:20:18 +0200 Subject: [PATCH] [matter] use multiprocessing module, improve handling of built packages --- services/matter | 64 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/services/matter b/services/matter index 7de53b9be..718734ae3 100755 --- a/services/matter +++ b/services/matter @@ -8,6 +8,7 @@ import argparse import tempfile import subprocess import errno +from multiprocessing import Process, Queue # Entropy imports sys.path.insert(0,'/usr/lib/entropy/libraries') @@ -455,6 +456,8 @@ class PackageBuilder(object): self._tot_spec = tot_spec self._pkg_number = pkg_number self._tot_pkgs = tot_pkgs + self._queue = Queue() + self._built_packages = [] @staticmethod def _build_standard_environment(repository=None): @@ -502,6 +505,12 @@ class PackageBuilder(object): purple(str(self._tot_pkgs)),) return my_str + def get_built_packages(self): + """ + Return the list of successfully built packages. + """ + return self._built_packages[:] + def run(self): """ Execute Package building action. @@ -533,23 +542,18 @@ class PackageBuilder(object): os.remove(tmp_path) # execute the update code - pid = os.fork() - if pid == 0: + proc = Process(target = self._run_builder, args = (std_env,)) + proc.start() + proc.join() + exit_st = proc.exitcode + while not self._queue.empty(): try: - os._exit(self._run_builder(std_env)) - except Exception as exc: - sys.stderr.write(repr(exc) + "\n") - os._exit(1) - else: - try: - rcpid, exit_st = os.waitpid(pid, os.P_WAIT) - except Exception as exc: - try: - os.kill(pid, signal.SIGTERM) - except OSError as err: - if err.errno != errno.ESRCH: - raise - exit_st = 1 + self._built_packages.append(self._queue.get(False, timeout=10)) + except Queue.Empty as err: + # race condition? is it really possible? perhaps process is + # not dead? resurrected from afterlife? + sys.stderr.write("WTF? " + repr(err) + "\n") + continue # run pkgpre, if any pkgpost = self._params.get("pkgpost") @@ -625,14 +629,18 @@ class PackageBuilder(object): portage.versions.pkgsplit(best_installed), portage.versions.pkgsplit(best_visible)) - if (cmp_res == 1) and (self._params.get("downgrade", "no") == "no"): + allow_rebuild = self._params.get("rebuild", "no") == "yes" + allow_downgrade = self._params.get("downgrade", "no") == "yes" + is_rebuild = cmp_res == 0 + + if (cmp_res == 1) and (not allow_downgrade): # downgrade in action and downgrade not allowed, aborting! print_warning( "package: %s, would be downgraded from %s to %s, aborting" % ( self._package, best_installed, best_visible,)) return 0 - if (cmp_res == 0) and (self._params.get("rebuild", "no") == "no"): + if (is_rebuild) and (not allow_rebuild): # rebuild in action and rebuild not allowed, aborting! print_warning( "package: %s, would be rebuilt to %s, aborting" % ( @@ -647,7 +655,8 @@ class PackageBuilder(object): emerge_settings, emerge_trees, mtimedb = \ load_emerge_config(trees=portage.db) - # non interactive properties + # non interactive properties, this is not really required + # accept-properties just sets os.environ... builtin_args = ["--accept-properties=-interactive"] myaction, myopts, myfiles = parse_opts( PackageBuilder.PORTAGE_BUILD_ARGS + builtin_args + \ @@ -733,6 +742,18 @@ class PackageBuilder(object): retval = action_build(emerge_settings, emerge_trees, mtimedb, myopts, myaction, myfiles, spinner) + for pkg in package_queue: + cpv = p.cpv + pkg_inst_match = portage.best(vardb.match(cpv)) + if pkg_inst_match: + # add to build queue + # NOTE: this doesn't actually know what packages have been + # actually built successfully if retval != 0 + # but I guess there is no better and more reliable way + # with current Portage API + print_info("package: %s, successfully built" % (cpv,)) + self._queue.put(cpv) + # NOTE: this is a WORKAROUND for Portage's post_emerge() calling # sys.exit() at the end. # Fixed in Portage >=2.2_alpha50 @@ -1140,7 +1161,10 @@ Environment variables passed to --pkgpre/--pkgpost executables: break if rc == 0: - local_completed.append(package) + built_packages = builder.get_built_packages() + print_info("built packages, in queue: %s" % ( + built_packages,)) + local_completed.extend(built_packages) tainted_repositories.add(spec["repository"]) elif rc < 0: # ignore warning and go ahead