Change in osmo-gsm-tester[master]: Introduce RemoteHost and refactor code to use it

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.org
Wed Jan 29 18:21:22 UTC 2020


pespin 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>


More information about the gerrit-log mailing list