pacemaker/crm_history_6_441f4448eba6.patch

246 lines
8.6 KiB
Diff
Raw Normal View History

- Upgrade to 1.1.6. - 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
2011-09-20 16:36:23 +02:00
# HG changeset patch
# User Dejan Muhamedagic <dejan@hello-penguin.com>
# Date 1313081065 -7200
# Node ID 441f4448eba6eda1a2cf44d3d63a0db9f8d56a20
# Parent c3068d22de72d1ba616d43c808091bef830eb9f6
Medium: Shell: reimplement the history latest command (bnc#710958)
This command is going to show logs for the latest transition.
Basically, it's the same as "history transition", but it will
wait for the current (if any) transition to finish.
(Also, the horrible transition command arg parsing has been
improved.)
diff --git a/shell/modules/report.py b/shell/modules/report.py
--- a/shell/modules/report.py
+++ b/shell/modules/report.py
@@ -467,8 +467,7 @@ class Report(Singleton):
def is_last_live_recent(self):
'''
Look at the last live hb_report. If it's recent enough,
- return True. Return True also if self.to_dt is not empty
- (not an open end report).
+ return True.
'''
try:
last_ts = os.stat(self.desc).st_mtime
@@ -800,6 +799,7 @@ class Report(Singleton):
if self.source != "live":
self.error("refresh not supported")
return False
+ self.last_live_update = 0
self.loc = self.manage_live_report(force)
self.report_setup()
self.ready = self.check_report()
@@ -884,18 +884,10 @@ class Report(Singleton):
print "Nodes:",' '.join(self.cibnode_l)
print "Groups:",' '.join(self.cibgrp_d.keys())
print "Resources:",' '.join(self.cibrsc_l)
- def latest(self):
- '''
- Get the very latest cluster events, basically from the
- latest transition.
- Some transitions may be empty though.
- '''
def events(self):
'''
Show all events.
'''
- if not self.prepare_source():
- return False
all_re_l = self.build_re("resource",self.cibrsc_l) + \
self.build_re("node",self.cibnode_l)
if not all_re_l:
@@ -906,6 +898,8 @@ class Report(Singleton):
'''
Search for events within the given transition.
'''
+ if not self.prepare_source():
+ return False
pe_base = os.path.basename(pe_file)
r = re.search("pe-[^-]+-([0-9]+)[.]", pe_base)
pe_num = r.group(1)
@@ -926,6 +920,9 @@ class Report(Singleton):
self.warn("strange, no timestamps found")
return False
# limit the log scope temporarily
+ common_info("logs for transition %s (%s-%s)" %
+ (pe_file.replace(self.loc+"/",""), \
+ shorttime(start_ts), shorttime(end_ts)))
self.logobj.set_log_timeframe(start_ts, end_ts)
self.events()
self.logobj.set_log_timeframe(self.from_dt, self.to_dt)
@@ -994,6 +991,11 @@ class Report(Singleton):
'Find a PE or dot file matching part of the path.'
pe_l = path.endswith(".dot") and self.dotlist() or self.pelist()
return [x for x in pe_l if x.endswith(path)]
+ def pe2dot(self, f):
+ f = f.replace("bz2","dot")
+ if os.path.isfile(f):
+ return f
+ return None
def find_file(self, f):
return file_find_by_name(self.loc, f)
diff --git a/shell/modules/ui.py.in b/shell/modules/ui.py.in
--- a/shell/modules/ui.py.in
+++ b/shell/modules/ui.py.in
@@ -1796,22 +1796,15 @@ Examine Pacemaker's history: node and re
return crm_report.info()
def latest(self,cmd):
"usage: latest"
- try:
- prev_level = levels.previous().myname()
- except:
- prev_level = ''
- if prev_level != "cibconfig":
- common_err("%s is available only when invoked from configure" % cmd)
- return False
- ts = cib_factory.last_commit_at()
- if not ts:
- common_err("no last commit time found")
- return False
if not wait4dc("transition", not options.batch):
return False
- self._set_source("live", ts)
+ self._set_source("live")
crm_report.refresh_source()
- return crm_report.events()
+ f = self._get_pe_byidx(-1)
+ if not f:
+ common_err("no transitions found")
+ return False
+ crm_report.show_transition_log(f)
def resource(self,cmd,*args):
"usage: resource <rsc> [<rsc> ...]"
return crm_report.resource(*args)
@@ -1853,6 +1846,30 @@ Examine Pacemaker's history: node and re
else:
s = '\n'.join(l)
page_string(s)
+ def _get_pe_byname(self, s):
+ l = crm_report.find_pe_files(s)
+ if len(l) == 0:
+ common_err("%s: path not found" % s)
+ return None
+ elif len(l) > 1:
+ common_err("%s: path ambiguous" % s)
+ return None
+ return l[0]
+ def _get_pe_byidx(self, idx):
+ l = crm_report.pelist()
+ if len(l) < abs(idx):
+ common_err("pe input file not found")
+ return None
+ return l[idx]
+ def _get_pe_bynum(self, n):
+ l = crm_report.pelist([n])
+ if len(l) == 0:
+ common_err("%s: PE file %d not found" % n)
+ return None
+ elif len(l) > 1:
+ common_err("%s: PE file %d ambiguous" % n)
+ return None
+ return l[0]
def transition(self,cmd,*args):
"""usage: transition [<number>|<file>] [nograph] [v...] [scores] [actions] [utilization]
transition showdot [<number>|<file>]"""
@@ -1864,48 +1881,35 @@ Examine Pacemaker's history: node and re
return False
subcmd = "showdot"
argl.remove(subcmd)
- f = None
- startarg = 1
- if argl and re.search('pe-', argl[0]):
- l = crm_report.find_pe_files(argl[0])
- if len(l) == 0:
- common_err("%s: path not found" % argl[0])
- return False
- elif len(l) > 1:
- common_err("%s: path ambiguous" % argl[0])
- return False
- f = l[0]
+ if argl:
+ if re.search('pe-', argl[0]):
+ f = self._get_pe_byname(argl[0])
+ argl.pop(0)
+ elif is_int(argl[0]):
+ n = int(argl[0])
+ if n <= 0:
+ f = self._get_pe_byidx(n-1)
+ else:
+ f = self._get_pe_bynum(n)
+ argl.pop(0)
+ else:
+ f = self._get_pe_byidx(-1)
else:
- try: n = convert2ints(argl[0])
- except: n = None
- 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":
- l = crm_report.dotlist(n)
- else:
- l = crm_report.pelist(n)
- if len(l) < abs(idx):
- if subcmd == "show":
- common_err("pe input file not found")
- else:
- common_err("dot file not found")
- return False
- f = l[idx]
+ f = self._get_pe_byidx(-1)
if not f:
return False
rc = True
if subcmd == "show":
self.pe_file = f # self.pe_file needed by self.ptest
+ common_info("running ptest with %s" % f)
rc = ptestlike(self.ptest,'vv',"%s %s" % \
- (cmd, subcmd), *argl[startarg:])
+ (cmd, subcmd), *argl)
else:
- show_dot_graph(f.replace("bz2","dot"))
+ f = crm_report.pe2dot(f)
+ if not f:
+ common_err("dot file not found in the report")
+ return False
+ show_dot_graph(f)
if rc:
crm_report.show_transition_log(f)
return rc
diff --git a/shell/modules/utils.py b/shell/modules/utils.py
--- a/shell/modules/utils.py
+++ b/shell/modules/utils.py
@@ -449,6 +449,9 @@ def check_range(a):
return False
return (int(a[0]) <= int(a[1]))
+def shorttime(ts):
+ return time.strftime("%X",time.localtime(ts))
+
def sort_by_mtime(l):
'Sort a (small) list of files by time mod.'
l2 = [(os.stat(x).st_mtime, x) for x in l]
@@ -489,6 +492,13 @@ def convert2ints(l):
else: # it's a string then
return int(l)
except: return None
+def is_int(s):
+ 'Check if the string can be converted to an integer.'
+ try:
+ i = int(s)
+ return True
+ except:
+ return False
def is_process(s):
proc = subprocess.Popen("ps -e -o pid,command | grep -qs '%s'" % s, \