4
from datetime import datetime
6
from landscape.lib.process import ProcessInformation
7
from landscape.manager.manager import ManagerPlugin
10
class ProcessNotFoundError(Exception):
14
class ProcessMismatchError(Exception):
18
class SignalProcessError(Exception):
22
class ProcessKiller(ManagerPlugin):
24
A management plugin that signals processes upon receiving a message from
27
def __init__(self, process_info=None):
28
if process_info is None:
29
process_info = ProcessInformation()
30
self.process_info = process_info
32
def register(self, registry):
33
super(ProcessKiller, self).register(registry)
34
registry.register_message("signal-process", self._handle_signal_process)
36
def _handle_signal_process(self, message):
37
self.call_with_operation_result(message, self.signal_process,
38
message["pid"], message["name"],
39
message["start-time"],
42
def signal_process(self, pid, name, start_time, signame):
43
logging.info("Sending %s signal to the process with PID %d.",
45
process_info = self.process_info.get_process_info(pid)
47
start_time = datetime.utcfromtimestamp(start_time)
48
message = ("The process %s with PID %d that started at %s UTC was "
49
"not found") % (name, pid, start_time)
50
raise ProcessNotFoundError(message)
51
elif abs(process_info["start-time"] - start_time) > 2:
52
# We don't check that the start time matches precisely because
53
# the way we obtain boot times isn't very precise, and this may
54
# cascade into having imprecise process start times.
55
expected_time = datetime.utcfromtimestamp(start_time)
56
actual_time = datetime.utcfromtimestamp(process_info["start-time"])
57
message = ("The process %s with PID %d that started at "
58
"%s UTC was not found. A process with the same "
59
"PID that started at %s UTC was found and not "
60
"sent the %s signal") % (name, pid, expected_time,
62
raise ProcessMismatchError(message)
64
signum = getattr(signal, "SIG%s" % (signame,))
68
# XXX Nothing is indicating what the problem was.
69
message = ("Attempting to send the %s signal to the process "
70
"%s with PID %d failed") % (signame, name, pid)
71
raise SignalProcessError(message)