" %s seconds" % _DAEMON_READY_TIMEOUT)
+def _WaitForSshDaemon(hostname, port, family):
+ """Wait for SSH daemon to become responsive.
+
+ """
+ hostip = netutils.GetHostname(name=hostname, family=family).ip
+
+ def _CheckSshDaemon():
+ if netutils.TcpPing(hostip, port, timeout=1.0, live_port_needed=True):
+ logging.debug("SSH daemon on %s:%s (IP address %s) has become"
+ " responsive", hostname, port, hostip)
+ else:
+ raise utils.RetryAgain()
+
+ try:
+ utils.Retry(_CheckSshDaemon, 1.0, _DAEMON_READY_TIMEOUT)
+ except utils.RetryTimeout:
+ raise errors.OpExecError("SSH daemon on %s:%s (IP address %s) didn't"
+ " become responsive within %s seconds" %
+ (hostname, port, hostip, _DAEMON_READY_TIMEOUT))
+
+
def RunNodeSetupCmd(cluster_name, node, basecmd, debug, verbose,
use_cluster_key, ask_key, strict_host_check, data):
"""Runs a command to configure something on a remote machine.
raise errors.OpExecError("Command '%s' failed: %s" %
(result.cmd, result.fail_reason))
+ _WaitForSshDaemon(node, netutils.GetDaemonPort(constants.SSH), family)
+
def _InitFileStorage(file_storage_dir):
"""Initialize if needed the file storage.
maintain_node_health=False, drbd_helper=None, uid_pool=None,
default_iallocator=None, primary_ip_version=None, ipolicy=None,
prealloc_wipe_disks=False, use_external_mip_script=False,
- hv_state=None, disk_state=None):
+ hv_state=None, disk_state=None, enabled_disk_templates=None):
"""Initialise the cluster.
@type candidate_pool_size: int
@param candidate_pool_size: master candidate pool size
+ @type enabled_disk_templates: list of string
+ @param enabled_disk_templates: list of disk_templates to be used in this
+ cluster
"""
# TODO: complete the docstring
" entries: %s" % invalid_hvs,
errors.ECODE_INVAL)
+ if not enabled_disk_templates:
+ raise errors.OpPrereqError("Enabled disk templates list must contain at"
+ " least one member", errors.ECODE_INVAL)
+ invalid_disk_templates = \
+ set(enabled_disk_templates) - constants.DISK_TEMPLATES
+ if invalid_disk_templates:
+ raise errors.OpPrereqError("Enabled disk templates list contains invalid"
+ " entries: %s" % invalid_disk_templates,
+ errors.ECODE_INVAL)
+
try:
ipcls = netutils.IPAddress.GetClassFromIpVersion(primary_ip_version)
except errors.ProgrammerError:
curr_helper),
errors.ECODE_INVAL)
+ logging.debug("Stopping daemons (if any are running)")
+ result = utils.RunCmd([pathutils.DAEMON_UTIL, "stop-all"])
+ if result.failed:
+ raise errors.OpExecError("Could not stop daemons, command %s"
+ " had exitcode %s and error '%s'" %
+ (result.cmd, result.exit_code, result.output))
+
if constants.ENABLE_FILE_STORAGE:
file_storage_dir = _InitFileStorage(file_storage_dir)
else:
utils.CommaJoin(unknown_params)),
errors.ECODE_INVAL)
utils.ForceDictType(dt_params, constants.DISK_DT_TYPES)
+ if template == constants.DT_DRBD8 and vg_name is not None:
+ # The default METAVG value is equal to the VG name set at init time,
+ # if provided
+ dt_params[constants.DRBD_DEFAULT_METAVG] = vg_name
+
try:
utils.VerifyDictOptions(diskparams, constants.DISK_DT_DEFAULTS)
except errors.OpPrereqError, err:
ipolicy=full_ipolicy,
hv_state_static=hv_state,
disk_state_static=disk_state,
+ enabled_disk_templates=enabled_disk_templates,
)
master_node_config = objects.Node(name=hostname.name,
primary_ip=hostname.ip,
" the node: %s", msg)
-def SetupNodeDaemon(cluster_name, node, ssh_key_check):
+def SetupNodeDaemon(opts, cluster_name, node):
"""Add a node to the cluster.
This function must be called before the actual opcode, and will ssh
@param cluster_name: the cluster name
@param node: the name of the new node
- @param ssh_key_check: whether to do a strict key check
"""
- sstore = ssconf.SimpleStore()
- family = sstore.GetPrimaryIPFamily()
- sshrunner = ssh.SshRunner(cluster_name,
- ipv6=(family == netutils.IP6Address.family))
-
- # set up inter-node password and certificate and restarts the node daemon
- # and then connect with ssh to set password and start ganeti-noded
- # note that all the below variables are sanitized at this point,
- # either by being constants or by the checks above
- sshrunner.CopyFileToNode(node, pathutils.NODED_CERT_FILE)
- sshrunner.CopyFileToNode(node, pathutils.RAPI_CERT_FILE)
- sshrunner.CopyFileToNode(node, pathutils.SPICE_CERT_FILE)
- sshrunner.CopyFileToNode(node, pathutils.SPICE_CACERT_FILE)
- sshrunner.CopyFileToNode(node, pathutils.CONFD_HMAC_KEY)
- for filename in sstore.GetFileList():
- sshrunner.CopyFileToNode(node, filename)
- mycommand = ("%s stop-all; %s start %s" %
- (pathutils.DAEMON_UTIL, pathutils.DAEMON_UTIL, constants.NODED))
-
- result = sshrunner.Run(node, constants.SSH_LOGIN_USER, mycommand, batch=False,
- ask_key=ssh_key_check,
- use_cluster_key=True,
- strict_host_check=ssh_key_check)
- if result.failed:
- raise errors.OpExecError("Remote command on node %s, error: %s,"
- " output: %s" %
- (node, result.fail_reason, result.output))
+ data = {
+ constants.NDS_CLUSTER_NAME: cluster_name,
+ constants.NDS_NODE_DAEMON_CERTIFICATE:
+ utils.ReadFile(pathutils.NODED_CERT_FILE),
+ constants.NDS_SSCONF: ssconf.SimpleStore().ReadAll(),
+ constants.NDS_START_NODE_DAEMON: True,
+ }
+
+ RunNodeSetupCmd(cluster_name, node, pathutils.NODE_DAEMON_SETUP,
+ opts.debug, opts.verbose,
+ True, opts.ssh_key_check, opts.ssh_key_check, data)
_WaitForNodeDaemon(node)