@atomic.action_timer("vm.run_command_over_ssh")
    def _run_command_over_ssh(self, ssh, command):
        validation.check_command_dict(command)

        # NOTE(pboldin): Here we `get' the values and not check for the keys
        # due to template-driven configuration generation that can leave keys
        # defined but values empty.
        if command.get("script_file") or command.get("script_inline"):
            cmd = command["interpreter"]
            if command.get("script_file"):
                stdin = open(command["script_file"], "rb")
            elif command.get("script_inline"):
                stdin = six.moves.StringIO(command["script_inline"])
        elif command.get("remote_path"):
            cmd = command["remote_path"]
            stdin = None

        if command.get("local_path"):
            remote_path = cmd[-1] if isinstance(cmd, (tuple, list)) else cmd
            ssh.put_file(command["local_path"], remote_path,
                         mode=self.USER_RWX_OTHERS_RX_ACCESS_MODE)

        if command.get("command_args"):
            if not isinstance(cmd, (list, tuple)):
                cmd = [cmd]
            # NOTE(pboldin): `ssh.execute' accepts either a string interpreted
            # as a command name or the list of strings that are converted into
            # single-line command with arguments.
            cmd = cmd + list(command["command_args"])

        return ssh.execute(cmd, stdin=stdin)
Parse a functioncall.
dataset/ETHPy150Open openstack/rally/rally/plugins/openstack/scenarios/vm/utils.py/VMScenario._run_command_over_ssh--crossover with--dataset/ETHPy150Open dansanderson/picotool/pico8/lua/parser.py/Parser._functioncall