#! /usr/bin/python -tt # 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # # Copyright Red Hat Inc. 2009 # # Author: James Antill # # FIXME: Doesn't copy updateinfo over # TODO: Add command to explicitly download pkgs and add them to the repo. # TODO: Some way to say "don't copy from these repos." or "only copy from these" # so we can just get updates/rawhide and not fedora (which doesn't lose # packages). import os import shutil import yum from yum.plugins import TYPE_CORE requires_api_version = '2.5' plugin_type = (TYPE_CORE,) def_local_repo_dir = '/var/lib/yum/plugins/local' local_repo_dir = '' def prereposetup_hook(conduit): global local_repo_dir local_repo_dir = conduit.confString('main', 'repodir', default=def_local_repo_dir) try: d_mtime = os.stat(local_repo_dir).st_mtime r_mtime = os.stat("%s/repodata/repomd.xml" % local_repo_dir).st_mtime if d_mtime > r_mtime: _rebuild(conduit) except: pass def postdownload_hook(conduit): if conduit.getErrors() or os.geteuid(): return reg = False done = 0 for pkg in conduit.getDownloadPackages(): fname = pkg.localPkg() if fname.startswith(local_repo_dir): reg = True continue dest = local_repo_dir + '/' + os.path.basename(fname) if os.path.exists(dest): continue if not done and not os.path.exists(local_repo_dir): os.makedirs(local_repo_dir) done += 1 shutil.copy2(fname, dest) if reg: if hasattr(conduit, 'registerPackageName'): conduit.registerPackageName("yum-plugin-local") if not done: return _rebuild(conduit, done) _reposetup(conduit) def _rebuild(conduit, done=None): enabled = conduit.confBool('createrepo', 'enabled', default=True) if not enabled: return cache_dir = conduit.confString('createrepo', 'cachedir', default=None) checksum = conduit.confString('createrepo', 'checksum', default=None) quiet = conduit.confBool('createrepo', 'quiet', default=True) verbose = conduit.confBool('createrepo', 'verbose', default=False) skip_stat = conduit.confBool('createrepo', 'skip_stat', default=False) unique_md = conduit.confBool('createrepo', 'unique_md_filenames', default=False) update = conduit.confBool('createrepo', 'update', default=True) databases = conduit.confBool('createrepo', 'databases', default=True) deltas = conduit.confBool('createrepo', 'enable_deltas', default=False) num_deltas = conduit.confInt('createrepo', 'deltas', default=None) old_package_dirs = conduit.confString('createrepo', 'oldpackagedirs', default=local_repo_dir) if conduit._base.verbose_logger.isEnabledFor(yum.logginglevels.DEBUG_3): quiet = False args = ["createrepo"] if quiet: args.append("--quiet") if verbose: args.append("--verbose") if databases: args.append("--database") if update: args.append("--update") if unique_md: args.append("--unique-md-filenames") if checksum is not None: args.append("--checksum") args.append(checksum) if skip_stat: args.append("--skip-stat") if cache_dir is not None: args.append("--cachedir") args.append(cache_dir) if deltas: args.append('--deltas') args.append('--oldpackagedirs') args.append(old_package_dirs) if num_deltas is not None: args.append('--num-deltas') args.append(num_deltas) args.append(local_repo_dir) if not quiet: if done is None: conduit.info(2, "== Rebuilding _local repo. ==") else: msg = "== Rebuilding _local repo. with %u new packages ==" % done conduit.info(2, msg) os.spawnvp(os.P_WAIT, "createrepo", args) # For the prerepo. check os.utime("%s/repodata/repomd.xml" % local_repo_dir, None) if not quiet: conduit.info(2, "== Done rebuild of _local repo. ==") def _reposetup(conduit): lrepo = [repo for repo in conduit._base.repos.listEnabled() if repo.id == "_local"] if lrepo: lrepo = lrepo[0] os.unlink("%s/cachecookie" % lrepo.cachedir) return conf_fname = '/etc/yum.repos.d/_local.repo' if os.path.exists(conf_fname): return open(conf_fname, "wb").write("""\ [_local] name=Automatic local repo. (manged by the "local" yum plugin). baseurl=file:%s enabled=1 gpgcheck=true # Metadata expire could be set to "never" because the local plugin will # automatically cause a cache refresh when new packages are added. However # it's really cheap to check, and this way people can dump stuff in whenever # and it never gets out of sync. for long. metadata_expire=1h # Make cost smaller, as we know it's "local". If you really want to be sure, # you can do this ... but the name will do pretty much the same thing, and that # way we can also see the other packages (with: --showduplicates list). # cost=500 """ % local_repo_dir)