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