def do_action(self, context, resource, action, ssh=None): ''' Issue action out-of-band to the given resource, making sure that the resource is in maintenance mode first ''' obj = cib_factory.find_object(resource) if not obj: context.fatal_error("Resource not found: %s" % (resource)) if not xmlutil.is_resource(obj.node): context.fatal_error("Not a resource: %s" % (resource)) if not self._in_maintenance_mode(obj): context.fatal_error("Not in maintenance mode.") if ssh is None: if action not in ('start', 'monitor'): if not self._runs_on_this_node(resource): context.fatal_error("Resource %s must be running on this node (%s)" % (resource, utils.this_node())) import rsctest return rsctest.call_resource(obj.node, action, [utils.this_node()], local_only=True) elif ssh == "ssh": import rsctest if action in ('start', 'promote', 'demote', 'recover', 'meta-data'): return rsctest.call_resource(obj.node, action, [utils.this_node()], local_only=True) else: all_nodes = cib_factory.node_id_list() return rsctest.call_resource(obj.node, action, all_nodes, local_only=False) else: context.fatal_error("Unknown argument: %s" % (ssh))
def _push_completer(args): try: n = utils.list_cluster_nodes() n.remove(utils.this_node()) return n except: n = []
def do_online(self, context, node=None): 'usage: online [<node>]' if not node: node = utils.this_node() if not utils.is_name_sane(node): return False return utils.ext_cmd(self.node_standby % (node, "off", "--lifetime='forever'")) == 0
def do_ready(self, context, node=None): 'usage: ready [<node>]' if not node: node = utils.this_node() if not utils.is_name_sane(node): return False return utils.ext_cmd(self.node_maint % (node, "off")) == 0
def runop(self, op, nodes=None, local_only=False): ''' Execute an operation. ''' if not nodes or self.run_on_all(op): nodes = self.nodes self.last_op = op self.set_rscenv(op) real_op = (op == "probe" and "monitor" or op) cmd = self.exec_cmd(real_op) common_debug("running %s on %s" % (real_op, nodes)) for attr in self.rscenv.keys(): # shell doesn't allow "-" in var names envvar = attr.replace("-", "_") cmd = "%s=%s %s" % (envvar, quote(self.rscenv[attr]), cmd) if local_only: self.ec_l[this_node()] = ext_cmd(cmd) else: from crm_pssh import do_pssh_cmd statuses = do_pssh_cmd(cmd, nodes, self.outdir, self.errdir, self.timeout) for i in range(len(nodes)): try: self.ec_l[nodes[i]] = statuses[i] except: self.ec_l[nodes[i]] = self.undef return
def do_push(self, context, *nodes): ''' Push corosync configuration to other cluster nodes. If no nodes are provided, configuration is pushed to all other cluster nodes. ''' if not nodes: nodes = utils.list_cluster_nodes() nodes.remove(utils.this_node()) return corosync.push_configuration(nodes)
def do_fence(self, context, node): 'usage: fence <node>' if not node: node = utils.this_node() if not utils.is_name_sane(node): return False if not config.core.force and \ not utils.ask("Do you really want to shoot %s?" % node): return False return utils.ext_cmd(self.node_fence % (node)) == 0
def diff_configuration(nodes, checksum=False): local_path = conf() this_node = utils.this_node() nodes = list(nodes) if checksum: utils.remote_checksum(local_path, nodes, this_node) elif len(nodes) == 1: utils.remote_diff_this(local_path, nodes, this_node) elif this_node in nodes: nodes.remove(this_node) utils.remote_diff_this(local_path, nodes, this_node) elif len(nodes): utils.remote_diff(local_path, nodes)
def do_action(self, context, resource, action, ssh=None): ''' Issue action out-of-band to the given resource, making sure that the resource is in maintenance mode first ''' obj = cib_factory.find_object(resource) if not obj: context.fatal_error("Resource not found: %s" % (resource)) if not xmlutil.is_resource(obj.node): context.fatal_error("Not a resource: %s" % (resource)) if not self._in_maintenance_mode(obj): context.fatal_error("Not in maintenance mode.") if ssh is None: if action not in ('start', 'monitor'): if not self._runs_on_this_node(resource): context.fatal_error( "Resource %s must be running on this node (%s)" % (resource, utils.this_node())) import rsctest return rsctest.call_resource(obj.node, action, [utils.this_node()], local_only=True) elif ssh == "ssh": import rsctest if action in ('start', 'promote', 'demote', 'recover', 'meta-data'): return rsctest.call_resource(obj.node, action, [utils.this_node()], local_only=True) else: all_nodes = cib_factory.node_id_list() return rsctest.call_resource(obj.node, action, all_nodes, local_only=False) else: context.fatal_error("Unknown argument: %s" % (ssh))
def do_clearstate(self, context, node=None): 'usage: clearstate <node>' if not node: node = utils.this_node() if not utils.is_name_sane(node): return False if not config.core.force and \ not utils.ask("Do you really want to drop state for node %s?" % node): return False if utils.is_pcmk_118(): return utils.ext_cmd(self.node_clear_state_118 % node) == 0 else: return utils.ext_cmd(self.node_clear_state % ("-M -c", node, node)) == 0 and \ utils.ext_cmd(self.node_clear_state % ("-R", node, node)) == 0
def _extract_localnode(hosts): """ Remove loal node from hosts list, so we can treat it separately """ this_node = utils.this_node() hosts2 = [] local_node = None for h, p, u in hosts: if h != this_node: hosts2.append((h, p, u)) else: local_node = (h, p, u) err_buf.debug("Local node: %s, Remote hosts: %s" % (local_node, ', '.join(h[0] for h in hosts2))) return local_node, hosts2
def _extract_localnode(hosts): """ Remove loal node from hosts list, so we can treat it separately """ this_node = utils.this_node() hosts2 = [] local_node = None for h, p, u in hosts: if h != this_node: hosts2.append((h, p, u)) else: local_node = (h, p, u) err_buf.debug("Local node: %s, Remote hosts: %s" % ( local_node, ', '.join(h[0] for h in hosts2))) return local_node, hosts2
def do_diff(self, context, filename, *nodes): "usage: diff <filename> [--checksum] [nodes...]. Diff file across cluster." this_node = utils.this_node() checksum = False if len(nodes) and nodes[0] == '--checksum': nodes = nodes[1:] checksum = True if not nodes: nodes = utils.list_cluster_nodes() if checksum: utils.remote_checksum(filename, nodes, this_node) elif len(nodes) == 1: utils.remote_diff_this(filename, nodes, this_node) elif this_node in nodes: nodes.remove(this_node) utils.remote_diff_this(filename, nodes, this_node) elif len(nodes): utils.remote_diff(filename, nodes)
def do_standby(self, context, *args): 'usage: standby [<node>] [<lifetime>]' argl = list(args) node = None lifetime = utils.fetch_lifetime_opt(argl, iso8601=False) if not argl: node = utils.this_node() elif len(argl) == 1: node = args[0] if not xmlutil.is_our_node(node): common_err("%s: node name not recognized" % node) return False else: syntax_err(args, context=context.get_command_name()) return False opts = '' if lifetime: opts = "--lifetime='%s'" % lifetime else: opts = "--lifetime='forever'" return utils.ext_cmd(self.node_standby % (node, "on", opts)) == 0
def diff_configuration(nodes, checksum=False): 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 diff") local_path = conf() this_node = utils.this_node() nodes = list(nodes) if checksum or len(nodes) > 2: _checksum(pssh, local_path, nodes, this_node) elif len(nodes) == 1: _diff_this(pssh, local_path, nodes, this_node) elif this_node in nodes: nodes.remove(this_node) _diff_this(pssh, local_path, nodes, this_node) elif len(nodes): _diff(pssh, local_path, nodes)
def _runs_on_this_node(self, resource): nodes = utils.running_on(resource) return set(nodes) == set([utils.this_node()])