Commit 6d846d0e authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add command line interface for running commands remotely

This patch adds a new command, “gnt-node restricted-command”. Since the
semantics are different from “gnt-cluster command”, the same subcommand
shouldn't be re-used.

The included man page update also includes a small description of how to
configure and use remote commands.

Restricted commands can be run on a whole node group or on any number of
manually chosen nodes.

The output is similar to “gnt-cluster command”.
Signed-off-by: default avatarMichael Hanselmann <>
Reviewed-by: default avatarGuido Trotter <>
parent 74434d27
......@@ -968,6 +968,47 @@ def SetNodeParams(opts, args):
return 0
def RestrictedCommand(opts, args):
"""Runs a remote command on node(s).
@param opts: Command line options selected by user
@type args: list
@param args: Command line arguments
@rtype: int
@return: Exit code
cl = GetClient()
if len(args) > 1 or opts.nodegroup:
# Expand node names
nodes = GetOnlineNodes(nodes=args[1:], cl=cl, nodegroup=opts.nodegroup)
raise errors.OpPrereqError("Node group or node names must be given",
op = opcodes.OpRestrictedCommand(command=args[0], nodes=nodes,
result = SubmitOrSend(op, opts, cl=cl)
exit_code = constants.EXIT_SUCCESS
for (node, (status, text)) in zip(nodes, result):
if status:
if opts.show_machine_names:
for line in text.splitlines():
ToStdout("%s: %s", node, line)
ToStdout("Node: %s", node)
exit_code = constants.EXIT_FAILURE
return exit_code
class ReplyStatus(object):
"""Class holding a reply status for synchronous confd clients.
......@@ -1058,6 +1099,7 @@ def ListDrbd(opts, args):
return constants.EXIT_SUCCESS
commands = {
"add": (
AddNode, [ArgHost(min=1, max=1)],
......@@ -1173,6 +1215,11 @@ commands = {
"[<node_name>]", "Query the list of used DRBD minors on the given node"),
"restricted-command": (
RestrictedCommand, [ArgUnknown(min=1, max=1)] + ARGS_MANY_NODES,
"<command> <node_name> [<node_name>...]",
"Executes a restricted command on node(s)"),
#: dictionary with aliases for commands
......@@ -612,6 +612,35 @@ specific and ``status`` can be one of ``OK``, ``WARNING``, ``CRITICAL`` or
``UNKNOWN``. Items with status ``WARNING`` or ``CRITICAL`` are logged and
annotated in the command line output.
| **restricted-command** [-M] [--sync]
| { -g *group* *command* | *command* *nodes*... }
Executes a restricted command on the specified nodes. Restricted commands are
not arbitrary, but must reside in
``@SYSCONFDIR@/ganeti/remote-commands`` on a node, either as a regular
file or as a symlink. The directory must be owned by root and not be
world- or group-writable. If a command fails verification or otherwise
fails to start, the node daemon log must be consulted for more detailed
Example for running a command on two nodes::
# gnt-node restricted-command mycommand \
The ``-g`` option can be used to run a command only on a specific node
group, e.g.::
# gnt-node restricted-command -g default mycommand
The ``-M`` option can be used to prepend the node name to all command
output lines. ``--sync`` forces the opcode to acquire the node lock(s)
in exclusive mode.
.. vim: set textwidth=72 :
.. Local Variables:
.. mode: rst
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment