1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#!/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 subprocess
import glib
import gio
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)
self._rpms = {}
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 = subprocess.Popen(['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(self._dir)
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._dir)
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
|