2c836f3eeb0b715f4f8f272d4c12244d52bae1ba
[platform/upstream/rpm.git] / python / rpm / transaction.py
1 #!/usr/bin/python
2
3 import rpm
4 from rpm._rpm import ts as _rpmts
5
6 # TODO: migrate relevant documentation from C-side
7 class TransactionSet(_rpmts):
8     _probFilter = 0
9     # FIXME: kludge for keeping refcounts on transaction element keys
10     _keyList = []
11
12     def _wrapSetGet(self, attr, val):
13         oval = getattr(self, attr)
14         setattr(self, attr, val)
15         return oval
16         
17     def setVSFlags(self, flags):
18         return self._wrapSetGet('_vsflags', flags)
19
20     def getVSFlags(self):
21         return self._vsflags
22
23     def setColor(self, color):
24         return self._wrapSetGet('_color', color)
25
26     def setPrefColor(self, color):
27         return self._wrapSetGet('_prefcolor', color)
28
29     def setFlags(self, flags):
30         return self._wrapSetGet('_flags', flags)
31
32     def setProbFilter(self, ignoreSet):
33         return self._wrapSetGet('_probFilter', ignoreSet)
34
35     def parseSpec(self, specfile):
36         import _rpmb
37         return _rpmb.spec(specfile)
38
39     def getKeys(self):
40         keys = []
41         for te in self:
42             keys.append(te.Key())
43         # Backwards compatibility goo - WTH does this return a *tuple* ?!
44         if not keys:
45             return None
46         else:
47             return tuple(keys)
48
49     def addInstall(self, item, key, how="u"):
50         if isinstance(item, str):
51             f = file(item)
52             header = self.hdrFromFdno(f)
53             f.close()
54         elif isinstance(item, file):
55             header = self.hdrFromFdno(item)
56         else:
57             header = item
58
59         if not how in ['u', 'i']:
60             raise ValueError('how argument must be "u" or "i"')
61         upgrade = (how == "u")
62
63         if not _rpmts.addInstall(self, header, key, upgrade):
64             raise rpm.error("adding package to transaction failed")
65         self._keyList.append(key)
66
67     def addErase(self, item):
68         hdrs = []
69         if isinstance(item, rpm.hdr):
70             hdrs = [item]
71         elif isinstance(item, rpm.mi):
72             hdrs = item
73         elif isinstance(item, int):
74             hdrs = self.dbMatch(rpm.RPMDBI_PACKAGES, item)
75         elif isinstance(item, str):
76             hdrs = self.dbMatch(rpm.RPMDBI_LABEL, item)
77         else:
78             raise TypeError("invalid type %s" % type(item))
79
80         for h in hdrs:
81             if not _rpmts.addErase(self, h):
82                 raise rpm.error("package not installed")
83
84         # garbage collection should take care but just in case...
85         if isinstance(hdrs, rpm.mi):
86             del hdrs
87
88     def run(self, callback, data):
89         rc = _rpmts.run(self, callback, data, self._probFilter)
90
91         # crazy backwards compatibility goo: None for ok, list of problems
92         # if transaction didnt complete and empty list if it completed
93         # with errors
94         if rc == 0:
95             return None
96
97         res = []
98         if rc > 0:
99             for prob in self.problems():
100                 item = ("%s" % prob, (prob.type, prob._str, prob._num))
101                 res.append(item)
102         return res
103
104     def check(self, *args, **kwds):
105         _rpmts.check(self, *args, **kwds)
106
107         probs = self.problems()
108         if not probs:
109             return None
110
111         # compatibility: munge problem strings into dependency tuples of doom
112         res = []
113         for p in probs:
114             # is it anything we need to care about?
115             if p.type == rpm.RPMPROB_CONFLICT:
116                 sense = rpm.RPMDEP_SENSE_CONFLICTS
117             elif p.type == rpm.RPMPROB_REQUIRES:
118                 sense = rpm.RPMDEP_SENSE_REQUIRES
119             else:
120                 continue
121
122             # strip arch, split to name, version, release
123             nevr = p.pkgNEVR.rsplit('.', 1)[0]
124             n, v, r = nevr.rsplit('-', 2)
125
126             # extract the dependency information
127             needs = p.altNEVR.split()[1:]
128             needname = needs[0]
129             needflags = rpm.RPMSENSE_ANY
130             if len(needs) == 3:
131                 needop = needs[1]
132                 if needop.find('<') >= 0: needflags |= rpm.RPMSENSE_LESS
133                 if needop.find('=') >= 0: needflags |= rpm.RPMSENSE_EQUAL
134                 if needop.find('>') >= 0: needflags |= rpm.RPMSENSE_GREATER
135                 needver = needs[2]
136             else:
137                 needver = ""
138
139             res.append(((n, v, r),(needname,needver),needflags,sense,p.key))
140
141         return res
142
143     def hdrCheck(self, blob):
144         res, msg = _rpmts.hdrCheck(self, blob)
145         # generate backwards compatibly broken exceptions
146         if res == rpm.RPMRC_NOKEY:
147             raise rpm.error("public key not available")
148         elif res == rpm.RPMRC_NOTTRUSTED:
149             raise rpm.error("public key not trusted")
150         elif res != rpm.RPMRC_OK:
151             raise rpm.error(msg)
152
153     def hdrFromFdno(self, fd):
154         res, h = _rpmts.hdrFromFdno(self, fd)
155         # generate backwards compatibly broken exceptions
156         if res == rpm.RPMRC_NOKEY:
157             raise rpm.error("public key not available")
158         elif res == rpm.RPMRC_NOTTRUSTED:
159             raise rpm.error("public key not trusted")
160         elif res != rpm.RPMRC_OK:
161             raise rpm.error("error reading package header")
162
163         return h