Add command-dict option to upload a local command
Add a command-dict option that instruct `_run_command_over_ssh' to upload a local file specified in `local_path' key to a remote path specified in `remote_path' key and execute in on the host. Change-Id: Ibaa6543ef6d6c95e8b9cdab989264d56f54e8e44 Implements: blueprint vm-workloads-framework
This commit is contained in:
@@ -39,6 +39,8 @@ class VMScenario(base.Scenario):
|
||||
VM scenarios are scenarios executed inside some launched VM instance.
|
||||
"""
|
||||
|
||||
USER_RWX_OTHERS_RX_ACCESS_MODE = 0o755
|
||||
|
||||
@base.atomic_action_timer("vm.run_command_over_ssh")
|
||||
def _run_command_over_ssh(self, ssh, command):
|
||||
"""Run command inside an instance.
|
||||
@@ -67,6 +69,11 @@ class VMScenario(base.Scenario):
|
||||
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)
|
||||
|
||||
return ssh.execute(cmd, stdin=stdin)
|
||||
|
||||
def _boot_server_with_fip(self, image, flavor,
|
||||
|
||||
@@ -73,17 +73,22 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
|
||||
:param interpreter: DEPRECATED. Use `command' instead. server's
|
||||
interpreter to run the script
|
||||
:param command: Command-specifying dictionary that either specifies
|
||||
remote command path via `remote_path', an inline script via
|
||||
remote command path via `remote_path' (can be uploaded from a
|
||||
local file specified by `local_path`), an inline script via
|
||||
`script_inline' or a local script file path using `script_file'.
|
||||
The `script_file' is checked to be accessible by the `file_exists'
|
||||
validator.
|
||||
Both `script_file' and `local_path' are checked to be accessible
|
||||
by the `file_exists' validator code.
|
||||
|
||||
The `script_inline' and `script_file' both require an `interpreter'
|
||||
value to specify the interpreter script should be run with.
|
||||
|
||||
Note that any of `interpreter' and `remote_path' can be an array
|
||||
prefixed with environment variables and suffixed with args for
|
||||
the `interpreter' command.
|
||||
the `interpreter' command. `remote_path's last component must be
|
||||
a path to a command to execute (also upload destination if a
|
||||
`local_path' is given). Uploading an interpreter is possible
|
||||
but requires that `remote_path' and `interpreter' path do match.
|
||||
|
||||
|
||||
Examples::
|
||||
|
||||
@@ -105,12 +110,34 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
|
||||
"remote_path": "/bin/false"
|
||||
}
|
||||
|
||||
# Copy a local command and run it
|
||||
command = {
|
||||
"remote_path": "/usr/local/bin/fio",
|
||||
"local_path": "/home/foobar/myfiodir/bin/fio"
|
||||
}
|
||||
|
||||
# Copy a local command and run it with environment variable
|
||||
command = {
|
||||
"remote_path": ["HOME=/root", "/usr/local/bin/fio"],
|
||||
"local_path": "/home/foobar/myfiodir/bin/fio"
|
||||
}
|
||||
|
||||
# Run an inline script sending it to a remote interpreter
|
||||
command = {
|
||||
"script_inline": "echo \"Hello, ${NAME:-World}\"",
|
||||
"interpreter": ["NAME=Earth", "/bin/sh"]
|
||||
}
|
||||
|
||||
# Run an inline script sending it to a uploaded remote
|
||||
# interpreter
|
||||
command = {
|
||||
"script_inline": "echo \"Hello, ${NAME:-World}\"",
|
||||
"interpreter": ["NAME=Earth", "/tmp/sh"],
|
||||
"remote_path": "/tmp/sh",
|
||||
"local_path": "/home/user/work/cve/sh-1.0/bin/sh"
|
||||
}
|
||||
|
||||
|
||||
:param volume_args: volume args for booting server from volume
|
||||
:param floating_network: external network name, for floating ip
|
||||
:param port: ssh port for SSH connection
|
||||
|
||||
@@ -73,6 +73,23 @@ class VMScenarioTestCase(test.ScenarioTestCase):
|
||||
["foo", "bar"],
|
||||
stdin=None)
|
||||
|
||||
def test__run_command_over_ssh_remote_path_copy(self):
|
||||
mock_ssh = mock.MagicMock()
|
||||
vm_scenario = utils.VMScenario()
|
||||
vm_scenario._run_command_over_ssh(
|
||||
mock_ssh,
|
||||
{
|
||||
"remote_path": ["foo", "bar"],
|
||||
"local_path": "/bin/false"
|
||||
}
|
||||
)
|
||||
mock_ssh.put_file.assert_called_once_with(
|
||||
"/bin/false", "bar", mode=0o755
|
||||
)
|
||||
mock_ssh.execute.assert_called_once_with(
|
||||
["foo", "bar"],
|
||||
stdin=None)
|
||||
|
||||
def test__run_command_over_ssh_fails(self):
|
||||
vm_scenario = utils.VMScenario()
|
||||
self.assertRaises(ValueError,
|
||||
|
||||
Reference in New Issue
Block a user