changeset: 10788:6f9cc20dba0d user: Dejan Muhamedagic date: Mon Jul 18 12:35:57 2011 +0200 summary: Dev: Shell: spawn transition command from peinputs diff -r b694b75d2e33 -r 6f9cc20dba0d doc/crm.8.txt --- a/doc/crm.8.txt Mon Jul 18 12:35:57 2011 +0200 +++ b/doc/crm.8.txt Mon Jul 18 12:35:57 2011 +0200 @@ -2565,6 +2565,21 @@ were created (the DC at the time). The ` all PE input files to the current working directory (and use ssh if necessary). +Usage: +............... + peinputs list [{|} ...] + peinputs get [{|} ...] + + range :: : +............... +Example: +............... + peinputs get 440:444 446 +............... + +[[cmdhelp_history_transition,show transition]] +==== `transition` + The `show` subcommand will print actions planned by the PE and run graphviz (`dotty`) to display a graphical representation. Of course, for the latter an X11 session is required. This command @@ -2581,22 +2596,20 @@ last one, i.e. the last transition. If t then the corresponding transition relative to the last one is chosen. +After the `ptest` output, logs about events that happened during +the transition are printed. + Usage: ............... - peinputs list [{|} ...] - peinputs get [{|} ...] - peinputs show [] [nograph] [v...] [scores] [actions] [utilization] - peinputs showdot [] - - range :: : + transition show [] [nograph] [v...] [scores] [actions] [utilization] + transition showdot [] ............... -Example: +Examples: ............... - peinputs get 440:444 446 - peinputs show - peinputs show 444 - peinputs show -1 - peinputs showdot 444 + transition show + transition show 444 + transition show -1 + transition showdot 444 ............... === `end` (`cd`, `up`) diff -r b694b75d2e33 -r 6f9cc20dba0d shell/modules/log_patterns.py --- a/shell/modules/log_patterns.py Mon Jul 18 12:35:57 2011 +0200 +++ b/shell/modules/log_patterns.py Mon Jul 18 12:35:57 2011 +0200 @@ -64,6 +64,6 @@ log_patterns = { } transition_patt = ( - "crmd: .* Processing graph.*derived from (.*bz2)", # transition start - "crmd: .* Transition.*Source=(.*bz2): (Stopped|Complete|Terminated)", # and stop + "crmd: .* Processing graph.*derived from .*/pe-[^-]+-(%%)[.]bz2", # transition start + "crmd: .* Transition.*Source=.*/pe-[^-]+-(%%)[.]bz2.: (Stopped|Complete|Terminated)", # and stop ) diff -r b694b75d2e33 -r 6f9cc20dba0d shell/modules/report.py --- a/shell/modules/report.py Mon Jul 18 12:35:57 2011 +0200 +++ b/shell/modules/report.py Mon Jul 18 12:35:57 2011 +0200 @@ -177,8 +177,12 @@ class LogSyslog(object): find out start/end file positions. Logs need to be already open. ''' - self.from_ts = convert_dt(from_dt) - self.to_ts = convert_dt(to_dt) + if isinstance(from_dt, datetime.datetime): + self.from_ts = convert_dt(from_dt) + self.to_ts = convert_dt(to_dt) + else: + self.from_ts = from_dt + self.to_ts = to_dt bad_logs = [] for log in self.f: f = self.f[log] @@ -498,13 +502,14 @@ class Report(Singleton): if not os.path.isdir(self.outdir): return [] l = [] + trans_re_l = [x.replace("%%","") for x in transition_patt] for node,rptlog,logfile,nextpos in a: node_l = [] fl = glob.glob("%s/*%s*" % (self.outdir,node)) if not fl: continue for s in file2list(fl[0]): - r = re.search(transition_patt[0], s) + r = re.search(trans_re_l[0], s) if not r: continue node_l.append(r.group(1)) @@ -680,7 +685,8 @@ class Report(Singleton): self.find_central_log() self.read_cib() self.set_node_colors() - self.logobj = None + self.logobj = LogSyslog(self.central_log, self.log_l, \ + self.from_dt, self.to_dt) def prepare_source(self): ''' Unpack a hb_report tarball. @@ -740,6 +746,15 @@ class Report(Singleton): try: clr = self.nodecolor[a[3]] except: return s return termctrl.render("${%s}%s${NORMAL}" % (clr,s)) + def display_logs(self, l): + if not options.batch and sys.stdout.isatty(): + page_string('\n'.join([ self.disp(x) for x in l ])) + else: # raw output + try: # in case user quits the next prog in pipe + for s in l: print s + except IOError, msg: + if not ("Broken pipe" in msg): + common_err(msg) def show_logs(self, log_l = [], re_l = []): ''' Print log lines, either matched by re_l or all. @@ -749,18 +764,7 @@ class Report(Singleton): if not self.central_log and not log_l: self.error("no logs found") return - if not self.logobj: - self.logobj = LogSyslog(self.central_log, log_l, \ - self.from_dt, self.to_dt) - l = self.logobj.get_matches(re_l, log_l) - if not options.batch and sys.stdout.isatty(): - page_string('\n'.join([ self.disp(x) for x in l ])) - else: # raw output - try: # in case user quits the next prog in pipe - for s in l: print s - except IOError, msg: - if not ("Broken pipe" in msg): - common_err(msg) + self.display_logs(self.logobj.get_matches(re_l, log_l)) def match_args(self, cib_l, args): for a in args: a_clone = re.sub(r':.*', '', a) @@ -812,6 +816,34 @@ class Report(Singleton): self.error("no resources or nodes found") return False self.show_logs(re_l = all_re_l) + def show_transition_log(self, pe_file): + ''' + Search for events within the given transition. + ''' + pe_base = os.path.basename(pe_file) + r = re.search("pe-[^-]+-([0-9]+)[.]bz2", pe_base) + pe_num = r.group(1) + trans_re_l = [x.replace("%%",pe_num) for x in transition_patt] + trans_start = self.logobj.search_logs(self.log_l, trans_re_l[0]) + trans_end = self.logobj.search_logs(self.log_l, trans_re_l[1]) + if not trans_start: + common_warn("transition %s start not found in logs" % pe_base) + return False + if not trans_end: + common_warn("transition %s end not found in logs" % pe_base) + return False + common_debug("transition start: %s" % trans_start[0]) + common_debug("transition end: %s" % trans_end[0]) + start_ts = syslog_ts(trans_start[0]) + end_ts = syslog_ts(trans_end[0]) + if not start_ts or not end_ts: + self.warn("strange, no timestamps found") + return False + # limit the log scope temporarily + self.logobj.set_log_timeframe(start_ts, end_ts) + self.events() + self.logobj.set_log_timeframe(self.from_dt, self.to_dt) + return True def resource(self,*args): ''' Show resource relevant logs. diff -r b694b75d2e33 -r 6f9cc20dba0d shell/modules/ui.py.in --- a/shell/modules/ui.py.in Mon Jul 18 12:35:57 2011 +0200 +++ b/shell/modules/ui.py.in Mon Jul 18 12:35:57 2011 +0200 @@ -1686,7 +1686,8 @@ Examine Pacemaker's history: node and re self.cmd_table["resource"] = (self.resource,(1,),1,0) self.cmd_table["node"] = (self.node,(1,),1,1) self.cmd_table["log"] = (self.log,(0,),1,0) - self.cmd_table["peinputs"] = (self.peinputs,(0,),1,0) + self.cmd_table["peinputs"] = (self.peinputs,(1,),1,0) + self.cmd_table["transition"] = (self.transition,(1,),1,0) self._set_source(options.history) def _no_source(self): common_error("we have no source set yet! please use the source command") @@ -1832,57 +1833,63 @@ Examine Pacemaker's history: node and re return run_ptest(s, nograph, scores, utilization, actions, verbosity) def peinputs(self,cmd,subcmd,*args): """usage: peinputs list [{|} ...] - peinputs get [{|} ...] - peinputs show [] [nograph] [v...] [scores] [actions] [utilization] - peinputs showdot []""" - if subcmd in ("get","list"): - if args: - l = [] - for s in args: - a = convert2ints(s.split(':')) - if len(a) == 2 and not check_range(a): - common_err("%s: invalid peinputs range" % a) - return False - l += crm_report.pelist(a) - else: - l = crm_report.pelist() - if not l: return False - if subcmd == "list": - s = get_stdout("ls -lrt %s" % ' '.join(l)) - page_string(s) - else: - print '\n'.join(l) - elif subcmd in ("show","showdot"): - try: n = convert2ints(args[0]) - except: n = None - startarg = 1 - if n is None: - idx = -1 - startarg = 0 # peinput number missing - elif n <= 0: - idx = n - 1 - n = [] # to get all peinputs - else: - idx = 0 - if subcmd == "showdot": - if not user_prefs.dotty: - common_err("install graphviz to draw transition graphs") + peinputs get [{|} ...]""" + if subcmd not in ("get","list"): + bad_usage(cmd,subcmd) + return False + if args: + l = [] + for s in args: + a = convert2ints(s.split(':')) + if len(a) == 2 and not check_range(a): + common_err("%s: invalid peinputs range" % a) return False - l = crm_report.dotlist(n) - else: - l = crm_report.pelist(n) - if len(l) < abs(idx): - common_err("pe input or dot file not found") + l += crm_report.pelist(a) + else: + l = crm_report.pelist() + if not l: return False + if subcmd == "list": + s = get_stdout("ls -lrt %s" % ' '.join(l)) + page_string(s) + else: + print '\n'.join(l) + def transition(self,cmd,subcmd,*args): + """usage: transition show [] [nograph] [v...] [scores] [actions] [utilization] + transition showdot []""" + if subcmd not in ("show", "showdot"): + bad_usage(cmd,subcmd) + return False + try: n = convert2ints(args[0]) + except: n = None + startarg = 1 + if n is None: + idx = -1 + startarg = 0 # peinput number missing + elif n <= 0: + idx = n - 1 + n = [] # to get all peinputs + else: + idx = 0 + if subcmd == "showdot": + if not user_prefs.dotty: + common_err("install graphviz to draw transition graphs") return False - if subcmd == "show": - self.pe_file = l[idx] - return ptestlike(self.ptest,'vv',"%s %s" % \ - (cmd, subcmd), *args[startarg:]) - else: - show_dot_graph(l[idx]) + l = crm_report.dotlist(n) else: - bad_usage(cmd,' '.join(subcmd,args)) + l = crm_report.pelist(n) + if len(l) < abs(idx): + common_err("pe input or dot file not found") return False + rc = True + if subcmd == "show": + self.pe_file = l[idx] + rc = ptestlike(self.ptest,'vv',"%s %s" % \ + (cmd, subcmd), *args[startarg:]) + if rc: + crm_report.show_transition_log(self.pe_file) + else: + show_dot_graph(l[idx]) + return rc class TopLevel(UserInterface): '''