X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/eaa4c57c43148a196080d69953e652ad755505e2..86aa9ba32f810956948ff4e578c828351998a82c:/lib/bootstrap.py diff --git a/lib/bootstrap.py b/lib/bootstrap.py index 0944fb7..dc92792 100644 --- a/lib/bootstrap.py +++ b/lib/bootstrap.py @@ -28,6 +28,7 @@ import os.path import re import logging import time +import tempfile from ganeti import rpc from ganeti import ssh @@ -255,6 +256,61 @@ def _WaitForMasterDaemon(): " %s seconds" % _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. + + @type cluster_name: string + @param cluster_name: Cluster name + @type node: string + @param node: Node name + @type basecmd: string + @param basecmd: Base command (path on the remote machine) + @type debug: bool + @param debug: Enable debug output + @type verbose: bool + @param verbose: Enable verbose output + @type use_cluster_key: bool + @param use_cluster_key: See L{ssh.SshRunner.BuildCmd} + @type ask_key: bool + @param ask_key: See L{ssh.SshRunner.BuildCmd} + @type strict_host_check: bool + @param strict_host_check: See L{ssh.SshRunner.BuildCmd} + @param data: JSON-serializable input data for script (passed to stdin) + + """ + cmd = [basecmd] + + # Pass --debug/--verbose to the external script if set on our invocation + if debug: + cmd.append("--debug") + + if verbose: + cmd.append("--verbose") + + family = ssconf.SimpleStore().GetPrimaryIPFamily() + srun = ssh.SshRunner(cluster_name, + ipv6=(family == netutils.IP6Address.family)) + scmd = srun.BuildCmd(node, constants.SSH_LOGIN_USER, + utils.ShellQuoteArgs(cmd), + batch=False, ask_key=ask_key, quiet=False, + strict_host_check=strict_host_check, + use_cluster_key=use_cluster_key) + + tempfh = tempfile.TemporaryFile() + try: + tempfh.write(serializer.DumpJson(data)) + tempfh.seek(0) + + result = utils.RunCmd(scmd, interactive=True, input_fd=tempfh) + finally: + tempfh.close() + + if result.failed: + raise errors.OpExecError("Command '%s' failed: %s" % + (result.cmd, result.fail_reason)) + + def _InitFileStorage(file_storage_dir): """Initialize if needed the file storage. @@ -644,7 +700,7 @@ def FinalizeClusterDestroy(master): " 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 @@ -653,36 +709,19 @@ def SetupNodeDaemon(cluster_name, node, ssh_key_check): @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)