def push_configuration(nodes): ''' Push the local configuration to the list of remote nodes ''' try: from psshlib import api as pssh _has_pssh = True except ImportError: _has_pssh = False if not _has_pssh: raise ValueError("PSSH is required to push") local_path = conf() opts = pssh.Options() opts.timeout = 60 opts.ssh_options += ['ControlPersist=no'] ok = True for host, result in pssh.copy(nodes, local_path, local_path, opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("Failed to push configuration to %s: %s" % (host, result)) ok = False else: err_buf.ok(host) return ok
def do_status(self, context): ''' Quick cluster health status. Corosync status, DRBD status... ''' stack = utils.cluster_stack() if not stack: err_buf.error( "No supported cluster stack found (tried heartbeat|openais|corosync)" ) if utils.cluster_stack() == 'corosync': print "Services:" for svc in ["corosync", "pacemaker"]: info = utils.service_info(svc) if info: print "%-16s %s" % (svc, info) else: print "%-16s unknown" % (svc) rc, outp = utils.get_stdout(['corosync-cfgtool', '-s'], shell=False) if rc == 0: print "" print outp else: print "Failed to get corosync status"
def verify(cib): rc, _, stderr = utils.get_stdout_stderr(cib_verify, cib) for i, line in enumerate(line for line in stderr.split('\n') if line): if i == 0: err_buf.error(_prettify(line, 0)) else: err_buf.writemsg(_prettify(line, 7)) return rc
def _copy_to_remote_dirs(hosts, path, opts): "Copy a local folder to same location on remote hosts" ok = True for host, result in _pssh_copy(hosts, path, path, opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: %s" % (host, result)) ok = False if not ok: raise ValueError("Failed when copying script data, aborting.")
def _run_cleanup(local_node, hosts, workdir, opts): "Clean up after the cluster script" if hosts and workdir: cleanscript = os.path.join(workdir, 'crm_clean.py') for host, result in _pssh_call(hosts, "%s %s" % (cleanscript, workdir), opts).iteritems(): if isinstance(result, pssh.Error): err_buf.debug("[%s]: Failed to clean up %s" % (host, workdir)) err_buf.error("[%s]: Clean: %s" % (host, result)) else: _print_output(host, *result) _cleanup_local(workdir)
def _create_remote_workdirs(hosts, path, opts): "Create workdirs on remote hosts" ok = True for host, result in _pssh_call(hosts, "mkdir -p %s" % (os.path.dirname(path)), opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: Start: %s" % (host, result)) ok = False if not ok: msg = "Failed to connect to one or more of these hosts via SSH: %s" % ( ', '.join(h[0] for h in hosts)) raise ValueError(msg)
def _print_debug(local_node, hosts, workdir, opts): "Print debug output (if any)" dbglog = os.path.join(workdir, 'crm_script.debug') for host, result in _pssh_call( hosts, "[ -f '%s' ] && cat '%s'" % (dbglog, dbglog), opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: %s" % (host, result)) else: _print_output(host, *result) if os.path.isfile(dbglog): f = open(dbglog).read() err_buf.ok("[%s]: %s" % (local_node, f))
def _print_debug(local_node, hosts, workdir, opts): "Print debug output (if any)" dbglog = os.path.join(workdir, 'crm_script.debug') for host, result in _pssh_call(hosts, "[ -f '%s' ] && cat '%s'" % (dbglog, dbglog), opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: %s" % (host, result)) else: _print_output(host, *result) if os.path.isfile(dbglog): f = open(dbglog).read() err_buf.ok("[%s]: %s" % (local_node, f))
def single_step(self, step_name, statefile): self.statefile = statefile for step in self.main['steps']: name, action, call = _step_action(step) if name == step_name: # if this is not the first step, load step data if step != self.main['steps'][0]: if os.path.isfile(statefile): self.data = json.load(open(statefile)) else: raise ValueError("No state for step: %s" % (step_name)) result = self.run_step(name, action, call) json.dump(self.data, open(self.statefile, 'w')) return result err_buf.error("%s: Step not found" % (step_name)) return False
def _copy_to_all(workdir, hosts, local_node, src, dst, opts): """ Copy src to dst both locally and remotely """ ok = True ret = _pssh_copy(hosts, src, dst, opts) for host, result in ret.iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: %s" % (host, result)) ok = False else: rc, out, err = result if rc != 0: err_buf.error("[%s]: %s" % (host, err)) ok = False if local_node and not src.startswith(workdir): try: if os.path.abspath(src) != os.path.abspath(dst): if os.path.isfile(src): shutil.copy(src, dst) else: shutil.copytree(src, dst) except (IOError, OSError, shutil.Error), e: err_buf.error("[%s]: %s" % (local_node, e)) ok = False
def do_status(self, context): ''' Quick cluster health status. Corosync status, DRBD status... ''' stack = utils.cluster_stack() if not stack: err_buf.error("No supported cluster stack found (tried heartbeat|openais|corosync)") if utils.cluster_stack() == 'corosync': print "Services:" for svc in ["corosync", "pacemaker"]: info = utils.service_info(svc) if info: print "%-16s %s" % (svc, info) else: print "%-16s unknown" % (svc) rc, outp = utils.get_stdout(['corosync-cfgtool', '-s'], shell=False) if rc == 0: print "" print outp else: print "Failed to get corosync status"
def do_run(self, context, cmd): ''' Execute the given command on all nodes, report outcome ''' try: from psshlib import api as pssh _has_pssh = True except ImportError: _has_pssh = False if not _has_pssh: context.fatal_error("PSSH not found") hosts = utils.list_cluster_nodes() opts = pssh.Options() for host, result in pssh.call(hosts, cmd, opts).iteritems(): if isinstance(result, pssh.Error): err_buf.error("[%s]: %s" % (host, result)) else: if result[0] != 0: err_buf.error("[%s]: rc=%s\n%s\n%s" % (host, result[0], result[1], result[2])) else: err_buf.ok("[%s]\n%s" % (host, result[1]))
def push_configuration(nodes): ''' Push the local configuration to the list of remote nodes ''' try: import parallax except ImportError: raise ValueError("parallax is required to push") local_path = conf() opts = parallax.Options() opts.timeout = 60 opts.ssh_options += ['ControlPersist=no'] ok = True for host, result in parallax.copy(nodes, local_path, local_path, opts).iteritems(): if isinstance(result, parallax.Error): err_buf.error("Failed to push configuration to %s: %s" % (host, result)) ok = False else: err_buf.ok(host) return ok
def _print_output(host, rc, out, err): "Print the output from a process that ran on host" if out: err_buf.ok("[%s]: %s" % (host, out)) if err: err_buf.error("[%s]: %s" % (host, err))
def error(self, fmt, *args): self.flush() err_buf.error(fmt % args)