def run_script(config_ssh, nodes, script, run_on_frontend=False, verbose=False): """Run a script in background on Linux nodes or SSH frontend servers """ # Configure ssh. failed_hosts = [] groups = _nodes_grouped(nodes) ssh = OpenLinuxSsh(config_ssh, groups, verbose=verbose) screen = f'{config_ssh["user"]}-{config_ssh["exp_id"]}' remote_script = os.path.join(_REMOTE_SHARED_DIR, os.path.basename(script)) script_data = {'screen': screen, 'path': remote_script} # Copy script on SSH frontend servers scp_result = ssh.scp(script, remote_script) failed_hosts.append(_get_failed_result(ssh.groups, scp_result, run_on_frontend)) # Make script executable run_result = ssh.run(_MAKE_EXECUTABLE_CMD.format(remote_script), with_proxy=False) failed_hosts.append(_get_failed_result(ssh.groups, run_result, run_on_frontend)) # Try cleanup and kill any running script (don't check the result) ssh.run(_QUIT_SCRIPT_CMD.format(**script_data), with_proxy=not run_on_frontend) # Run script result = ssh.run(_RUN_SCRIPT_CMD.format(**script_data), with_proxy=not run_on_frontend, use_pty=False) for hosts in filter(None, failed_hosts): result.setdefault('1', []).extend(hosts) return {"run-script": result}
def copy_file(config_ssh, nodes, file_path, verbose=False): """Copy a file to SSH frontend servers """ # Configure ssh. groups = _nodes_grouped(nodes) ssh = OpenLinuxSsh(config_ssh, groups, verbose=verbose) # relative path with native client remote_file = os.path.join(_REMOTE_SHARED_DIR, os.path.basename(file_path)) result = ssh.scp(file_path, remote_file) return {"copy-file": result}
def test_scp(copy_file, init): # pylint: disable=unused-argument """Test wait for ssh nodes to be available.""" config_ssh = { 'user': '******', 'exp_id': 123, } src = 'test_src' dst = 'test_dst' groups = _nodes_grouped(_ROOT_NODES) node_ssh = OpenLinuxSsh(config_ssh, groups, verbose=True) ret = node_ssh.scp(src, dst) assert copy_file.call_count == 2 assert ret == {'0': ['saclay.iot-lab.info', 'grenoble.iot-lab.info']} copy_file.side_effect = SFTPError() ret = node_ssh.scp(src, dst) assert ret == {'1': ['saclay.iot-lab.info', 'grenoble.iot-lab.info']}
def flash(config_ssh, nodes, firmware, verbose=False): """Flash the firmware of co-microcontroller """ failed_hosts = [] # configure ssh and remote firmware names. groups = _nodes_grouped(nodes) ssh = OpenLinuxSsh(config_ssh, groups, verbose=verbose) remote_fw = os.path.join(_REMOTE_SHARED_DIR, os.path.basename(firmware)) # copy the firmware to the site SSH servers # scp create remote directory if it doesn't exist result = ssh.scp(firmware, remote_fw) # We delete failed hosts for the next command if '1' in result: failed_hosts = [ssh.groups.pop(res) for res in result['1']] # Run firmware update. bin_opt = "--bin" if remote_fw.endswith(".bin") else "" result = ssh.run(_FLASH_CMD.format(fw=remote_fw, bin=bin_opt)) for hosts in failed_hosts: result.setdefault('1', []).extend(hosts) return {"flash": result}