This allows the user to manually call a repair command
on a specified node with a given input.

Signed-off-by: Bhimanavajjula Aditya <[email protected]>
---
 lib/cli_opts.py        |  6 ++++++
 lib/client/gnt_node.py | 17 +++++++++++++++++
 man/gnt-node.rst       | 17 +++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/lib/cli_opts.py b/lib/cli_opts.py
index 231f9de..5ffb9ba 100644
--- a/lib/cli_opts.py
+++ b/lib/cli_opts.py
@@ -124,6 +124,7 @@ __all__ = [
   "IGNORE_SOFT_ERRORS_OPT",
   "IGNORE_SIZE_OPT",
   "INCLUDEDEFAULTS_OPT",
+  "INPUT_OPT",
   "INSTALL_IMAGE_OPT",
   "INSTANCE_COMMUNICATION_NETWORK_OPT",
   "INSTANCE_COMMUNICATION_OPT",
@@ -1623,6 +1624,11 @@ LONG_SLEEP_OPT = cli_option(
     "--long-sleep", default=False, dest="long_sleep",
     help="Allow long shutdowns when backing up instances", action="store_true")
 
+INPUT_OPT = cli_option("--input", dest="input", default=None,
+                       help=("input to be passed as stdin"
+                             " to the repair command"),
+                       type="string")
+
 #: Options provided by all commands
 COMMON_OPTS = [DEBUG_OPT, REASON_OPT]
 
diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py
index 22e5107..57922f1 100644
--- a/lib/client/gnt_node.py
+++ b/lib/client/gnt_node.py
@@ -1040,6 +1040,19 @@ def RestrictedCommand(opts, args):
   return exit_code
 
 
+def RepairCommand(opts, args):
+  cl = GetClient()
+  if opts.input:
+    input = opts.input.decode('string_escape')
+  else:
+    input = None
+  op = opcodes.OpRepairCommand(command=args[0], node_name=args[1],
+                               input=input)
+  result = SubmitOrSend(op, opts, cl=cl)
+  print result
+  return constants.EXIT_SUCCESS
+
+
 class ReplyStatus(object):
   """Class holding a reply status for synchronous confd clients.
 
@@ -1249,6 +1262,10 @@ commands = {
     [SYNC_OPT, PRIORITY_OPT] + SUBMIT_OPTS + [SHOW_MACHINE_OPT, NODEGROUP_OPT],
     "<command> <node_name> [<node_name>...]",
     "Executes a restricted command on node(s)"),
+  "repair-command": (
+    RepairCommand, [ArgUnknown(min=1, max=1), ArgNode(min=1, max=1)],
+    [SUBMIT_OPT, INPUT_OPT], "{--input <input>} <command> <node_name>",
+    "Executes a repair command on a node"),
   }
 
 #: dictionary with aliases for commands
diff --git a/man/gnt-node.rst b/man/gnt-node.rst
index 71b6fd7..f49dd04 100644
--- a/man/gnt-node.rst
+++ b/man/gnt-node.rst
@@ -647,6 +647,23 @@ 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.
 
+REPAIR-COMMAND
+~~~~~~~~~~~~~~~~~~
+
+| **repair-command** { --input *input* } *command* *node*
+
+Executes a repair command. Repair commands reside in
+``@SYSCONFDIR@/ganeti/node-repair-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::
+
+    # gnt-node repair-command --input "input string" \
+      mycommand node.example.com
+
 Tags
 ~~~~
 
-- 
2.5.0.457.gab17608

Reply via email to