diff --git a/call-control b/call-control index 56f8e91..2782a66 100755 --- a/call-control +++ b/call-control @@ -1,90 +1,90 @@ -#!/usr/bin/env python +#!/usr/bin/python2 """Call control engine for OpenSIPS""" if __name__ == '__main__': import callcontrol import sys from application import log from application.process import process, ProcessError from argparse import ArgumentParser name = 'call-control' fullname = 'SIP call-control engine' description = 'Implementation of a call-control engine for SIP' process.configuration.user_directory = None process.configuration.subdirectory = 'callcontrol' process.runtime.subdirectory = 'callcontrol' parser = ArgumentParser(usage='%(prog)s [options]') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(callcontrol.__version__)) parser.add_argument('--systemd', action='store_true', help='run as a systemd simple service and log to journal') parser.add_argument('--no-fork', action='store_false', dest='fork', help='run in the foreground and log to the terminal') parser.add_argument('--config-dir', dest='config_directory', default=None, help='the configuration directory ({})'.format(process.configuration.system_directory), metavar='PATH') parser.add_argument('--runtime-dir', dest='runtime_directory', default=None, help='the runtime directory ({})'.format(process.runtime.directory), metavar='PATH') parser.add_argument('--debug', action='store_true', help='enable verbose logging') parser.add_argument('--debug-memory', action='store_true', help='enable memory debugging') options = parser.parse_args() log.Formatter.prefix_format = '{record.levelname:<8s} ' if options.config_directory is not None: process.configuration.local_directory = options.config_directory if options.runtime_directory is not None: process.runtime.directory = options.runtime_directory try: process.runtime.create_directory() except ProcessError as e: log.critical('Cannot start %s: %s', fullname, e) sys.exit(1) if options.systemd: from systemd.journal import JournalHandler log.set_handler(JournalHandler(SYSLOG_IDENTIFIER=name)) log.capture_output() elif options.fork: try: process.daemonize(pidfile='{}.pid'.format(name)) except ProcessError, e: log.critical('Cannot start %s: %s', fullname, e) sys.exit(1) log.use_syslog(name) log.info('Starting %s %s', fullname, callcontrol.__version__) try: process.wait_for_network(wait_time=10, wait_message='Waiting for network to become available...') except KeyboardInterrupt: sys.exit(0) except RuntimeError as e: log.critical('Cannot start %s: %s' % (fullname, e)) sys.exit(1) from callcontrol.controller import CallControlServer if options.debug: log.level.current = log.level.DEBUG if options.debug_memory: from application.debug.memory import memory_dump try: server = CallControlServer() except Exception, e: log.critical('Could not create %s: %s', fullname, e) if type(e) is not RuntimeError: log.exception() sys.exit(1) try: server.run() except Exception, e: log.critical('Could not run %s: %s', fullname, e) if type(e) is not RuntimeError: log.exception() if options.debug_memory: memory_dump() diff --git a/call-control-cli b/call-control-cli index e1d614d..3ac773e 100755 --- a/call-control-cli +++ b/call-control-cli @@ -1,117 +1,117 @@ -#!/usr/bin/env python +#!/usr/bin/python2 import callcontrol import socket import sys from application import log from application.process import process from argparse import ArgumentParser class CallControlCommand(object): def __init__(self, command, **kw): self.command = command self.kw = kw def __str__(self): arguments = [self.command] arguments.extend('{}: {}'.format(key, value) for key, value in self.kw.items()) return '\r\n'.join(arguments) + '\r\n\r\n' def execute(self): target = process.runtime.file('socket') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: # noinspection PyShadowingNames try: sock.connect(target) sock.sendall(str(self)) response = '' while True: data = sock.recv(4096) response += data if not data or data.endswith('\r\n\r\n'): break except socket.error as e: raise RuntimeError('could not send command to {}: {}'.format(target, e)) finally: sock.close() for line in response.rstrip().splitlines(): print(line) @classmethod def handler(cls, options): raise NotImplementedError class ListCommand(CallControlCommand): def __init__(self, user=None): if user is not None: kw = dict(command='debug', show='sessions', user=user) else: kw = dict(command='debug', show='sessions') super(ListCommand, self).__init__(**kw) @classmethod def handler(cls, options): return cls(options.user).execute() class ShowCommand(CallControlCommand): def __init__(self, call_id): super(ShowCommand, self).__init__(command='debug', show='session', callid=call_id) @classmethod def handler(cls, options): return cls(options.call_id).execute() class TerminateCommand(CallControlCommand): def __init__(self, call_id): super(TerminateCommand, self).__init__(command='terminate', callid=call_id) @classmethod def handler(cls, options): return cls(options.call_id).execute() if __name__ == '__main__': name = 'call-control-cli' description = 'Command line interface tool for call-control' log.Formatter.prefix_format = '{record.levelname:<8s} ' process.configuration.user_directory = None process.configuration.subdirectory = 'callcontrol' process.runtime.subdirectory = 'callcontrol' parser = ArgumentParser(description="This script can issue commands to a running instance of a call-control server. Use '%(prog)s COMMAND --help' for help on a specific command.") parser.add_argument('--version', action='version', version='%(prog)s {}'.format(callcontrol.__version__)) parser.add_argument('--runtime-dir', dest='runtime_directory', default=None, help='the runtime directory ({})'.format(process.runtime.directory), metavar='PATH') subparsers = parser.add_subparsers(title='supported commands', dest='command') parser_list = subparsers.add_parser('list', help='list existing sessions') parser_list.add_argument('user', nargs='?', help='optional user to filter results by') parser_list.set_defaults(handler=ListCommand.handler) parser_show = subparsers.add_parser('show', help='show details about a specific session') parser_show.add_argument('call_id', help='the call-id for the session') parser_show.set_defaults(handler=ShowCommand.handler) parser_terminate = subparsers.add_parser('terminate', help='terminate a specific session') parser_terminate.add_argument('call_id', help='the call-id for the session') parser_terminate.set_defaults(handler=TerminateCommand.handler) args = parser.parse_args() if args.runtime_directory is not None: process.runtime.directory = args.runtime_directory try: args.handler(args) except Exception as e: log.critical('Failed to execute command: {}'.format(e)) sys.exit(1) diff --git a/setup.py b/setup.py index ae12cf2..efa73bd 100755 --- a/setup.py +++ b/setup.py @@ -1,31 +1,31 @@ -#!/usr/bin/python +#!/usr/bin/python2 import callcontrol from distutils.core import setup setup( name='callcontrol', version=callcontrol.__version__, description='SIP call control engine', long_description='Call control engine for OpenSIPS', url='http://callcontrol.ag-projects.com', license='GPLv2', author='AG Projects', author_email='support@ag-projects.com', platforms=['Platform Independent'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Service Providers', 'License :: GNU General Public License 2 (GPLv2)', 'Operating System :: OS Independent', 'Programming Language :: Python' ], data_files=[('/etc/callcontrol', ['config.ini.sample'])], packages=['callcontrol', 'callcontrol.rating', 'callcontrol.rating.backends'], scripts=['call-control', 'call-control-cli'] )