#!/usr/bin/python import os, sys import tempfile from time import time, sleep import subprocess, shlex, multiprocessing from argparse import ArgumentParser from distutils.dir_util import mkpath import signal def fail(msg): print(msg) sys.exit(-1) if os.getuid() != 0: fail('Please run this program as root/with sudo') cur_dir = os.path.abspath(os.path.dirname(__file__)) server_path = os.path.join(cur_dir, 'automation', 'trex_control_plane', 'server') if server_path not in sys.path: sys.path.append(server_path) ext_libs_path = os.path.join(cur_dir, 'external_libs') if ext_libs_path not in sys.path: sys.path.append(ext_libs_path) if 'start-live' not in sys.argv: import CCustomLogger CCustomLogger.setup_daemon_logger('TRexServer', '/var/log/trex/trex_daemon_server.log') import trex_server import netstat try: from termstyle import termstyle except ImportError: import termstyle def get_daemon_pid(): pid = None for conn in netstat.netstat(): if conn[2] == '0.0.0.0' and int(conn[3]) == args.daemon_port and conn[6] == 'LISTEN': pid = conn[7] if pid is None: raise Exception('Found the connection, but could not determine pid: %s' % conn) break return pid # faster variant of get_daemon_pid def is_running(): for conn in netstat.netstat(with_pid = False): if conn[2] == '0.0.0.0' and int(conn[3]) == args.daemon_port and conn[6] == 'LISTEN': return True return False def show_daemon_status(): if is_running(): print(termstyle.green('TRex server daemon is running')) else: print(termstyle.red('TRex server daemon is NOT running')) def start_daemon(): if is_running(): print(termstyle.red('TRex server daemon is already running')) return # Usual daemon will die with current process, detach it with double fork # https://www.safaribooksonline.com/library/view/python-cookbook/0596001673/ch06s08.html pid = os.fork() if pid > 0: for i in range(50): if is_running(): print(termstyle.green('TRex server daemon is started')) os._exit(0) sleep(0.1) fail(termstyle.red('TRex server daemon failed to run')) os.setsid() pid = os.fork() if pid > 0: os._exit(0) trex_server.do_main_program() def start_live(): if is_running(): fail(termstyle.red('TRex server daemon is already running')) trex_server.do_main_program() def restart_daemon(): if is_running(): kill_daemon() sleep(0.5) start_daemon() def kill_daemon(): pid = get_daemon_pid() if not pid: print(termstyle.red('TRex server daemon is NOT running')) return True pid = int(pid) for sig in (signal.SIGTERM, signal.SIGKILL): os.kill(pid, sig) for i in range(50): if not is_running(): print(termstyle.green('TRex server daemon is killed')) return True sleep(0.1) fail('Failed to kill trex_daemon, even with -9. Please review manually.\n' \ 'Return code: %s\nStdout: %s\nStderr: %s' % return_code, stdout, stderr) # should not happen ### Main ### actions_help = '''Specify action command to be applied on server. (*) start : start the application in as a daemon process. (*) show : prompt an updated status of daemon process (running/ not running). (*) stop : exit the daemon process. (*) restart : stop, then start again the application as daemon process (*) start-live : start the application in live mode (no daemon process). ''' action_funcs = {'start': start_daemon, 'show': show_daemon_status, 'stop': kill_daemon, 'restart': restart_daemon, 'start-live': start_live, } trex_server.trex_parser.add_argument('action', choices=action_funcs.keys(), action='store', help=actions_help) trex_server.trex_parser.usage = None args = trex_server.trex_parser.parse_args() daemon_dir = os.path.dirname(os.path.realpath(__file__)) mkpath('/var/log/trex') mkpath('/var/run/trex') action_funcs[args.action]()