1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import string
18 try:
19
20 import xmlrpclib
21 except ImportError:
22
23 import xmlrpc.client as xmlrpclib
24 import random
25
26
27 from spacewalk.common.usix import LongType
28 from spacewalk.common import rhnCache, rhnFlags, rhn_rpm
29 from spacewalk.common.rhnLog import log_debug
30 from spacewalk.common.rhnConfig import CFG
31 from spacewalk.common.rhnException import rhnFault
32 from spacewalk.common.rhnTranslate import _
33
34
35 from spacewalk.server.rhnHandler import rhnHandler
36 from spacewalk.server import rhnChannel, rhnSQL, rhnLib
37
38
39
40
41
43
45 rhnHandler.__init__(self)
46
47 self.functions = []
48 self.functions.append("poll_status")
49 self.functions.append("poll_packages")
50 self.functions.append("tie_uuid")
51 self.functions.append("has_base_channel")
52
53 _query_lookup_server = rhnSQL.Statement("""
54 select s.id
55 from rhnServer s,
56 rhnServerUuid su
57 where su.uuid = :uuid
58 and su.server_id = s.id
59 order by modified desc
60 """)
61 _query_lookup_base_channel = rhnSQL.Statement("""
62 select c.label
63 from rhnChannel c,
64 rhnServerChannel sc
65 where sc.server_id = :server_id
66 and sc.channel_id = c.id
67 and c.parent_channel is null
68 """)
69
88
89
102
103
105 checkin_interval = (CFG.CHECKIN_INTERVAL +
106 random.random() * CFG.CHECKIN_INTERVAL_MAX_OFFSET)
107 return {
108 'checkin_interval': int(checkin_interval),
109 'server_status': 'normal'
110 }
111
112
113 - def poll_packages(self, release, server_arch, timestamp=0, uuid=None):
114 log_debug(1, release, server_arch, timestamp, uuid)
115
116
117 release = str(release)
118 server_arch = rhnLib.normalize_server_arch(server_arch)
119 timestamp = str(timestamp)
120 uuid = str(uuid)
121
122
123 channel_list = []
124
125 channel_list = rhnChannel.applet_channels_for_uuid(uuid)
126
127
128
129 if not channel_list:
130 channel_list = rhnChannel.get_channel_for_release_arch(release,
131 server_arch)
132 channel_list = [channel_list]
133
134 if not channel_list:
135 log_debug(8, "No channels for release = '%s', arch = '%s', uuid = '%s'" % (
136 release, server_arch, uuid))
137 return {'last_modified': 0, 'contents': []}
138
139 last_channel_changed_ts = max([a["last_modified"] for a in channel_list])
140
141
142 last_channel_changed_ts = str(LongType(last_channel_changed_ts) + 1)
143
144
145 client_cache_invalidated = None
146
147
148
149 if "server_channels_changed" in channel_list[0]:
150 sc_ts = channel_list[0]["server_channels_changed"]
151
152 if sc_ts and (sc_ts >= last_channel_changed_ts):
153 client_cache_invalidated = 1
154
155 if (last_channel_changed_ts <= timestamp) and (not client_cache_invalidated):
156
157
158
159 log_debug(3, "Client has current data")
160 return {'use_cached_copy': 1}
161
162
163 rhnFlags.set("compress_response", 1)
164
165
166 rhnFlags.set("XMLRPC-Encoded-Response", 1)
167
168
169 label_list = [str(a["id"]) for a in channel_list]
170 label_list.sort()
171 log_debug(4, "label_list", label_list)
172 cache_key = "applet-poll-%s" % string.join(label_list, "-")
173
174 ret = rhnCache.get(cache_key, last_channel_changed_ts)
175 if ret:
176 log_debug(3, "Cache HIT for", cache_key)
177 return ret
178
179
180
181
182
183
184 ret = {'last_modified': last_channel_changed_ts, 'contents': []}
185
186
187
188
189 qlist = []
190 qdict = {}
191 for c in channel_list:
192 v = c["id"]
193 k = "channel_%s" % v
194 qlist.append(":%s" % k)
195 qdict[k] = v
196 qlist = string.join(qlist, ", ")
197
198
199
200
201
202
203
204 h = rhnSQL.prepare("""
205 select distinct
206 pn.name,
207 pe.version,
208 pe.release,
209 pe.epoch,
210 e_sq.errata_advisory,
211 e_sq.errata_synopsis,
212 e_sq.errata_id
213 from
214 rhnPackageName pn,
215 rhnPackageEVR pe,
216 rhnChannelNewestPackage cnp
217 left join
218 ( select sq_e.id as errata_id,
219 sq_e.synopsis as errata_synopsis,
220 sq_e.advisory as errata_advisory,
221 sq_ep.package_id
222 from
223 rhnErrata sq_e,
224 rhnErrataPackage sq_ep,
225 rhnChannelErrata sq_ce
226 where sq_ce.errata_id = sq_ep.errata_id
227 and sq_ce.errata_id = sq_e.id
228 and sq_ce.channel_id in ( %s )
229 ) e_sq
230 on cnp.package_id = e_sq.package_id
231 where
232 cnp.channel_id in ( %s )
233 and cnp.name_id = pn.id
234 and cnp.evr_id = pe.id
235 """ % (qlist, qlist))
236 h.execute(**qdict)
237
238 plist = h.fetchall_dict()
239
240 if not plist:
241
242 ret = xmlrpclib.dumps((ret, ), methodresponse=1)
243 return ret
244
245 contents = {}
246
247 for p in plist:
248 for k in p.keys():
249 if p[k] is None:
250 p[k] = ""
251 p["nevr"] = "%s-%s-%s:%s" % (
252 p["name"], p["version"], p["release"], p["epoch"])
253 p["nvr"] = "%s-%s-%s" % (p["name"], p["version"], p["release"])
254
255 pkg_name = p["name"]
256
257 if pkg_name in contents:
258 stored_pkg = contents[pkg_name]
259
260 s = [stored_pkg["name"],
261 stored_pkg["version"],
262 stored_pkg["release"],
263 stored_pkg["epoch"]]
264
265 n = [p["name"],
266 p["version"],
267 p["release"],
268 p["epoch"]]
269
270 log_debug(7, "comparing vres", s, n)
271 if rhn_rpm.nvre_compare(s, n) < 0:
272 log_debug(7, "replacing %s with %s" % (pkg_name, p))
273 contents[pkg_name] = p
274 else:
275
276 pass
277 else:
278 log_debug(7, "initial store for %s" % pkg_name)
279 contents[pkg_name] = p
280
281 ret["contents"] = list(contents.values())
282
283
284
285 ret = xmlrpclib.dumps((ret, ), methodresponse=1)
286 rhnCache.set(cache_key, ret, last_channel_changed_ts)
287
288 return ret
289