summaryrefslogtreecommitdiffstats
path: root/scripts/scapy_daemon_server
diff options
context:
space:
mode:
authorYaroslav Brustinov <ybrustin@cisco.com>2017-01-02 19:10:25 +0200
committerYaroslav Brustinov <ybrustin@cisco.com>2017-01-02 19:10:25 +0200
commit9fb4cf6f17e3e028d4e01514a947ccb2828738ac (patch)
tree0ed2cf89874a95e2773be8a72993f6c0d438b9a1 /scripts/scapy_daemon_server
parenta681613fd3fc06b0ecb4159b95d55619603c1519 (diff)
add warning about lack of read permissions for user "nobody" to run scapy server.
add flag to disable scapy server run. Change-Id: I65ccfb24ed4a5461fe2a13d8be0f07fad8a50bae Signed-off-by: Yaroslav Brustinov <ybrustin@cisco.com>
Diffstat (limited to 'scripts/scapy_daemon_server')
-rwxr-xr-xscripts/scapy_daemon_server93
1 files changed, 66 insertions, 27 deletions
diff --git a/scripts/scapy_daemon_server b/scripts/scapy_daemon_server
index a5e4df06..e19c8b3c 100755
--- a/scripts/scapy_daemon_server
+++ b/scripts/scapy_daemon_server
@@ -6,6 +6,7 @@ import time
import subprocess, shlex
from argparse import ArgumentParser, RawTextHelpFormatter
import errno
+import pwd
def fail(msg):
print(msg)
@@ -14,8 +15,8 @@ def fail(msg):
if os.getuid() != 0:
fail('Please run this program as root/with sudo')
-pwd = os.path.abspath(os.path.dirname(__file__))
-ext_libs_path = os.path.join(pwd, 'external_libs')
+cur_dir = os.path.abspath(os.path.dirname(__file__))
+ext_libs_path = os.path.join(cur_dir, 'external_libs')
if ext_libs_path not in sys.path:
sys.path.append(ext_libs_path)
@@ -30,34 +31,46 @@ def inv(f):
return lambda *a, **k: not f(*a, **k)
-def progress(success_check, start_msg, success_msg, fail_msg, timeout = 10, poll_rate = 0.5):
+def progress(success_check, start_msg, success_msg, fail_msg, timeout = 35, poll_rate = 0.5, fail_check = None):
sys.stdout.write('%s...' % start_msg)
sys.stdout.flush()
for i in range(int(timeout/poll_rate)):
if success_check():
print(termstyle.green(' ' + success_msg))
return 0
+ if fail_check and fail_check():
+ print(termstyle.red(' ' + fail_msg))
+ return 1
time.sleep(poll_rate)
sys.stdout.write('.')
sys.stdout.flush()
- if success_check():
- print(termstyle.green(' ' + success_msg))
- return 0
- print(termstyle.red(' ' + fail_msg))
+ print(termstyle.red(' Timeout'))
return 1
-def run_command(command, timeout = 15, poll_rate = 0.1, cwd = None):
- assert timeout > 0, 'Timeout should be positive'
- assert poll_rate > 0, 'Poll rate should be positive'
+def demote_func():
+ pw_record = pwd.getpwnam('nobody')
+ os.setgid(pw_record.pw_gid)
+ os.setuid(pw_record.pw_uid)
+
+
+def run_command(command, timeout = 30, poll_rate = 0.1, cwd = None, demote = False, is_daemon = False):
+ if not is_daemon:
+ assert timeout > 0, 'Timeout should be positive'
+ assert poll_rate > 0, 'Poll rate should be positive'
+
+ preexec_fn = demote_func if demote else None
+
+ try: # P2
+ stdout_file = tempfile.TemporaryFile(bufsize = 0)
+ except: # P3
+ stdout_file = tempfile.TemporaryFile(buffering = 0)
+
try:
- tempfile.TemporaryFile(bufsize=0)
- temp_params = {'bufsize': 0}
- except:
- tempfile.TemporaryFile(buffering=0)
- temp_params = {'buffering': 0}
- with tempfile.TemporaryFile(**temp_params) as stdout_file:
- proc = subprocess.Popen(shlex.split(command), stdout = stdout_file, stderr = subprocess.STDOUT, cwd = cwd, close_fds = True, universal_newlines = True)
+ proc = subprocess.Popen(shlex.split(command), stdout = stdout_file, stderr = subprocess.STDOUT, cwd = cwd,
+ close_fds = True, universal_newlines = True, preexec_fn = preexec_fn)
+ if is_daemon:
+ return proc, stdout_file
for i in range(int(timeout/poll_rate)):
time.sleep(poll_rate)
if proc.poll() is not None: # process stopped
@@ -68,6 +81,9 @@ def run_command(command, timeout = 15, poll_rate = 0.1, cwd = None):
return (errno.ETIMEDOUT, '%s\n\n...Timeout of %s second(s) is reached!' % (stdout_file.read(), timeout))
stdout_file.seek(0)
return (proc.returncode, stdout_file.read())
+ finally:
+ if not is_daemon:
+ stdout_file.close()
def get_daemon_pid():
@@ -100,15 +116,37 @@ def start_daemon():
if is_running():
print(termstyle.red('Scapy server is already running'))
return
- server_path = os.path.join(pwd, 'automation', 'trex_control_plane', 'stl', 'services', 'scapy_server')
- with tempfile.TemporaryFile() as stdout_file:
- subprocess.Popen(shlex.split("taskset -c %s su -s /bin/bash -c '%s scapy_zmq_server.py -s %s' nobody" % (args.core, sys.executable, args.port)),
- stdout = stdout_file, stderr = subprocess.STDOUT, cwd = server_path, close_fds = True, universal_newlines = True)
- ret = progress(is_running, 'Starting Scapy server', 'Scapy server is started', 'Scapy server failed to run')
+ check_path = cur_dir
+ last_err_path = None
+ ret = -1
+ while ret and check_path != '/':
+ ret, out = run_command("ls %s" % check_path, demote = True)
if ret:
- stdout_file.seek(0)
- print('Output: %s' % stdout_file.read())
- sys.exit(1)
+ last_err_path = check_path
+ check_path = os.path.abspath(os.path.join(check_path, '..'))
+ if last_err_path:
+ msg = '''
+Error: current path is not readable by user "nobody" (starting at {path}).
+Two possible solutions:
+
+ 1. (Recommended)
+ Copy TRex to some public location (/tmp or /scratch, assuming it has proper permissions (chmod 777 etc.))
+
+ 2. (Not recommended)
+ Change permissions of current path. (Starting from directory {path}).
+ chmod 777 {path} -R
+'''.format(path = last_err_path)
+ fail(msg)
+
+ server_path = os.path.join(cur_dir, 'automation', 'trex_control_plane', 'stl', 'services', 'scapy_server')
+ cmd = 'taskset -c {core} {python} ./scapy_zmq_server.py -s {port}'.format(core = args.core, python = sys.executable, port = args.port)
+ proc, stdout_file = run_command(cmd, demote = True, is_daemon = True, cwd = server_path)
+ ret = progress(is_running, 'Starting Scapy server', 'Scapy server is started', 'Scapy server failed to run', fail_check = proc.poll)
+ if proc.poll():
+ stdout_file.seek(0)
+ print('Output: %s' % stdout_file.read())
+ stdout_file.close()
+ sys.exit(1)
def restart_daemon():
@@ -124,14 +162,15 @@ def kill_daemon():
print(termstyle.red('Scapy server is NOT running'))
return True
run_command('kill %s' % pid) # usual kill
- ret = progress(inv(is_running), 'Killing Scapy server', 'Scapy server is killed', 'failed')
+ ret = progress(inv(is_running), 'Killing Scapy server', 'Scapy server is killed', 'failed', timeout = 15)
if not ret:
return
_, out = run_command('kill -9 %s' % pid) # unconditional kill
- ret = progress(inv(is_running), 'Killing Scapy server with -9', 'Scapy server is killed', 'failed')
+ ret = progress(inv(is_running), 'Killing Scapy server with -9', 'Scapy server is killed', 'failed', timeout = 15)
if ret:
fail('Failed to kill Scapy server, even with -9. Please review manually.\nOutput: %s' % out)
+
### Main ###
if __name__ == '__main__':