Revision b3989551

b/lib/cmdlib.py
1763 1763
    return result
1764 1764

  
1765 1765

  
1766
class LUClusterCopyFile(NoHooksLU):
1767
  """Copy file to cluster.
1768

  
1769
  """
1770
  _OP_REQP = ["nodes", "filename"]
1771

  
1772
  def CheckPrereq(self):
1773
    """Check prerequisites.
1774

  
1775
    It should check that the named file exists and that the given list
1776
    of nodes is valid.
1777

  
1778
    """
1779
    if not os.path.exists(self.op.filename):
1780
      raise errors.OpPrereqError("No such filename '%s'" % self.op.filename)
1781

  
1782
    self.nodes = _GetWantedNodes(self, self.op.nodes)
1783

  
1784
  def Exec(self, feedback_fn):
1785
    """Copy a file from master to some nodes.
1786

  
1787
    Args:
1788
      opts - class with options as members
1789
      args - list containing a single element, the file name
1790
    Opts used:
1791
      nodes - list containing the name of target nodes; if empty, all nodes
1792

  
1793
    """
1794
    filename = self.op.filename
1795

  
1796
    myname = utils.HostInfo().name
1797

  
1798
    for node in self.nodes:
1799
      if node == myname:
1800
        continue
1801
      if not self.ssh.CopyFileToNode(node, filename):
1802
        logger.Error("Copy of file %s to node %s failed" % (filename, node))
1803

  
1804

  
1805 1766
class LUDumpClusterConfig(NoHooksLU):
1806 1767
  """Return a text-representation of the cluster-config.
1807 1768

  
......
1821 1782
    return self.cfg.DumpConfig()
1822 1783

  
1823 1784

  
1824
class LURunClusterCommand(NoHooksLU):
1825
  """Run a command on some nodes.
1826

  
1827
  """
1828
  _OP_REQP = ["command", "nodes"]
1829

  
1830
  def CheckPrereq(self):
1831
    """Check prerequisites.
1832

  
1833
    It checks that the given list of nodes is valid.
1834

  
1835
    """
1836
    self.nodes = _GetWantedNodes(self, self.op.nodes)
1837

  
1838
  def Exec(self, feedback_fn):
1839
    """Run a command on some nodes.
1840

  
1841
    """
1842
    # put the master at the end of the nodes list
1843
    master_node = self.sstore.GetMasterNode()
1844
    if master_node in self.nodes:
1845
      self.nodes.remove(master_node)
1846
      self.nodes.append(master_node)
1847

  
1848
    data = []
1849
    for node in self.nodes:
1850
      result = self.ssh.Run(node, "root", self.op.command)
1851
      data.append((node, result.output, result.exit_code))
1852

  
1853
    return data
1854

  
1855

  
1856 1785
class LUActivateInstanceDisks(NoHooksLU):
1857 1786
  """Bring up an instance's disks.
1858 1787

  
b/lib/mcpu.py
45 45
    # Cluster
46 46
    opcodes.OpDestroyCluster: cmdlib.LUDestroyCluster,
47 47
    opcodes.OpQueryClusterInfo: cmdlib.LUQueryClusterInfo,
48
    opcodes.OpClusterCopyFile: cmdlib.LUClusterCopyFile,
49
    opcodes.OpRunClusterCommand: cmdlib.LURunClusterCommand,
50 48
    opcodes.OpVerifyCluster: cmdlib.LUVerifyCluster,
51 49
    opcodes.OpMasterFailover: cmdlib.LUMasterFailover,
52 50
    opcodes.OpDumpClusterConfig: cmdlib.LUDumpClusterConfig,
b/lib/opcodes.py
171 171
  __slots__ = []
172 172

  
173 173

  
174
class OpClusterCopyFile(OpCode):
175
  """Copy a file to multiple nodes."""
176
  OP_ID = "OP_CLUSTER_COPYFILE"
177
  __slots__ = ["nodes", "filename"]
178

  
179

  
180
class OpRunClusterCommand(OpCode):
181
  """Run a command on multiple nodes."""
182
  OP_ID = "OP_CLUSTER_RUNCOMMAND"
183
  __slots__ = ["nodes", "command"]
184

  
185

  
186 174
class OpVerifyCluster(OpCode):
187 175
  """Verify the cluster state."""
188 176
  OP_ID = "OP_CLUSTER_VERIFY"
b/scripts/gnt-cluster
22 22
import sys
23 23
from optparse import make_option
24 24
import pprint
25
import os.path
25 26

  
26 27
from ganeti.cli import *
27 28
from ganeti import opcodes
......
29 30
from ganeti import errors
30 31
from ganeti import utils
31 32
from ganeti import bootstrap
33
from ganeti import ssh
34
from ganeti import ssconf
32 35

  
33 36

  
34 37
def InitCluster(opts, args):
......
156 159
    nodes - list containing the name of target nodes; if empty, all nodes
157 160

  
158 161
  """
159
  op = opcodes.OpClusterCopyFile(filename=args[0], nodes=opts.nodes)
160
  SubmitOpCode(op)
162
  filename = args[0]
163
  if not os.path.exists(filename):
164
    raise errors.OpPrereqError("No such filename '%s'" % filename)
165

  
166
  myname = utils.HostInfo().name
167

  
168
  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
169
  results = [row[0] for row in SubmitOpCode(op) if row[0] != myname]
170
  srun = ssh.SshRunner()
171
  for node in results:
172
    if not srun.CopyFileToNode(node, filename):
173
      print >> sys.stderr, ("Copy of file %s to node %s failed" %
174
                            (filename, node))
175

  
161 176
  return 0
162 177

  
163 178

  
......
172 187

  
173 188
  """
174 189
  command = " ".join(args)
175
  nodes = opts.nodes
176
  op = opcodes.OpRunClusterCommand(command=command, nodes=nodes)
177
  result = SubmitOpCode(op)
178
  for node, output, exit_code in result:
190
  op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes)
191
  nodes = [row[0] for row in SubmitOpCode(op)]
192

  
193
  sstore = ssconf.SimpleStore()
194
  master_node = sstore.GetMasterNode()
195
  srun = ssh.SshRunner(sstore=sstore)
196

  
197
  if master_node in nodes:
198
    nodes.remove(master_node)
199
    nodes.append(master_node)
200

  
201
  for name in nodes:
202
    result = srun.Run(name, "root", command)
179 203
    print ("------------------------------------------------")
180
    print ("node: %s" % node)
181
    print ("%s" % output)
182
    print ("return code = %s" % exit_code)
204
    print ("node: %s" % name)
205
    print ("%s" % result.output)
206
    print ("return code = %s" % result.exit_code)
207

  
208
  return 0
183 209

  
184 210

  
185 211
def VerifyCluster(opts, args):

Also available in: Unified diff