def do_trace(self, context, rsc_id, op, interval=None): 'usage: trace <rsc> <op> [<interval>]' rsc = self._get_trace_rsc(rsc_id) if not rsc: return False if not interval: interval = op == "monitor" and "non-0" or "0" if op == "probe": op = "monitor" op_node = xmlutil.find_operation(rsc.node, op, interval) if op_node is None and utils.crm_msec(interval) != 0: common_err("not allowed to create non-0 interval operation %s" % op) return False if op_node is None: head_pl = ["op", []] head_pl[1].append(["name", op]) head_pl[1].append(["interval", interval]) head_pl[1].append([vars.trace_ra_attr, "1"]) cli_list = [] cli_list.append(head_pl) if not rsc.add_operation(cli_list): return False else: op_node = rsc.set_op_attr(op_node, vars.trace_ra_attr, "1") if not cib_factory.commit(): return False if op == "monitor" and utils.crm_msec(interval) != 0: common_warn("please CLEANUP the RA trace directory %s regularly!" % config.path.heartbeat_dir) else: common_info("restart %s to get the trace" % rsc_id) return True
def sanity_check_ops(self, id, ops, default_timeout): ''' ops is a list of operations - do all operations exist - are timeouts sensible ''' rc = 0 n_ops = {} for op in ops: n_op = op[0] == "monitor" and monitor_name_pl(op[1]) or op[0] n_ops[n_op] = {} for p, v in op[1]: if p in self.skip_op_attr: continue n_ops[n_op][p] = v for req_op in self.required_ops: if req_op not in n_ops: if not (self.ra_class == "stonith" and req_op in ("start", "stop")): n_ops[req_op] = {} intervals = {} for op in n_ops: if self.ra_class == "stonith" and op in ("start", "stop"): continue if op not in self.actions(): common_warn("%s: action %s not advertised in meta-data, it may not be supported by the RA" % (id, op)) rc |= 1 if "interval" in n_ops[op]: v = n_ops[op]["interval"] v_msec = crm_msec(v) if op in ("start", "stop") and v_msec != 0: common_warn("%s: Specified interval for %s is %s, it must be 0" % (id, op, v)) rc |= 1 if op.startswith("monitor") and v_msec != 0: if v_msec not in intervals: intervals[v_msec] = 1 else: common_warn("%s: interval in %s must be unique" % (id, op)) rc |= 1 try: adv_timeout = self.actions()[op]["timeout"] except: continue if "timeout" in n_ops[op]: v = n_ops[op]["timeout"] timeout_string = "specified timeout" else: v = default_timeout timeout_string = "default timeout" if crm_msec(v) < 0: continue if crm_time_cmp(adv_timeout, v) > 0: common_warn("%s: %s %s for %s is smaller than the advised %s" % (id, timeout_string, v, op, adv_timeout)) rc |= 1 return rc
def _trace_op_interval(self, context, rsc_id, rsc, op, interval): op_node = xmlutil.find_operation(rsc.node, op, interval) if op_node is None and utils.crm_msec(interval) != 0: context.err("Operation %s with interval %s not found in %s" % (op, interval, rsc_id)) if op_node is None: if not self._add_trace_op(rsc, op, interval): context.err("Failed to add trace for %s:%s" % (rsc_id, op)) else: rsc.set_op_attr(op_node, constants.trace_ra_attr, "1")
def _trace_op_interval(self, context, rsc_id, rsc, op, interval): op_node = xmlutil.find_operation(rsc.node, op, interval) if op_node is None and utils.crm_msec(interval) != 0: context.fatal_error("Operation %s with interval %s not found in %s" % (op, interval, rsc_id)) if op_node is None: if not self._add_trace_op(rsc, op, interval): context.fatal_error("Failed to add trace for %s:%s" % (rsc_id, op)) else: rsc.set_op_attr(op_node, constants.trace_ra_attr, "1")
def test_msec(): assert utils.crm_msec('1ms') == 1 assert utils.crm_msec('1s') == 1000 assert utils.crm_msec('1us') == 0 assert utils.crm_msec('1') == 1000 assert utils.crm_msec('1m') == 60*1000 assert utils.crm_msec('1h') == 60*60*1000
def find_operation(rsc_node, name, interval="0"): ''' Setting interval to "non-0" means get the first op with interval different from 0. ''' op_node_l = rsc_node.findall("operations") for ops in op_node_l: for c in ops.iterchildren("op"): if c.get("name") != name: continue if (interval == "non-0" and crm_msec(c.get("interval")) > 0) or \ crm_time_cmp(c.get("interval"), interval) == 0: return c
def find_operation(rsc_node, name, interval=None): ''' Setting interval to "non-0" means get the first op with interval different from 0. Not setting interval at all means get the only matching op, or the 0 op (if any) ''' matching_name = [] for ops in rsc_node.findall("operations"): matching_name.extend( [op for op in ops.iterchildren("op") if op.get("name") == name]) if interval is None and len(matching_name) == 1: return matching_name[0] interval = interval or "0" for op in matching_name: opint = op.get("interval") if interval == "non-0" and crm_msec(opint) > 0: return op if crm_time_cmp(opint, interval) == 0: return op return None
def find_operation(rsc_node, name, interval=None): ''' Setting interval to "non-0" means get the first op with interval different from 0. Not setting interval at all means get the only matching op, or the 0 op (if any) ''' matching_name = [] for ops in rsc_node.findall("operations"): matching_name.extend([op for op in ops.iterchildren("op") if op.get("name") == name]) if interval is None and len(matching_name) == 1: return matching_name[0] interval = interval or "0" for op in matching_name: opint = op.get("interval") if interval == "non-0" and crm_msec(opint) > 0: return op if crm_time_cmp(opint, interval) == 0: return op return None
def get_op_timeout(rsc_node, op, default_timeout): interval = (op == "monitor" and "non-0" or "0") op_n = find_operation(rsc_node, op == "probe" and "monitor" or op, interval) timeout = op_n is not None and op_n.get("timeout") or default_timeout return crm_msec(timeout)