summaryrefslogtreecommitdiffstats
path: root/BuildManager/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'BuildManager/build.py')
-rw-r--r--BuildManager/build.py231
1 files changed, 231 insertions, 0 deletions
diff --git a/BuildManager/build.py b/BuildManager/build.py
new file mode 100644
index 0000000..3bf93c5
--- /dev/null
+++ b/BuildManager/build.py
@@ -0,0 +1,231 @@
+from BuildManager.fileutil import *
+from BuildManager.package import *
+from BuildManager import *
+import thread
+import popen2
+import select
+import fcntl
+import thread
+import sys, os
+import time
+import shutil
+
+__all__ = ["PackageBuilder"]
+
+GLOBAL_PKGLIST_LOCK = thread.allocate_lock()
+
+STAGE_UNPACK = 0
+STAGE_PREP = 1
+STAGE_COMPILE = 2
+STAGE_INSTALL = 3
+STAGE_SOURCE = 4
+STAGE_BINARY = 5
+STAGE_ALL = 6
+
+STAGE_DICT = {"unpack": STAGE_UNPACK,
+ "prep": STAGE_PREP,
+ "compile": STAGE_COMPILE,
+ "install": STAGE_INSTALL,
+ "source": STAGE_SOURCE,
+ "binary": STAGE_BINARY,
+ "all": STAGE_ALL}
+
+class PackageBuilder:
+ def __init__(self, opts):
+ self.opts = opts
+ self.stage = STAGE_DICT[opts.mode]
+
+ def run(self):
+ self.pkglist = PackageList()
+ logger.info("creating package list")
+ for filename in self.opts.args:
+ pkg = Package(filename, self.opts.build_log)
+ for ignore in self.opts.ignore:
+ if ignore.match(pkg.name):
+ break
+ else:
+ self.pkglist.append(pkg)
+ for dir in self.opts.filter_renew:
+ filterpkglist(pkglist, dir, "not_has_ge")
+ for dir in self.opts.filter_refresh:
+ filterpkglist(pkglist, dir, "not_has_lt")
+ self.pkgsleft = len(self.pkglist)
+ if self.pkgsleft == 0:
+ logger.info("no packages to process")
+ return True
+ elif self.pkgsleft > 1 and self.pkgsleft % 10 != 0:
+ logger.info("package list has %d packages" % pkgsleft)
+ self.pkglist_lock = thread.allocate_lock()
+ self.failures = 0
+ if self.opts.parallel != 1:
+ logger.info("starting threads")
+ for i in range(self.opts.parallel-1):
+ thread.start_new_thread(self_processlist, ())
+ self._processlist()
+ while self.pkgsleft > 0:
+ time.sleep(2)
+ return not self.failures
+
+ def _processlist(self):
+ while 1:
+ self.pkglist_lock.acquire()
+ if not self.pkglist:
+ self.pkglist_lock.release()
+ return 1
+ if self.pkgsleft % 10 == 0:
+ logger.info("package list has %d packages" % self.pkgsleft)
+ pkg = self.pkglist.pop(0)
+ logger.info("processing package %s-%s-%s" %
+ (pkg.name, pkg.version, pkg.release))
+ self.pkglist_lock.release()
+ ret = buildpkg(pkg=pkg,
+ stage=self.stage,
+ unpack_dir=self.opts.unpack_dir,
+ passtrough=" ".join(self.opts.options),
+ show_log=self.opts.show_log,
+ dryrun=self.opts.dryrun)
+ if ret:
+ if pkg.type == "srpm":
+ if self.opts.move_succeeded_srpm:
+ move_file(pkg.file,
+ self.opts.move_succeeded_srpm,
+ dryrun=self.opts.dryrun)
+ elif self.opts.copy_succeeded_srpm:
+ copy_file(pkg.file,
+ self.opts.copy_succeeded_srpm,
+ dryrun=self.opts.dryrun)
+ elif self.opts.remove_succeeded_srpm:
+ logger.info("removing %s" % pkg.file)
+ if not self.opts.dryrun:
+ os.unlink(pkg.file)
+ if self.opts.move_srpm:
+ dir = os.path.join(pkg.builddir, "SRPMS")
+ for file in os.listdir(dir):
+ move_file(os.path.join(dir, file),
+ self.opts.move_srpm,
+ dryrun=self.opts.dryrun)
+ if self.opts.move_rpm:
+ dir = os.path.join(pkg.builddir, "RPMS")
+ for subdir in os.listdir(dir):
+ subdir = os.path.join(dir, subdir)
+ for file in os.listdir(subdir):
+ move_file(os.path.join(subdir, file),
+ self.opts.move_rpm,
+ dryrun=self.opts.dryrun)
+ if self.opts.move_log:
+ move_file(pkg.log,
+ self.opts.move_log,
+ dryrun=self.dryrun)
+ if self.opts.clean or self.opts.clean_on_success:
+ if pkg.builddir != "/":
+ logger.info("cleaning build directory")
+ if not self.opts.dryrun:
+ shutil.rmtree(pkg.builddir)
+ else:
+ self.failures += 1
+ if pkg.type == "srpm":
+ if self.opts.move_failed_srpm:
+ move_file(pkg.file,
+ self.opts.move_failed_srpm,
+ dryrun=self.opts.dryrun)
+ elif self.opts.copy_failed_srpm:
+ copy_file(pkg.file,
+ self.opts.copy_failed_srpm,
+ dryrun=self.opts.dryrun)
+ elif self.opts.remove_failed_srpm:
+ logger.info("removing %s" % pkg.file)
+ if not self.opts.dryrun:
+ os.unlink(pkg.file)
+ if self.opts.move_failed_log:
+ move_file(pkg.log,
+ self.opts.move_failed_log,
+ dryrun=self.opts.dryrun)
+ if self.opts.clean:
+ if pkg.builddir != "/":
+ logger.info("cleaning build directory")
+ if not self.opts.dryrun:
+ shutil.rmtree(pkg.builddir)
+ self.pkglist_lock.acquire()
+ self.pkgsleft -= 1
+ self.pkglist_lock.release()
+
+def filterpkglist(pkglist, directory, rule):
+ filterlist = PackageList()
+ logger.info("creating package list filter for "+directory)
+ for filename in os.listdir(directory):
+ filename = os.path.join(directory, filename)
+ if os.path.isfile(filename):
+ filterlist.append(Package(filename))
+ logger.info("filtering")
+ if rule[:4] == "not_":
+ filterfunc_tmp = getattr(filterlist, rule[4:])
+ filterfunc = lambda x: not filterfunc_tmp(x)
+ else:
+ filterfunc = getattr(filterlist, rule)
+ pkglist[:] = filter(filterfunc, pkglist)
+
+
+def buildpkglist(pkglist, stage, unpack_dir, passtrough="",
+ show_log=0, dryrun=0):
+ while 1:
+ GLOBAL_PKGLIST_LOCK.acquire()
+ if not pkglist:
+ GLOBAL_PKGLIST_LOCK.release()
+ return 1
+ pkg = pkglist[0]
+ del pkglist[0]
+ GLOBAL_PKGLIST_LOCK.release()
+ buildpkg(pkg, stage, unpack_dir, passtrough, show_log, dryrun)
+
+def buildpkg(pkg, stage, unpack_dir, passtrough="", show_log=0, dryrun=0):
+ stagestr = ["unpacking",
+ "running prep stage",
+ "running prep and compile stage",
+ "running prep, compile, and install stages",
+ "building source package",
+ "building binary packages",
+ "building source and binary packages"][stage]
+ logger.info(stagestr)
+ ret = 0
+ if pkg.type == "srpm" and not (dryrun or pkg.unpack(unpack_dir)):
+ logger.error("failed unpacking")
+ return 0
+ else:
+ status = 0
+ if stage != STAGE_UNPACK:
+ stagechar = ["p","c","i","s","b","a"][stage-1]
+ if not dryrun and os.path.isdir(pkg.builddir+"/BUILDROOT"):
+ tmppath = " --define '_tmppath %s/BUILDROOT'" % pkg.builddir
+ else:
+ tmppath = ""
+ cmd = "rpm -b%s --define '_topdir %s'%s %s %s 2>&1" % \
+ (stagechar,pkg.builddir,tmppath,passtrough,pkg.spec)
+ logger.debug("rpm command: "+cmd)
+ if not dryrun:
+ log = open(pkg.log, "w")
+ pop = popen2.Popen3(cmd)
+ fc = pop.fromchild
+ flags = fcntl.fcntl (fc.fileno(), fcntl.F_GETFL, 0)
+ flags = flags | os.O_NONBLOCK
+ fcntl.fcntl (fc.fileno(), fcntl.F_SETFL, flags)
+ while 1:
+ r,w,x = select.select([fc.fileno()], [], [], 2)
+ if r:
+ data = fc.read()
+ if show_log:
+ sys.stdout.write(data)
+ log.write(data)
+ log.flush()
+ status = pop.poll()
+ if status != -1:
+ break
+ log.close()
+ if status == 0:
+ logger.info("succeeded!")
+ ret = 1
+ else:
+ logger.error("failed!")
+ ret = 0
+ return ret
+
+# vim:ts=4:sw=4