Revision 6d846d0e
b/lib/client/gnt_node.py | ||
---|---|---|
968 | 968 |
return 0 |
969 | 969 |
|
970 | 970 |
|
971 |
def RestrictedCommand(opts, args): |
|
972 |
"""Runs a remote command on node(s). |
|
973 |
|
|
974 |
@param opts: Command line options selected by user |
|
975 |
@type args: list |
|
976 |
@param args: Command line arguments |
|
977 |
@rtype: int |
|
978 |
@return: Exit code |
|
979 |
|
|
980 |
""" |
|
981 |
cl = GetClient() |
|
982 |
|
|
983 |
if len(args) > 1 or opts.nodegroup: |
|
984 |
# Expand node names |
|
985 |
nodes = GetOnlineNodes(nodes=args[1:], cl=cl, nodegroup=opts.nodegroup) |
|
986 |
else: |
|
987 |
raise errors.OpPrereqError("Node group or node names must be given", |
|
988 |
errors.ECODE_INVAL) |
|
989 |
|
|
990 |
op = opcodes.OpRestrictedCommand(command=args[0], nodes=nodes, |
|
991 |
use_locking=opts.do_locking) |
|
992 |
result = SubmitOrSend(op, opts, cl=cl) |
|
993 |
|
|
994 |
exit_code = constants.EXIT_SUCCESS |
|
995 |
|
|
996 |
for (node, (status, text)) in zip(nodes, result): |
|
997 |
ToStdout("------------------------------------------------") |
|
998 |
if status: |
|
999 |
if opts.show_machine_names: |
|
1000 |
for line in text.splitlines(): |
|
1001 |
ToStdout("%s: %s", node, line) |
|
1002 |
else: |
|
1003 |
ToStdout("Node: %s", node) |
|
1004 |
ToStdout(text) |
|
1005 |
else: |
|
1006 |
exit_code = constants.EXIT_FAILURE |
|
1007 |
ToStdout(text) |
|
1008 |
|
|
1009 |
return exit_code |
|
1010 |
|
|
1011 |
|
|
971 | 1012 |
class ReplyStatus(object): |
972 | 1013 |
"""Class holding a reply status for synchronous confd clients. |
973 | 1014 |
|
... | ... | |
1058 | 1099 |
|
1059 | 1100 |
return constants.EXIT_SUCCESS |
1060 | 1101 |
|
1102 |
|
|
1061 | 1103 |
commands = { |
1062 | 1104 |
"add": ( |
1063 | 1105 |
AddNode, [ArgHost(min=1, max=1)], |
... | ... | |
1173 | 1215 |
ListDrbd, ARGS_ONE_NODE, |
1174 | 1216 |
[NOHDR_OPT, SEP_OPT], |
1175 | 1217 |
"[<node_name>]", "Query the list of used DRBD minors on the given node"), |
1218 |
"restricted-command": ( |
|
1219 |
RestrictedCommand, [ArgUnknown(min=1, max=1)] + ARGS_MANY_NODES, |
|
1220 |
[SYNC_OPT, PRIORITY_OPT, SUBMIT_OPT, SHOW_MACHINE_OPT, NODEGROUP_OPT], |
|
1221 |
"<command> <node_name> [<node_name>...]", |
|
1222 |
"Executes a restricted command on node(s)"), |
|
1176 | 1223 |
} |
1177 | 1224 |
|
1178 | 1225 |
#: dictionary with aliases for commands |
b/man/gnt-node.rst | ||
---|---|---|
612 | 612 |
``UNKNOWN``. Items with status ``WARNING`` or ``CRITICAL`` are logged and |
613 | 613 |
annotated in the command line output. |
614 | 614 |
|
615 |
|
|
616 |
RESTRICTED-COMMAND |
|
617 |
~~~~~~~~~~~~~~~~~~ |
|
618 |
|
|
619 |
| **restricted-command** [-M] [--sync] |
|
620 |
| { -g *group* *command* | *command* *nodes*... } |
|
621 |
|
|
622 |
Executes a restricted command on the specified nodes. Restricted commands are |
|
623 |
not arbitrary, but must reside in |
|
624 |
``@SYSCONFDIR@/ganeti/remote-commands`` on a node, either as a regular |
|
625 |
file or as a symlink. The directory must be owned by root and not be |
|
626 |
world- or group-writable. If a command fails verification or otherwise |
|
627 |
fails to start, the node daemon log must be consulted for more detailed |
|
628 |
information. |
|
629 |
|
|
630 |
Example for running a command on two nodes:: |
|
631 |
|
|
632 |
# gnt-node restricted-command mycommand \ |
|
633 |
node1.example.com node2.example.com |
|
634 |
|
|
635 |
The ``-g`` option can be used to run a command only on a specific node |
|
636 |
group, e.g.:: |
|
637 |
|
|
638 |
# gnt-node restricted-command -g default mycommand |
|
639 |
|
|
640 |
The ``-M`` option can be used to prepend the node name to all command |
|
641 |
output lines. ``--sync`` forces the opcode to acquire the node lock(s) |
|
642 |
in exclusive mode. |
|
643 |
|
|
615 | 644 |
.. vim: set textwidth=72 : |
616 | 645 |
.. Local Variables: |
617 | 646 |
.. mode: rst |
Also available in: Unified diff