Commit b3989551 authored by Iustin Pop's avatar Iustin Pop
Browse files

Fix gnt-cluster “command” and “copyfile”

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
parent 0db7ac4d
......@@ -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.
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:
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:
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.
......@@ -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,
......@@ -171,18 +171,6 @@ class OpQueryClusterInfo(OpCode):
__slots__ = []
class OpClusterCopyFile(OpCode):
"""Copy a file to multiple nodes."""
__slots__ = ["nodes", "filename"]
class OpRunClusterCommand(OpCode):
"""Run a command on multiple nodes."""
__slots__ = ["nodes", "command"]
class OpVerifyCluster(OpCode):
"""Verify the cluster state."""
......@@ -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)
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:
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):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment