Created
March 7, 2017 13:55
-
-
Save rtnpro/419817151e5d3d2356bf53c4cbe3ec2f to your computer and use it in GitHub Desktop.
Yum repo update checker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| import rpmUtils.arch | |
| import yum | |
| from distutils.version import LooseVersion | |
| class YumRepoUpdateCheck(yum.YumBase): | |
| """ | |
| Check Yum repos for updates. | |
| """ | |
| def __init__(self, repo_id, baseurls, arch='x86_64'): | |
| """ | |
| Args: | |
| repo_id (str): Repo id | |
| baseurls (list): A list of upstream repo links | |
| archlist (list): A list of arch strings | |
| """ | |
| super(YumRepoUpdateCheck, self).__init__() | |
| self.baseurls = baseurls | |
| self.repo_id = repo_id | |
| self.yruc_basecachedir = yum.misc.getCacheDir() | |
| self.setCacheDir(self.yruc_basecachedir) | |
| self.archlist = [arch] | |
| def setup_repos(self): | |
| """ | |
| Setup repos for upstream repos and retrieve repo data. | |
| """ | |
| for n, baseurl in enumerate(self.baseurls): | |
| repo_id = '%s%s' % (self.repo_id, n + 1) | |
| # create new repo object | |
| repo = yum.yumRepo.YumRepository(repo_id) | |
| repo.name = repo_id | |
| if baseurl.startswith('mirror:'): | |
| repo.mirrorlist = baseurl[len('mirror:'):] | |
| elif baseurl.startswith('/'): | |
| repo.baseurl = ['file:' + baseurl] | |
| else: | |
| repo.baseurl = [baseurl] | |
| repo.basecachedir = self.yruc_basecachedir | |
| repo.base_persistdir = self.yruc_basecachedir | |
| repo.metadata_expire = 0 | |
| repo.timestamp_check = False | |
| # add repo to the list of repos | |
| self.repos.add(repo) | |
| # enable repo | |
| self.repos.enableRepo(repo_id) | |
| self.doRepoSetup(thisrepo=repo_id) | |
| if '*' in self.archlist: | |
| archs = rpmUtils.arch.arches | |
| archlist = list(set(archs.keys()).union(set(archs.values()))) | |
| else: | |
| archlist = self.archlist | |
| # load sacks for the repo | |
| self._getSacks(archlist=archlist, thisrepo=repo_id) | |
| def iter_newest_packages(self): | |
| pkgs = sorted(self.pkgSack.returnPackages()) | |
| last_new_pkg = None | |
| for pkg in pkgs: | |
| if last_new_pkg: | |
| if pkg.name == last_new_pkg.name: | |
| if LooseVersion(pkg.version) > LooseVersion(last_new_pkg.version): | |
| last_new_pkg = pkg | |
| elif LooseVersion(pkg.version) == LooseVersion(last_new_pkg.version) \ | |
| and LooseVersion(pkg.release) > LooseVersion(last_new_pkg.release): | |
| last_new_pkg = pkg | |
| else: | |
| yield last_new_pkg | |
| last_new_pkg = pkg | |
| else: | |
| last_new_pkg = pkg | |
| yield last_new_pkg | |
| def compare(self, opkgs, npkgs): | |
| """ | |
| Compare new pkg data with old ones | |
| Args: | |
| opkgs: Sorted list of pkg tuple | |
| npkgs: Sorted list of pkg tuple | |
| """ | |
| opkg = None | |
| # old index | |
| oi = 0 | |
| modified = [] | |
| added = [] | |
| removed = [] | |
| len_opkgs = len(opkgs) | |
| for pkg in npkgs: | |
| if len_opkgs == 0: | |
| added.append((None, pkg)) | |
| continue | |
| n, a, e, v, r = opkgs[oi] | |
| _n, _a, _e, _v, _r = pkg | |
| while n < _n: | |
| removed.append((opkg, None)) | |
| oi += 1 | |
| n, a, e, v, r = opkgs[oi] | |
| if n > _n: | |
| added.append((None, pkg)) | |
| elif n == _n: | |
| oi += 1 | |
| if _v != v or _r != r: | |
| modified.append((opkg, pkg)) | |
| while oi < len_opkgs: | |
| removed.append((opkgs[oi], None)) | |
| oi += 1 | |
| return (added, modified, removed) | |
| def main(): | |
| baseurls = [ | |
| 'http://mirror.centos.org/centos/7.3.1611/os/x86_64/', | |
| 'http://mirror.centos.org/centos/7.3.1611/updates/x86_64/' | |
| ] | |
| yruc = YumRepoUpdateCheck('upstream', baseurls, 'x86_64') | |
| yruc.setup_repos() | |
| try: | |
| with open('repodata.json') as f: | |
| opkgs = json.load(f) | |
| except: | |
| opkgs = [] | |
| npkgs = [pkg.pkgtup for pkg in yruc.iter_newest_packages()] | |
| added, modified, removed = yruc.compare(opkgs, npkgs) | |
| print 'Added: {}, Modified: {}, Removed: {}'.format( | |
| len(added), len(modified), len(removed)) | |
| with open('repodata.json', 'w') as f: | |
| json.dump(npkgs, f, indent=2) | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment