This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17065 ) Change subject: Introduce RemoteHost and refactor code to use it ...................................................................... Introduce RemoteHost and refactor code to use it Let's move code related to coping stuff to remote hosts and managing remote processes under a class where relevant information is stored. This simplifies parameters being passed all over and allows to reuse more code. Change-Id: Ifff5ded8fdb28e8ef267cebe6c5f30a910cae11a --- M src/osmo_gsm_tester/bts_oc2g.py M src/osmo_gsm_tester/bts_osmotrx.py M src/osmo_gsm_tester/bts_sysmo.py M src/osmo_gsm_tester/process.py A src/osmo_gsm_tester/remote.py 5 files changed, 169 insertions(+), 117 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/65/17065/1 diff --git a/src/osmo_gsm_tester/bts_oc2g.py b/src/osmo_gsm_tester/bts_oc2g.py index ec4ed3d..7b46fc8 100644 --- a/src/osmo_gsm_tester/bts_oc2g.py +++ b/src/osmo_gsm_tester/bts_oc2g.py @@ -41,14 +41,6 @@ def _direct_pcu_enabled(self): return util.str2bool(self.conf.get('direct_pcu')) - def launch_remote(self, name, popen_args, remote_cwd=None, keepalive=False): - run_dir = self.run_dir.new_dir(name) - proc = process.RemoteProcess(name, run_dir, self.remote_user, self.remote_addr(), remote_cwd, - popen_args) - self.suite_run.remember_to_stop(proc, keepalive) - proc.launch() - return proc - def create_pcu(self): return pcu_oc2g.OsmoPcuOC2G(self.suite_run, self, self.conf) @@ -116,15 +108,19 @@ if not self.inst.isfile('bin', OsmoBtsOC2G.BTS_OC2G_BIN): raise log.Error('No osmo-bts-oc2g binary in', self.inst) - remote_run_dir = util.Dir(OsmoBtsOC2G.REMOTE_DIR) - - self.remote_inst = process.copy_inst_ssh(self.run_dir, self.inst, remote_run_dir, self.remote_user, - self.remote_addr(), OsmoBtsOC2G.BTS_OC2G_BIN, self.config_file) - + rem_host = remote.RemoteHost(self.run_dir, self.remote_user, self.remote_addr()) + remote_prefix_dir = util.Dir(OsmoBtsOC2G.REMOTE_DIR) + self.remote_inst = util.Dir(remote_prefix_dir.child(os.path.basename(str(self.inst)))) + remote_run_dir = util.Dir(remote_prefix_dir.child(OsmoBtsOC2G.BTS_OC2G_BIN)) remote_config_file = remote_run_dir.child(OsmoBtsOC2G.BTS_OC2G_CFG) - remote_lib = self.remote_inst.child('lib') - remote_binary = self.remote_inst.child('bin', 'osmo-bts-oc2g') + rem_host.recreate_remote_dir(self.remote_inst) + rem_host.scp('scp-inst-to-remote', str(self.inst), remote_prefix_dir) + rem_host.create_remote_dir(remote_run_dir) + rem_host.scp('scp-cfg-to-remote', self.config_file, remote_config_file) + + remote_lib = self.remote_inst.child('lib') + remote_binary = self.remote_inst.child('bin', OsmoBtsOC2G.BTS_OC2G_BIN) args = ('LD_LIBRARY_PATH=%s' % remote_lib, remote_binary, '-c', remote_config_file, '-r', '1', '-i', self.bsc.addr()) @@ -132,6 +128,7 @@ if self._direct_pcu_enabled(): args += ('-M',) - self.proc_bts = self.launch_remote('osmo-bts-oc2g', args, remote_cwd=remote_run_dir, keepalive=keepalive) - + proc = rem_host.RemoteProcess(OsmoBtsOC2G.BTS_OC2G_BIN, args) + self.suite_run.remember_to_stop(proc, keepalive) + proc.launch() # vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/bts_osmotrx.py b/src/osmo_gsm_tester/bts_osmotrx.py index 9110d8a..78c17cc 100644 --- a/src/osmo_gsm_tester/bts_osmotrx.py +++ b/src/osmo_gsm_tester/bts_osmotrx.py @@ -18,10 +18,9 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os -import stat import pprint from abc import ABCMeta, abstractmethod -from . import log, config, util, template, process, bts_osmo +from . import log, config, util, template, process, remote, bts_osmo from . import powersupply from .event_loop import MainLoop @@ -263,72 +262,41 @@ proc.launch() return proc - def launch_process_remote(self, name, popen_args, remote_cwd=None, keepalive=False): - run_dir = self.run_dir.new_dir(name) - proc = process.RemoteProcess(name, run_dir, self.remote_user, self.listen_ip, remote_cwd, - popen_args) - self.suite_run.remember_to_stop(proc, keepalive) - proc.launch() - return proc - - def generate_wrapper_script(self): - wrapper_script = self.run_dir.new_file(OsmoTrx.WRAPPER_SCRIPT) - with open(wrapper_script, 'w') as f: - r = """#!/bin/bash - mypid=0 - sign_handler() { - sig=$1 - echo "received signal handler $sig, killing $mypid" - kill $mypid - } - trap 'sign_handler SIGTERM' SIGTERM - trap 'sign_handler SIGINT' SIGINT - trap 'sign_handler SIGHUP' SIGHUP - "$@" & - mypid=$! - echo "waiting for $mypid" - wait $mypid - echo "process $mypid finished" - """ - f.write(r) - st = os.stat(wrapper_script) - os.chmod(wrapper_script, st.st_mode | stat.S_IEXEC) - return wrapper_script - - def inst_compatible_for_remote(self): - proc = process.run_remote_sync(self.run_dir, self.remote_user, self.listen_ip, 'uname-m', ('uname', '-m')) - if "x86_64" in (proc.get_stdout() or ''): - return True - return False - def start_remotely(self, keepalive): # Run remotely through ssh. We need to run osmo-trx under a wrapper # script since osmo-trx ignores SIGHUP and will keep running after # we close local ssh session. The wrapper script catches SIGHUP and # sends SIGINT to it. - remote_run_dir = util.Dir(OsmoTrx.REMOTE_DIR) + + rem_host = remote.RemoteHost(self.run_dir, self.remote_user, self.listen_ip) + + remote_prefix_dir = util.Dir(OsmoTrx.REMOTE_DIR) + remote_run_dir = util.Dir(remote_prefix_dir.child(self.binary_name())) remote_config_file = remote_run_dir.child(OsmoTrx.CONF_OSMO_TRX) - have_inst = self.inst_compatible_for_remote() + have_inst = rem_host.inst_compatible_for_remote() if have_inst: self.inst = util.Dir(os.path.abspath(self.suite_run.trial.get_inst('osmo-trx'))) - # if self.inst is None, we still want to copy config file, create remote run dir, etc. - self.remote_inst = process.copy_inst_ssh(self.run_dir, self.inst, remote_run_dir, self.remote_user, - self.listen_ip, self.binary_name(), self.config_file) - - wrapper_script = self.generate_wrapper_script() - remote_wrapper_script = remote_run_dir.child(OsmoTrx.WRAPPER_SCRIPT) - process.scp(self.run_dir, self.remote_user, self.listen_ip, 'scp-wrapper-to-remote', wrapper_script, remote_wrapper_script) + rem_host.recreate_remote_dir(remote_prefix_dir) + if have_inst: + self.remote_inst = util.Dir(remote_prefix_dir.child(os.path.basename(str(self.inst)))) + rem_host.create_remote_dir(self.remote_inst) + rem_host.scp('scp-inst-to-remote', str(self.inst), remote_prefix_dir) + rem_host.create_remote_dir(remote_run_dir) + rem_host.scp('scp-cfg-to-remote', self.config_file, remote_config_file) if have_inst: remote_lib = self.remote_inst.child('lib') remote_binary = self.remote_inst.child('bin', self.binary_name()) - args = ('LD_LIBRARY_PATH=%s' % remote_lib, remote_wrapper_script, remote_binary, '-C', remote_config_file) + args = (remote_binary, '-C', remote_config_file) else: # Use whatever is available i nremote system PATH: - args = (remote_wrapper_script, self.binary_name(), '-C', remote_config_file) - - self.proc_trx = self.launch_process_remote(self.binary_name(), args, remote_cwd=remote_run_dir, keepalive=keepalive) + remote_lib = None + remote_binary = self.binary_name() + args = (remote_binary, '-C', remote_config_file) + self.proc_trx = rem_host.RemoteProcessFixIgnoreSIGHUP(self.binary_name(), remote_run_dir, args, prepend_ldlibpath=remote_lib) + self.suite_run.remember_to_stop(self.proc_trx, keepalive) + self.proc_trx.launch() ############## # PUBLIC (test API included) diff --git a/src/osmo_gsm_tester/bts_sysmo.py b/src/osmo_gsm_tester/bts_sysmo.py index 66d305a..90d4790 100644 --- a/src/osmo_gsm_tester/bts_sysmo.py +++ b/src/osmo_gsm_tester/bts_sysmo.py @@ -19,7 +19,7 @@ import os import pprint -from . import log, config, util, template, process, pcu_sysmo, bts_osmo +from . import log, config, util, template, process, remote, pcu_sysmo, bts_osmo class SysmoBts(bts_osmo.OsmoBts): ############## @@ -41,14 +41,6 @@ def _direct_pcu_enabled(self): return util.str2bool(self.conf.get('direct_pcu')) - def launch_remote(self, name, popen_args, remote_cwd=None, keepalive=False): - run_dir = self.run_dir.new_dir(name) - proc = process.RemoteProcess(name, run_dir, self.remote_user, self.remote_addr(), remote_cwd, - popen_args) - self.suite_run.remember_to_stop(proc, keepalive) - proc.launch() - return proc - def create_pcu(self): return pcu_sysmo.OsmoPcuSysmo(self.suite_run, self, self.conf) @@ -110,17 +102,21 @@ if not self.inst.isfile('bin', SysmoBts.BTS_SYSMO_BIN): raise log.Error('No osmo-bts-sysmo binary in', self.inst) - remote_run_dir = util.Dir(SysmoBts.REMOTE_DIR) - - self.remote_inst = process.copy_inst_ssh(self.run_dir, self.inst, remote_run_dir, self.remote_user, - self.remote_addr(), SysmoBts.BTS_SYSMO_BIN, self.config_file) - process.run_remote_sync(self.run_dir, self.remote_user, self.remote_addr(), 'reload-dsp-firmware', - ('/bin/sh', '-c', '"cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0"')) - + rem_host = remote.RemoteHost(self.run_dir, self.remote_user, self.remote_addr()) + remote_prefix_dir = util.Dir(SysmoBts.REMOTE_DIR) + self.remote_inst = util.Dir(remote_prefix_dir.child(os.path.basename(str(self.inst)))) + remote_run_dir = util.Dir(remote_prefix_dir.child(SysmoBts.BTS_SYSMO_BIN)) remote_config_file = remote_run_dir.child(SysmoBts.BTS_SYSMO_CFG) - remote_lib = self.remote_inst.child('lib') - remote_binary = self.remote_inst.child('bin', 'osmo-bts-sysmo') + rem_host.recreate_remote_dir(self.remote_inst) + rem_host.scp('scp-inst-to-remote', str(self.inst), remote_prefix_dir) + rem_host.create_remote_dir(remote_run_dir) + rem_host.scp('scp-cfg-to-remote', self.config_file, remote_config_file) + + rem_host.run_remote_sync('reload-dsp-firmware', ('/bin/sh', '-c', '"cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0"')) + + remote_lib = self.remote_inst.child('lib') + remote_binary = self.remote_inst.child('bin', SysmoBts.BTS_SYSMO_BIN) args = ('LD_LIBRARY_PATH=%s' % remote_lib, remote_binary, '-c', remote_config_file, '-r', '1', '-i', self.bsc.addr()) @@ -128,6 +124,8 @@ if self._direct_pcu_enabled(): args += ('-M',) - self.proc_bts = self.launch_remote('osmo-bts-sysmo', args, remote_cwd=remote_run_dir, keepalive=keepalive) + proc = rem_host.RemoteProcess(SysmoBts.BTS_SYSMO_BIN, args) + self.suite_run.remember_to_stop(proc, keepalive) + proc.launch() # vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/process.py b/src/osmo_gsm_tester/process.py index 06da3bf..1c2f592 100644 --- a/src/osmo_gsm_tester/process.py +++ b/src/osmo_gsm_tester/process.py @@ -406,32 +406,4 @@ proc = NetNSProcess(name, run_dir, netns, popen_args) proc.launch_sync() return proc - -def run_remote_sync(run_dir, remote_user, remote_addr, name, popen_args, remote_cwd=None): - run_dir = run_dir.new_dir(name) - proc = RemoteProcess(name, run_dir, remote_user, remote_addr, remote_cwd, popen_args) - proc.launch_sync() - return proc - -def scp(run_dir, remote_user, remote_addr, name, local_path, remote_path): - run_local_sync(run_dir, name, ('scp', '-r', local_path, '%s@%s:%s' % (remote_user, remote_addr, remote_path))) - -# If no inst binaries copying is required (eg. because binary+libs is already available in distro), inst can be None. -def copy_inst_ssh(run_dir, inst, remote_dir, remote_user, remote_addr, remote_rundir_append, cfg_file_name): - remote_dir_str = str(remote_dir) - run_remote_sync(run_dir, remote_user, remote_addr, 'rm-remote-dir', ('test', '!', '-d', remote_dir_str, '||', 'rm', '-rf', remote_dir_str)) - run_remote_sync(run_dir, remote_user, remote_addr, 'mk-remote-dir', ('mkdir', '-p', remote_dir_str)) - if inst is not None: - remote_inst = Dir(remote_dir.child(os.path.basename(str(inst)))) - scp(run_dir, remote_user, remote_addr, 'scp-inst-to-remote', str(inst), remote_dir_str) - else: - remote_inst = None - - remote_run_dir = remote_dir.child(remote_rundir_append) - run_remote_sync(run_dir, remote_user, remote_addr, 'mk-remote-run-dir', ('mkdir', '-p', remote_run_dir)) - - remote_config_file = remote_dir.child(os.path.basename(cfg_file_name)) - scp(run_dir, remote_user, remote_addr, 'scp-cfg-to-remote', cfg_file_name, remote_config_file) - return remote_inst - # vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/remote.py b/src/osmo_gsm_tester/remote.py new file mode 100644 index 0000000..92dd113 --- /dev/null +++ b/src/osmo_gsm_tester/remote.py @@ -0,0 +1,117 @@ +# osmo_gsm_tester: specifics for remote nodes +# +# Copyright (C) 2020 by sysmocom - s.f.m.c. GmbH +# +# Author: Pau Espin Pedrol <pespin at sysmocom.de> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import stat +import os +import re +import pprint + +from . import log, util, config, template, process, osmo_ctrl, pcap_recorder + +class RemoteHost(log.Origin): + + WRAPPER_SCRIPT = 'ssh_sigkiller.sh' + + def __init__(self, run_dir, remote_user = 'root', remote_host = 'localhost', remote_cwd=None): + super().__init__(log.C_RUN, 'host-' + remote_user + '@' + remote_host) + self.run_dir = util.Dir(run_dir.new_dir(self.name())) + self.remote_user = remote_user + self.remote_host = remote_host + self.remote_cwd = remote_cwd + + def user(self): + return self.remote_user + + def host(self): + return self.remote_host + + def cwd(self): + return self.remote_cwd + + def RemoteProcess(self, name, popen_args, **popen_kwargs): + run_dir = self.run_dir.new_dir(name) + return process.RemoteProcess(name, run_dir, self.user(), self.host(), self.cwd(), popen_args, **popen_kwargs) + + def generate_wrapper_script(self): + wrapper_script = self.run_dir.new_file(RemoteHost.WRAPPER_SCRIPT) + with open(wrapper_script, 'w') as f: + r = """#!/bin/bash + mypid=0 + sign_handler() { + sig=$1 + echo "received signal handler $sig, killing $mypid" + kill $mypid + } + trap 'sign_handler SIGTERM' SIGTERM + trap 'sign_handler SIGINT' SIGINT + trap 'sign_handler SIGHUP' SIGHUP + $@ & + mypid=$! + echo "waiting for $mypid" + wait $mypid + echo "process $mypid finished" + """ + f.write(r) + st = os.stat(wrapper_script) + os.chmod(wrapper_script, st.st_mode | stat.S_IEXEC) + return wrapper_script + + def RemoteProcessFixIgnoreSIGHUP(self, name, remote_dir, popen_args, prepend_ldlibpath=None, **popen_kwargs): + # Run remotely through ssh. We need to run binary under a wrapper + # script since osmo-trx ignores SIGHUP and will keep running after + # we close local ssh session. The wrapper script catches SIGHUP and + # sends SIGINT to it. + self.create_remote_dir(remote_dir) + + wrapper_script = self.generate_wrapper_script() + remote_wrapper_script = remote_dir.child(RemoteHost.WRAPPER_SCRIPT) + self.scp('scp-wrapper-to-remote', wrapper_script, remote_wrapper_script) + + # Used fi to run stuff from an osmo-gsm-tester copied inst + if prepend_ldlibpath is not None: + args = ('LD_LIBRARY_PATH=%s' % prepend_ldlibpath, remote_wrapper_script,) + popen_args + else: + args = (remote_wrapper_script,) + popen_args + return self.RemoteProcess(name, args, **popen_kwargs) + + def run_remote_sync(self, name, popen_args): + proc = self.RemoteProcess(name, popen_args) + proc.launch_sync() + return proc + + def rm_remote_dir(self, remote_dir): + remote_dir_str = str(remote_dir) + self.run_remote_sync('rm-remote-dir', ('test', '!', '-d', remote_dir_str, '||', 'rm', '-rf', remote_dir_str)) + + def create_remote_dir(self, remote_dir): + remote_dir_str = str(remote_dir) + self.run_remote_sync('mk-remote-dir', ('mkdir', '-p', remote_dir_str)) + + def recreate_remote_dir(self, remote_dir): + self.rm_remote_dir(remote_dir) + self.create_remote_dir(remote_dir) + + def inst_compatible_for_remote(self): + proc = self.run_remote_sync('uname-m', ('uname', '-m')) + if "x86_64" in (proc.get_stdout() or ''): + return True + return False + + def scp(self, name, local_path, remote_path): + process.run_local_sync(self.run_dir, name, ('scp', '-r', local_path, '%s@%s:%s' % (self.user(), self.host(), remote_path))) -- To view, visit https://gerrit.osmocom.org/c/osmo-gsm-tester/+/17065 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Change-Id: Ifff5ded8fdb28e8ef267cebe6c5f30a910cae11a Gerrit-Change-Number: 17065 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200129/d14486ac/attachment.htm>