From 6ed8d50169bb513b419e1a6bcc5092cbf15b5497 Mon Sep 17 00:00:00 2001 From: Michael E Brown Date: Thu, 8 Jan 2009 14:05:35 -0600 Subject: initial work to copy spec/sources and build srpm. --- py/mock.py | 43 ++++++++++++++++++++++++++++++++++++++++ py/mock/backend.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/py/mock.py b/py/mock.py index d04c859..0f02880 100755 --- a/py/mock.py +++ b/py/mock.py @@ -72,6 +72,9 @@ def command_parse(config_opts): parser.add_option("--rebuild", action="store_const", const="rebuild", dest="mode", default='rebuild', help="rebuild the specified SRPM(s)") + parser.add_option("--buildsrpm", action="store_const", const="buildsrpm", + dest="mode", + help="Build a SRPM from spec (--spec ...) and sources (--sources ...)") parser.add_option("--shell", action="store_const", const="shell", dest="mode", help="run the specified command interactively within the chroot." @@ -157,6 +160,11 @@ def command_parse(config_opts): help="Change to the specified directory (relative to the chroot)" " before running command when using --chroot") + parser.add_option("--spec", action="store", + help="Specifies spec file to use to build an SRPM (used only with --buildsrpm)") + parser.add_option("--sources", action="store", + help="Specifies sources to use to build an SRPM (used only with --buildsrpm)") + # verbosity parser.add_option("-v", "--verbose", action="store_const", const=2, dest="verbose", default=1, help="verbose build") @@ -377,6 +385,38 @@ def do_rebuild(config_opts, chroot, srpms): chroot.clean() raise +def do_buildsrpm(config_opts, chroot, options, args): + start = time.time() + try: + log.info("Start(%s) Config(%s)" % (srpm, chroot.sharedRootName)) + if config_opts['clean'] and chroot.state() != "clean": + chroot.clean() + chroot.init() + + # TODO: validate spec path + # TODO: validate SOURCES path + + chroot.buildsrpm(spec=options.spec, sources=options.sources, timeout=config_opts['rpmbuild_timeout']) + + elapsed = time.time() - start + log.info("Done(%s) Config(%s) %d minutes %d seconds" + % (srpm, config_opts['chroot_name'], elapsed//60, elapsed%60)) + log.info("Results and/or logs in: %s" % chroot.resultdir) + + if config_opts["cleanup_on_success"]: + log.info("Cleaning up build root ('clean_on_success=True')") + chroot.clean() + + except (Exception, KeyboardInterrupt): + elapsed = time.time() - start + log.error("Exception(%s) Config(%s) %d minutes %d seconds" + % (srpm, chroot.sharedRootName, elapsed//60, elapsed%60)) + log.info("Results and/or logs in: %s" % chroot.resultdir) + if config_opts["cleanup_on_failure"]: + log.info("Cleaning up build root ('clean_on_failure=True')") + chroot.clean() + raise + def main(ret): "Main executable entry point." # drop unprivleged to parse args, etc. @@ -578,6 +618,9 @@ def main(ret): elif options.mode == 'rebuild': do_rebuild(config_opts, chroot, args) + elif options.mode == 'buildsrpm': + do_buildsrpm(config_opts, chroot, options, args) + elif options.mode == 'orphanskill': mock.util.orphansKill(chroot.makeChrootPath()) elif options.mode == 'copyin': diff --git a/py/mock/backend.py b/py/mock/backend.py index 6cfd603..dccfdf9 100644 --- a/py/mock/backend.py +++ b/py/mock/backend.py @@ -444,6 +444,64 @@ class Root(object): # tell caching we are done building self._callHooks('postbuild') + + # + # UNPRIVLEGED: + # Everything in this function runs as the build user + # -> except hooks. :) + # + decorate(traceLog()) + def buildsrpm(self, spec, sources, timeout): + """build an srpm into binary rpms, capture log""" + + # tell caching we are building + self._callHooks('earlyprebuild') + + try: + self._mountall() + self.uidManager.becomeUser(self.chrootuid, self.chrootgid) + self.state("setup") + + # copy spec/sources + shutil.copy(spec, self.makeChrootPath(self.builddir, "SPECS")) + os.unlink(self.makeChrootPath(self.builddir, "SOURCES")) + shutil.copytree(sources, self.makeChrootPath(self.builddir, "SOURCES")) + + spec = self.makeChrootPath(self.builddir, "SPECS", os.path.basename(spec)) + chrootspec = spec.replace(self.makeChrootPath(), '') # get rid of rootdir prefix + + # Completely/Permanently drop privs while running the following: + os.environ["HOME"] = self.homedir + self.doChroot( + ["bash", "--login", "-c", 'rpmbuild -bs --target %s --nodeps %s' % (self.rpmbuild_arch, chrootspec)], + shell=False, + logger=self.build_log, timeout=timeout, + uid=self.chrootuid, + gid=self.chrootgid, + ) + + rebuiltSrpmFile = glob.glob("%s/%s/SRPMS/*.src.rpm" % (self.makeChrootPath(), self.builddir)) + if len(rebuiltSrpmFile) != 1: + raise mock.exception.PkgError, "Didnt find single rebuilt srpm." + + rebuiltSrpmFile = rebuiltSrpmFile[0] + + srpms = glob.glob(self.makeChrootPath(self.builddir) + '/SRPMS/*.rpm') + self.root_log.debug("Copying packages to result dir") + for item in srpms: + shutil.copy2(item, self.resultdir) + + finally: + self.uidManager.restorePrivs() + self._umountall() + + # tell caching we are done building + self._callHooks('postbuild') + + + + + # ============= # 'Private' API # ============= -- cgit From e7a3dd309ae0777ae46b838912087cadd2528e57 Mon Sep 17 00:00:00 2001 From: Michael E Brown Date: Thu, 8 Jan 2009 14:25:03 -0600 Subject: cant use srpm var, use spec file instead. its ofr info only. --- py/mock.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/py/mock.py b/py/mock.py index 0f02880..567e9ac 100755 --- a/py/mock.py +++ b/py/mock.py @@ -388,19 +388,19 @@ def do_rebuild(config_opts, chroot, srpms): def do_buildsrpm(config_opts, chroot, options, args): start = time.time() try: - log.info("Start(%s) Config(%s)" % (srpm, chroot.sharedRootName)) + # TODO: validate spec path (exists) + # TODO: validate SOURCES path (exists) + + log.info("Start(%s) Config(%s)" % (os.path.basename(options.spec), chroot.sharedRootName)) if config_opts['clean'] and chroot.state() != "clean": chroot.clean() chroot.init() - # TODO: validate spec path - # TODO: validate SOURCES path - chroot.buildsrpm(spec=options.spec, sources=options.sources, timeout=config_opts['rpmbuild_timeout']) elapsed = time.time() - start log.info("Done(%s) Config(%s) %d minutes %d seconds" - % (srpm, config_opts['chroot_name'], elapsed//60, elapsed%60)) + % (os.path.basename(options.spec), config_opts['chroot_name'], elapsed//60, elapsed%60)) log.info("Results and/or logs in: %s" % chroot.resultdir) if config_opts["cleanup_on_success"]: -- cgit From 4796f583735f291d1314a23223423354f51dc6a5 Mon Sep 17 00:00:00 2001 From: Michael E Brown Date: Thu, 8 Jan 2009 14:35:58 -0600 Subject: another srpm -> spec change in buildsrpm. add state for building srpm. --- py/mock.py | 2 +- py/mock/backend.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/py/mock.py b/py/mock.py index 567e9ac..d18bb51 100755 --- a/py/mock.py +++ b/py/mock.py @@ -410,7 +410,7 @@ def do_buildsrpm(config_opts, chroot, options, args): except (Exception, KeyboardInterrupt): elapsed = time.time() - start log.error("Exception(%s) Config(%s) %d minutes %d seconds" - % (srpm, chroot.sharedRootName, elapsed//60, elapsed%60)) + % (os.path.basename(options.spec), chroot.sharedRootName, elapsed//60, elapsed%60)) log.info("Results and/or logs in: %s" % chroot.resultdir) if config_opts["cleanup_on_failure"]: log.info("Cleaning up build root ('clean_on_failure=True')") diff --git a/py/mock/backend.py b/py/mock/backend.py index dccfdf9..baeb8e1 100644 --- a/py/mock/backend.py +++ b/py/mock/backend.py @@ -471,6 +471,7 @@ class Root(object): chrootspec = spec.replace(self.makeChrootPath(), '') # get rid of rootdir prefix # Completely/Permanently drop privs while running the following: + self.state("buildsrpm") os.environ["HOME"] = self.homedir self.doChroot( ["bash", "--login", "-c", 'rpmbuild -bs --target %s --nodeps %s' % (self.rpmbuild_arch, chrootspec)], -- cgit From 305c142babcbc5150b716b38e63cd8f9de6f4ef7 Mon Sep 17 00:00:00 2001 From: Michael E Brown Date: Thu, 8 Jan 2009 14:37:39 -0600 Subject: unlink->rmdir --- py/mock/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mock/backend.py b/py/mock/backend.py index baeb8e1..285a6ae 100644 --- a/py/mock/backend.py +++ b/py/mock/backend.py @@ -464,7 +464,7 @@ class Root(object): # copy spec/sources shutil.copy(spec, self.makeChrootPath(self.builddir, "SPECS")) - os.unlink(self.makeChrootPath(self.builddir, "SOURCES")) + os.rmdir(self.makeChrootPath(self.builddir, "SOURCES")) shutil.copytree(sources, self.makeChrootPath(self.builddir, "SOURCES")) spec = self.makeChrootPath(self.builddir, "SPECS", os.path.basename(spec)) -- cgit