1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 from spacewalk.common.rhnTranslate import _
20 from spacewalk.common import rhnFlags
21 from spacewalk.common.rhnLib import parseRPMName
22 from spacewalk.common.rhnLog import log_debug, log_error
23 from spacewalk.common.rhnException import rhnFault
24
25
26 from spacewalk.server.rhnHandler import rhnHandler
27 from spacewalk.server import rhnSQL, rhnCapability
28
29
31
32 """ Errata class --- retrieve (via xmlrpc) package errata. """
33
35 rhnHandler.__init__(self)
36
37 self.functions = []
38 self.functions.append('GetByPackage')
39 self.functions.append('getPackageErratum')
40 self.functions.append('getErrataInfo')
41 self.functions.append('getErrataNamesById')
42
44 """ Clients v1- Get errata for a package given "n-v-r" format
45 IN: pkg: "n-v-r" (old client call)
46 or [n,v,r]
47 osRel: OS release
48 RET: a hash by errata that applies to this package
49 (ie, newer packages are available). We also limit the scope
50 for a particular osRel.
51 """
52 if type(pkg) == type(''):
53 pkg = parseRPMName(pkg)
54 log_debug(1, pkg, osRel)
55
56 transport = rhnFlags.get('outputTransportOptions')
57 transport['X-RHN-Action'] = 'GetByPackage'
58
59
60 if type(pkg[0]) != type(''):
61 log_error("Invalid package name: %s %s" % (type(pkg[0]), pkg[0]))
62 raise rhnFault(30, _("Expected a package name, not: %s") % pkg[0])
63
64
65 h = rhnSQL.prepare("""
66 select distinct
67 e.id errata_id,
68 e.advisory_type errata_type,
69 e.advisory advisory,
70 e.topic topic,
71 e.description description,
72 e.synopsis synopsis
73 from
74 rhnErrata e,
75 rhnPublicChannelFamily pcf,
76 rhnChannelFamilyMembers cfm,
77 rhnErrataPackage ep,
78 rhnChannelPackage cp,
79 rhnChannelErrata ce,
80 rhnDistChannelMap dcm,
81 rhnPackage p
82 where 1=1
83 and p.name_id = LOOKUP_PACKAGE_NAME(:name)
84 -- map to a channel
85 and p.id = cp.package_id
86 and cp.channel_id = dcm.channel_id
87 and dcm.release = :dist
88 and dcm.org_id is null
89 -- map to an errata as well
90 and p.id = ep.package_id
91 and ep.errata_id = e.id
92 -- the errata and the channel have to be linked
93 and ce.channel_id = cp.channel_id
94 -- and the channel has to be public
95 and cp.channel_id = cfm.channel_id
96 and cfm.channel_family_id = pcf.channel_family_id
97 -- and get the erratum
98 and e.id = ce.errata_id
99 """)
100 h.execute(name=pkg[0], dist=str(osRel))
101 return self._sanitize_result(h)
102
104 """ Clients v2+ - Get errata for a package given [n,v,r,e,a,...] format
105
106 Sing-along: You say erratum(sing), I say errata(pl)! :)
107 IN: pkg: [n,v,r,e,s,a,ch,...]
108 RET: a hash by errata that applies to this package
109 """
110 log_debug(5, system_id, pkg)
111 if type(pkg) != type([]) or len(pkg) < 7:
112 log_error("Got invalid package specification: %s" % str(pkg))
113 raise rhnFault(30, _("Expected a package, not: %s") % pkg)
114
115 self.auth_system(system_id)
116
117 log_debug(1, self.server_id, pkg)
118
119 transport = rhnFlags.get('outputTransportOptions')
120 transport['X-RHN-Action'] = 'getPackageErratum'
121
122 name, ver, rel, epoch, arch, size, channel = pkg[:7]
123 if epoch in ['', 'none', 'None']:
124 epoch = None
125
126
127
128
129 h = rhnSQL.prepare("""
130 select distinct
131 e.id errata_id,
132 e.advisory_type errata_type,
133 e.advisory advisory,
134 e.topic topic,
135 e.description description,
136 e.synopsis synopsis
137 from
138 rhnServerChannel sc,
139 rhnChannelPackage cp,
140 rhnChannelErrata ce,
141 rhnErrata e,
142 rhnErrataPackage ep,
143 rhnPackage p
144 where
145 p.name_id = LOOKUP_PACKAGE_NAME(:name)
146 and p.evr_id = LOOKUP_EVR(:epoch, :ver, :rel)
147 -- map to a channel
148 and p.id = cp.package_id
149 -- map to an errata as well
150 and p.id = ep.package_id
151 and ep.errata_id = e.id
152 -- the errata and the channel have to be linked
153 and e.id = ce.errata_id
154 and ce.channel_id = cp.channel_id
155 -- and the server has to be subscribed to the channel
156 and cp.channel_id = sc.channel_id
157 and sc.server_id = :server_id
158 """)
159 h.execute(name=name, ver=ver, rel=rel, epoch=epoch,
160 server_id=str(self.server_id))
161 return self._sanitize_result(h)
162
164 ret = []
165
166 while 1:
167 row = h.fetchone_dict()
168 if row is None:
169 break
170 for k in row.keys():
171 if row[k] is None:
172 row[k] = "N/A"
173 ret.append(row)
174
175 return ret
176
177
179 log_debug(5, system_id, errata_id)
180
181 self.auth_system(system_id)
182
183 log_debug(1, self.server_id, errata_id)
184
185 client_caps = rhnCapability.get_client_capabilities()
186 log_debug(3, "Client Capabilities", client_caps)
187 multiarch = 0
188 cap_info = None
189 if client_caps and 'packages.update' in client_caps:
190 cap_info = client_caps['packages.update']
191 if cap_info and cap_info['version'] > 1:
192 multiarch = 1
193
194 statement = """
195 select distinct
196 pn.name,
197 pe.epoch,
198 pe.version,
199 pe.release,
200 pa.label arch
201 from
202 rhnPackageName pn,
203 rhnPackageEVR pe,
204 rhnPackage p,
205 rhnPackageArch pa,
206 rhnChannelPackage cp,
207 rhnServerChannel sc,
208 rhnErrataPackage ep
209 where
210 ep.errata_id = :errata_id
211 and ep.package_id = p.id
212 and p.name_id = pn.id
213 and p.evr_id = pe.id
214 and p.package_arch_id = pa.id
215 and sc.server_id = :server_id
216 and sc.channel_id = cp.channel_id
217 and cp.package_id = p.id
218 """
219
220 h = rhnSQL.prepare(statement)
221 h.execute(errata_id=errata_id, server_id=self.server_id)
222
223 packages = h.fetchall_dict()
224 ret = []
225 if not packages:
226 return []
227
228 for package in packages:
229 if package['name'] is not None:
230 if package['epoch'] is None:
231 package['epoch'] = ""
232
233 pkg_arch = ''
234 if multiarch:
235 pkg_arch = package['arch'] or ''
236 ret.append([package['name'],
237 package['version'],
238 package['release'],
239 package['epoch'],
240 pkg_arch])
241 return ret
242
244 """Return a list of RhnErrata tuples of (id, advisory_name)
245
246 IN: system_id - id of the system requesting this info (must be
247 subscribed to the channel that contains the erratas)
248 errata_ids - a list of RhnErrata ids
249
250 Only the erratas that belong to channels that the client system
251 is subscribed to are returned. If no erratas match this
252 criterion, then an empty list is returned.
253
254 """
255 log_debug(5, system_id, errata_ids)
256 self.auth_system(system_id)
257
258 log_debug(1, self.server_id, errata_ids)
259
260 sql_list, bound_vars = _bind_list(errata_ids)
261 bound_vars.update({'server_id': self.server_id})
262
263 sql = """SELECT DISTINCT e.id, e.advisory_name
264 FROM rhnErrata e,
265 rhnPackage p,
266 rhnChannelPackage cp,
267 rhnServerChannel sc,
268 rhnErrataPackage ep
269 WHERE e.id in (%s) AND
270 ep.errata_id = e.id AND
271 ep.package_id = p.id AND
272 sc.server_id = :server_id AND
273 sc.channel_id = cp.channel_id AND
274 cp.package_id = p.id"""
275 h = rhnSQL.prepare(sql % sql_list)
276 h.execute(**bound_vars)
277
278 return h.fetchall()
279
280
282 """Transform a list into an sql list with bound parameters
283
284 IN: elems - a list of elements
285
286 Returns a tuple of:
287 sql_list - a comma separated list of parameter numbers: 'p_0, p_1, p_2'
288 bound_vars - a dict of parameter names and values {'p_0': 42, 'p_1': 34}
289
290 """
291 bound_names = []
292 bound_vars = {}
293 for i, elem in enumerate(elems):
294 bound_vars['p_%s' % i] = elem
295 bound_names.append(':p_%s' % i)
296 sql_list = ', '.join(bound_names)
297 return sql_list, bound_vars
298
299
300 if __name__ == "__main__":
301 print("You can not run this module by itself")
302 import sys
303 sys.exit(-1)
304
305