mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 06:25:34 +00:00
more command handling for CCSession stuff
added CCSession to Boss module removed hard-coded boss stuff from cmd-ctrld and bindctl removed a few unnecessary subscriptions from default channels git-svn-id: svn://bind10.isc.org/svn/bind10/branches/parkinglot@576 e5f2f494-b856-4b98-b285-d166d9295462
This commit is contained in:
@@ -93,20 +93,28 @@ class BoB:
|
|||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("[XX] handling new config:")
|
print("[XX] handling new config:")
|
||||||
print(new_config)
|
print(new_config)
|
||||||
|
# TODO
|
||||||
|
|
||||||
def command_handler(self, command):
|
def command_handler(self, command):
|
||||||
|
# a command is of the form [ "command", { "arg1": arg1, "arg2": arg2 } ]
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("[XX] Boss got command:")
|
print("[XX] Boss got command:")
|
||||||
print(command)
|
print(command)
|
||||||
answer = None
|
answer = None
|
||||||
if "command" in command:
|
if type(command) != list or len(command) == 0:
|
||||||
cmd = command["command"]
|
|
||||||
if cmd == "shutdown":
|
|
||||||
self.shutdown()
|
|
||||||
else:
|
|
||||||
answer = { "result": [ 1, "unknown command: " + cmd ] }
|
|
||||||
else:
|
|
||||||
answer = { "result": [ 1, "bad command" ] }
|
answer = { "result": [ 1, "bad command" ] }
|
||||||
|
else:
|
||||||
|
cmd = command[0]
|
||||||
|
if cmd == "shutdown":
|
||||||
|
print("[XX] got shutdown command")
|
||||||
|
self.runnable = False
|
||||||
|
answer = { "result": [ 0 ] }
|
||||||
|
elif cmd == "print_message":
|
||||||
|
if len(command) > 1 and type(command[1]) == dict and "message" in command[1]:
|
||||||
|
print(command[1]["message"])
|
||||||
|
answer = { "result": [ 0 ] }
|
||||||
|
else:
|
||||||
|
answer = { "result": [ 1, "Unknown command" ] }
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
@@ -140,7 +148,7 @@ class BoB:
|
|||||||
self.cc_session = ISC.CC.Session(self.c_channel_port)
|
self.cc_session = ISC.CC.Session(self.c_channel_port)
|
||||||
except ISC.CC.session.SessionError:
|
except ISC.CC.session.SessionError:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.cc_session.group_subscribe("Boss", "boss")
|
#self.cc_session.group_subscribe("Boss", "boss")
|
||||||
|
|
||||||
# start the configuration manager
|
# start the configuration manager
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
@@ -161,7 +169,7 @@ class BoB:
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("[XX] starting ccsession")
|
print("[XX] starting ccsession")
|
||||||
self.ccs = isc.config.CCSession("bob", "bob.spec", self.config_handler, self.command_handler)
|
self.ccs = isc.config.CCSession("Boss", "bob.spec", self.config_handler, self.command_handler)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("[XX] ccsession started")
|
print("[XX] ccsession started")
|
||||||
|
|
||||||
@@ -280,56 +288,60 @@ class BoB:
|
|||||||
else:
|
else:
|
||||||
sys.stdout.write("Unknown child pid %d exited.\n" % pid)
|
sys.stdout.write("Unknown child pid %d exited.\n" % pid)
|
||||||
|
|
||||||
def recv_and_process_cc_msg(self):
|
# 'old' command style, uncommented for now
|
||||||
"""Receive and process the next message on the c-channel,
|
# move the handling below move to command_handler please
|
||||||
if any."""
|
#def recv_and_process_cc_msg(self):
|
||||||
msg, envelope = self.cc_session.group_recvmsg(False)
|
#"""Receive and process the next message on the c-channel,
|
||||||
print(msg)
|
#if any."""
|
||||||
if msg is None:
|
#self.ccs.checkCommand()
|
||||||
return
|
#msg, envelope = self.cc_session.group_recvmsg(False)
|
||||||
if not ((type(msg) is dict) and (type(envelope) is dict)):
|
#print(msg)
|
||||||
if self.verbose:
|
#if msg is None:
|
||||||
sys.stdout.write("Non-dictionary message\n")
|
# return
|
||||||
return
|
#if not ((type(msg) is dict) and (type(envelope) is dict)):
|
||||||
if not "command" in msg:
|
# if self.verbose:
|
||||||
if self.verbose:
|
# sys.stdout.write("Non-dictionary message\n")
|
||||||
if "msg" in envelope:
|
# return
|
||||||
del envelope['msg']
|
#if not "command" in msg:
|
||||||
sys.stdout.write("Unknown message received\n")
|
# if self.verbose:
|
||||||
sys.stdout.write(pprint.pformat(envelope) + "\n")
|
# if "msg" in envelope:
|
||||||
sys.stdout.write(pprint.pformat(msg) + "\n")
|
# del envelope['msg']
|
||||||
return
|
# sys.stdout.write("Unknown message received\n")
|
||||||
cmd = msg['command']
|
# sys.stdout.write(pprint.pformat(envelope) + "\n")
|
||||||
if not (type(cmd) is list):
|
# sys.stdout.write(pprint.pformat(msg) + "\n")
|
||||||
if self.verbose:
|
# return
|
||||||
sys.stdout.write("Non-list command\n")
|
|
||||||
return
|
|
||||||
|
|
||||||
|
#cmd = msg['command']
|
||||||
|
#if not (type(cmd) is list):
|
||||||
|
# if self.verbose:
|
||||||
|
# sys.stdout.write("Non-list command\n")
|
||||||
|
# return
|
||||||
|
#
|
||||||
# done checking and extracting... time to execute the command
|
# done checking and extracting... time to execute the command
|
||||||
if cmd[0] == "shutdown":
|
#if cmd[0] == "shutdown":
|
||||||
if self.verbose:
|
# if self.verbose:
|
||||||
sys.stdout.write("shutdown command received\n")
|
# sys.stdout.write("shutdown command received\n")
|
||||||
self.runnable = False
|
# self.runnable = False
|
||||||
# XXX: reply here?
|
# # XXX: reply here?
|
||||||
elif cmd[0] == "getProcessList":
|
#elif cmd[0] == "getProcessList":
|
||||||
if self.verbose:
|
# if self.verbose:
|
||||||
sys.stdout.write("getProcessList command received\n")
|
# sys.stdout.write("getProcessList command received\n")
|
||||||
live_processes = [ ]
|
# live_processes = [ ]
|
||||||
for proc_info in processes:
|
# for proc_info in processes:
|
||||||
live_processes.append({ "name": proc_info.name,
|
# live_processes.append({ "name": proc_info.name,
|
||||||
"args": proc_info.args,
|
# "args": proc_info.args,
|
||||||
"pid": proc_info.pid, })
|
# "pid": proc_info.pid, })
|
||||||
dead_processes = [ ]
|
# dead_processes = [ ]
|
||||||
for proc_info in dead_processes:
|
# for proc_info in dead_processes:
|
||||||
dead_processes.append({ "name": proc_info.name,
|
# dead_processes.append({ "name": proc_info.name,
|
||||||
"args": proc_info.args, })
|
# "args": proc_info.args, })
|
||||||
cc.group_reply(envelope, { "response": cmd,
|
# cc.group_reply(envelope, { "response": cmd,
|
||||||
"sent": msg["sent"],
|
# "sent": msg["sent"],
|
||||||
"live_processes": live_processes,
|
# "live_processes": live_processes,
|
||||||
"dead_processes": dead_processes, })
|
# "dead_processes": dead_processes, })
|
||||||
else:
|
#else:
|
||||||
if self.verbose:
|
# if self.verbose:
|
||||||
sys.stdout.write("Unknown command %s\n" % str(cmd))
|
# sys.stdout.write("Unknown command %s\n" % str(cmd))
|
||||||
|
|
||||||
def restart_processes(self):
|
def restart_processes(self):
|
||||||
"""Restart any dead processes."""
|
"""Restart any dead processes."""
|
||||||
@@ -427,7 +439,7 @@ def main():
|
|||||||
# In our main loop, we check for dead processes or messages
|
# In our main loop, we check for dead processes or messages
|
||||||
# on the c-channel.
|
# on the c-channel.
|
||||||
wakeup_fd = wakeup_pipe[0]
|
wakeup_fd = wakeup_pipe[0]
|
||||||
cc_fd = boss_of_bind.cc_session._socket.fileno()
|
ccs_fd = boss_of_bind.ccs.getSocket().fileno()
|
||||||
while boss_of_bind.runnable:
|
while boss_of_bind.runnable:
|
||||||
# XXX: get time for next restart for timeout
|
# XXX: get time for next restart for timeout
|
||||||
|
|
||||||
@@ -435,7 +447,7 @@ def main():
|
|||||||
# even if they are resumable, so we have to catch
|
# even if they are resumable, so we have to catch
|
||||||
# the exception
|
# the exception
|
||||||
try:
|
try:
|
||||||
(rlist, wlist, xlist) = select.select([wakeup_fd, cc_fd], [], [])
|
(rlist, wlist, xlist) = select.select([wakeup_fd, ccs_fd], [], [])
|
||||||
except select.error as err:
|
except select.error as err:
|
||||||
if err.args[0] == errno.EINTR:
|
if err.args[0] == errno.EINTR:
|
||||||
(rlist, wlist, xlist) = ([], [], [])
|
(rlist, wlist, xlist) = ([], [], [])
|
||||||
@@ -444,8 +456,8 @@ def main():
|
|||||||
break
|
break
|
||||||
|
|
||||||
for fd in rlist + xlist:
|
for fd in rlist + xlist:
|
||||||
if fd == cc_fd:
|
if fd == ccs_fd:
|
||||||
boss_of_bind.recv_and_process_cc_msg()
|
boss_of_bind.ccs.checkCommand()
|
||||||
elif fd == wakeup_fd:
|
elif fd == wakeup_fd:
|
||||||
os.read(wakeup_fd, 32)
|
os.read(wakeup_fd, 32)
|
||||||
|
|
||||||
|
@@ -50,21 +50,10 @@ def prepare_config_commands(tool):
|
|||||||
|
|
||||||
tool.add_module_info(module)
|
tool.add_module_info(module)
|
||||||
|
|
||||||
def prepare_boss_command(tool):
|
|
||||||
# Prepare the command 'shutdown' for Boss, this is one 'hardcode' exception.
|
|
||||||
shutdown_cmd = CommandInfo(name = 'shutdown', desc = "stop one module",
|
|
||||||
need_inst_param = False)
|
|
||||||
boss_module = ModuleInfo(name = "Boss", desc = "boss of bind10")
|
|
||||||
boss_module.add_command(shutdown_cmd)
|
|
||||||
tool.add_module_info(boss_module)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
tool = BindCmdInterpreter("localhost:8080")
|
tool = BindCmdInterpreter("localhost:8080")
|
||||||
prepare_config_commands(tool)
|
prepare_config_commands(tool)
|
||||||
prepare_boss_command(tool)
|
|
||||||
tool.run()
|
tool.run()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
@@ -108,7 +108,7 @@ class CommandControl():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cc = ISC.CC.Session()
|
self.cc = ISC.CC.Session()
|
||||||
self.cc.group_subscribe('Cmd-Ctrld')
|
self.cc.group_subscribe('Cmd-Ctrld')
|
||||||
self.cc.group_subscribe('Boss', 'Cmd-Ctrld')
|
#self.cc.group_subscribe('Boss', 'Cmd-Ctrld')
|
||||||
self.command_spec = self.get_cmd_specification()
|
self.command_spec = self.get_cmd_specification()
|
||||||
self.config_spec = self.get_data_specification()
|
self.config_spec = self.get_data_specification()
|
||||||
self.config_data = self.get_config_data()
|
self.config_data = self.get_config_data()
|
||||||
@@ -149,11 +149,6 @@ class CommandControl():
|
|||||||
msg = {'command' : content}
|
msg = {'command' : content}
|
||||||
print('cmd-ctrld send command \'%s\' to %s' %(command_name, module_name))
|
print('cmd-ctrld send command \'%s\' to %s' %(command_name, module_name))
|
||||||
try:
|
try:
|
||||||
# Do special for Boss shutdown. TODO, avoid specicialism
|
|
||||||
if module_name == 'Boss' and command_name == 'shutdown':
|
|
||||||
self.cc.group_sendmsg(msg, module_name, 'boss')
|
|
||||||
return {}
|
|
||||||
|
|
||||||
self.cc.group_sendmsg(msg, module_name)
|
self.cc.group_sendmsg(msg, module_name)
|
||||||
answer, env = self.cc.group_recvmsg(False)
|
answer, env = self.cc.group_recvmsg(False)
|
||||||
if answer and 'result' in answer.keys() and type(answer['result']) == list:
|
if answer and 'result' in answer.keys() and type(answer['result']) == list:
|
||||||
|
@@ -70,7 +70,7 @@ my_command_handler(isc::data::ElementPtr command)
|
|||||||
{
|
{
|
||||||
isc::data::ElementPtr answer = isc::data::Element::createFromString("{ \"result\": [0] }");
|
isc::data::ElementPtr answer = isc::data::Element::createFromString("{ \"result\": [0] }");
|
||||||
|
|
||||||
cout << "[XX] Handle command: " << endl << command->str() << endl;
|
cout << "[XX] Parkinglot handle command: " << endl << command->str() << endl;
|
||||||
if (command->get(0)->stringValue() == "print_message")
|
if (command->get(0)->stringValue() == "print_message")
|
||||||
{
|
{
|
||||||
cout << command->get(1)->get("message") << endl;
|
cout << command->get(1)->get("message") << endl;
|
||||||
|
@@ -90,8 +90,8 @@ CommandSession::CommandSession(std::string module_name,
|
|||||||
|
|
||||||
session_.establish();
|
session_.establish();
|
||||||
session_.subscribe(module_name, "*");
|
session_.subscribe(module_name, "*");
|
||||||
session_.subscribe("Boss", "*");
|
//session_.subscribe("Boss", "*");
|
||||||
session_.subscribe("statistics", "*");
|
//session_.subscribe("statistics", "*");
|
||||||
read_data_definition(spec_file_name);
|
read_data_definition(spec_file_name);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
// send the data specification
|
// send the data specification
|
||||||
|
@@ -91,6 +91,9 @@ class ConfigManager:
|
|||||||
cmd = msg["command"]
|
cmd = msg["command"]
|
||||||
try:
|
try:
|
||||||
if cmd[0] == "get_commands":
|
if cmd[0] == "get_commands":
|
||||||
|
print("[XX] bind-cfgd got get_commands");
|
||||||
|
print("[XX] sending:")
|
||||||
|
print(self.commands)
|
||||||
answer["result"] = [ 0, self.commands ]
|
answer["result"] = [ 0, self.commands ]
|
||||||
elif cmd[0] == "get_data_spec":
|
elif cmd[0] == "get_data_spec":
|
||||||
if len(cmd) > 1 and cmd[1]['module_name'] != '':
|
if len(cmd) > 1 and cmd[1]['module_name'] != '':
|
||||||
@@ -163,6 +166,9 @@ class ConfigManager:
|
|||||||
raise ie
|
raise ie
|
||||||
elif "data_specification" in msg:
|
elif "data_specification" in msg:
|
||||||
# todo: validate? (no direct access to spec as
|
# todo: validate? (no direct access to spec as
|
||||||
|
# todo: use DataDefinition class?
|
||||||
|
print("[XX] bind-cfgd got specification:")
|
||||||
|
print(msg["data_specification"])
|
||||||
spec = msg["data_specification"]
|
spec = msg["data_specification"]
|
||||||
if "config_data" in spec:
|
if "config_data" in spec:
|
||||||
self.set_config(spec["module_name"], spec["config_data"])
|
self.set_config(spec["module_name"], spec["config_data"])
|
||||||
|
@@ -41,9 +41,16 @@ class CCSession:
|
|||||||
self.__sendSpec()
|
self.__sendSpec()
|
||||||
self.__getFullConfig()
|
self.__getFullConfig()
|
||||||
|
|
||||||
#do we need getSocket()?
|
def getSocket(self):
|
||||||
|
"""Returns the socket from the command channel session"""
|
||||||
|
return self._session._socket
|
||||||
|
|
||||||
def checkCommand():
|
def getSession(self):
|
||||||
|
"""Returns the command-channel session that is used, so the
|
||||||
|
application can use it directly"""
|
||||||
|
return self._session
|
||||||
|
|
||||||
|
def checkCommand(self):
|
||||||
"""Check whether there is a command on the channel.
|
"""Check whether there is a command on the channel.
|
||||||
Call the command callback function if so"""
|
Call the command callback function if so"""
|
||||||
msg, env = self._session.group_recvmsg(False)
|
msg, env = self._session.group_recvmsg(False)
|
||||||
|
Reference in New Issue
Block a user