4
# Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
5
# This file is part of GlusterFS.
7
# This file is licensed to you under your choice of the GNU Lesser
8
# General Public License, version 3 or any later version (LGPLv3 or
9
# later), or the GNU General Public License, version 2 (GPLv2), in all
10
# cases as published by the Free Software Foundation.
13
from __future__ import print_function
20
import SocketServer as socketserver
22
from argparse import ArgumentParser, RawDescriptionHelpFormatter
24
from eventtypes import all_events
27
from eventsapiconf import SERVER_ADDRESSv4, SERVER_ADDRESSv6, PID_FILE
28
from eventsapiconf import AUTO_BOOL_ATTRIBUTES, AUTO_INT_ATTRIBUTES
29
from utils import logger, PidFile, PidFileLockFailed, boolify
31
# Subclass so that specifically IPv4 packets are captured
32
class UDPServerv4(socketserver.ThreadingUDPServer):
33
address_family = socket.AF_INET
35
# Subclass so that specifically IPv6 packets are captured
36
class UDPServerv6(socketserver.ThreadingUDPServer):
37
address_family = socket.AF_INET6
39
class GlusterEventsRequestHandler(socketserver.BaseRequestHandler):
42
data = self.request[0].strip()
43
if sys.version_info >= (3,):
44
data = self.request[0].strip().decode("utf-8")
46
logger.debug("EVENT: {0} from {1}".format(repr(data),
47
self.client_address[0]))
49
# Event Format <TIMESTAMP> <TYPE> <DETAIL>
50
ts, key, value = data.split(" ", 2)
52
logger.warn("Invalid Event Format {0}".format(data))
57
# Format key=value;key=value
58
data_dict = dict(x.split('=') for x in value.split(';'))
60
logger.warn("Unable to parse Event {0}".format(data))
63
for k, v in data_dict.items():
65
if k in AUTO_BOOL_ATTRIBUTES:
66
data_dict[k] = boolify(v)
67
if k in AUTO_INT_ATTRIBUTES:
70
# Auto Conversion failed, Retain the old value
74
# Event Type to Function Map, Received event data will be in
75
# the form <TIMESTAMP> <TYPE> <DETAIL>, Get Event name for the
76
# received Type/Key and construct a function name starting with
77
# handle_ For example: handle_event_volume_create
78
func_name = "handle_" + all_events[int(key)].lower()
80
# This type of Event is not handled?
81
logger.warn("Unhandled Event: {0}".format(key))
84
if func_name is not None:
85
# Get function from handlers module
86
func = getattr(handlers, func_name, None)
87
# If func is None, then handler unimplemented for that event.
89
func(ts, int(key), data_dict)
91
# Generic handler, broadcast whatever received
92
handlers.generic_handler(ts, int(key), data_dict)
95
def signal_handler_sigusr2(sig, frame):
97
utils.restart_webhook_pool()
100
def UDP_server_thread(sock):
104
def init_event_server():
107
utils.init_webhook_pool()
109
port = utils.get_config("port")
111
sys.stderr.write("Unable to get Port details from Config\n")
114
# Creating the Eventing Server, UDP Server for IPv4 packets
116
serverv4 = UDPServerv4((SERVER_ADDRESSv4, port),
117
GlusterEventsRequestHandler)
118
except socket.error as e:
119
sys.stderr.write("Failed to start Eventsd for IPv4: {0}\n".format(e))
122
server_thread1 = threading.Thread(target=UDP_server_thread,
124
server_thread1.start()
125
# Creating the Eventing Server, UDP Server for IPv6 packets
127
serverv6 = UDPServerv6((SERVER_ADDRESSv6, port),
128
GlusterEventsRequestHandler)
129
except socket.error as e:
130
sys.stderr.write("Failed to start Eventsd for IPv6: {0}\n".format(e))
133
server_thread2 = threading.Thread(target=UDP_server_thread,
135
server_thread2.start()
136
if serverv4 is None and serverv6 is None:
137
sys.stderr.write("Failed to start Eventsd: {0}\n".format(e))
142
parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
144
parser.add_argument("-p", "--pid-file", help="PID File",
147
return parser.parse_args()
153
with PidFile(args.pid_file):
155
except PidFileLockFailed as e:
156
sys.stderr.write("Failed to get lock for pid file({0}): {1}".format(
158
except KeyboardInterrupt:
162
if __name__ == "__main__":
163
signal.signal(signal.SIGUSR2, signal_handler_sigusr2)