0440703030
- PE: Demote from Master does not clear previous errors - crmd: Prevent secondary DC fencing resulting from CIB updates that are lost due to elections - crmd: Log duplicate DC detection as a WARNING not ERROR - crmd: Bug lf#2632 - Correctly handle nodes that return faster than stonith - Core: Treat GNUTLS_E_UNEXPECTED_PACKET_LENGTH as normal termination of a TLS session - cib: Call gnutls_bye() and shutdown() when disconnecting from remote TLS connections - cib: Remove disconnected remote connections from mainloop - cib: Attempt a graceful sign-off for remote TLS connections - Core: Ensure there is sufficient space for EOS when building short-form option strings (prevents segfault) - Core: Fix variable expansion in pkg-config files - PE: Resolve memory leak reported by valgrind - PE: Fix memory leak for re-allocated resources reported by valgrind - PE: Improve the merging with template's operations - crmd: Allow nodes to fence themselves if they're the last one standing (lf#2584) - stonith: Add an API call for listing installed agents - stonith: Allow the fencing history to be queried - stonith: Ensure completed operations are recorded as such in the history - stonith: Support --quiet to display just the seconds since epoch at which a node was last shot - stonith: Serialize actions for a given device - stonith: Add missing entries to stonith_error2string() (missing OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/pacemaker?expand=0&rev=18
316 lines
12 KiB
Diff
316 lines
12 KiB
Diff
changeset: 10788:6f9cc20dba0d
|
|
user: Dejan Muhamedagic <dejan@hello-penguin.com>
|
|
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 [{<range>|<number>} ...]
|
|
+ peinputs get [{<range>|<number>} ...]
|
|
+
|
|
+ range :: <n1>:<n2>
|
|
+...............
|
|
+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 [{<range>|<number>} ...]
|
|
- peinputs get [{<range>|<number>} ...]
|
|
- peinputs show [<number>] [nograph] [v...] [scores] [actions] [utilization]
|
|
- peinputs showdot [<number>]
|
|
-
|
|
- range :: <n1>:<n2>
|
|
+ transition show [<number>] [nograph] [v...] [scores] [actions] [utilization]
|
|
+ transition showdot [<number>]
|
|
...............
|
|
-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 [{<range>|<number>} ...]
|
|
- peinputs get [{<range>|<number>} ...]
|
|
- peinputs show [<number>] [nograph] [v...] [scores] [actions] [utilization]
|
|
- peinputs showdot [<number>]"""
|
|
- 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 [{<range>|<number>} ...]"""
|
|
+ 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 [<number>] [nograph] [v...] [scores] [actions] [utilization]
|
|
+ transition showdot [<number>]"""
|
|
+ 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):
|
|
'''
|
|
|