From 6d846d0e768731381d98d5b151406a7918b54c5f Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 15 Nov 2012 11:16:32 +0100 Subject: [PATCH] Add command line interface for running commands remotely MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: Michael Hanselmann <hansmi@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/client/gnt_node.py | 47 ++++++++++++++++++++++++++++++++++++++++++ man/gnt-node.rst | 29 ++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py index 7c8add06e..74d6a6ede 100644 --- a/lib/client/gnt_node.py +++ b/lib/client/gnt_node.py @@ -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) + else: + raise errors.OpPrereqError("Node group or node names must be given", + errors.ECODE_INVAL) + + op = opcodes.OpRestrictedCommand(command=args[0], nodes=nodes, + use_locking=opts.do_locking) + result = SubmitOrSend(op, opts, cl=cl) + + exit_code = constants.EXIT_SUCCESS + + for (node, (status, text)) in zip(nodes, result): + ToStdout("------------------------------------------------") + if status: + if opts.show_machine_names: + for line in text.splitlines(): + ToStdout("%s: %s", node, line) + else: + ToStdout("Node: %s", node) + ToStdout(text) + else: + exit_code = constants.EXIT_FAILURE + ToStdout(text) + + 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 = { ListDrbd, ARGS_ONE_NODE, [NOHDR_OPT, SEP_OPT], "[<node_name>]", "Query the list of used DRBD minors on the given node"), + "restricted-command": ( + RestrictedCommand, [ArgUnknown(min=1, max=1)] + ARGS_MANY_NODES, + [SYNC_OPT, PRIORITY_OPT, SUBMIT_OPT, SHOW_MACHINE_OPT, NODEGROUP_OPT], + "<command> <node_name> [<node_name>...]", + "Executes a restricted command on node(s)"), } #: dictionary with aliases for commands diff --git a/man/gnt-node.rst b/man/gnt-node.rst index 5e18c2678..d03d7f0e9 100644 --- a/man/gnt-node.rst +++ b/man/gnt-node.rst @@ -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 +~~~~~~~~~~~~~~~~~~ + +| **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 +information. + +Example for running a command on two nodes:: + + # gnt-node restricted-command mycommand \ + node1.example.com node2.example.com + +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 -- GitLab