11
11
from landscape.lib.twisted_util import gather_results
12
12
from landscape.lib.fetch import fetch_async
14
from landscape.package.taskhandler import PackageTaskHandler, run_task_handler
14
from landscape.package.taskhandler import (
15
PackageTaskHandlerConfiguration, PackageTaskHandler, run_task_handler)
15
16
from landscape.package.store import UnknownHashIDRequest
19
20
MAX_UNKNOWN_HASHES_PER_REQUEST = 500
23
class PackageReporterConfiguration(PackageTaskHandlerConfiguration):
24
"""Specialized configuration for the Landscape package-reporter."""
26
def make_parser(self):
28
Specialize L{Configuration.make_parser}, adding options
29
reporter-specific options.
31
parser = super(PackageReporterConfiguration, self).make_parser()
32
parser.add_option("--force-smart-update", default=False,
34
help="Force running smart-update.")
22
38
class PackageReporter(PackageTaskHandler):
23
39
"""Report information about the system packages.
26
42
@cvar smart_update_interval: Time interval in minutes to pass to
27
43
the C{--after} command line option of C{smart-update}.
45
config_factory = PackageReporterConfiguration
29
47
queue_name = "reporter"
30
49
smart_update_interval = 60
31
50
smart_update_filename = "/usr/lib/landscape/smart-update"
136
156
@return: a deferred returning (out, err, code)
158
if self._config.force_smart_update:
161
args = ("--after", "%d" % self.smart_update_interval)
138
162
result = getProcessOutputAndValue(self.smart_update_filename,
139
args=("--after", "%d" %
140
self.smart_update_interval))
142
165
def callback((out, err, code)):
143
166
# smart-update --after N will exit with error code 1 when it
216
238
# This problem would happen for example when switching the client from
217
239
# one Landscape server to another, because the uuid-changed event would
218
240
# cause a resynchronize task to be created by the monitor. See #417122.
220
#self._store.clear_hash_id_requests()
222
242
return succeed(None)
328
348
request = self._store.add_hash_id_request(unknown_hashes)
329
349
message["request-id"] = request.id
330
350
result = self._broker.send_message(message, True)
331
352
def set_message_id(message_id):
332
353
request.message_id = message_id
333
355
def send_message_failed(failure):
336
359
return result.addCallbacks(set_message_id, send_message_failed)
338
361
def detect_changes(self):
343
366
- are now installed, and were not;
344
367
- are now available, and were not;
368
- are now locked, and were not;
345
369
- were previously available but are not anymore;
346
370
- were previously installed but are not anymore;
371
- were previously locked but are not anymore;
373
Additionally it will report package locks that:
375
- are now set, and were not;
376
- were previously set but are not anymore;
348
378
In all cases, the server is notified of the new situation
349
379
with a "packages" message.
353
383
old_installed = set(self._store.get_installed())
354
384
old_available = set(self._store.get_available())
355
385
old_upgrades = set(self._store.get_available_upgrades())
386
old_locked = set(self._store.get_locked())
357
388
current_installed = set()
358
389
current_available = set()
359
390
current_upgrades = set()
391
current_locked = set()
361
393
for package in self._facade.get_packages():
362
394
hash = self._facade.get_package_hash(package)
422
for package in self._facade.get_locked_packages():
423
hash = self._facade.get_package_hash(package)
424
id = self._store.get_hash_id(hash)
426
current_locked.add(id)
390
428
new_installed = current_installed - old_installed
391
429
new_available = current_available - old_available
392
430
new_upgrades = current_upgrades - old_upgrades
431
new_locked = current_locked - old_locked
394
433
not_installed = old_installed - current_installed
395
434
not_available = old_available - current_available
396
435
not_upgrades = old_upgrades - current_upgrades
436
not_locked = old_locked - current_locked
399
439
if new_installed:
426
472
logging.info("Queuing message with changes in known packages: "
427
473
"%d installed, %d available, %d available upgrades, "
428
"%d not installed, %d not available, %d not "
429
"available upgrades."
474
"%d locked, %d not installed, %d not available, "
475
"%d not available upgrades, %d not locked."
430
476
% (len(new_installed), len(new_available),
431
len(new_upgrades), len(not_installed),
432
len(not_available), len(not_upgrades)))
477
len(new_upgrades), len(new_locked),
478
len(not_installed), len(not_available),
479
len(not_upgrades), len(not_locked)))
434
481
def update_currently_known(result):
435
482
if new_installed:
438
485
self._store.remove_installed(not_installed)
439
486
if new_available:
440
487
self._store.add_available(new_available)
489
self._store.add_locked(new_locked)
441
490
if not_available:
442
491
self._store.remove_available(not_available)
444
493
self._store.add_available_upgrades(new_upgrades)
446
495
self._store.remove_available_upgrades(not_upgrades)
497
self._store.remove_locked(not_locked)
499
result.addCallback(update_currently_known)
503
def detect_package_locks_changes(self):
504
"""Detect changes in known package locks.
506
This method will verify if there are package locks that:
508
- are now set, and were not;
509
- were previously set but are not anymore;
511
In all cases, the server is notified of the new situation
512
with a "packages" message.
514
old_package_locks = set(self._store.get_package_locks())
515
current_package_locks = set(self._facade.get_package_locks())
517
set_package_locks = current_package_locks - old_package_locks
518
unset_package_locks = old_package_locks - current_package_locks
521
if set_package_locks:
522
message["created"] = sorted(set_package_locks)
523
if unset_package_locks:
524
message["deleted"] = sorted(unset_package_locks)
527
result = succeed(None)
529
message["type"] = "package-locks"
531
result = self._broker.send_message(message, True)
533
logging.info("Queuing message with changes in known package locks:"
534
" %d created, %d deleted." %
535
(len(set_package_locks), len(unset_package_locks)))
537
def update_currently_known(result):
538
if set_package_locks:
539
self._store.add_package_locks(set_package_locks)
540
if unset_package_locks:
541
self._store.remove_package_locks(unset_package_locks)
448
543
result.addCallback(update_currently_known)