summaryrefslogtreecommitdiffstats
path: root/rpmci/dynrepo.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpmci/dynrepo.py')
-rw-r--r--rpmci/dynrepo.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/rpmci/dynrepo.py b/rpmci/dynrepo.py
new file mode 100644
index 0000000..e6cdc90
--- /dev/null
+++ b/rpmci/dynrepo.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+
+# dynrepo.py:
+# Monitor set of RPMs in a directory.
+#
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Colin Walters <walters@verbum.org>
+
+import os
+import sys
+import logging
+
+import glib
+import rpm
+import rpmUtils
+import rpmUtils.miscutils
+
+from . import async_subprocess
+
+class Repo(object):
+ def __init__(self, dirpath):
+ self._dir = dirpath
+ self._dir_gfile = gio.File(path=dirpath)
+ self._monitor = self._dir_gfile.monitor(gio.FILE_MONITOR_NONE)
+ self._monitor.connect('changed', self._on_dir_changed)
+
+ def get_rpms(self):
+ return self._rpms
+
+ def get_rpms_for_name(self, name, arch):
+ result = []
+ for filename,(n,a,e,v,r) in self._rpms.iteritems():
+ if n == name and (arch is None or a == arch):
+ result.append((filename, n, a, e, v, r))
+ return result
+
+ def get_latest_srpm_for_name(self, name):
+ rpms = self.get_rpms_for_name(name, 'src')
+ cmpevr=rpmUtils.miscutils.compareEVR
+ if rpms:
+ rpms.sort(lambda a,b: cmpevr(a[3:6], b[3:6]))
+ return rpms[-1]
+ return None
+
+ def add_srpm(self, srpm_path):
+ basename = os.path.basename(srpm_path)
+ os.link(srpm_path, os.path.join(self._dir, basename))
+
+ def _delete_old_rpms_in_dir(self, dirpath):
+ proc = popen_verbose(['repomanage', '-o', '.'], stdout=subprocess.PIPE,
+ stderr=sys.stderr,
+ cwd=dirpath)
+ output = proc.communicate()[0]
+ for line in output.split('\n'):
+ if line.endswith('.rpm') and os.path.exists(line):
+ os.unlink(line)
+
+ def update_repo_sync(self):
+ self._delete_old_rpms_in_dir(dirpath)
+ subprocess.check_call(['createrepo', '.'], cwd=self._dir)
+
+ def _headers_from_packages(self, rpmlist):
+ result = {}
+ ts = rpm.TransactionSet()
+ ts.setVSFlags(~(rpm._RPMVSF_NOPAYLOAD))
+ for pkg in rpmlist:
+ pkg_path = os.path.join(self._dir, pkg)
+ try:
+ header = rpmUtils.miscutils.hdrFromPackage(ts, pkg_path)
+ except rpmUtils.RpmUtilsError, e:
+ logging.exception(e)
+ continue
+ (n,a,e,v,r) = rpmUtils.miscutils.pkgTupleFromHeader(header)
+ del header
+ result[pkg] = (n,a,e,v,r)
+ return result
+
+ def _on_dir_changed(self, mon, gfile, other, event):
+ self._reload()
+
+ def _reload(self):
+ dir_contents = os.listdir(self._dirpath)
+ messages = set()
+ rpmlist = set()
+ for filename in dir_contents:
+ if filename.endswith('.tmp'):
+ continue
+ if not filename.endswith('.rpm'):
+ continue
+ rpmlist.add(filename)
+
+ deleted = []
+ for rpm in self._rpms:
+ if rpm not in rpmlist:
+ deleted.add(rpm)
+ for rpm in deleted:
+ del self._rpms[rpm]
+ new = []
+ for rpm in self._rpms:
+ if rpm not in rpmlist:
+ new.append(rpm)
+ for rpm,data in self._headers_from_packages(new).iteritems():
+ self._rpms[rpm] = data