CI: Harmonize exec_script() API
Instead of making the function a class member, make it an instance member because (1) it is more aligned with other functions, notably, run(), and (2) especially for RemoteCmd() it can be faster, as successive exec_script() calls do not require a new SSH connection.
This commit is contained in:
@@ -426,7 +426,8 @@ class Cluster:
|
||||
logging.debug(f'Running physims from server: {node}')
|
||||
script = "scripts/oc-deploy-physims.sh"
|
||||
options = f"oaicicd-core-for-ci-ran {oc_release} {image_tag} {self.eNBSourceCodePath}"
|
||||
ret = cls_cmd.runScript(node, script, 600, options)
|
||||
with cls_cmd.getConnection(node) as c:
|
||||
ret = c.exec_script(script, 600, options)
|
||||
logging.debug(f'"{script}" finished with code {ret.returncode}, output:\n{ret.stdout}')
|
||||
with cls_cmd.getConnection(node) as ssh:
|
||||
details_json = archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/{oc_release}-tests.json')
|
||||
|
||||
+5
-15
@@ -45,12 +45,6 @@ def getConnection(host, d=None):
|
||||
else:
|
||||
return RemoteCmd(host, d=d)
|
||||
|
||||
def runScript(host, path, timeout, parameters=None, redirect=None, silent=False):
|
||||
if is_local(host):
|
||||
return LocalCmd.exec_script(path, timeout, parameters, redirect, silent)
|
||||
else:
|
||||
return RemoteCmd.exec_script(host, path, timeout, parameters, redirect, silent)
|
||||
|
||||
# provides a partial interface for the legacy SSHconnection class (getBefore(), command())
|
||||
class Cmd(metaclass=abc.ABCMeta):
|
||||
def cd(self, d, silent=False):
|
||||
@@ -111,12 +105,12 @@ class LocalCmd(Cmd):
|
||||
logging.debug(f'Working dir is {self.cwd}')
|
||||
self.cp = sp.CompletedProcess(args='', returncode=0, stdout='')
|
||||
|
||||
def exec_script(path, timeout, parameters=None, redirect=None, silent=False):
|
||||
def exec_script(self, path, timeout, parameters=None, redirect=None, silent=False):
|
||||
if redirect and not redirect.startswith("/"):
|
||||
raise ValueError(f"redirect must be absolute, but is {redirect}")
|
||||
c = f"{path} {parameters}" if parameters else path
|
||||
if not redirect:
|
||||
ret = sp.run(c, shell=True, timeout=timeout, stdout=sp.PIPE, stderr=sp.STDOUT)
|
||||
ret = sp.run(c, shell=True, cwd=self.cwd, timeout=timeout, stdout=sp.PIPE, stderr=sp.STDOUT)
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
else:
|
||||
with open(redirect, "w") as f:
|
||||
@@ -238,18 +232,15 @@ class RemoteCmd(Cmd):
|
||||
cfg['sock'] = paramiko.ProxyCommand(ucfg['proxycommand'])
|
||||
return cfg
|
||||
|
||||
def exec_script(host, path, timeout, parameters=None, redirect=None, silent=False):
|
||||
def exec_script(self, path, timeout, parameters=None, redirect=None, silent=False):
|
||||
if redirect and not redirect.startswith("/"):
|
||||
raise ValueError(f"redirect must be absolute, but is {redirect}")
|
||||
p = parameters if parameters else ""
|
||||
r = f"> {redirect}" if redirect else ""
|
||||
if not silent:
|
||||
logging.debug(f"local> ssh {host} bash -s {p} < {path} {r} # {path} from localhost")
|
||||
client = RemoteCmd._ssh_init()
|
||||
cfg = RemoteCmd._lookup_ssh_config(host)
|
||||
client.connect(**cfg)
|
||||
logging.debug(f"local> ssh {self.hostname} bash -s {p} < {path} {r}")
|
||||
bash_opt = 'BASH_XTRACEFD=1' # write bash set -x output to stdout, see bash(1)
|
||||
stdin, stdout, stderr = client.exec_command(f"{bash_opt} bash -s {p} {r}", timeout=timeout)
|
||||
stdin, stdout, stderr = self.client.exec_command(f"{bash_opt} bash -s {p} {r}", timeout=timeout)
|
||||
# open() the file f at path, read() it and write() it into the stdin of the bash -s cmd
|
||||
with open(path) as f:
|
||||
stdin.write(f.read())
|
||||
@@ -259,7 +250,6 @@ class RemoteCmd(Cmd):
|
||||
if redirect: cmd += f" &> {redirect}"
|
||||
ret = sp.CompletedProcess(args=cmd, returncode=stdout.channel.recv_exit_status(), stdout=stdout.read(size=None) + stderr.read(size=None))
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
client.close()
|
||||
return ret
|
||||
|
||||
def run(self, line, timeout=300, silent=False, reportNonZero=True):
|
||||
|
||||
@@ -66,7 +66,8 @@ def CreateWorkspace(host, sourcePath, ranRepository, ranCommitID, ranTargetBranc
|
||||
ranTargetBranch = 'develop'
|
||||
options += f" {ranTargetBranch}"
|
||||
logging.info(f'execute "{script}" with options "{options}" on node {host}')
|
||||
ret = cls_cmd.runScript(host, script, 90, options)
|
||||
with cls_cmd.getConnection(host) as c:
|
||||
ret = c.exec_script(script, 90, options)
|
||||
logging.debug(f'"{script}" finished with code {ret.returncode}, output:\n{ret.stdout}')
|
||||
return ret.returncode == 0
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ class CoreNetwork:
|
||||
words = line[1:].strip().split(" ")
|
||||
script_name = words[0]
|
||||
options = " ".join(words[1:])
|
||||
ret = cls_cmd.runScript(host, script_name, 300, parameters=options, silent=silent)
|
||||
with cls_cmd.getConnection(host) as c:
|
||||
ret = c.exec_script(script_name, 300, parameters=options, silent=silent)
|
||||
return ret
|
||||
|
||||
def _command(self, cmd_list, must_succeed=False, silent=False):
|
||||
|
||||
@@ -234,7 +234,8 @@ def Custom_Command(HTML, node, command):
|
||||
|
||||
def Custom_Script(HTML, node, script):
|
||||
logging.info(f"Executing custom script on {node}")
|
||||
ret = cls_cmd.runScript(node, script, 90)
|
||||
with cls_cmd.getConnection(node) as c:
|
||||
ret = c.exec_script(script, 90)
|
||||
logging.debug(f"Custom_Script: {script} on node: {node} - return code {ret.returncode}, output:\n{ret.stdout}")
|
||||
status = 'OK'
|
||||
message = [ret.stdout]
|
||||
|
||||
+12
-6
@@ -36,17 +36,20 @@ class TestCmd(unittest.TestCase):
|
||||
self.assertEqual(ret.stdout, "test")
|
||||
|
||||
def test_local_script(self):
|
||||
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-world.sh", 1)
|
||||
with cls_cmd.getConnection("localhost") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-world.sh", 1)
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-world.sh")
|
||||
self.assertEqual(ret.returncode, 0)
|
||||
self.assertEqual(ret.stdout, "+ echo hello, world\nhello, world")
|
||||
|
||||
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-fail.sh", 1, "TESTFAIL")
|
||||
with cls_cmd.getConnection("localhost") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-fail.sh", 1, "TESTFAIL")
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL")
|
||||
self.assertEqual(ret.returncode, 1)
|
||||
self.assertEqual(ret.stdout, "TESTFAIL")
|
||||
|
||||
ret = cls_cmd.runScript("localhost", "tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
|
||||
with cls_cmd.getConnection("localhost") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL2 &> /tmp/result")
|
||||
self.assertEqual(ret.returncode, 1)
|
||||
self.assertEqual(ret.stdout, "")
|
||||
@@ -75,17 +78,20 @@ class TestCmd(unittest.TestCase):
|
||||
|
||||
@unittest.skip("need to be able to passwordlessly SSH to localhost, also disable stty -ixon")
|
||||
def test_remote_script(self):
|
||||
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-world.sh", 1)
|
||||
with cls_cmd.getConnection("127.0.0.1") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-world.sh", 1)
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-world.sh")
|
||||
self.assertEqual(ret.returncode, 0)
|
||||
self.assertEqual(ret.stdout, "+ echo hello, world\nhello, world")
|
||||
|
||||
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-fail.sh", 1, "TESTFAIL")
|
||||
with cls_cmd.getConnection("127.0.0.1") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-fail.sh", 1, "TESTFAIL")
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL")
|
||||
self.assertEqual(ret.returncode, 1)
|
||||
self.assertEqual(ret.stdout, "TESTFAIL")
|
||||
|
||||
ret = cls_cmd.runScript("127.0.0.1", "tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
|
||||
with cls_cmd.getConnection("127.0.0.1") as ssh:
|
||||
ret = ssh.exec_script("tests/scripts/hello-fail.sh", 1, "TESTFAIL2", "/tmp/result")
|
||||
self.assertEqual(ret.args, "tests/scripts/hello-fail.sh TESTFAIL2 &> /tmp/result")
|
||||
self.assertEqual(ret.returncode, 1)
|
||||
self.assertEqual(ret.stdout, "")
|
||||
|
||||
Reference in New Issue
Block a user