summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/server/singleton_daemon.py
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-06-07 13:02:08 +0300
committerHanoh Haim <hhaim@cisco.com>2016-06-07 13:02:08 +0300
commit38bcd9c376add0f94e3f660bbcf0558c55f31135 (patch)
treef5d6fd309f7995b94d0558ea4ec29ba00faa1c73 /scripts/automation/trex_control_plane/server/singleton_daemon.py
parent0814f72d66600967c9bf5f1c743ce0ee64e5c1f2 (diff)
parent918ae3cda75a01c8a4769df79bf6bfd0b270a41f (diff)
Merge branch 'master' of csi-sceasr-b94:/auto/proj-pcube-b/apps/PL-b/tools/repo//trex-core
Diffstat (limited to 'scripts/automation/trex_control_plane/server/singleton_daemon.py')
-rwxr-xr-xscripts/automation/trex_control_plane/server/singleton_daemon.py39
1 files changed, 29 insertions, 10 deletions
diff --git a/scripts/automation/trex_control_plane/server/singleton_daemon.py b/scripts/automation/trex_control_plane/server/singleton_daemon.py
index 7cfbc3bc..8fdedc6e 100755
--- a/scripts/automation/trex_control_plane/server/singleton_daemon.py
+++ b/scripts/automation/trex_control_plane/server/singleton_daemon.py
@@ -6,10 +6,12 @@ import tempfile
import types
from subprocess import Popen
from time import sleep
+import outer_packages
+import jsonrpclib
# uses Unix sockets for determine running process.
# (assumes used daemons will register proper socket)
-# all daemons should use -p argument as listening tcp port
+# all daemons should use -p argument as listening tcp port and check_connectivity RPC method
class SingletonDaemon(object):
# run_cmd can be function of how to run daemon or a str to run at subprocess
@@ -28,14 +30,14 @@ class SingletonDaemon(object):
# returns True if daemon is running
def is_running(self):
- lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
try:
- lock_socket.bind('\0' + self.tag) # the check is ~200000 faster and more reliable than checking via 'netstat' or 'ps' etc.
+ lock_socket = register_socket(self.tag) # the check is ~200000 faster and more reliable than checking via 'netstat' or 'ps' etc.
+ lock_socket.shutdown(socket.SHUT_RDWR)
lock_socket.close()
except socket.error: # Unix socket in use
return True
# Unix socket is not used, but maybe it's old version of daemon not using socket
- return bool(self.get_pid())
+ return bool(self.get_pid_by_listening_port())
# get pid of running daemon by registered Unix socket (most robust way)
@@ -73,7 +75,7 @@ class SingletonDaemon(object):
# kill daemon
- def kill(self, timeout = 5):
+ def kill(self, timeout = 10):
pid = self.get_pid()
if not pid:
return False
@@ -88,17 +90,27 @@ class SingletonDaemon(object):
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]))
- poll_rate = 0.1
- for i in range(inr(timeout / poll_rate)):
+ for i in range(int(timeout / poll_rate)):
if not self.is_running():
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):
+ daemon = jsonrpclib.Server('http://127.0.0.1:%s/' % self.port)
+ poll_rate = 0.1
+ for i in range(int(timeout/poll_rate)):
+ try:
+ daemon.check_connectivity()
+ return True
+ except socket.error: # daemon is not up yet
+ sleep(poll_rate)
+ return False
# start daemon
# returns True if success, False if already running
- def start(self, timeout = 5):
+ def start(self, timeout = 20):
if self.is_running():
raise Exception('%s is already running' % self.name)
if not self.run_cmd:
@@ -112,6 +124,8 @@ class SingletonDaemon(object):
if timeout > 0:
poll_rate = 0.1
for i in range(int(timeout/poll_rate)):
+ if self.is_running():
+ break
sleep(poll_rate)
if bool(proc.poll()): # process ended with error
stdout_file.seek(0)
@@ -120,7 +134,9 @@ class SingletonDaemon(object):
elif proc.poll() == 0: # process runs other process, and ended
break
if self.is_running():
- return True
+ if self.check_connectivity():
+ return True
+ raise Exception('Daemon process is running, but no connectivity')
raise Exception('%s failed to run.' % self.name)
# restart the daemon
@@ -136,8 +152,9 @@ def register_socket(tag):
lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
try:
lock_socket.bind('\0%s' % tag)
+ return lock_socket
except socket.error:
- raise Exception('Error: process with tag %s is already running.' % tag)
+ raise socket.error('Error: process with tag %s is already running.' % tag)
# runs command
def run_command(command, timeout = 15, cwd = None):
@@ -153,6 +170,8 @@ def run_command(command, timeout = 15, cwd = None):
if proc.poll() is None:
proc.kill() # timeout
return (errno.ETIME, '', 'Timeout on running: %s' % command)
+ else:
+ proc.wait()
stdout_file.seek(0)
stderr_file.seek(0)
return (proc.returncode, stdout_file.read().decode(errors = 'replace'), stderr_file.read().decode(errors = 'replace'))