Hello community,

here is the log from the commit of package crmsh for openSUSE:Factory checked 
in at 2014-10-11 19:26:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/crmsh (Old)
 and      /work/SRC/openSUSE:Factory/.crmsh.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "crmsh"

Changes:
--------
--- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes      2014-09-28 
19:54:13.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2014-10-11 
19:28:33.000000000 +0200
@@ -1,0 +2,19 @@
+Fri Oct 10 17:30:14 UTC 2014 - kgronl...@suse.com
+
+- high: report: Find nodes for any log type (boo#900654)
+- high: hb_report: Collect logs from journald (boo#900654)
+- upstream cs: 2.1.0-98-g2405e74
+
+-------------------------------------------------------------------
+Fri Oct 10 08:50:08 UTC 2014 - kgronl...@suse.com
+
+- high: ui_maintenance: Add maintenance sublevel (bnc#899234)
+- medium: rsctest: Add basic support for systemd services
+- medium: ui_maintenance: Combine action and actionssh into a single command
+- low: rsctest: Better error message for unsupported action
+- low: cibconfig: Improve wording of commit prompt
+- high: cibconfig: Delay reinitialization after commit (bnc#900271)
+- medium: main: Disable interspersed args
+- upstream cs: 2.1.0-95-g744ad66
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.5NmvSC/_old  2014-10-11 19:28:34.000000000 +0200
+++ /var/tmp/diff_new_pack.5NmvSC/_new  2014-10-11 19:28:34.000000000 +0200
@@ -41,7 +41,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0+
 Group:          %{pkg_group}
-Version:        2.1+git82
+Version:        2.1+git98
 Release:        %{?crmsh_release}%{?dist}
 Url:            http://crmsh.github.io
 Source0:        crmsh.tar.bz2

++++++ crmsh.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/doc/crm.8.adoc new/crmsh/doc/crm.8.adoc
--- old/crmsh/doc/crm.8.adoc    2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/doc/crm.8.adoc    2014-10-10 19:26:22.000000000 +0200
@@ -3808,6 +3808,76 @@
 weak-bond resource-1 resource-2
 ........
 
+[[cmdhelp_maintenance,Maintenance mode commands]]
+=== `maintenance` - Maintenance mode commands
+
+Maintenance mode commands are commands that manipulate resources
+directly without going through the cluster infrastructure. Therefore,
+it is essential to ensure that the cluster does not attempt to monitor
+or manipulate the resources while these commands are being executed.
+
+To ensure this, these commands require that maintenance mode is set
+either for the particular resource, or for the whole cluster.
+
+[[cmdhelp_maintenance_on,Enable maintenance mode]]
+==== `on`
+
+Enables maintenances mode, either for the whole cluster
+or for the given resource.
+
+Usage:
+...............
+on
+on <rsc>
+...............
+Example:
+...............
+on rsc1
+...............
+
+[[cmdhelp_maintenance_off,Disable maintenance mode]]
+==== `off`
+
+Disables maintenances mode, either for the whole cluster
+or for the given resource.
+
+Usage:
+...............
+off
+off <rsc>
+...............
+Example:
+...............
+off rsc1
+...............
+
+[[cmdhelp_maintenance_action,Invoke a resource action]]
+==== `action`
+
+Invokes the given action for the resource. This is
+done directly via the resource agent, so the command must
+be issued while the cluster or the resource is in 
+maintenance mode.
+
+Unless the action is `start` or `monitor`, the action must be invoked
+on the same node as where the resource is running. If the resource is
+running on multiple nodes, the command will fail.
+
+To use pssh for executing resource actions on multiple nodes, append
+`ssh` after the action name. This requires SSH access to be configured
+between the nodes and the pssh package to be installed.
+
+Usage:
+...............
+action <rsc> <action>
+action <rsc> <action> ssh
+...............
+Example:
+...............
+action webserver reload
+action webserver monitor ssh
+...............
+
 [[cmdhelp_history,Cluster history]]
 === `history` - Cluster history
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/doc/website-v1/Makefile 
new/crmsh/doc/website-v1/Makefile
--- old/crmsh/doc/website-v1/Makefile   2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/doc/website-v1/Makefile   2014-10-10 19:26:22.000000000 +0200
@@ -1,4 +1,5 @@
 ASCIIDOC := asciidoc
+CRMCONF := crm.conf
 SRC := faq.adoc documentation.adoc development.adoc installation.adoc \
        configuration.adoc about.adoc rsctest-guide.adoc \
        history-guide.adoc start-guide.adoc man-1.2.adoc scripts.adoc 
man-2.0.adoc
@@ -20,33 +21,33 @@
 
 all: site
 
-gen/index.html: index.adoc crm.conf
+gen/index.html: index.adoc $(CRMCONF)
        @mkdir -p $(dir $@)
-       @$(ASCIIDOC) --unsafe -b html5 -f crm.conf -o $@ $<
+       @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
        @python ./postprocess.py -o $@ $<
 
-gen/%/index.html: %.adoc crm.conf
+gen/%/index.html: %.adoc $(CRMCONF)
        @mkdir -p $(dir $@)
-       @$(ASCIIDOC) --unsafe -b html5 -f crm.conf -o $@ $<
+       @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
        @python ./postprocess.py -o $@ $<
 
-gen/man/index.html: ../crm.8.adoc crm.conf
+gen/man/index.html: ../crm.8.adoc $(CRMCONF)
        @mkdir -p $(dir $@)
-       @$(ASCIIDOC) --unsafe -b html5 -f crm.conf -o $@ $<
+       @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
        @python ./postprocess.py -o $@ $<
 
-gen/404.html: 404.adoc crm.conf
+gen/404.html: 404.adoc $(CRMCONF)
        @mkdir -p $(dir $@)
-       @$(ASCIIDOC) --unsafe -b html5 -f crm.conf -o $@ $<
+       @$(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
        @python ./postprocess.py -o $@ $<
 
-news.adoc: $(NEWS) crm.conf
+news.adoc: $(NEWS) $(CRMCONF)
        @echo "news:"; $(NEWS)
        python ./make-news.py $@ $(NEWS)
 
 gen/news/index.html: news.adoc
        @mkdir -p $(dir $@)
-       $(ASCIIDOC) --unsafe -b html5 -f crm.conf -o $@ $<
+       $(ASCIIDOC) --unsafe -b html5 -f $(CRMCONF) -o $@ $<
        @python ./postprocess.py -o $@ $<
 
 gen/css/%.css: css/%.css
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/doc/website-v1/crmold.conf 
new/crmsh/doc/website-v1/crmold.conf
--- old/crmsh/doc/website-v1/crmold.conf        1970-01-01 01:00:00.000000000 
+0100
+++ new/crmsh/doc/website-v1/crmold.conf        2014-10-10 19:26:22.000000000 
+0200
@@ -0,0 +1,602 @@
+#
+# html5.conf
+#
+# Asciidoc configuration file.
+# html5 backend.
+#
+
+[miscellaneous]
+outfilesuffix=.html
+
+[attributes]
+basebackend=html
+basebackend-html=
+basebackend-html5=
+b
+[replacements2]
+# Line break.
+(?m)^(.*)\s\+$=\1<br>
+
+[replacements]
+ifdef::asciidoc7compatible[]
+# Superscripts.
+\^(.+?)\^=<sup>\1</sup>
+# Subscripts.
+~(.+?)~=<sub>\1</sub>
+endif::asciidoc7compatible[]
+
+[ruler-blockmacro]
+<hr>
+
+[pagebreak-blockmacro]
+<div style="page-break-after:always"></div>
+
+[blockdef-pass]
+asciimath-style=template="asciimathblock",subs=()
+latexmath-style=template="latexmathblock",subs=()
+
+[macros]
+(?u)^(?P<name>audio|video)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=#
+# math macros.
+# Special characters are escaped in HTML math markup.
+(?su)[\\]?(?P<name>asciimath|latexmath):(?P<subslist>\S*?)\[(?P<passtext>.*?)(?<!\\)\]=[specialcharacters]
+(?u)^(?P<name>asciimath|latexmath)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#[specialcharacters]
+
+[asciimath-inlinemacro]
+`{passtext}`
+
+[asciimath-blockmacro]
+<div class="mathblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+`{passtext}`
+</div></div>
+
+[asciimathblock]
+<div class="mathblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+`|`
+</div></div>
+
+[latexmath-inlinemacro]
+{passtext}
+
+[latexmath-blockmacro]
+<div class="mathblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+{passtext}
+</div></div>
+
+[latexmathblock]
+<div class="mathblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+|
+</div></div>
+
+[image-inlinemacro]
+<span class="image{role? {role}}">
+<a class="image" href="{link}">
+{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" 
alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? 
title="{title}"}>
+{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? 
height="{height}"}{title? title="{title}"}
+{data-uri#}{sys:"{python}" -u -c "import mimetypes,base64,sys; print 
'src=\"data:'+mimetypes.guess_type(r'{target}')[0]+';base64,'; 
base64.encode(sys.stdin,sys.stdout)" < 
"{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
+{link#}</a>
+</span>
+
+[image-blockmacro]
+<div class="imageblock{style? {style}}{role? {role}}{unbreakable-option? 
unbreakable}"{id? id="{id}"}{align? style="text-align:{align};"}{float? 
style="float:{float};"}>
+<div class="content">
+<a class="image" href="{link}">
+{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" 
alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}>
+{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? 
height="{height}"}
+{data-uri#}{sys:"{python}" -u -c "import mimetypes,base64,sys; print 
'src=\"data:'+mimetypes.guess_type(r'{target}')[0]+';base64,'; 
base64.encode(sys.stdin,sys.stdout)" < 
"{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
+{link#}</a>
+</div>
+<div class="title">{caption={figure-caption} {counter:figure-number}. 
}{title}</div>
+</div>
+
+[audio-blockmacro]
+<div class="audioblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content">
+<audio src="{imagesdir=}{imagesdir?/}{target}"{autoplay-option? 
autoplay}{nocontrols-option! controls}{loop-option? loop}>
+Your browser does not support the audio tag.
+</audio>
+</div></div>
+
+[video-blockmacro]
+<div class="videoblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content">
+<video src="{imagesdir=}{imagesdir?/}{target}"{width? width="{width}"}{height? 
height="{height}"}{poster? poster="{poster}"}{autoplay-option? 
autoplay}{nocontrols-option! controls}{loop-option? loop}>
+Your browser does not support the video tag.
+</video>
+</div></div>
+
+[unfloat-blockmacro]
+<div style="clear:both;"></div>
+
+[toc-blockmacro]
+template::[toc]
+
+[indexterm-inlinemacro]
+# Index term.
+{empty}
+
+[indexterm2-inlinemacro]
+# Index term.
+# Single entry index term that is visible in the primary text flow.
+{1}
+
+[footnote-inlinemacro]
+# footnote:[<text>].
+<span class="footnote"><br>[{0}]<br></span>
+
+[footnoteref-inlinemacro]
+# footnoteref:[<id>], create reference to footnote.
+{2%}<span class="footnoteref"><br><a href="#_footnote_{1}">[{1}]</a><br></span>
+# footnoteref:[<id>,<text>], create footnote with ID.
+{2#}<span class="footnote" id="_footnote_{1}"><br>[{2}]<br></span>
+
+[callout-inlinemacro]
+ifndef::icons[]
+<b>&lt;{index}&gt;</b>
+endif::icons[]
+ifdef::icons[]
+ifndef::data-uri[]
+<img src="{icon={iconsdir}/callouts/{index}.png}" alt="{index}">
+endif::data-uri[]
+ifdef::data-uri[]
+<img alt="{index}" src="data:image/png;base64,
+{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" 
< 
"{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{index}.png}")}"}">
+endif::data-uri[]
+endif::icons[]
+
+# Comment line macros.
+[comment-inlinemacro]
+{showcomments#}<br><span class="comment">{passtext}</span><br>
+
+[comment-blockmacro]
+{showcomments#}<p><span class="comment">{passtext}</span></p>
+
+[literal-inlinemacro]
+# Inline literal.
+<span class="monospaced">{passtext}</span>
+
+# List tags.
+[listtags-bulleted]
+list=<div class="ulist{style? {style}}{compact-option? compact}{role? 
{role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[listtags-numbered]
+# The start attribute is not valid XHTML 1.1 but all browsers support it.
+list=<div class="olist{style? {style}}{compact-option? compact}{role? 
{role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol 
class="{style}"{start? start="{start}"}>|</ol></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[listtags-labeled]
+list=<div class="dlist{compact-option? compact}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
+entry=
+label=
+term=<dt class="hdlist1{strong-option? strong}">|</dt>
+item=<dd>|</dd>
+text=<p>|</p>
+
+[listtags-horizontal]
+list=<div class="hdlist{compact-option? compact}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<table>{labelwidth?<col 
width="{labelwidth}%">}{itemwidth?<col width="{itemwidth}%">}|</table></div>
+label=<td class="hdlist1{strong-option? strong}">|</td>
+term=|<br>
+entry=<tr>|</tr>
+item=<td class="hdlist2">|</td>
+text=<p style="margin-top: 0;">|</p>
+
+[listtags-qanda]
+list=<div class="qlist{style? {style}}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
+entry=<li>|</li>
+label=
+term=<p><em>|</em></p>
+item=
+text=<p>|</p>
+
+[listtags-callout]
+ifndef::icons[]
+list=<div class="colist{style? {style}}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
+item=<li>|</li>
+text=<p>|</p>
+endif::icons[]
+ifdef::icons[]
+list=<div class="colist{style? {style}}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<table>|</table></div>
+ifndef::data-uri[]
+item=<tr><td><img src="{iconsdir}/callouts/{listindex}.png" 
alt="{listindex}"></td><td>|</td></tr>
+endif::data-uri[]
+ifdef::data-uri[]
+item=<tr><td><img alt="{listindex}" src="data:image/png;base64, 
{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" 
< 
"{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{listindex}.png}")}"}"></td><td>|</td></tr>
+endif::data-uri[]
+text=|
+endif::icons[]
+
+[listtags-glossary]
+list=<div class="dlist{style? {style}}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
+label=
+entry=
+term=<dt>|</dt>
+item=<dd>|</dd>
+text=<p>|</p>
+
+[listtags-bibliography]
+list=<div class="ulist{style? {style}}{role? {role}}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[tags]
+# Quoted text.
+emphasis=<em>{1?<span class="{1}">}|{1?</span>}</em>
+strong=<strong>{1?<span class="{1}">}|{1?</span>}</strong>
+monospaced=<span class="monospaced{1? {1}}">|</span>
+singlequoted={lsquo}{1?<span class="{1}">}|{1?</span>}{rsquo}
+doublequoted={ldquo}{1?<span class="{1}">}|{1?</span>}{rdquo}
+unquoted={1?<span class="{1}">}|{1?</span>}
+superscript=<sup>{1?<span class="{1}">}|{1?</span>}</sup>
+subscript=<sub>{1?<span class="{1}">}|{1?</span>}</sub>
+
+ifdef::deprecated-quotes[]
+# Override with deprecated quote attributes.
+emphasis={role?<span class="{role}">}<em{1,2,3? 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</em>{role?</span>}
+strong={role?<span class="{role}">}<strong{1,2,3? 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</strong>{role?</span>}
+monospaced=<span class="monospaced{role? {role}}"{1,2,3? 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</span>
+singlequoted={role?<span class="{role}">}{1,2,3?<span 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8216;|{amp}#8217;{1,2,3?</span>}{role?</span>}
+doublequoted={role?<span class="{role}">}{1,2,3?<span 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8220;|{amp}#8221;{1,2,3?</span>}{role?</span>}
+unquoted={role?<span class="{role}">}{1,2,3?<span 
style="{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}">}|{1,2,3?</span>}{role?</span>}
+superscript={role?<span class="{role}">}<sup{1,2,3? 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sup>{role?</span>}
+subscript={role?<span class="{role}">}<sub{1,2,3? 
style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sub>{role?</span>}
+endif::deprecated-quotes[]
+
+# Inline macros
+[http-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[https-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[ftp-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[file-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[irc-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[mailto-inlinemacro]
+<a href="mailto:{target}";>{0={target}}</a>
+[link-inlinemacro]
+<a href="{target}">{0={target}}</a>
+[callto-inlinemacro]
+<a href="{name}:{target}">{0={target}}</a>
+# anchor:id[text]
+[anchor-inlinemacro]
+<a id="{target}"></a>
+# [[id,text]]
+[anchor2-inlinemacro]
+<a id="{1}"></a>
+# [[[id]]]
+[anchor3-inlinemacro]
+<a id="{1}"></a>[{1}]
+# xref:id[text]
+[xref-inlinemacro]
+<a href="#{target}">{0=[{target}]}</a>
+# <<id,text>>
+[xref2-inlinemacro]
+<a href="#{1}">{2=[{1}]}</a>
+
+# Special word substitution.
+[emphasizedwords]
+<em>{words}</em>
+[monospacedwords]
+<span class="monospaced">{words}</span>
+[strongwords]
+<strong>{words}</strong>
+
+# Paragraph substitution.
+[paragraph]
+<div class="paragraph{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>{title?<div class="title">{title}</div>}<p>
+|
+</p></div>
+
+[admonitionparagraph]
+template::[admonitionblock]
+
+# Delimited blocks.
+[listingblock]
+<div class="listingblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content monospaced">
+<pre>
+|
+</pre>
+</div></div>
+
+[literalblock]
+<div class="literalblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{title}</div>
+<div class="content monospaced">
+<pre>
+|
+</pre>
+</div></div>
+
+[sidebarblock]
+<div class="sidebarblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+|
+</div></div>
+
+[openblock]
+<div class="openblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{title}</div>
+<div class="content">
+|
+</div></div>
+
+[partintroblock]
+template::[openblock]
+
+[abstractblock]
+template::[quoteblock]
+
+[quoteblock]
+<div class="quoteblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{title}</div>
+<div class="content">
+|
+</div>
+<div class="attribution">
+<em>{citetitle}</em>{attribution?<br>}
+&#8212; {attribution}
+</div></div>
+
+[verseblock]
+<div class="verseblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{title}</div>
+<pre class="content">
+|
+</pre>
+<div class="attribution">
+<em>{citetitle}</em>{attribution?<br>}
+&#8212; {attribution}
+</div></div>
+
+[exampleblock]
+<div class="exampleblock{role? {role}}{unbreakable-option? unbreakable}"{id? 
id="{id}"}>
+<div class="title">{caption={example-caption} {counter:example-number}. 
}{title}</div>
+<div class="content">
+|
+</div></div>
+
+[admonitionblock]
+<div class="admonitionblock{role? {role}}{unbreakable-option? 
unbreakable}"{id? id="{id}"}>
+<table><tr>
+<td class="icon">
+{data-uri%}{icons#}<img src="{icon={iconsdir}/{name}.png}" alt="{caption}">
+{data-uri#}{icons#}<img alt="{caption}" src="data:image/png;base64,
+{data-uri#}{icons#}{sys:"{python}" -u -c "import base64,sys; 
base64.encode(sys.stdin,sys.stdout)" < 
"{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/{name}.png}")}"}">
+{icons%}<div class="title">{caption}</div>
+</td>
+<td class="content">
+<div class="title">{title}</div>
+|
+</td>
+</tr></table>
+</div>
+
+# Tables.
+[tabletags-default]
+colspec=<col{autowidth-option! style="width:{colpcwidth}%;"}>
+bodyrow=<tr>|</tr>
+headdata=<th class="tableblock halign-{halign=left} valign-{valign=top}" 
{colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }>|</th>
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" 
{colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }>|</td>
+paragraph=<p class="tableblock">|</p>
+
+[tabletags-header]
+paragraph=<p class="tableblock header">|</p>
+
+[tabletags-emphasis]
+paragraph=<p class="tableblock"><em>|</em></p>
+
+[tabletags-strong]
+paragraph=<p class="tableblock"><strong>|</strong></p>
+
+[tabletags-monospaced]
+paragraph=<p class="tableblock monospaced">|</p>
+
+[tabletags-verse]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" 
{colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }><div 
class="verse">|</div></td>
+paragraph=
+
+[tabletags-literal]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" 
{colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }><div 
class="literal monospaced"><pre>|</pre></div></td>
+paragraph=
+
+[tabletags-asciidoc]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" 
{colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" 
}><div>|</div></td>
+paragraph=
+
+[table]
+<table class="tableblock frame-{frame=all} grid-{grid=all}{role? 
{role}}{unbreakable-option? unbreakable}"{id? id="{id}"}
+style="
+margin-left:{align@left:0}{align@center|right:auto}; 
margin-right:{align@left|center:auto}{align@right:0};
+float:{float};
+{autowidth-option%}width:{tablepcwidth}%;
+{autowidth-option#}{width#style=width:{tablepcwidth}%;}
+">
+<caption class="title">{caption={table-caption} {counter:table-number}. 
}{title}</caption>
+{colspecs}
+{headrows#}<thead>
+{headrows}
+{headrows#}</thead>
+{footrows#}<tfoot>
+{footrows}
+{footrows#}</tfoot>
+<tbody>
+{bodyrows}
+</tbody>
+</table>
+
+#--------------------------------------------------------------------
+# Deprecated old table definitions.
+#
+
+[miscellaneous]
+# Screen width in pixels.
+pagewidth=800
+pageunits=px
+
+[old_tabledef-default]
+template=old_table
+colspec=<col style="width:{colwidth}{pageunits};" />
+bodyrow=<tr>|</tr>
+headdata=<th class="tableblock halign-{colalign=left}">|</th>
+footdata=<td class="tableblock halign-{colalign=left}">|</td>
+bodydata=<td class="tableblock halign-{colalign=left}">|</td>
+
+[old_table]
+<table class="tableblock frame-{frame=all} grid-{grid=all}"{id? id="{id}"}>
+<caption class="title">{caption={table-caption}}{title}</caption>
+{colspecs}
+{headrows#}<thead>
+{headrows}
+{headrows#}</thead>
+{footrows#}<tfoot>
+{footrows}
+{footrows#}</tfoot>
+<tbody style="vertical-align:top;">
+{bodyrows}
+</tbody>
+</table>
+
+# End of deprecated old table definitions.
+#--------------------------------------------------------------------
+
+[floatingtitle]
+<h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}{id? id="{id}"} 
class="float">{title}</h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}>
+
+[preamble]
+# Untitled elements between header and first section title.
+<div id="preamble">
+<div class="sectionbody">
+|
+</div>
+</div>
+
+# Document sections.
+[sect0]
+<h1{id? id="{id}"}>{title}</h1>
+|
+
+[sect1]
+<div class="sect1{style? {style}}{role? {role}}">
+<h2{id? id="{id}"}>{numbered?{sectnum} }{title}</h2>
+<div class="sectionbody">
+|
+</div>
+</div>
+
+[sect2]
+<div class="sect2{style? {style}}{role? {role}}">
+<h3{id? id="{id}"}>{numbered?{sectnum} }{title}</h3>
+|
+</div>
+
+[sect3]
+<div class="sect3{style? {style}}{role? {role}}">
+<h4{id? id="{id}"}>{numbered?{sectnum} }{title}</h4>
+|
+</div>
+
+[sect4]
+<div class="sect4{style? {style}}{role? {role}}">
+<h5{id? id="{id}"}>{title}</h5>
+|
+</div>
+
+[appendix]
+<div class="sect1{style? {style}}{role? {role}}">
+<h2{id? id="{id}"}>{numbered?{sectnum} }{appendix-caption} 
{counter:appendix-number:A}: {title}</h2>
+<div class="sectionbody">
+|
+</div>
+</div>
+
+[toc]
+<div id="toc">
+  <div id="toctitle">{toc-title}</div>
+  <noscript><p><b>JavaScript must be enabled in your browser to display the 
table of contents.</b></p></noscript>
+</div>
+
+[header]
+<!DOCTYPE html>
+<html lang="{lang=en}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset={encoding}">
+<meta name="generator" content="AsciiDoc {asciidoc-version}">
+<meta name="description" content="{description}">
+<meta name="keywords" content="{keywords}">
+<title>crmsh - {title}</title>
+{title%}<title>crmsh - {doctitle=}</title>
+<link rel="stylesheet" href="http://crmsh.nongnu.org/css/font-awesome.min.css";>
+<link rel="stylesheet" href="http://crmsh.nongnu.org/css/crm.css"; 
type="text/css">
+<link 
href='http://fonts.googleapis.com/css?family=Open+Sans:400,700|Ubuntu+Mono' 
rel='stylesheet' type='text/css'>
+<link href="http://crmsh.github.io/atom.xml"; type="application/atom+xml" 
rel="alternate" title="crmsh atom feed">
+<style>
+\#movenotice {
+            width: 600px;
+            margin-top: 1em;
+            margin-bottom: 1em;
+            margin-left: auto;
+            margin-right: auto;
+            font-size: 100%;
+            padding: 4px;
+            border: 2px dashed red;
+}
+</style>
+</head>
+<body>
+<div id="header">
+<h1><a href="http://crmsh.github.io/index.html";><span class="fa-stack">
+  <i class="fa fa-square fa-stack-2x"></i>
+  <i class="fa fa-terminal fa-stack-1x fa-inverse"></i>
+</span>crmsh</a></h1>
+<div id="topbar">
+<ul>
+<li><a href="http://crmsh.github.io/news";>News</a></li>
+<li><a href="http://crmsh.github.io/documentation";>Documentation</a></li>
+<li><a href="http://crmsh.github.io/development";>Development</a></li>
+<li><a href="http://crmsh.github.io/about";>About</a></li>
+</ul>
+</div>
+</div>
+<!--TOC-->
+<div id="container">
+<div id="content">
+
+<div id="movenotice">We have moved! The website for crmsh is now <a 
href="http://crmsh.github.io";>http://crmsh.github.io</a>.</div>
+
+<h1>{doctitle}</h1>
+
+[footer]
+</div>
+</div>
+<div id="footer">
+<div id="footer-text">
+</div>
+</div>
+
+<a href="https://github.com/crmsh/crmsh";><img style="position: absolute; top: 
0; right: 0; border: 0;" 
src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67";
 alt="Fork me on GitHub" 
data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png";></a>
+
+</body>
+</html>
+
+ifdef::doctype-manpage[]
+[synopsis]
+template::[sect1]
+endif::doctype-manpage[]
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/hb_report/hb_report.in 
new/crmsh/hb_report/hb_report.in
--- old/crmsh/hb_report/hb_report.in    2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/hb_report/hb_report.in    2014-10-10 19:26:22.000000000 +0200
@@ -305,11 +305,14 @@
 #
 findlog() {
        local logf=""
+       collect_journal $FROM_TIME $TO_TIME $WORKDIR/$JOURNAL_F
        if [ "$HA_LOGFACILITY" ]; then
                logf=`findmsg $UNIQUE_MSG | awk '{print $1}'`
        fi
        if [ -f "$logf" ]; then
                echo $logf
+       elif [ -f "$WORKDIR/$JOURNAL_F" ]; then
+               echo $WORKDIR/$JOURNAL_F
        else
                echo ${HA_DEBUGFILE:-$HA_LOGFILE}
                [ "${HA_DEBUGFILE:-$HA_LOGFILE}" ] &&
@@ -1094,6 +1097,29 @@
                fi
        fi
 }
+collect_journal() {
+       local from_time to_time outf
+       from_time="$1"
+       to_time="$2"
+       outf="$3"
+       if which journalctl > /dev/null 2>&1; then
+               if isnumber "$from_time" && [ $from_time -eq 0 ]; then
+                       from_time=$(date "+%Y-%m-%d %H:%M")
+               elif isnumber "$from_time"; then
+                       from_time=$(echo "$from_time" | awk '{ print 
strftime("%Y-%m-%d %H:%M", $1); }')
+               fi
+               if isnumber "$to_time" && [ $to_time -eq 0 ]; then
+                       to_time=$(date "+%Y-%m-%d %H:%M")
+               elif isnumber "$to_time"; then
+                       to_time=$(echo "$to_time" | awk '{ print 
strftime("%Y-%m-%d %H:%M", $1); }')
+               fi
+               if [ -f $outf ]; then
+                       warning "$outf already exists"
+               fi
+               debug "journalctl from: '$1' until: '$2' from_time '$from_time' 
to_time: '$to_time' > $outf"
+               journalctl --since "$from_time" --until "$to_time" --no-pager | 
tail -n +2 > $outf
+       fi
+}
 #
 # get all other info (config, stats, etc)
 #
@@ -1314,12 +1340,13 @@
 ANALYSIS_F=analysis.txt
 DESCRIPTION_F=description.txt
 HALOG_F=ha-log.txt
+JOURNAL_F=journal.log
 BT_F=backtraces.txt
 SYSINFO_F=sysinfo.txt
 SYSSTATS_F=sysstats.txt
 DLM_DUMP_F=dlm_dump.txt
 TIME_F=time.txt
-export ANALYSIS_F DESCRIPTION_F HALOG_F BT_F SYSINFO_F SYSSTATS_F DLM_DUMP_F 
TIME_F
+export ANALYSIS_F DESCRIPTION_F HALOG_F JOURNAL_F BT_F SYSINFO_F SYSSTATS_F 
DLM_DUMP_F TIME_F
 CRM_MON_F=crm_mon.txt
 MEMBERSHIP_F=members.txt
 HB_UUID_F=hb_uuid.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/Makefile.am 
new/crmsh/modules/Makefile.am
--- old/crmsh/modules/Makefile.am       2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/Makefile.am       2014-10-10 19:26:22.000000000 +0200
@@ -59,6 +59,7 @@
                        ui_context.py \
                        ui_corosync.py \
                        ui_history.py \
+                       ui_maintenance.py \
                        ui_node.py \
                        ui_options.py \
                        ui_ra.py \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/cibconfig.py 
new/crmsh/modules/cibconfig.py
--- old/crmsh/modules/cibconfig.py      2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/cibconfig.py      2014-10-10 19:26:22.000000000 +0200
@@ -304,9 +304,10 @@
                 if edit_file(tmp) != 0:
                     break
                 s = open(tmp).read()
-                if hash(s) != filehash and (not self.save(self._post_edit(s))
-                                            and ask("Do you want to edit 
again?")):
-                    continue
+                if hash(s) != filehash:
+                    ok = self.save(self._post_edit(s))
+                    if not ok and ask("Edit or discard changes (yes to edit, 
no to discard)?"):
+                        continue
                 rc = True
             os.unlink(tmp)
         except OSError, e:
@@ -530,7 +531,7 @@
     '''
     Edit or display a set of cib objects (using cli notation).
     '''
-    vim_stx_str = "#vim:set syntax=pcmk\n"
+    vim_stx_str = "# vim: set filetype=pcmk:\n"
 
     def __init__(self, *args):
         CibObjectSet.__init__(self, *args)
@@ -1201,6 +1202,11 @@
         else:
             return self
 
+    def meta_attributes(self, name):
+        "Returns all meta attribute values with the given name"
+        v = self.node.xpath('./meta_attributes/nvpair[@name="%s"]/@value' % 
(name))
+        return v
+
     def find_child_in_node(self, child):
         for c in self.node.iterchildren():
             if c.tag == child.obj_type and \
@@ -2313,7 +2319,6 @@
             if is_live_cib():
                 self.last_commit_time = t
             self.reset()
-            self.initialize()
         return rc
 
     def _update_schema(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/main.py new/crmsh/modules/main.py
--- old/crmsh/modules/main.py   2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/main.py   2014-10-10 19:26:22.000000000 +0200
@@ -105,6 +105,7 @@
 
 See the crm(8) man page or call %prog help for more details.""",
                           version="%prog " + config.CRM_VERSION)
+    parser.disable_interspersed_args()
     parser.add_option("-f", "--file", dest="filename", metavar="FILE",
                       help="Load commands from the given file. If a dash (-) " 
+
                       "is used in place of a file name, crm will read commands 
" +
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/report.py new/crmsh/modules/report.py
--- old/crmsh/modules/report.py 2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/report.py 2014-10-10 19:26:22.000000000 +0200
@@ -727,8 +727,7 @@
     def get_nodes(self):
         return sorted([os.path.basename(p)
                        for p in os.listdir(self.loc)
-                       if os.path.isdir(os.path.join(self.loc, p)) and
-                       os.path.isfile(os.path.join(self.loc, p, 
"ha-log.txt"))])
+                       if self.find_node_log(p) is not None])
 
     def check_nodes(self):
         'Verify if the nodes in cib match the nodes in the report.'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/rsctest.py new/crmsh/modules/rsctest.py
--- old/crmsh/modules/rsctest.py        2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/rsctest.py        2014-10-10 19:26:22.000000000 +0200
@@ -18,7 +18,7 @@
 import os
 import sys
 from msg import common_err, common_debug, common_warn, common_info
-from utils import rmdir_r, quote
+from utils import rmdir_r, quote, this_node, ext_cmd
 from xmlutil import get_topmost_rsc, get_op_timeout, get_child_nvset_node, 
is_ms, is_cloned
 
 
@@ -166,11 +166,10 @@
         '''defined in subclasses'''
         pass
 
-    def runop(self, op, nodes=None):
+    def runop(self, op, nodes=None, local_only=False):
         '''
         Execute an operation.
         '''
-        from crm_pssh import do_pssh_cmd
         if not nodes or self.run_on_all(op):
             nodes = self.nodes
         self.last_op = op
@@ -182,12 +181,16 @@
             # shell doesn't allow "-" in var names
             envvar = attr.replace("-", "_")
             cmd = "%s=%s %s" % (envvar, quote(self.rscenv[attr]), 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
+        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 stop(self, node):
@@ -305,6 +308,31 @@
         return cmd
 
 
+class RASystemd(RADriver):
+    '''
+    Execute operations on systemd resources.
+    '''
+
+    # Error codes are meaningless for systemd...
+    SYSD_OK = 0
+    SYSD_ERR_GENERIC = 1
+    SYSD_NOT_RUNNING = 3
+
+    def __init__(self, *args):
+        RADriver.__init__(self, *args)
+        self.ec_ok = self.SYSD_OK
+        self.ec_stopped = self.SYSD_NOT_RUNNING
+        self.ec_master = self.unused
+
+    def set_rscenv(self, op):
+        RADriver.set_rscenv(self, op)
+
+    def exec_cmd(self, op):
+        op = "status" if op == "monitor" else op
+        cmd = "systemctl %s %s.service" % (op, self.ra_type)
+        return cmd
+
+
 class RAStonith(RADriver):
     '''
     Execute operations on Stonith resources.
@@ -355,7 +383,8 @@
 ra_driver = {
     "ocf": RAOCF,
     "lsb": RALSB,
-    "stonith": RAStonith
+    "stonith": RAStonith,
+    "systemd": RASystemd
 }
 
 
@@ -430,4 +459,31 @@
         rc |= test_node(node)
     return rc
 
+
+def call_resource(rsc, cmd, nodes, local_only):
+    """
+    Calls the given operation on the resource.
+    local_only: Only performs the call locally (don't use pssh).
+    """
+    ra_class = rsc.get("class")
+    if ra_class not in ra_driver:
+        common_err("Calling '%s' for resource not supported" % (cmd))
+        return False
+    d = ra_driver[ra_class](rsc, [])
+
+    import ra
+    agent = ra.get_ra(rsc)
+    actions = agent.actions().keys() + ['meta-data', 'validate-all']
+
+    if cmd not in actions:
+        common_err("action '%s' not supported by %s" % (cmd, ra.name))
+        return False
+    d.runop(cmd, nodes, local_only=local_only)
+    for node in nodes:
+        ok = d.is_ok(node)
+        if not ok:
+            common_err("%s failed with rc=%d on %s" %
+                       (cmd, d.op_status(node), node))
+    return all(d.is_ok(node) for node in nodes)
+
 # vim:ts=4:sw=4:et:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/ui_maintenance.py 
new/crmsh/modules/ui_maintenance.py
--- old/crmsh/modules/ui_maintenance.py 1970-01-01 01:00:00.000000000 +0100
+++ new/crmsh/modules/ui_maintenance.py 2014-10-10 19:26:22.000000000 +0200
@@ -0,0 +1,108 @@
+# Copyright (C) 2014 Kristoffer Gronlund <kgronl...@suse.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+import command
+import completers as compl
+from cibconfig import cib_factory
+import utils
+import xmlutil
+
+_compl_actions = compl.choice(['start', 'stop', 'monitor', 'meta-data', 
'validate-all',
+                               'promote', 'demote', 'notify', 'reload', 
'migrate_from',
+                               'migrate_to', 'recover'])
+
+
+class Maintenance(command.UI):
+    '''
+    Commands that should only be run while in
+    maintenance mode.
+    '''
+    name = "maintenance"
+
+    rsc_maintenance = "crm_resource -r '%s' --meta -p maintenance -v '%s'"
+
+    def __init__(self):
+        command.UI.__init__(self)
+
+    def requires(self):
+        return cib_factory.initialize()
+
+    def _onoff(self, resource, onoff):
+        if resource is not None:
+            return utils.ext_cmd(self.rsc_maintenance % (resource, onoff)) == 0
+        else:
+            return cib_factory.create_object('property', 'maintenance-mode=%s' 
% (onoff))
+
+    @command.skill_level('administrator')
+    @command.completers_repeating(compl.call(cib_factory.rsc_id_list))
+    def do_on(self, context, resource=None):
+        '''
+        Enable maintenance mode (for the optional resource or for everything)
+        '''
+        return self._onoff(resource, 'true')
+
+    @command.skill_level('administrator')
+    @command.completers_repeating(compl.call(cib_factory.rsc_id_list))
+    def do_off(self, context, resource=None):
+        '''
+        Disable maintenance mode (for the optional resource or for everything)
+        '''
+        return self._onoff(resource, 'false')
+
+    def _in_maintenance_mode(self, obj):
+        if cib_factory.get_property("maintenance-mode") == "true":
+            return True
+        v = obj.meta_attributes("maintenance")
+        return v and all(x == 'true' for x in v)
+
+    def _runs_on_this_node(self, resource):
+        nodes = utils.running_on(resource)
+        return set(nodes) == set([utils.this_node()])
+
+    @command.skill_level('administrator')
+    @command.completers(compl.call(cib_factory.rsc_id_list), _compl_actions, 
compl.choice(["ssh"]))
+    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))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/ui_ra.py new/crmsh/modules/ui_ra.py
--- old/crmsh/modules/ui_ra.py  2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/ui_ra.py  2014-10-10 19:26:22.000000000 +0200
@@ -57,7 +57,7 @@
             if c in self.provider_classes:
                 providers = ra.ra_providers_all(c)
                 if providers:
-                    print "%s / " % (c, ' '.join(providers))
+                    print "%s / %s" % (c, ' '.join(providers))
             else:
                 print "%s" % c
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/ui_root.py new/crmsh/modules/ui_root.py
--- old/crmsh/modules/ui_root.py        2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/ui_root.py        2014-10-10 19:26:22.000000000 +0200
@@ -35,16 +35,17 @@
 import cmd_status
 import ui_cib
 import ui_cluster
-import ui_corosync
-import ui_resource
 import ui_configure
+import ui_corosync
 import ui_history
-import ui_ra
-import ui_site
+import ui_maintenance
 import ui_node
-import ui_report
 import ui_options
+import ui_ra
+import ui_report
+import ui_resource
 import ui_script
+import ui_site
 
 
 class Root(command.UI):
@@ -55,32 +56,6 @@
     # name is the user-visible name of this CLI level.
     name = 'root'
 
-    @command.level(ui_cluster.Cluster)
-    @command.help('''Cluster setup and management
-Commands at this level enable low-level cluster configuration
-management with HA awareness.
-''')
-    def do_cluster(self):
-        pass
-
-    @command.level(ui_corosync.Corosync)
-    @command.help('''Corosync configuration management
-Corosync is the underlying messaging layer for most HA clusters.
-This level provides commands for editing and managing the corosync
-configuration.
-''')
-    def do_corosync(self):
-        pass
-
-    @command.level(ui_script.Script)
-    @command.help('''Cluster scripts
-Cluster scripts can perform cluster-wide configuration,
-validation and management. See the `list` command for
-an overview of available scripts.
-''')
-    def do_script(self):
-        pass
-
     @command.level(ui_cib.CibShadow)
     @command.help('''manage shadow CIBs
 A shadow CIB is a regular cluster configuration which is kept in
@@ -91,13 +66,12 @@
     def do_cib(self):
         pass
 
-    @command.level(ui_resource.RscMgmt)
-    @command.help('''resources management
-Everything related to resources management is available at this
-level. Most commands are implemented using the crm_resource(8)
-program.
+    @command.level(ui_cluster.Cluster)
+    @command.help('''Cluster setup and management
+Commands at this level enable low-level cluster configuration
+management with HA awareness.
 ''')
-    def do_resource(self):
+    def do_cluster(self):
         pass
 
     @command.level(ui_configure.CibConfig)
@@ -111,20 +85,13 @@
     def do_configure(self):
         pass
 
-    @command.level(ui_node.NodeMgmt)
-    @command.help('''nodes management
-A few node related tasks such as node standby are implemented
-here.
-''')
-    def do_node(self):
-        pass
-
-    @command.level(ui_options.CliOptions)
-    @command.help('''user preferences
-Several user preferences are available. Note that it is possible
-to save the preferences to a startup file.
+    @command.level(ui_corosync.Corosync)
+    @command.help('''Corosync configuration management
+Corosync is the underlying messaging layer for most HA clusters.
+This level provides commands for editing and managing the corosync
+configuration.
 ''')
-    def do_options(self):
+    def do_corosync(self):
         pass
 
     @command.level(ui_history.History)
@@ -136,13 +103,28 @@
     def do_history(self):
         pass
 
-    @command.level(ui_site.Site)
-    @command.help('''Geo-cluster support
-The site level.
+    @command.level(ui_maintenance.Maintenance)
+    @command.help('''maintenance
+Commands that should only be executed while in
+maintenance mode.
+''')
+    def do_maintenance(self):
+        pass
 
-Geo-cluster related management.
+    @command.level(ui_node.NodeMgmt)
+    @command.help('''nodes management
+A few node related tasks such as node standby are implemented
+here.
 ''')
-    def do_site(self):
+    def do_node(self):
+        pass
+
+    @command.level(ui_options.CliOptions)
+    @command.help('''user preferences
+Several user preferences are available. Note that it is possible
+to save the preferences to a startup file.
+''')
+    def do_options(self):
         pass
 
     @command.level(ui_ra.RA)
@@ -162,6 +144,33 @@
     def do_report(self, context, *args):
         return ui_report.create_report(context, args)
 
+    @command.level(ui_resource.RscMgmt)
+    @command.help('''resources management
+Everything related to resources management is available at this
+level. Most commands are implemented using the crm_resource(8)
+program.
+''')
+    def do_resource(self):
+        pass
+
+    @command.level(ui_script.Script)
+    @command.help('''Cluster scripts
+Cluster scripts can perform cluster-wide configuration,
+validation and management. See the `list` command for
+an overview of available scripts.
+''')
+    def do_script(self):
+        pass
+
+    @command.level(ui_site.Site)
+    @command.help('''Geo-cluster support
+The site level.
+
+Geo-cluster related management.
+''')
+    def do_site(self):
+        pass
+
     @command.help('''show cluster status
 Show cluster status. The status is displayed by `crm_mon`. Supply
 additional arguments for more information or different format.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/utils.py new/crmsh/modules/utils.py
--- old/crmsh/modules/utils.py  2014-09-26 12:07:07.000000000 +0200
+++ new/crmsh/modules/utils.py  2014-10-10 19:26:22.000000000 +0200
@@ -1329,6 +1329,23 @@
     return None
 
 
+def running_on(resource):
+    "returns list of node names where the given resource is running"
+    rsc_locate = "crm_resource --resource '%s' --locate"
+    rc, out, err = get_stdout_stderr(rsc_locate % (resource))
+    if rc != 0:
+        return []
+    nodes = []
+    head = "resource %s is running on: " % (resource)
+    for line in out.split('\n'):
+        if line.strip().startswith(head):
+            w = line[len(head):].split()
+            if w:
+                nodes.append(w[0])
+    common_debug("%s running on: %s" % (resource, nodes))
+    return nodes
+
+
 # This RE matches nvpair values that can
 # be left unquoted
 _NOQUOTES_RE = re.compile(r'^[\w\.-]+$')

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to