summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaroslav Brustinov <ybrustin@cisco.com>2016-06-17 15:39:00 +0300
committerYaroslav Brustinov <ybrustin@cisco.com>2016-06-17 15:39:00 +0300
commit3207f14a91cc01b44b28ba541e5968f58a7e5ec2 (patch)
tree385b01222b2ad25a9b98403634b7e0b4161c40ea
parent0e3621ee07983ce18b83761a794356e910702c42 (diff)
add ctrl+c as first try to kill daemons/TRex.
master daemon change directory to "/" to deal with case it's directory was deleted and update_trex() was used. remove check connection to daemons as part of init of client (can be done manually per needed daemon)
-rwxr-xr-xscripts/automation/trex_control_plane/server/singleton_daemon.py31
-rwxr-xr-xscripts/automation/trex_control_plane/server/trex_server.py19
-rwxr-xr-xscripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py67
-rwxr-xr-xscripts/master_daemon.py11
4 files changed, 52 insertions, 76 deletions
diff --git a/scripts/automation/trex_control_plane/server/singleton_daemon.py b/scripts/automation/trex_control_plane/server/singleton_daemon.py
index 8fdedc6e..79deace1 100755
--- a/scripts/automation/trex_control_plane/server/singleton_daemon.py
+++ b/scripts/automation/trex_control_plane/server/singleton_daemon.py
@@ -2,6 +2,7 @@ import errno
import os
import shlex
import socket
+import signal
import tempfile
import types
from subprocess import Popen
@@ -73,31 +74,27 @@ class SingletonDaemon(object):
if pid:
return pid
-
- # kill daemon
- def kill(self, timeout = 10):
- pid = self.get_pid()
- if not pid:
- return False
- ret_code, stdout, stderr = run_command('kill %s' % pid) # usual kill
- if ret_code:
- raise Exception('Failed to run kill command for %s: %s' % (self.name, [ret_code, stdout, stderr]))
+ def kill_by_signal(self, pid, signal_name, timeout):
+ os.kill(pid, signal_name)
poll_rate = 0.1
for i in range(int(timeout / poll_rate)):
if not self.is_running():
return True
sleep(poll_rate)
- ret_code, stdout, stderr = run_command('kill -9 %s' % pid) # unconditional kill
- if ret_code:
- raise Exception('Failed to run kill -9 command for %s: %s' % (self.name, [ret_code, stdout, stderr]))
- for i in range(int(timeout / poll_rate)):
- if not self.is_running():
+
+ # kill daemon, with verification
+ def kill(self, timeout = 15):
+ pid = self.get_pid()
+ if not pid:
+ return False
+ # try Ctrl+C, usual kill, kill -9
+ for signal_name in [signal.SIGINT, signal.SIGTERM, signal.SIGKILL]:
+ if self.kill_by_signal(pid, signal_name, timeout):
return True
- sleep(poll_rate)
raise Exception('Could not kill %s, even with -9' % self.name)
# try connection as RPC client, return True upon success, False if fail
- def check_connectivity(self, timeout = 5):
+ def check_connectivity(self, timeout = 15):
daemon = jsonrpclib.Server('http://127.0.0.1:%s/' % self.port)
poll_rate = 0.1
for i in range(int(timeout/poll_rate)):
@@ -140,7 +137,7 @@ class SingletonDaemon(object):
raise Exception('%s failed to run.' % self.name)
# restart the daemon
- def restart(self, timeout = 5):
+ def restart(self, timeout = 15):
if self.is_running():
self.kill(timeout)
return self.start(timeout)
diff --git a/scripts/automation/trex_control_plane/server/trex_server.py b/scripts/automation/trex_control_plane/server/trex_server.py
index 5e278a74..3da629ec 100755
--- a/scripts/automation/trex_control_plane/server/trex_server.py
+++ b/scripts/automation/trex_control_plane/server/trex_server.py
@@ -387,23 +387,14 @@ class CTRexServer(object):
return trex_cmds_list
- def kill_all_trexes(self):
+ # Silently tries to kill TRexes with given signal.
+ # Responsibility of client to verify with get_trex_cmds.
+ def kill_all_trexes(self, signal_name):
logger.info('Processing kill_all_trexes() command.')
trex_cmds_list = self.get_trex_cmds()
- if not trex_cmds_list:
- return False
for pid, cmd in trex_cmds_list:
- logger.info('Killing process %s %s' % (pid, cmd))
- run_command('kill %s' % pid)
- ret_code_ps, _, _ = run_command('ps -p %s' % pid)
- if not ret_code_ps:
- logger.info('Killing with -9.')
- run_command('kill -9 %s' % pid)
- ret_code_ps, _, _ = run_command('ps -p %s' % pid)
- if not ret_code_ps:
- logger.info('Could not kill process.')
- raise Exception('Could not kill process %s %s' % (pid, cmd))
- return True
+ logger.info('Killing with signal %s process %s %s' % (signal_name, pid, cmd))
+ os.kill(int(pid), signal_name)
def wait_until_kickoff_finish (self, timeout = 40):
diff --git a/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py
index 3b01560a..e1b298db 100755
--- a/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py
+++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py
@@ -13,6 +13,7 @@ from distutils.util import strtobool
from collections import deque, OrderedDict
from json import JSONDecoder
import traceback
+import signal
try:
from . import outer_packages
@@ -92,42 +93,9 @@ class CTRexClient(object):
self.decoder = JSONDecoder()
self.history = jsonrpclib.history.History()
self.master_daemon_path = "http://{hostname}:{port}/".format( hostname = self.trex_host, port = master_daemon_port )
+ self.master_daemon = jsonrpclib.Server(self.master_daemon_path, history = self.history)
self.trex_server_path = "http://{hostname}:{port}/".format( hostname = self.trex_host, port = trex_daemon_port )
- self.connect_master()
- self.connect_server()
-
-
- def connect_master(self):
- '''
- Connects to Master daemon via JsonRPC.
- This daemon controls TRex daemon server.
- Return true if success, false if fail
- '''
- try:
- print('Connecting to Master daemon @ %s ...' % self.master_daemon_path)
- self.master_daemon = jsonrpclib.Server(self.master_daemon_path, history = self.history)
- self.check_master_connectivity()
- print('Connected to Master daemon.')
- return True
- except Exception as e:
- print(e)
- return False
-
- def connect_server(self):
- '''
- Connects to TRex daemon server via JsonRPC.
- This daemon controls TRex. (start/stop)
- Return true if success, false if fail
- '''
- try:
- print('Connecting to TRex daemon server @ %s ...' % self.trex_server_path)
- self.server = jsonrpclib.Server(self.trex_server_path, history = self.history)
- self.check_server_connectivity()
- print('Connected TRex server daemon.')
- return True
- except Exception as e:
- print(e)
- return False
+ self.server = jsonrpclib.Server(self.trex_server_path, history = self.history)
def add (self, x, y):
@@ -322,18 +290,28 @@ class CTRexClient(object):
finally:
self.prompt_verbose_data()
- def kill_all_trexes(self):
+ def kill_all_trexes(self, timeout = 15):
"""
Kills running TRex processes (if exists) on the server, not only owned by current daemon.
Raises exception upon error killing.
:return:
- + **True** if any process killed
+ + **True** if processes killed/not running
+ **False** otherwise.
"""
try:
- return self.server.kill_all_trexes()
+ poll_rate = 0.1
+ # try Ctrl+C, usual kill, -9
+ for signal_name in [signal.SIGINT, signal.SIGTERM, signal.SIGKILL]:
+ self.server.kill_all_trexes(signal_name)
+ for i in range(int(timeout / poll_rate)):
+ if not self.get_trex_cmds():
+ return True
+ sleep(poll_rate)
+ if self.get_trex_cmds():
+ return False
+ return True
except AppError as err:
self._handle_AppError_exception(err.args[0])
finally:
@@ -1518,8 +1496,15 @@ class CTRexResult(object):
return result
-
-
if __name__ == "__main__":
- pass
+ c = CTRexClient('127.0.0.1')
+ print('restarting daemon')
+ c.restart_trex_daemon()
+ print('kill any running')
+ c.kill_all_trexes()
+ print('start')
+ c.start_stateless()
+ print('sleep')
+ time.sleep(5)
+ print('done')
diff --git a/scripts/master_daemon.py b/scripts/master_daemon.py
index 3f130bdb..e50d49ee 100755
--- a/scripts/master_daemon.py
+++ b/scripts/master_daemon.py
@@ -119,14 +119,16 @@ def start_master_daemon_func():
server.register_function(stl_rpc_proxy.start, 'start_stl_rpc_proxy')
server.register_function(stl_rpc_proxy.stop, 'stop_stl_rpc_proxy')
server.register_function(server.funcs.keys, 'get_methods') # should be last
- signal.signal(signal.SIGTSTP, stop_handler)
- signal.signal(signal.SIGTERM, stop_handler)
+ signal.signal(signal.SIGTSTP, stop_handler) # ctrl+z
+ signal.signal(signal.SIGTERM, stop_handler) # kill
server.serve_forever()
+ except KeyboardInterrupt:
+ logging.info('Ctrl+C')
except Exception as e:
logging.error('Closing due to error: %s' % e)
-def stop_handler(*args, **kwargs):
- logging.info('Got killed explicitly.')
+def stop_handler(signalnum, *args, **kwargs):
+ logging.info('Got signal %s, exiting.' % signalnum)
sys.exit(0)
# returns True if given path is under current dir or /tmp
@@ -191,6 +193,7 @@ master_daemon = SingletonDaemon('Master daemon', 'trex_master_daemon', args
tmp_dir = '/tmp/trex-tmp'
logging_file = '/var/log/trex/master_daemon.log'
logging_file_bu = '/var/log/trex/master_daemon.log_bu'
+os.chdir('/')
if not _check_path_under_current_or_temp(args.trex_dir):
raise Exception('Only allowed to use path under /tmp or current directory')