Revision 827f753e

b/lib/bootstrap.py
227 227
                 mac_prefix, vg_name, def_bridge)
228 228

  
229 229
  ssh.WriteKnownHostsFile(cfg, ss, constants.SSH_KNOWN_HOSTS_FILE)
230

  
231
def SetupNodeDaemon(node):
232
  """Add a node to the cluster.
233

  
234
  This function must be called before the actual opcode, and will ssh to the
235
  remote node, copy the needed files, and start ganeti-noded, allowing the master
236
  to do the rest via normal rpc calls.
237

  
238
  Args:
239
    node: fully qualified domain name for the new node
240

  
241
  """
242
  ss = ssconf.SimpleStore()
243
  sshrunner = ssh.SshRunner(ss)
244
  gntpass = ss.GetNodeDaemonPassword()
245
  if not re.match('^[a-zA-Z0-9.]{1,64}$', gntpass):
246
    raise errors.OpExecError("ganeti password corruption detected")
247
  f = open(constants.SSL_CERT_FILE)
248
  try:
249
    gntpem = f.read(8192)
250
  finally:
251
    f.close()
252
  # in the base64 pem encoding, neither '!' nor '.' are valid chars,
253
  # so we use this to detect an invalid certificate; as long as the
254
  # cert doesn't contain this, the here-document will be correctly
255
  # parsed by the shell sequence below
256
  if re.search('^!EOF\.', gntpem, re.MULTILINE):
257
    raise errors.OpExecError("invalid PEM encoding in the SSL certificate")
258
  if not gntpem.endswith("\n"):
259
    raise errors.OpExecError("PEM must end with newline")
260

  
261
  # set up inter-node password and certificate and restarts the node daemon
262
  # and then connect with ssh to set password and start ganeti-noded
263
  # note that all the below variables are sanitized at this point,
264
  # either by being constants or by the checks above
265
  mycommand = ("umask 077 && "
266
               "echo '%s' > '%s' && "
267
               "cat > '%s' << '!EOF.' && \n"
268
               "%s!EOF.\n%s restart" %
269
               (gntpass, ss.KeyToFilename(ss.SS_NODED_PASS),
270
                constants.SSL_CERT_FILE, gntpem,
271
                constants.NODE_INITD_SCRIPT))
272

  
273
  result = sshrunner.Run(node, 'root', mycommand, batch=False, ask_key=True)
274
  if result.failed:
275
    raise errors.OpExecError("Remote command on node %s, error: %s,"
276
                             " output: %s" %
277
                             (node, result.fail_reason, result.output))
278

  
279
  return 0
280

  
b/lib/cmdlib.py
1529 1529
    new_node = self.new_node
1530 1530
    node = new_node.name
1531 1531

  
1532
    # set up inter-node password and certificate and restarts the node daemon
1533
    gntpass = self.sstore.GetNodeDaemonPassword()
1534
    if not re.match('^[a-zA-Z0-9.]{1,64}$', gntpass):
1535
      raise errors.OpExecError("ganeti password corruption detected")
1536
    f = open(constants.SSL_CERT_FILE)
1537
    try:
1538
      gntpem = f.read(8192)
1539
    finally:
1540
      f.close()
1541
    # in the base64 pem encoding, neither '!' nor '.' are valid chars,
1542
    # so we use this to detect an invalid certificate; as long as the
1543
    # cert doesn't contain this, the here-document will be correctly
1544
    # parsed by the shell sequence below
1545
    if re.search('^!EOF\.', gntpem, re.MULTILINE):
1546
      raise errors.OpExecError("invalid PEM encoding in the SSL certificate")
1547
    if not gntpem.endswith("\n"):
1548
      raise errors.OpExecError("PEM must end with newline")
1549
    logger.Info("copy cluster pass to %s and starting the node daemon" % node)
1550

  
1551
    # and then connect with ssh to set password and start ganeti-noded
1552
    # note that all the below variables are sanitized at this point,
1553
    # either by being constants or by the checks above
1554
    ss = self.sstore
1555
    mycommand = ("umask 077 && "
1556
                 "echo '%s' > '%s' && "
1557
                 "cat > '%s' << '!EOF.' && \n"
1558
                 "%s!EOF.\n%s restart" %
1559
                 (gntpass, ss.KeyToFilename(ss.SS_NODED_PASS),
1560
                  constants.SSL_CERT_FILE, gntpem,
1561
                  constants.NODE_INITD_SCRIPT))
1562

  
1563
    result = self.ssh.Run(node, 'root', mycommand, batch=False, ask_key=True)
1564
    if result.failed:
1565
      raise errors.OpExecError("Remote command on node %s, error: %s,"
1566
                               " output: %s" %
1567
                               (node, result.fail_reason, result.output))
1568

  
1569 1532
    # check connectivity
1570
    time.sleep(4)
1571

  
1572 1533
    result = rpc.call_version([node])[node]
1573 1534
    if result:
1574 1535
      if constants.PROTOCOL_VERSION == result:
b/scripts/gnt-node
28 28
from ganeti import utils
29 29
from ganeti import constants
30 30
from ganeti import errors
31
from ganeti import bootstrap
31 32

  
32 33

  
33 34
_LIST_DEF_FIELDS = [
......
59 60
    "on the target machine (%s) with the ones of the current one\n"
60 61
    "and grant full intra-cluster ssh root access to/from it\n" % node)
61 62

  
63
  bootstrap.SetupNodeDaemon(node)
64

  
62 65
  op = opcodes.OpAddNode(node_name=args[0], secondary_ip=opts.secondary_ip,
63 66
                         readd=opts.readd)
64 67
  SubmitOpCode(op)

Also available in: Unified diff