diff options
author | Will Woods <wwoods@redhat.com> | 2009-03-05 18:05:34 -0500 |
---|---|---|
committer | Will Woods <wwoods@redhat.com> | 2009-03-05 18:05:34 -0500 |
commit | 87db0232f329e722f9f8cd97ec50285b14069f04 (patch) | |
tree | 787a4d4f72f2d5e8a376a64fe8e894287de5d83c /debuginfofs-mirror | |
parent | c9e5a68ad5f6febaed4093817fcce2b9a8d80a5b (diff) | |
download | debuginfofs-87db0232f329e722f9f8cd97ec50285b14069f04.tar.gz debuginfofs-87db0232f329e722f9f8cd97ec50285b14069f04.tar.xz debuginfofs-87db0232f329e722f9f8cd97ec50285b14069f04.zip |
Rearrange files a bit, and add Requires(post/preun) for semanage
Diffstat (limited to 'debuginfofs-mirror')
-rwxr-xr-x | debuginfofs-mirror | 352 |
1 files changed, 0 insertions, 352 deletions
diff --git a/debuginfofs-mirror b/debuginfofs-mirror deleted file mode 100755 index 695cef2..0000000 --- a/debuginfofs-mirror +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/python -# Given Fedora arch and version, fetch all debuginfo packages from the mirrors -# Copyright 2009 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Author: Will Woods <wwoods@redhat.com> - -import os -import sys -import stat -import shutil -import tempfile -import optparse -import ConfigParser -import rpmUtils.arch -# Why, yes, I do like to arrange imports by line length -from subprocess import Popen, PIPE -# Yum stuff -sys.path.insert(0,'/usr/share/yum-cli') -import yum.misc -import yum.Errors -from yum import _ -from utils import YumUtilBase -from yum.parser import varReplace -from yum.yumRepo import YumRepository - -configfile = '/etc/debuginfofs.conf' -c = ConfigParser.RawConfigParser() -try: - c.read(configfile) - conf = dict(c.items('general')) -except (IOError, - ConfigParser.MissingSectionHeaderError, - ConfigParser.NoSectionError): - print "Error: no 'cachedir' in %s" % configfile - sys.exit(1) - -class DebuginfoFSDownloader(YumUtilBase): - NAME = 'debuginfofs-mirror' - VERSION = '0.1' - USAGE = 'usage: %s REPOID [REPOID..]' % NAME - def __init__(self): - YumUtilBase.__init__(self, - DebuginfoFSDownloader.NAME, - DebuginfoFSDownloader.VERSION, - DebuginfoFSDownloader.USAGE) - self.optparser = self.getOptionParser() - - def modify_options(self): - o = self.optparser - # FIXME: remove some inappropriate options (--enablerepo etc) - o.add_option("--cachedir", default=conf['cachedir'], - help="directory to use for caching RPMs and metadata") - o.add_option("--exportdir", default=conf['exportdir'], - help="toplevel directory for debuginfofs exported data") - # TODO - #o.add_option("--distro", default="Fedora", - # help="Use debuginfo repos for this distro.") - # TODO: validate releasever/basearch - o.add_option("--releasever", default="10", - help="download debuginfo for this version of the distro.") - o.add_option("--basearch", default="i386", - help="download debuginfo for this arch") - o.add_option("--savecache", default=False, action="store_true", - help="don't delete downloaded RPMs after unpacking them") - o.add_option("--force-download", default=False, action="store_true", - help="download and unpack RPMs even if they already exist") - o.add_option("--download-only", default=False, action="store_true", - help="download RPMs but don't bother unpacking them") - o.add_option("--keep-src", default=False, action="store_true", - help="keep the contents of /usr/src/debug from each package") - - def setup(self): - self.modify_options() - try: - # sets self.cmds - opt = self.doUtilConfigSetup() - except yum.Errors.RepoError, e: - self.logger.error(str(e)) - sys.exit(50) - # Kinda stupid, setting up and then immediately tearing down all repos.. - self.repos.disableRepo('*') - self.repos.setCacheDir(opt.cachedir) - # No yum cache needed, since we're saving the packages ourselves - self.conf.cache = 0 - self.repos.setCache(0) - - return opt - - def listDownloads(self, packages): - '''Returns a string representation of the packages to be downloaded''' - n_wid = s_wid = 1 - coldata = [] - for p in packages: - nevra = pkg_to_nevra(p) - size = self.format_number(int(p.returnSimple('packagesize'))) - if len(nevra) > n_wid: - n_wid = len(nevra) - if len(size) > s_wid: - s_wid = len(size) - coldata.append((nevra, size)) - hr = '=' * self.term.columns - head = self.fmtColumns(((_('Package'),-n_wid),(_('Size'),-s_wid)), u" ") - out = u"""%s\n%s\n%s""" % (hr, head, hr) - for nevra, size in coldata: - cols = ((nevra,-n_wid),(size, s_wid)) - line = self.fmtColumns(cols, u" ", u"\n") - out += line - return out - -def pkg_to_nevra(p): - '''return NEVRA string for package object p''' - (n,a,e,v,r) = p.pkgtup - return "%s-%s:%s-%s.%s" % (n,e,v,r,a) - -def fix_perms(targetdir): - '''Make all files readable, and all directories read+execute''' - def chmod_or(f, mask): - mode = os.lstat(f)[0] - if not stat.S_ISLNK(mode): - newmode = mode | mask - if newmode != mode: - os.chmod(f, newmode) - for top, dirs, files in os.walk(targetdir): - chmod_or(top, 0555) - for f in files: - chmod_or(os.path.join(top, f), 0444) - -def _unpack_rpm(rpm, targetdir, includepat=None, excludepat=None): - '''Unpack the given rpm into the given directory''' - if not os.path.isdir(targetdir): - os.makedirs(targetdir,mode=0755) - os.chdir(targetdir) - cpio = ['cpio','--quiet','-iud'] - if excludepat: - cpio += ['-f', excludepat] - if includepat: - cpio += [includepat] - p1 = Popen(['rpm2cpio',rpm], stdout=PIPE) - p2 = Popen(cpio, stdin=p1.stdout, stdout=PIPE) - output = p2.communicate()[0] # should be empty - if p2.returncode != 0: - raise OSError, "cpio failed: %s output:\n%s" % (str(p2.returncode),output) - # Fix perms so all files are readable - fix_perms(targetdir) - -def unpack_rpm(rpm, targetdir, includepat=None, excludepat=None): - '''Unpack the given rpm into a temporary directory alongside the targetdir, - then rename the temp dir once finished.''' - dir = os.path.dirname(targetdir) - if not os.path.isdir(dir): - os.makedirs(targetdir,mode=0755) - tmpdir = tempfile.mkdtemp(dir=dir) - try: - _unpack_rpm(rpm, tmpdir, includepat, excludepat) - if os.path.isdir(targetdir): - shutil.rmtree(targetdir) - os.rename(tmpdir,targetdir) - return True - except (OSError, IOError), e: - print "unpack_rpm failed: %s" % str(e) - shutil.rmtree(tmpdir) - return False - -def mkdebuginfolinks(sourcedir, targetdir, warn_on_collision=False): - '''hardlink debuginfo from sourcedir into targetdir''' - count = 0 - for top, dirs, files in os.walk(sourcedir, topdown=True): - if '/usr/lib/debug/.build-id/' not in top: - continue - for u in [os.path.join(top,f) for f in files if f.endswith('.debug')]: - target = os.path.realpath(u) - linkname = u.split('/usr/lib/debug/.build-id/')[1] - newlink = os.path.join(targetdir,linkname) - try: - os.makedirs(os.path.dirname(newlink),mode=0755) - except OSError, e: - if e.errno != 17: - raise e - if os.path.exists(newlink): - if warn_on_collision and (os.stat(newlink) != os.stat(target)): - # TODO: better logging here - print "WARNING: collision or damaged debuginfo detected" - print "%s exists - removing" % (newlink,) - os.unlink(newlink) - os.link(target,newlink) - count += 1 - return count - -# TODO: break this up into more logical chunks -def main(): - y = DebuginfoFSDownloader() - opt = y.setup() - # FIXME this is stupid - figure out how --verbose works - if opt.verbose: - y.logger = y.verbose_logger - # Validate some of the opts - # Check permissions on exportdir/cachedir - perms_ok = True - for d in (opt.exportdir, opt.cachedir): - if not os.access(d,os.W_OK): - perms_ok = False - y.logger.error("you don't have write permission on %s" % d) - if not perms_ok: - sys.exit(1) - - if opt.basearch not in rpmUtils.arch.arches: - y.logger.error("Unrecognized arch %s" % opt.basearch) - sys.exit(1) - - # kind of a cheap hack - use values from conf and opt to re-parse URLs - my_yumvar = y.conf.yumvar - my_yumvar.update(conf) - for a in 'basearch', 'releasever': - v = getattr(opt,a,None) - if v: - my_yumvar[a] = v - # Another cheap hack - lie about our arch - if opt.basearch == 'i386': - # hacks upon hacks. blerg. - rpmUtils.arch.canonArch = 'i686' - else: - rpmUtils.arch.canonArch = opt.basearch - - # Set up the requested repos - for repoid in y.cmds: - try: - d = dict([(k,varReplace(v,my_yumvar)) for k,v in c.items(repoid)]) - except ConfigParser.NoSectionError: - y.logger.error("Unknown repo ID %s" % repoid) - continue - if 'mirrorlist' in d: - y.logger.info("Adding repo %s with mirrorlist %s" % (repoid,d['mirrorlist'])) - repo = YumRepository('%s-%s-%s-debuginfofs' % \ - (repoid, opt.releasever, opt.basearch)) - repo.name = repo.id - repo.mirrorlist = d['mirrorlist'] - repo.cache = 0 - repo.enable() - repo.basecachedir = opt.cachedir - repo.cachedir = repo.id - y.repos.add(repo) - y.repos.doSetup(thisrepo=repo.id) - # FIXME: locking - don't setup a repo that's in use by another process - - repolist = y.repos.listEnabled() - if repolist: - # Set up progress callbacks for new repos - y.setupProgressCallbacks() - for r in repolist: - try: - r.ready() - except yum.Errors.RepoError, e: - y.logger.error(str(e)) - sys.exit(1) - else: - y.logger.error("Couldn't find any repos to set up.") - repos = [s for s in c.sections() if s != 'general'] - y.logger.error("Known repos: %s" % ", ".join(repos)) - sys.exit(1) - - # Figure out which packages we need to fetch - download_packages = [] - unpack_packages = [] - for p in y.pkgSack.returnPackages(): - repo = y.repos.getRepo(p.repoid) - remote = p.returnSimple('relativepath') - local = os.path.join(opt.cachedir,os.path.basename(remote)) - p.localpath = local - n = p.pkgtup[0] - nevra = pkg_to_nevra(p) - #/var/www/debuginfofs/packages/c/coreutils/coreutils-0:6.12-18.fc10.i386 - newdir = os.path.join(n[0],n,nevra) - targetdir = os.path.join(opt.exportdir,'packages',newdir) - # Don't bother checking - just add everything to the list - if opt.force_download: - download_packages.append(p) - continue - - # Skip it if it's already unpacked - if os.path.isdir(targetdir): - y.logger.info("Already unpacked %s" % nevra) - os.utime(targetdir, None) - continue - - # XXX does y.downloadPackages handle this for us? - if (os.path.exists(local) and - os.path.getsize(local) == int(p.returnSimple('packagesize'))): - y.logger.info("Already downloaded %s" % nevra) - unpack_packages.append(p) - else: - download_packages.append(p) - - if not (unpack_packages or download_packages): - y.verbose_logger.info(_('Nothing to do!')) - sys.exit(0) - - # Show what will be downloaded and get confirmation - y.verbose_logger.info(y.listDownloads(download_packages)) - y.reportDownloadSize(download_packages) - # FIXME: show some info on unpack_packages - y.verbose_logger.info("Downloading to cachedir %s" % opt.cachedir) - y.verbose_logger.info("Unpacking to exportdir %s" % opt.exportdir) - if y._promptWanted(): - if not y.userconfirm(): - y.logger.info(_('Exiting on user Command')) - sys.exit(1) - - # Download, unpack, and hardlink debuginfo data - excludepat=None - if not opt.keep_src: - excludepat="*/usr/src/debug/*" - for p in unpack_packages + download_packages: - if p in download_packages: - repo = y.repos.getRepo(p.repoid) - # FIXME handle possible errors here - repo.getPackage(p) - if opt.download_only: - continue - local = p.localpath - n = p.pkgtup[0] - nevra = pkg_to_nevra(p) - newdir = os.path.join(n[0],n,nevra) - targetdir = os.path.join(opt.exportdir,'packages',newdir) - - y.verbose_logger.info("Unpacking %s" % nevra) - unpack_rpm(local, targetdir, excludepat=excludepat) - # Remove cached package now that we've unpacked it - if not opt.savecache: - os.unlink(local) - # Make hardlinks - r = mkdebuginfolinks(targetdir, os.path.join(opt.exportdir,'build-id')) - y.logger.info("Linked %3i debuginfo file%s" % (r, r != 1 and "s" or "")) - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print "Exiting on keyboard interrupt" |