1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import re
18 import sys
19
20 from spacewalk.common.usix import ListType, IntType
21
22 from spacewalk.common import rhnFlags
23 from spacewalk.common.rhnLog import log_debug, log_error
24 from spacewalk.common.rhnException import rhnException
25 from spacewalk.server import rhnSQL
26 from spacewalk.server.rhnServer import server_kickstart
27
28
29 __rhnexport__ = ['remove',
30 'update',
31 'refresh_list',
32 'delta',
33 'runTransaction',
34 'verify']
35
36
39
40 _query_insert_attribute_verify_results = rhnSQL.Statement("""
41 insert into rhnServerActionVerifyResult (
42 server_id, action_id,
43 package_name_id,
44 package_evr_id,
45 package_arch_id,
46 package_capability_id,
47 attribute, size_differs, mode_differs, checksum_differs,
48 devnum_differs, readlink_differs, uid_differs,
49 gid_differs, mtime_differs
50 )
51 values (
52 :server_id, :action_id,
53 lookup_package_name(:package_name),
54 lookup_evr(:epoch || '', :version, :release),
55 lookup_package_arch(:arch),
56 lookup_package_capability(:filename),
57 :attrib, :test_S, :test_M, :test_5,
58 :test_D, :test_L, :test_U,
59 :test_G, :test_T
60 )
61 """)
62
63 _query_insert_missing_verify_results = rhnSQL.Statement("""
64 insert into rhnServerActionVerifyMissing (
65 server_id,
66 action_id,
67 package_name_id,
68 package_evr_id,
69 package_arch_id,
70 package_capability_id
71 )
72 values (
73 :server_id,
74 :action_id,
75 lookup_package_name(:package_name),
76 lookup_evr(:epoch || '', :version, :release),
77 lookup_package_arch(:arch),
78 lookup_package_capability(:filename)
79 )
80 """)
81
82 _query_delete_verify_results = rhnSQL.Statement("""
83 delete from rhnServerActionVerifyResult
84 where server_id = :server_id
85 and action_id = :action_id
86 """)
87
88 _query_delete_verify_missing = rhnSQL.Statement("""
89 delete from rhnServerActionVerifyMissing
90 where server_id = :server_id
91 and action_id = :action_id
92 """)
93
94
95 -def verify(server_id, action_id, data={}):
96 log_debug(3, action_id)
97
98 if (not data) or ('verify_info' not in data):
99
100 log_error("Insufficient package verify information returned",
101 server_id, action_id, data)
102 return
103
104 log_debug(4, "pkg verify data", data)
105
106
107 h = rhnSQL.prepare(_query_delete_verify_results)
108 h.execute(server_id=server_id, action_id=action_id)
109
110 h = rhnSQL.prepare(_query_delete_verify_missing)
111 h.execute(server_id=server_id, action_id=action_id)
112
113 attrib_tests = ['S', 'M', '5', 'D', 'L', 'U', 'G', 'T']
114
115
116 verify_attribs = {'server_id': [], 'action_id': [], 'package_name': [],
117 'epoch': [], 'version': [], 'release': [], 'arch': [],
118 'filename': [], 'attrib': [], }
119 for test in attrib_tests:
120 verify_attribs["test_" + test] = []
121
122
123 missing_files = {'server_id': [], 'action_id': [], 'package_name': [],
124 'epoch': [], 'version': [], 'release': [], 'arch': [],
125 'filename': []}
126
127
128 uq_packages = {}
129
130 for package_spec, responses in data['verify_info']:
131 package_spec = list(package_spec)
132
133 if package_spec[3] == '':
134 package_spec[3] = None
135 package_spec = tuple(package_spec)
136 if package_spec in uq_packages:
137
138 continue
139
140
141 hash = {}
142 for response in responses:
143 try:
144 dict = _parse_response_line(response, attrib_tests)
145 except InvalidResponseLine:
146 log_error("packages.verify: (%s, %s): invalid line %s"
147 % (server_id, action_id, response))
148 continue
149
150 hash[dict['filename']] = dict
151
152
153 for filename, dict in hash.items():
154 dict['server_id'] = server_id
155 dict['action_id'] = action_id
156
157 dict['package_name'] = package_spec[0]
158 dict['version'] = package_spec[1]
159 dict['release'] = package_spec[2]
160 dict['epoch'] = package_spec[3]
161 dict['arch'] = package_spec[4]
162
163 if 'missing' not in dict:
164 _hash_append(verify_attribs, dict)
165 else:
166 _hash_append(missing_files, dict)
167
168
169 uq_packages[package_spec] = None
170
171 if verify_attribs['action_id']:
172 h = rhnSQL.prepare(_query_insert_attribute_verify_results)
173 h.executemany(**verify_attribs)
174
175 if missing_files['action_id']:
176 h = rhnSQL.prepare(_query_insert_missing_verify_results)
177 h.executemany(**missing_files)
178
179 rhnSQL.commit()
180
181
182
183
186
187
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 res_re = re.compile("^(?P<ts>[\S]+)\s+(?P<attr>[cdglr]?)\s* (?P<filename>[\S]+)$")
208
209 m = res_re.match(response)
210
211 if not m:
212 raise InvalidResponseLine
213
214 ts, attr, filename = m.groups()
215
216
217 if ts == 'missing':
218 return {'filename': filename, 'missing': None}
219
220
221
222
223
224
225 if len(ts) < len(tests):
226 raise InvalidResponseLine
227
228 if not filename:
229 raise InvalidResponseLine
230
231 dict = {
232 'attrib': attr or None,
233 'filename': filename,
234 }
235
236 for i in range(len(tests)):
237 val = ts[i]
238 t_name = tests[i]
239 if val == t_name:
240 val = 'Y'
241 elif val == '.':
242 val = 'N'
243 elif val != '?':
244 raise InvalidResponseLine
245 dict["test_" + t_name] = val
246
247 return dict
248
249
254
255
256 -def update(server_id, action_id, data={}):
257 log_debug(3, server_id, action_id)
258
259 action_status = rhnFlags.get('action_status')
260
261 if action_status == 3:
262
263 kickstart_state = 'failed'
264 next_action_type = None
265 else:
266 kickstart_state = 'deployed'
267
268
269
270 try:
271 ks_session_type = server_kickstart.get_kickstart_session_type(server_id, action_id)
272 except rhnException:
273 re = sys.exc_info()[1]
274 ks_session_type = None
275
276 if ks_session_type is None:
277 next_action_type = "None"
278 elif ks_session_type == 'para_guest':
279 next_action_type = 'kickstart_guest.initiate'
280 else:
281 next_action_type = 'kickstart.initiate'
282
283 log_debug(4, "next_action_type: %s" % next_action_type)
284
285
286
287
288
289 if next_action_type != "None":
290 server_kickstart.update_kickstart_session(server_id, action_id,
291 action_status, kickstart_state=kickstart_state,
292 next_action_type=next_action_type)
293
294 _mark_dep_failures(server_id, action_id, data)
295
296
297 -def remove(server_id, action_id, data={}):
300
301
302 _query_delete_dep_failures = rhnSQL.Statement("""
303 delete from rhnActionPackageRemovalFailure
304 where server_id = :server_id and action_id = :action_id
305 """)
306 _query_insert_dep_failures = rhnSQL.Statement("""
307 insert into rhnActionPackageRemovalFailure (
308 server_id, action_id, name_id, evr_id, capability_id,
309 flags, suggested, sense)
310 values (
311 :server_id, :action_id, LOOKUP_PACKAGE_NAME(:name),
312 LOOKUP_EVR(:epoch, :version, :release),
313 LOOKUP_PACKAGE_CAPABILITY(:needs_name, :needs_version),
314 :flags, LOOKUP_PACKAGE_NAME(:suggested, :ignore_null), :sense)
315 """)
316
317
319 if not data:
320 log_debug(4, "Nothing to do")
321 return
322 failed_deps = data.get('failed_deps')
323 if not failed_deps:
324 log_debug(4, "No failed deps")
325 return
326
327 if not isinstance(failed_deps, ListType):
328
329 log_error("action_extra_data.packages.remove: server %s, action %s: "
330 "wrong type %s" % (server_id, action_id, type(failed_deps)))
331 return
332
333 inserts = {}
334 for f in ('server_id', 'action_id',
335 'name', 'version', 'release', 'epoch',
336 'needs_name', 'needs_version', 'ignore_null',
337 'flags', 'suggested', 'sense'):
338 inserts[f] = []
339
340 for failed_dep in failed_deps:
341 try:
342 pkg, needs_pkg, flags, suggested, sense = _check_dep(server_id,
343 action_id, failed_dep)
344 except InvalidDep:
345 continue
346
347 inserts['server_id'].append(server_id)
348 inserts['action_id'].append(action_id)
349 inserts['name'] .append(pkg[0])
350 inserts['version'].append(pkg[1])
351 inserts['release'].append(pkg[2])
352 inserts['epoch'].append(None)
353
354 inserts['needs_name'].append(needs_pkg[0])
355 inserts['needs_version'].append(needs_pkg[1])
356
357 inserts['flags'].append(flags)
358 inserts['suggested'].append(suggested)
359 inserts['ignore_null'].append(1)
360 inserts['sense'].append(sense)
361
362 h = rhnSQL.prepare(_query_delete_dep_failures)
363 rowcount = h.execute(server_id=server_id, action_id=action_id)
364 log_debug(5, "Removed old rows", rowcount)
365
366 h = rhnSQL.prepare(_query_insert_dep_failures)
367
368 rowcount = h.execute_bulk(inserts)
369 log_debug(5, "Inserted rows", rowcount)
370
371
373 log_debug(5, failed_dep)
374 if not failed_dep:
375 return
376 if not isinstance(failed_dep, ListType):
377
378 log_error("action_extra_data.packages.remove: server %s, action %s: "
379 "failed dep type error: %s" % (
380 server_id, action_id, type(failed_dep)))
381 raise InvalidDep
382
383
384 if len(failed_dep) < 5:
385 log_error("action_extra_data.packages.remove: server %s, action %s: "
386 "failed dep: not enough entries: %s" % (
387 server_id, action_id, len(failed_dep)))
388 raise InvalidDep
389
390 pkg, needs_pkg, flags, suggested, sense = failed_dep[:5]
391
392 if not isinstance(pkg, ListType) or len(pkg) < 3:
393 log_error("action_extra_data.packages.remove: server %s, action %s: "
394 "failed dep: bad package spec %s (type %s, len %s)" % (
395 server_id, action_id, pkg, type(pkg), len(pkg)))
396 raise InvalidDep
397 pkg = list(map(str, pkg[:3]))
398
399 if not isinstance(needs_pkg, ListType) or len(needs_pkg) < 2:
400 log_error("action_extra_data.packages.remove: server %s, action %s: "
401 "failed dep: bad needs package spec %s (type %s, len %s)" % (
402 server_id, action_id, needs_pkg, type(needs_pkg),
403 len(needs_pkg)))
404 raise InvalidDep
405 needs_pkg = list(map(str, needs_pkg[:2]))
406
407 if not isinstance(flags, IntType):
408 log_error("action_extra_data.packages.remove: server %s, action %s: "
409 "failed dep: bad flags type %s" % (server_id, action_id, type(flags)))
410 raise InvalidDep
411
412 if not isinstance(sense, IntType):
413 log_error("action_extra_data.packages.remove: server %s, action %s: "
414 "failed dep: bad sense type %s" % (server_id, action_id, type(sense)))
415 raise InvalidDep
416
417 return pkg, needs_pkg, flags, str(suggested), sense
418
419
421 if not data:
422 return
423 log_debug(2, "action_extra_data.packages.refresh_list: Should do something "
424 "useful with this data", server_id, action_id, data)
425
426
427 -def delta(server_id, action_id, data={}):
428 if not data:
429 return
430 log_debug(2, "action_extra_data.packages.delta: Should do something "
431 "useful with this data", server_id, action_id, data)
432
433
447
448
449
450
452 if action_status == 3:
453
454 return server_kickstart.update_kickstart_session(server_id,
455 action_id, action_status, kickstart_state='complete',
456 next_action_type=None)
457
458
459 ks_session_id = server_kickstart.get_kickstart_session_id(server_id,
460 action_id)
461
462 if ks_session_id is None:
463 return server_kickstart.update_kickstart_session(server_id,
464 action_id, action_status, kickstart_state='complete',
465 next_action_type=None)
466
467
468 server_profile = server_kickstart.get_server_package_profile(server_id)
469
470 server_kickstart.schedule_config_deploy(server_id, action_id,
471 ks_session_id, server_profile=server_profile)
472 return ks_session_id
473