Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 600720 Details for
Bug 843745
RFE: Add support for automatically downloading, building and installing dependencies in the chroot
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch to add --megadeps command
megadeps.patch (text/plain), 16.03 KB, created by
Nick Coghlan
on 2012-07-27 08:52:58 UTC
(
hide
)
Description:
Patch to add --megadeps command
Filename:
MIME Type:
Creator:
Nick Coghlan
Created:
2012-07-27 08:52:58 UTC
Size:
16.03 KB
patch
obsolete
>diff --git a/mock.spec.in b/mock.spec.in >index 9fc4b56..875eca1 100644 >--- a/mock.spec.in >+++ b/mock.spec.in >@@ -11,7 +11,7 @@ > Summary: Builds packages inside chroots > Name: mock > Version: %{release_version} >-Release: 1%{?dist} >+Release: 1%{?dist}.jfearn1 > License: GPLv2+ > Group: Development/Tools > Source: https://fedorahosted.org/mock/attachment/wiki/MockTarballs/%{name}-%{version}.tar.gz >@@ -121,6 +121,9 @@ chmod 2775 /var/cache/mock > %dir /var/lib/mock > > %changelog >+* Wed Mar 21 2012 Jeff Fearn <jfearn@redhat.com> - 1.1.21-1-jfearn1 >+- Add megadeps to recursively fetch and build deps >+ > * Wed Feb 8 2012 Clark Williams <williams@redhat.com> - 1.1.21-1 > - from Dennis Gilmore <dennis@ausil.us> > - add Fedora 17 mock configs >diff --git a/py/mock.py b/py/mock.py >index be0f501..33acae5 100755 >--- a/py/mock.py >+++ b/py/mock.py >@@ -29,6 +29,7 @@ > mock [options] --copyin path [..path] destination > mock [options] --copyout path [..path] destination > mock [options] --scm-enable [--scm-option key=value] >+ mock [options] --megadeps {SRPM|RPM} > """ > > # library imports >@@ -124,6 +125,9 @@ def command_parse(config_opts): > parser.add_option("--copyout", action="store_const", const="copyout", > dest="mode", > help="Copy file(s) from the specified chroot") >+ parser.add_option("--megadeps", action="store_const", const="megadeps", >+ dest="mode", >+ help="recursivley build and install dependencies for a specified SRPM") > > # options > parser.add_option("-r", "--root", action="store", type="string", dest="chroot", >@@ -215,7 +219,7 @@ def command_parse(config_opts): > > (options, args) = parser.parse_args() > if len(args) and args[0] in ('chroot', 'shell', >- 'rebuild', 'install', 'installdeps', 'remove', 'init', 'clean'): >+ 'rebuild', 'install', 'installdeps', 'remove', 'init', 'clean', 'megadeps'): > options.mode = args[0] > args = args[1:] > >@@ -865,7 +869,20 @@ def main(ret): > else: > shutil.copy(src, dest) > chroot.unlockBuildRoot() >+ elif options.mode == 'megadeps': >+ if len(args) == 0: >+ log.critical("You must specify an SRPM file.") >+ sys.exit(50) > >+ for hdr in mockbuild.util.yieldSrpmHeaders(args, plainRpmOk=1): >+ pass >+ chroot.tryLockBuildRoot() >+ try: >+ chroot._mountall() >+ chroot.installOrBuildSrpmDeps(*args) >+ finally: >+ chroot._umountall() >+ chroot.unlockBuildRoot() > chroot.state("end") > > >diff --git a/py/mockbuild/backend.py b/py/mockbuild/backend.py >index bea176f..a938205 100644 >--- a/py/mockbuild/backend.py >+++ b/py/mockbuild/backend.py >@@ -15,6 +15,7 @@ import shutil > import stat > import pwd > import grp >+import re > try: > import uuid > gotuuid = True >@@ -551,6 +552,230 @@ class Root(object): > finally: > self.uidManager.restorePrivs() > >+ decorate(traceLog()) >+ def installOrBuildSrpmDeps(self, *srpms): >+ """figure out deps from srpm. call yum to install them. fetch and build rpm for missing deps.""" >+ # This code sources SRPMS from sources not trusted to provide binary RPMS. >+ # The SRPMS are rebuilt, RPMS are built and installed. >+ # TODO Should output a list of SRPMS, the build order for them, and the actual SRPMS >+ try: >+ # Looping makes this go infinite recursive >+ self.uidManager.becomeUser( 0, 0) >+ def _yum_and_check(cmd): >+ self.root_log.info("Checking: %s" % cmd) >+ try: >+ self.uidManager.becomeUser(0, 0) >+ output = self._yum(cmd, returnOutput=1) >+ self.root_log.info("OK: %s: %s" % (cmd, output)) >+ except mockbuild.exception.YumError, e: >+ # goes boom if we don't set this since yum failed and hook was skipped. >+ self._callHooks("postyum") >+ output = str(e) >+ self.root_log.info("Result: %s" % output) >+ try_again = 1 >+ for line in output.split('\n'): >+ if line.lower().find('No Package found for'.lower()) != -1 or line.lower().find('Requires:'.lower()) != -1: >+ if line.lower().find('No Package found for'.lower()) != -1: >+ # builddep generates this >+ match = re.search('No Package found for (.*)$', line) >+ elif line.lower().find('Requires:'.lower()) != -1: >+ # install generates this >+ match = re.search('Requires: (.*)$', line) >+ pkg = match.group(1) >+ try: >+ _yumdownloader_and_build(pkg); >+ except mockbuild.exception.BuildError, e: >+ raise mockbuild.exception.BuildError, "I died: %s" % pkg >+ elif line.lower().find('Nothing to do'.lower()) != -1: >+ # probably already got installed >+ try_again = 0 >+ pass >+ break >+ # try again >+ if try_again: >+ _yum_and_check(cmd) >+ >+ def _yumdownloader_and_build(pkg): >+ self.root_log.info("Package: %s" % pkg) >+ >+ # self._yum doesn't allow us to override repos >+ cmd = 'yum --installroot %s whatprovides "%s" --enablerepo=* -q' % (self.makeChrootPath(), pkg) >+ try: >+ output = mockbuild.util.do(cmd, returnOutput=1, shell=True) >+ self.root_log.info("OK: %s: %s" % (cmd, output)) >+ if output.split('\n')[0].lower().find('Warning: 3.0.x versions'.lower()) != -1: >+ package = pkg >+ else: >+ package = output.split('\n')[0]; >+ # Everything after a space is the description, trim it off >+ self.root_log.info("package: %s" % package) >+ match = re.search('^([^ ]*)', package) >+ if match: >+ package = match.group(1) >+ self.root_log.info("package: %s" % package) >+ # Assumes N-V-R ... >+ match = re.search('^(.*)-\d[^-]*-\d[^-]*$', package) >+ if match: >+ package = match.group(1) >+ self.root_log.info("package: %s" % package) >+ # Catch ecpoch >+ match = re.match('\d+:(.*)$', package) >+ if match: >+ package = match.group(1) >+ self.root_log.info("package: %s" % package) >+ >+ # since we don't want to update perl, use CPAN to get newer modules >+ match = re.search('^perl$', package) >+ if not match: >+ pkg = package >+ except mockbuild.exception.Error, e: >+ self.root_log.info("NOK: %s: %s" % (cmd, str(e))) >+ raise mockbuild.exception.BuildError, "%s has unknown source. Exiting." % pkg >+ >+ self.root_log.info("%s not found in trusted RPM source, looking elsewhere..." % pkg) >+ myuuid = str(uuid.uuid1()) >+ >+ try: >+ cmd = "yumdownloader --installroot %s --source --enablerepo=* --destdir=%stmp/%s '%s'" % (self.makeChrootPath(), self.makeChrootPath(), myuuid, pkg) >+ self.root_log.info("Trying: %s" % (cmd)) >+ output = mockbuild.util.do(cmd, returnOutput=1, shell=True) >+ self.root_log.info("%s found in trusted SRPM source.\n%s" % (pkg, output)) >+ except mockbuild.exception.Error, e: >+ output = str(e) >+ self.root_log.info("%s not found in trusted SRPM source looking elsewhere...\n%s" % (pkg, output)) >+ for line in output.split('\n'): >+ if line.lower().find('No Package'.lower()) != -1 or line.lower().find('No Match'.lower()) != -1: >+ # Sometimes we can build SRPMS from other sources! >+ if pkg.find('perl') != -1: >+ self.root_log.info("Checking cpan for %s" % pkg) >+ pkg = _cpanspec(pkg, myuuid) >+ else: >+ self.root_log.info("%s not found in any source. Exiting." % pkg) >+ raise mockbuild.exception.BuildError, "%s not found in any source. Exiting." % pkg >+ >+ depSrpmFile = glob.glob("%stmp/%s/*.src.rpm" % (self.makeChrootPath(), myuuid)) >+ self.root_log.info("SRPM is %s" % depSrpmFile[0]) >+ _yum_and_check(['builddep', '--nogpgcheck', depSrpmFile[0]]) >+ _buildNinstall(depSrpmFile[0]) >+ >+ def _buildNinstall(srpmFile): >+ self.root_log.info("Building and installing: %s" % srpmFile) >+ self.uidManager._becomeUser(0, 0) >+ # BUGBUG why do we need to keep trying this... >+ try: >+ self._umountall() >+ except mockbuild.exception.Error, e: >+ pass >+ self.root_log.info("Building: %s" % srpmFile) >+ self.uidManager._becomeUser(0, 0) >+ try: >+ self.build(srpm=srpmFile, timeout=0) >+ except mockbuild.exception.Error, e: >+ self.root_log.info("Building failed: %s\n%s" % (srpmFile, str(e))) >+ raise mockbuild.exception.BuildError, "Building failed: %s" % str(e) >+ self.root_log.info("Built: %s" % srpmFile) >+ # Delele all RPM related files to allow recursion >+ srpms = glob.glob("%s/%s/SRPMS/*.src.rpm" % (self.makeChrootPath(), self.builddir)) >+ for srpm in srpms: >+ os.remove(srpm) >+ self.root_log.info("Deleting: %s" % srpm) >+ specs = glob.glob("%s/%s/SPECS/*.spec" % (self.makeChrootPath(), self.builddir)) >+ for spec in specs: >+ os.remove(spec) >+ self.root_log.info("Deleting: %s" % spec) >+ # If install deps are missing then recursing breaks by trying to install >+ # these packages at the same time as the dep packages >+ # so we need to move them before recursing >+ # any runtime deps that are missing and require building >+ # so move them out of normal process path >+ myuuid = str(uuid.uuid1()) >+ old_dir = "%s/%s/RPMS/" % (self.makeChrootPath(), self.builddir) >+ rpms = os.listdir(old_dir) >+ new_dir = "%s/tmp/%s" % (self.makeChrootPath(), myuuid) >+ os.mkdir(new_dir) >+ for rpm in rpms: >+ os.renames(os.path.join(old_dir, rpm), os.path.join(new_dir, rpm)) >+ rpms = glob.glob("%s/*.rpm" % new_dir) >+ # stuff RPMS in a yum repo so deps checking works >+ self.root_log.info("Running createrepo on binary rpms in resultdir") >+ self.uidManager.dropPrivsTemp() >+ # -x is exclude eh >+ cmd = ['/usr/bin/createrepo', '-d', '-q', '-x', '*src.rpm'] >+ cmd.append('--update') >+ cmd.append(self.resultdir) >+ try: >+ mockbuild.util.do(cmd) >+ except mockbuild.exception.Error, e: >+ self.root_log.info("%s failed\n%s" % (cmd, str(e))) >+ raise mockbuild.exception.BuildError, "create repo failed: %s" % str(e) >+ self.uidManager.restorePrivs() >+ self.root_log.info("Installing: %s" % " ".join(rpms)) >+ # Install RPMS so runtime deps can be built >+ try: >+ # make sure we have run time deps >+ _yum_and_check(['install'] + list(rpms) ) >+ except mockbuild.exception.Error, e: >+ self.root_log.info("%s go boom\n%s" % (rpms[0], str(e))) >+ raise mockbuild.exception.BuildError, "Build failed: %s" % str(e) >+ shutil.rmtree(new_dir) >+ self.uidManager.restorePrivs() >+ self.root_log.info("Completed: %s\n" % srpmFile) >+ >+ def _cpanspec(pkg, myuuid): >+ # get the perl Module itself >+ module = pkg >+ if re.search('perl\(', module): >+ # Convert perl(Foo::Bar) to Foo::Bar >+ module = re.sub('perl', '', module) >+ module = re.sub('\(', '', module) >+ module = re.sub('\)', '', module) >+ else: >+ # Convert perl-Foo-Bar to Foo::Bar >+ module = re.sub('perl-', '', module) >+ module = re.sub('-', '::', module) >+ >+ try: >+ pwd = os.getcwd() >+ mydir = "%s/tmp/%s" % (self.makeChrootPath(), myuuid) >+ os.mkdir(mydir) >+ os.chdir(mydir) >+ cmd = 'cpanspec --force --srpm --packager "mock <mock@example.com>" %s' % module >+ output = mockbuild.util.do(cmd, returnOutput=1, shell=True) >+ self.root_log.info("%s found in source in CPAN.\n%s" % (module, output)) >+ for line in output.split('\n'): >+ if line.lower().find('Wrote: '.lower()) != 1: >+ match = re.search('Wrote: (.*)$', line) >+ if match: >+ srpm = match.group(1) >+ pkg = os.path.basename(srpm) >+ pkg = re.sub('-\d.*$', '', pkg) >+ self.root_log.info("pkg is %s " % pkg) >+ os.chdir(pwd) >+ except mockbuild.exception.Error, e: >+ self.root_log.info("%s not found in CPAN. Exiting.\n%s " % (module, str(e))) >+ raise mockbuild.exception.BuildError, "%s. Not found in CPAN. Exiting.\n%s" % (module, str(e)) >+ return(pkg) >+ >+ # first, install pre-existing deps and configured additional ones >+ deps = list(self.preExistingDeps) >+ for hdr in mockbuild.util.yieldSrpmHeaders(srpms, plainRpmOk=1): >+ # get text buildreqs >+ deps.extend(mockbuild.util.getAddtlReqs(hdr, self.more_buildreqs)) >+ if deps: >+ # everything exists, okay, install them all. >+ # pass build reqs to installer >+ args = ['resolvedep'] + deps >+ _yum_and_check(args) >+ # nothing made us exit, so we continue >+ args[0] = 'install' >+ self._yum(args, returnOutput=1) >+ >+ # install actual build dependencies >+ _yum_and_check(['builddep', '--nogpgcheck'] + list(srpms)) >+ _buildNinstall(srpms[0]) >+ finally: >+ self.uidManager.restorePrivs() >+ return > > #decorate(traceLog()) > def _show_installed_packages(self): >@@ -615,6 +840,7 @@ class Root(object): > logger=self.build_log, timeout=timeout, > uid=self.chrootuid, > gid=self.chrootgid, >+ returnOutput=1 > ) > > rebuiltSrpmFile = glob.glob("%s/%s/SRPMS/*.src.rpm" % (self.makeChrootPath(), self.builddir)) >@@ -638,6 +864,7 @@ class Root(object): > logger=self.build_log, timeout=timeout, > uid=self.chrootuid, > gid=self.chrootgid, >+ returnOutput=1 > ) > > bd_out = self.makeChrootPath(self.builddir)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 843745
: 600720