From b39895510a1983409e943646e06095620752ad18 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Mon, 23 Jun 2008 16:55:22 +0000
Subject: [PATCH] =?UTF-8?q?Fix=20gnt-cluster=20=E2=80=9Ccommand=E2=80=9D?=
 =?UTF-8?q?=20and=20=E2=80=9Ccopyfile=E2=80=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since the disabling of forking in the master daemon, the two ssh-based
subcommands were not working anymore. However, there is no need at all
for the commands to be run from the master daemon (permissions to read
the cluster private ssh key notwithstanding), they can be run directly
from the command line utilities.

The patch removes the two opcodes OpRunClusterCommand and
OpClusterCopyFile (and their associated LUs) and changes the code in
β€˜gnt-cluster’ to query the list of nodes and run directly the SshRunner
over the list. As such, all forking is done from the gnt-cluster script,
and the commands are working again.

Reviewed-by: imsnah
---
 lib/cmdlib.py       | 71 ---------------------------------------------
 lib/mcpu.py         |  2 --
 lib/opcodes.py      | 12 --------
 scripts/gnt-cluster | 44 ++++++++++++++++++++++------
 4 files changed, 35 insertions(+), 94 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index cf028bcd5..cc1ead5f4 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1763,45 +1763,6 @@ class LUQueryClusterInfo(NoHooksLU):
     return result
 
 
-class LUClusterCopyFile(NoHooksLU):
-  """Copy file to cluster.
-
-  """
-  _OP_REQP = ["nodes", "filename"]
-
-  def CheckPrereq(self):
-    """Check prerequisites.
-
-    It should check that the named file exists and that the given list
-    of nodes is valid.
-
-    """
-    if not os.path.exists(self.op.filename):
-      raise errors.OpPrereqError("No such filename '%s'" % self.op.filename)
-
-    self.nodes = _GetWantedNodes(self, self.op.nodes)
-
-  def Exec(self, feedback_fn):
-    """Copy a file from master to some nodes.
-
-    Args:
-      opts - class with options as members
-      args - list containing a single element, the file name
-    Opts used:
-      nodes - list containing the name of target nodes; if empty, all nodes
-
-    """
-    filename = self.op.filename
-
-    myname = utils.HostInfo().name
-
-    for node in self.nodes:
-      if node == myname:
-        continue
-      if not self.ssh.CopyFileToNode(node, filename):
-        logger.Error("Copy of file %s to node %s failed" % (filename, node))
-
-
 class LUDumpClusterConfig(NoHooksLU):
   """Return a text-representation of the cluster-config.
 
@@ -1821,38 +1782,6 @@ class LUDumpClusterConfig(NoHooksLU):
     return self.cfg.DumpConfig()
 
 
-class LURunClusterCommand(NoHooksLU):
-  """Run a command on some nodes.
-
-  """
-  _OP_REQP = ["command", "nodes"]
-
-  def CheckPrereq(self):
-    """Check prerequisites.
-
-    It checks that the given list of nodes is valid.
-
-    """
-    self.nodes = _GetWantedNodes(self, self.op.nodes)
-
-  def Exec(self, feedback_fn):
-    """Run a command on some nodes.
-
-    """
-    # put the master at the end of the nodes list
-    master_node = self.sstore.GetMasterNode()
-    if master_node in self.nodes:
-      self.nodes.remove(master_node)
-      self.nodes.append(master_node)
-
-    data = []
-    for node in self.nodes:
-      result = self.ssh.Run(node, "root", self.op.command)
-      data.append((node, result.output, result.exit_code))
-
-    return data
-
-
 class LUActivateInstanceDisks(NoHooksLU):
   """Bring up an instance's disks.
 
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 2e7f3039c..ff2c80ccf 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -45,8 +45,6 @@ class Processor(object):
     # Cluster
     opcodes.OpDestroyCluster: cmdlib.LUDestroyCluster,
     opcodes.OpQueryClusterInfo: cmdlib.LUQueryClusterInfo,
-    opcodes.OpClusterCopyFile: cmdlib.LUClusterCopyFile,
-    opcodes.OpRunClusterCommand: cmdlib.LURunClusterCommand,
     opcodes.OpVerifyCluster: cmdlib.LUVerifyCluster,
     opcodes.OpMasterFailover: cmdlib.LUMasterFailover,
     opcodes.OpDumpClusterConfig: cmdlib.LUDumpClusterConfig,
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 11385c013..906573880 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -171,18 +171,6 @@ class OpQueryClusterInfo(OpCode):
   __slots__ = []
 
 
-class OpClusterCopyFile(OpCode):
-  """Copy a file to multiple nodes."""
-  OP_ID = "OP_CLUSTER_COPYFILE"
-  __slots__ = ["nodes", "filename"]
-
-
-class OpRunClusterCommand(OpCode):
-  """Run a command on multiple nodes."""
-  OP_ID = "OP_CLUSTER_RUNCOMMAND"
-  __slots__ = ["nodes", "command"]
-
-
 class OpVerifyCluster(OpCode):
   """Verify the cluster state."""
   OP_ID = "OP_CLUSTER_VERIFY"
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index 9f4b493aa..c980ae7df 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -22,6 +22,7 @@
 import sys
 from optparse import make_option
 import pprint
+import os.path
 
 from ganeti.cli import *
 from ganeti import opcodes
@@ -29,6 +30,8 @@ from ganeti import constants
 from ganeti import errors
 from ganeti import utils
 from ganeti import bootstrap
+from ganeti import ssh
+from ganeti import ssconf
 
 
 def InitCluster(opts, args):
@@ -156,8 +159,20 @@ def ClusterCopyFile(opts, args):
     nodes - list containing the name of target nodes; if empty, all nodes
 
   """
-  op = opcodes.OpClusterCopyFile(filename=args[0], nodes=opts.nodes)
-  SubmitOpCode(op)
+  filename = args[0]
+  if not os.path.exists(filename):
+    raise errors.OpPrereqError("No such filename '%s'" % filename)
+
+  myname = utils.HostInfo().name
+
+  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
+  results = [row[0] for row in SubmitOpCode(op) if row[0] != myname]
+  srun = ssh.SshRunner()
+  for node in results:
+    if not srun.CopyFileToNode(node, filename):
+      print >> sys.stderr, ("Copy of file %s to node %s failed" %
+                            (filename, node))
+
   return 0
 
 
@@ -172,14 +187,25 @@ def RunClusterCommand(opts, args):
 
   """
   command = " ".join(args)
-  nodes = opts.nodes
-  op = opcodes.OpRunClusterCommand(command=command, nodes=nodes)
-  result = SubmitOpCode(op)
-  for node, output, exit_code in result:
+  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
+  nodes = [row[0] for row in SubmitOpCode(op)]
+
+  sstore = ssconf.SimpleStore()
+  master_node = sstore.GetMasterNode()
+  srun = ssh.SshRunner(sstore=sstore)
+
+  if master_node in nodes:
+    nodes.remove(master_node)
+    nodes.append(master_node)
+
+  for name in nodes:
+    result = srun.Run(name, "root", command)
     print ("------------------------------------------------")
-    print ("node: %s" % node)
-    print ("%s" % output)
-    print ("return code = %s" % exit_code)
+    print ("node: %s" % name)
+    print ("%s" % result.output)
+    print ("return code = %s" % result.exit_code)
+
+  return 0
 
 
 def VerifyCluster(opts, args):
-- 
GitLab