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:
Pavel Boldin
2015-04-24 01:07:59 +03:00
parent 3579913037
commit 5fe701efc2
3 changed files with 55 additions and 4 deletions

View File

@@ -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,

View File

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

View File

@@ -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,