Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624448
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
117 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/cts/schemas/test-3/ref/lifetime-1.ref-3 b/cts/schemas/test-3/ref/lifetime-1.ref-3
index 982c439a39..1eb33227dd 100644
--- a/cts/schemas/test-3/ref/lifetime-1.ref-3
+++ b/cts/schemas/test-3/ref/lifetime-1.ref-3
@@ -1,152 +1,136 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0" original="1">
<configuration original="1">
<!-- The essential elements of this test are:
* There are four location constraints:
* ban-rsc1-node1 uses node/score and has a lifetime element with two
defined rules.
* ban-rsc2-node1 uses a top-level rule and has a lifetime element
with two referenced rules.
* ban-rsc3-node1 uses node/score and has a lifetime element with one
defined rule.
* ban-rsc4-node1 uses a top-level rule and has a lifetime element
with one referenced rule.
* There are two colocation constraints:
* rsc2-with-rsc1 has a lifetime element with two defined rules.
* rsc4-with-rsc3 has a lifetime element with two referenced rules.
* There are two order constraints:
* rsc1-then-rsc2 has a lifetime element with two defined rules.
* rsc3-then-rsc4 has a lifetime element with two referenced rules.
* A cluster_property_set ("cluster-properties") references two rules
that are defined in the lifetime elements of colocation and order
constraints.
In this situation:
* All lifetime elements should be removed.
* For ban-rsc1-node1, the node/score attributes should be removed and a
compound "and" rule should be created containing the following:
* A rule version of the node/score attributes
* A compound "or" rule containing the lifetime rules
* For ban-rsc1-node2, a compound "and" rule should be created
containing the following:
* The existing top-level rule
* A compound "or" rule containing the lifetime rules
* For ban-rsc1-node3, a compound "and" rule should be created
containing the following:
* A rule version of the node/score attributes
* The lifetime rule
* For ban-rsc1-node4, a compound "and" rule should be created
containing the following:
* The existing top-level rule
* The lifetime rule
* A new location constraint should be created with a rsc-pattern that
can't match any resources. It should have a compound rule containing
all the rules defined in the lifetime elements of the colocation and
order constraints that are referenced elsewhere
(rsc2-with-rsc1-lifetime-rule1 and rsc1-then-rsc2-lifetime-rule2).
-->
<crm_config original="1">
<cluster_property_set id="cluster-properties" original="1">
<rule id="cluster-properties-rule" original="1">
<rule id="rsc1-then-rsc2-lifetime-rule2" original="0">
<date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
</rule>
<rule id="rsc2-with-rsc1-lifetime-rule1" original="0">
<date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
</rule>
</rule>
</cluster_property_set>
</crm_config>
<nodes original="1">
<node id="node1" uname="node1" type="member" original="1"/>
</nodes>
<resources original="1">
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
</resources>
<constraints original="1">
- <rsc_location id="ban-rsc1-node1" rsc="rsc1" score="-INFINITY" node="node1" original="1">
- <lifetime original="1">
- <rule id="ban-rsc1-node1-lifetime-rule1" original="1">
- <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
+ <rsc_location id="ban-rsc1-node1" rsc="rsc1" original="1">
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-node-score-rule" score="-INFINITY">
+ <expression id="pcmk__3_10_upgrade-ban-rsc1-node1-node-score-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc1-node1-lifetime-rule1" original="1">
+ <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
+ </rule>
+ <rule id="ban-rsc1-node1-lifetime-rule2" original="1">
+ <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
+ </rule>
</rule>
- <rule id="ban-rsc1-node1-lifetime-rule2" original="1">
- <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
- </rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="ban-rsc2-node1" rsc="rsc2" original="1">
- <rule id="ban-rsc2-node1-rule" score="-INFINITY" original="1">
- <expression id="ban-rsc2-node1-rule-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
- </rule>
- <lifetime original="1">
- <rule id="ban-rsc1-node1-lifetime-rule1" original="0">
- <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-ban-rsc2-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc2-node1-rule" score="-INFINITY" original="1">
+ <expression id="ban-rsc2-node1-rule-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-ban-rsc2-node1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc1-node1-lifetime-rule1" original="0">
+ <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ </rule>
+ <rule id="ban-rsc1-node1-lifetime-rule2" original="0">
+ <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ </rule>
</rule>
- <rule id="ban-rsc1-node1-lifetime-rule2" original="0">
- <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
- </rule>
- </lifetime>
+ </rule>
</rsc_location>
- <rsc_location id="ban-rsc3-node1" rsc="rsc3" score="-INFINITY" node="node1" original="1">
- <lifetime original="1">
+ <rsc_location id="ban-rsc3-node1" rsc="rsc3" original="1">
+ <rule id="pcmk__3_10_upgrade-ban-rsc3-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="pcmk__3_10_upgrade-ban-rsc3-node1-node-score-rule" score="-INFINITY">
+ <expression id="pcmk__3_10_upgrade-ban-rsc3-node1-node-score-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ </rule>
<rule id="ban-rsc3-node1-lifetime-rule" original="1">
<date_expression id="ban-rsc3-node1-lifetime-rule-expr" operation="in_range" start="2004-001" original="1"/>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="ban-rsc4-node1" rsc="rsc4" original="1">
- <rule id="ban-rsc4-node1-rule" score="-INFINITY" original="1">
- <expression id="ban-rsc4-node1-rule-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
- </rule>
- <lifetime original="1">
+ <rule id="pcmk__3_10_upgrade-ban-rsc4-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc4-node1-rule" score="-INFINITY" original="1">
+ <expression id="ban-rsc4-node1-rule-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
+ </rule>
<rule id="ban-rsc3-node1-lifetime-rule" original="0">
<date_expression id="ban-rsc3-node1-lifetime-rule-expr" operation="in_range" start="2004-001" original="0"/>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
- <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1" original="1">
- <lifetime original="1">
+ <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1" original="1"/>
+ <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3" original="1"/>
+ <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2" original="1"/>
+ <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4" original="1"/>
+ <rsc_location id="pcmk__3_10_upgrade-coloc-order-lifetime-rules" rsc-pattern="a^">
+ <rule id="pcmk__3_10_upgrade-coloc-order-lifetime-rules-rule" score="-INFINITY">
<rule id="rsc2-with-rsc1-lifetime-rule1" original="1">
<date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
</rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2" original="1">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3" original="1">
- <lifetime original="1">
- <rule id="rsc2-with-rsc1-lifetime-rule1" original="0">
- <date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
- </rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2" original="0">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2" original="1">
- <lifetime original="1">
- <rule id="rsc1-then-rsc2-lifetime-rule1" original="1">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
- </rule>
<rule id="rsc1-then-rsc2-lifetime-rule2" original="1">
<date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
</rule>
- </lifetime>
- </rsc_order>
- <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4" original="1">
- <lifetime original="1">
- <rule id="rsc1-then-rsc2-lifetime-rule1" original="0">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
- </rule>
- <rule id="rsc1-then-rsc2-lifetime-rule2" original="0">
- <date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
- </rule>
- </lifetime>
- </rsc_order>
+ </rule>
+ </rsc_location>
</constraints>
</configuration>
<status original="1"/>
</cib>
diff --git a/cts/schemas/test-3/ref/lifetime-1.ref-99 b/cts/schemas/test-3/ref/lifetime-1.ref-99
index 1669699672..98eccc1c60 100644
--- a/cts/schemas/test-3/ref/lifetime-1.ref-99
+++ b/cts/schemas/test-3/ref/lifetime-1.ref-99
@@ -1,134 +1,126 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0">
<configuration>
<!-- The essential elements of this test are:
* There are four location constraints:
* ban-rsc1-node1 uses node/score and has a lifetime element with two
defined rules.
* ban-rsc2-node1 uses a top-level rule and has a lifetime element
with two referenced rules.
* ban-rsc3-node1 uses node/score and has a lifetime element with one
defined rule.
* ban-rsc4-node1 uses a top-level rule and has a lifetime element
with one referenced rule.
* There are two colocation constraints:
* rsc2-with-rsc1 has a lifetime element with two defined rules.
* rsc4-with-rsc3 has a lifetime element with two referenced rules.
* There are two order constraints:
* rsc1-then-rsc2 has a lifetime element with two defined rules.
* rsc3-then-rsc4 has a lifetime element with two referenced rules.
* A cluster_property_set ("cluster-properties") references two rules
that are defined in the lifetime elements of colocation and order
constraints.
In this situation:
* All lifetime elements should be removed.
* For ban-rsc1-node1, the node/score attributes should be removed and a
compound "and" rule should be created containing the following:
* A rule version of the node/score attributes
* A compound "or" rule containing the lifetime rules
* For ban-rsc1-node2, a compound "and" rule should be created
containing the following:
* The existing top-level rule
* A compound "or" rule containing the lifetime rules
* For ban-rsc1-node3, a compound "and" rule should be created
containing the following:
* A rule version of the node/score attributes
* The lifetime rule
* For ban-rsc1-node4, a compound "and" rule should be created
containing the following:
* The existing top-level rule
* The lifetime rule
* A new location constraint should be created with a rsc-pattern that
can't match any resources. It should have a compound rule containing
all the rules defined in the lifetime elements of the colocation and
order constraints that are referenced elsewhere
(rsc2-with-rsc1-lifetime-rule1 and rsc1-then-rsc2-lifetime-rule2).
-->
<crm_config>
<cluster_property_set id="cluster-properties">
<rule id="cluster-properties-rule">
<rule id-ref="rsc1-then-rsc2-lifetime-rule2"/>
<rule id-ref="rsc2-with-rsc1-lifetime-rule1"/>
</rule>
</cluster_property_set>
</crm_config>
<nodes>
<node id="node1" uname="node1" type="member"/>
</nodes>
<resources>
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker"/>
</resources>
<constraints>
- <rsc_location id="ban-rsc1-node1" rsc="rsc1" score="-INFINITY" node="node1">
- <lifetime>
- <rule id="ban-rsc1-node1-lifetime-rule1">
- <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
+ <rsc_location id="ban-rsc1-node1" rsc="rsc1">
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-node-score-rule" score="-INFINITY">
+ <expression id="pcmk__3_10_upgrade-ban-rsc1-node1-node-score-rule-expr" attribute="#uname" operation="eq" value="node1"/>
</rule>
- <rule id="ban-rsc1-node1-lifetime-rule2">
- <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
+ <rule id="pcmk__3_10_upgrade-ban-rsc1-node1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc1-node1-lifetime-rule1">
+ <date_expression id="ban-rsc1-node1-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
+ </rule>
+ <rule id="ban-rsc1-node1-lifetime-rule2">
+ <date_expression id="ban-rsc1-node1-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="ban-rsc2-node1" rsc="rsc2">
- <rule id="ban-rsc2-node1-rule" score="-INFINITY">
- <expression id="ban-rsc2-node1-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ <rule id="pcmk__3_10_upgrade-ban-rsc2-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc2-node1-rule" score="-INFINITY">
+ <expression id="ban-rsc2-node1-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-ban-rsc2-node1-lifetime-or-rule" boolean-op="or">
+ <rule id-ref="ban-rsc1-node1-lifetime-rule1"/>
+ <rule id-ref="ban-rsc1-node1-lifetime-rule2"/>
+ </rule>
</rule>
- <lifetime>
- <rule id-ref="ban-rsc1-node1-lifetime-rule1"/>
- <rule id-ref="ban-rsc1-node1-lifetime-rule2"/>
- </lifetime>
</rsc_location>
- <rsc_location id="ban-rsc3-node1" rsc="rsc3" score="-INFINITY" node="node1">
- <lifetime>
+ <rsc_location id="ban-rsc3-node1" rsc="rsc3">
+ <rule id="pcmk__3_10_upgrade-ban-rsc3-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="pcmk__3_10_upgrade-ban-rsc3-node1-node-score-rule" score="-INFINITY">
+ <expression id="pcmk__3_10_upgrade-ban-rsc3-node1-node-score-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ </rule>
<rule id="ban-rsc3-node1-lifetime-rule">
<date_expression id="ban-rsc3-node1-lifetime-rule-expr" operation="in_range" start="2004-001"/>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="ban-rsc4-node1" rsc="rsc4">
- <rule id="ban-rsc4-node1-rule" score="-INFINITY">
- <expression id="ban-rsc4-node1-rule-expr" attribute="#uname" operation="eq" value="node1"/>
- </rule>
- <lifetime>
+ <rule id="pcmk__3_10_upgrade-ban-rsc4-node1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc4-node1-rule" score="-INFINITY">
+ <expression id="ban-rsc4-node1-rule-expr" attribute="#uname" operation="eq" value="node1"/>
+ </rule>
<rule id-ref="ban-rsc3-node1-lifetime-rule"/>
- </lifetime>
+ </rule>
</rsc_location>
- <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1">
- <lifetime>
+ <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1"/>
+ <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3"/>
+ <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2"/>
+ <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4"/>
+ <rsc_location id="pcmk__3_10_upgrade-coloc-order-lifetime-rules" rsc-pattern="a^">
+ <rule id="pcmk__3_10_upgrade-coloc-order-lifetime-rules-rule" score="-INFINITY">
<rule id="rsc2-with-rsc1-lifetime-rule1">
<date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
</rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3">
- <lifetime>
- <rule id-ref="rsc2-with-rsc1-lifetime-rule1"/>
- <rule id-ref="rsc2-with-rsc1-lifetime-rule2"/>
- </lifetime>
- </rsc_colocation>
- <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2">
- <lifetime>
- <rule id="rsc1-then-rsc2-lifetime-rule1">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
- </rule>
<rule id="rsc1-then-rsc2-lifetime-rule2">
<date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
</rule>
- </lifetime>
- </rsc_order>
- <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4">
- <lifetime>
- <rule id-ref="rsc1-then-rsc2-lifetime-rule1"/>
- <rule id-ref="rsc1-then-rsc2-lifetime-rule2"/>
- </lifetime>
- </rsc_order>
+ </rule>
+ </rsc_location>
</constraints>
</configuration>
<status/>
</cib>
diff --git a/cts/schemas/test-3/ref/lifetime-2.ref-3 b/cts/schemas/test-3/ref/lifetime-2.ref-3
index 8fb1725898..e3483efadb 100644
--- a/cts/schemas/test-3/ref/lifetime-2.ref-3
+++ b/cts/schemas/test-3/ref/lifetime-2.ref-3
@@ -1,70 +1,34 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0" original="1">
<configuration original="1">
<!-- The essential elements of this test are:
* There are two colocation constraints:
* rsc2-with-rsc1 has a lifetime element with two defined rules.
* rsc4-with-rsc3 has a lifetime element with two referenced rules.
* There are two order constraints:
* rsc1-then-rsc2 has a lifetime element with two defined rules.
* rsc3-then-rsc4 has a lifetime element with two referenced rules.
* The rules defined in the colocation and order constraints are not
referenced anywhere else.
In this situation, all lifetime elements should be removed, along with
their rule definitions.
-->
<crm_config original="1"/>
<nodes original="1">
<node id="node1" uname="node1" type="member" original="1"/>
</nodes>
<resources original="1">
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
</resources>
<constraints original="1">
- <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1" original="1">
- <lifetime original="1">
- <rule id="rsc2-with-rsc1-lifetime-rule1" original="1">
- <date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
- </rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2" original="1">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3" original="1">
- <lifetime original="1">
- <rule id="rsc2-with-rsc1-lifetime-rule1" original="0">
- <date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
- </rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2" original="0">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2" original="1">
- <lifetime original="1">
- <rule id="rsc1-then-rsc2-lifetime-rule1" original="1">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
- </rule>
- <rule id="rsc1-then-rsc2-lifetime-rule2" original="1">
- <date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
- </rule>
- </lifetime>
- </rsc_order>
- <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4" original="1">
- <lifetime original="1">
- <rule id="rsc1-then-rsc2-lifetime-rule1" original="0">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
- </rule>
- <rule id="rsc1-then-rsc2-lifetime-rule2" original="0">
- <date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
- </rule>
- </lifetime>
- </rsc_order>
+ <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1" original="1"/>
+ <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3" original="1"/>
+ <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2" original="1"/>
+ <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4" original="1"/>
</constraints>
</configuration>
<status original="1"/>
</cib>
diff --git a/cts/schemas/test-3/ref/lifetime-2.ref-99 b/cts/schemas/test-3/ref/lifetime-2.ref-99
index 72e59f6ce5..9621fe4ea2 100644
--- a/cts/schemas/test-3/ref/lifetime-2.ref-99
+++ b/cts/schemas/test-3/ref/lifetime-2.ref-99
@@ -1,62 +1,34 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0">
<configuration>
<!-- The essential elements of this test are:
* There are two colocation constraints:
* rsc2-with-rsc1 has a lifetime element with two defined rules.
* rsc4-with-rsc3 has a lifetime element with two referenced rules.
* There are two order constraints:
* rsc1-then-rsc2 has a lifetime element with two defined rules.
* rsc3-then-rsc4 has a lifetime element with two referenced rules.
* The rules defined in the colocation and order constraints are not
referenced anywhere else.
In this situation, all lifetime elements should be removed, along with
their rule definitions.
-->
<crm_config/>
<nodes>
<node id="node1" uname="node1" type="member"/>
</nodes>
<resources>
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker"/>
</resources>
<constraints>
- <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1">
- <lifetime>
- <rule id="rsc2-with-rsc1-lifetime-rule1">
- <date_expression id="rsc2-with-rsc1-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
- </rule>
- <rule id="rsc2-with-rsc1-lifetime-rule2">
- <date_expression id="rsc2-with-rsc1-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
- </rule>
- </lifetime>
- </rsc_colocation>
- <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3">
- <lifetime>
- <rule id-ref="rsc2-with-rsc1-lifetime-rule1"/>
- <rule id-ref="rsc2-with-rsc1-lifetime-rule2"/>
- </lifetime>
- </rsc_colocation>
- <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2">
- <lifetime>
- <rule id="rsc1-then-rsc2-lifetime-rule1">
- <date_expression id="rsc1-then-rsc2-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
- </rule>
- <rule id="rsc1-then-rsc2-lifetime-rule2">
- <date_expression id="rsc1-then-rsc2-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
- </rule>
- </lifetime>
- </rsc_order>
- <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4">
- <lifetime>
- <rule id-ref="rsc1-then-rsc2-lifetime-rule1"/>
- <rule id-ref="rsc1-then-rsc2-lifetime-rule2"/>
- </lifetime>
- </rsc_order>
+ <rsc_colocation id="rsc2-with-rsc1" score="INFINITY" rsc="rsc2" with-rsc="rsc1"/>
+ <rsc_colocation id="rsc4-with-rsc3" score="INFINITY" rsc="rsc4" with-rsc="rsc3"/>
+ <rsc_order id="rsc1-then-rsc2" first="rsc1" then="rsc2"/>
+ <rsc_order id="rsc3-then-rsc4" first="rsc3" then="rsc4"/>
</constraints>
</configuration>
<status/>
</cib>
diff --git a/cts/schemas/test-3/ref/multiple-location-rules.ref-3 b/cts/schemas/test-3/ref/multiple-location-rules.ref-3
index 7b72e5629e..e6372e2ba7 100644
--- a/cts/schemas/test-3/ref/multiple-location-rules.ref-3
+++ b/cts/schemas/test-3/ref/multiple-location-rules.ref-3
@@ -1,155 +1,163 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0" original="1">
<configuration original="1">
<!-- The essential elements of this test are:
* There is a location constraint (ban-rsc1) containing a rsc attribute
and two top-level rules.
* There is a location constraint (allow-rsc1) containing a rsc
attribute and one top-level rule.
* There is a location constraint (allow-rsc2) containing a rsc
attribute and one top-level rule with two nested rules.
* There is a location constraint (ban-rsc3-rsc4-node1-node2) containing
two resource_set elements (with id attributes), two top-level
rules, and two rule elements (with id attributes) within a lifetime
element.
* There is a location constraint (ban-rsc3-rsc4-node1-node2) containing
two resource_set elements (with id-ref attributes), two top-level
rules, and two rule elements (with id-ref attributes) within a
lifetime element.
In this situation:
* ban-rsc1 should be replaced by two new location constraints, each
containing one of the original rules.
* allow-rsc1 and allow-rsc2 should be unmodified.
* ban-rsc3-rsc4-node1-node2 should be replaced by two new location
constraints, each containing one of the original rules. The first of
the new constraints should contain the original resource_set and
lifetime rule elements, while the second should contain id-refs to
them.
* ban-rsc3-rsc4-node3-node4 should be replaced by two new location
constraints, each containing one of the original rules. Both of the
new constraints should contain the original resource_set and lifetime
rule elements, which are id-refs to resource sets defined in
ban-rsc3-rsc4-node1-node2.
* The rules within a lifetime element should be converted to an "or"
rule set nested alongside an "and" rule set containing the other
top-level rule.
-->
<crm_config original="1"/>
<nodes original="1">
<node id="node1" uname="node1" type="member" original="1"/>
<node id="node2" uname="node2" type="member" original="1"/>
<node id="node3" uname="node3" type="member" original="1"/>
<node id="node4" uname="node3" type="member" original="1"/>
</nodes>
<resources original="1">
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker" original="1"/>
</resources>
<constraints original="1">
<rsc_location id="pcmk__3_10_upgrade-ban-rsc1-1" rsc="rsc1" original="0">
<rule id="ban-rsc1-rule1" score="-INFINITY" original="1">
<expression id="ban-rsc1-rule1-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
</rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc1-2" rsc="rsc1" original="0">
<rule id="ban-rsc1-rule2" score="-INFINITY" original="1">
<expression id="ban-rsc1-rule2-expr" attribute="#uname" operation="eq" value="node2" original="1"/>
</rule>
</rsc_location>
<rsc_location id="allow-rsc1" rsc="rsc1" original="1">
<rule id="allow-rsc1-rule" score="INFINITY" original="1">
<expression id="allow-rsc1-rule-expr" attribute="#uname" operation="eq" value="node3" original="1"/>
</rule>
</rsc_location>
<rsc_location id="allow-rsc2" rsc="rsc2" original="1">
<rule id="allow-rsc2-rule" score="INFINITY" boolean-op="or" original="1">
<rule id="allow-rsc2-rule-subrule1" original="1">
<expression id="allow-rsc2-rule-subrule1-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
</rule>
<rule id="allow-rsc2-rule-subrule2" original="1">
<expression id="allow-rsc2-rule-subrule2-expr" attribute="#uname" operation="eq" value="node2" original="1"/>
</rule>
</rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1" original="0">
<resource_set id="ban-rsc3-rsc4-node1-node2-set1" original="1">
<resource_ref id="rsc3" original="1"/>
</resource_set>
<resource_set id="ban-rsc3-rsc4-node1-node2-set2" original="1">
<resource_ref id="rsc4" original="1"/>
</resource_set>
- <rule id="ban-rsc3-rsc4-node1-node2-rule1" score="-INFINITY" original="1">
- <expression id="ban-rsc3-rsc4-node1-node2-rule1-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
- </rule>
- <lifetime original="1">
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="1">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node1-node2-rule1" score="-INFINITY" original="1">
+ <expression id="ban-rsc3-rsc4-node1-node2-rule1-expr" attribute="#uname" operation="eq" value="node1" original="1"/>
</rule>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="1">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="1">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="1"/>
+ </rule>
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="1">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="1"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2" original="0">
<resource_set id="ban-rsc3-rsc4-node1-node2-set1" original="0">
<resource_ref id="rsc3" original="0"/>
</resource_set>
<resource_set id="ban-rsc3-rsc4-node1-node2-set2" original="0">
<resource_ref id="rsc4" original="0"/>
</resource_set>
- <rule id="ban-rsc3-rsc4-node1-node2-rule2" score="-INFINITY" original="1">
- <expression id="ban-rsc3-rsc4-node1-node2-rule2-expr" attribute="#uname" operation="eq" value="node2" original="1"/>
- </rule>
- <lifetime original="0">
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node1-node2-rule2" score="-INFINITY" original="1">
+ <expression id="ban-rsc3-rsc4-node1-node2-rule2-expr" attribute="#uname" operation="eq" value="node2" original="1"/>
</rule>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ </rule>
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1" original="0">
<resource_set id="ban-rsc3-rsc4-node1-node2-set1" original="0">
<resource_ref id="rsc3" original="0"/>
</resource_set>
<resource_set id="ban-rsc3-rsc4-node1-node2-set2" original="0">
<resource_ref id="rsc4" original="0"/>
</resource_set>
- <rule id="ban-rsc3-rsc4-node3-node4-rule1" score="-INFINITY" original="1">
- <expression id="ban-rsc3-rsc4-node3-node4-rule1-expr" attribute="#uname" operation="eq" value="node3" original="1"/>
- </rule>
- <lifetime original="1">
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node3-node4-rule1" score="-INFINITY" original="1">
+ <expression id="ban-rsc3-rsc4-node3-node4-rule1-expr" attribute="#uname" operation="eq" value="node3" original="1"/>
</rule>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ </rule>
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2" original="0">
<resource_set id="ban-rsc3-rsc4-node1-node2-set1" original="0">
<resource_ref id="rsc3" original="0"/>
</resource_set>
<resource_set id="ban-rsc3-rsc4-node1-node2-set2" original="0">
<resource_ref id="rsc4" original="0"/>
</resource_set>
- <rule id="ban-rsc3-rsc4-node3-node4-rule2" score="-INFINITY" original="1">
- <expression id="ban-rsc3-rsc4-node3-node4-rule2-expr" attribute="#uname" operation="eq" value="node4" original="1"/>
- </rule>
- <lifetime original="0">
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node3-node4-rule2" score="-INFINITY" original="1">
+ <expression id="ban-rsc3-rsc4-node3-node4-rule2-expr" attribute="#uname" operation="eq" value="node4" original="1"/>
</rule>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001" original="0"/>
+ </rule>
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2" original="0">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001" original="0"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
</constraints>
</configuration>
<status original="1"/>
</cib>
diff --git a/cts/schemas/test-3/ref/multiple-location-rules.ref-99 b/cts/schemas/test-3/ref/multiple-location-rules.ref-99
index 28f9636a6e..20495cffe1 100644
--- a/cts/schemas/test-3/ref/multiple-location-rules.ref-99
+++ b/cts/schemas/test-3/ref/multiple-location-rules.ref-99
@@ -1,131 +1,139 @@
<cib crm_feature_set="3.19.7" validate-with="pacemaker-4.0" epoch="16" num_updates="0" admin_epoch="0">
<configuration>
<!-- The essential elements of this test are:
* There is a location constraint (ban-rsc1) containing a rsc attribute
and two top-level rules.
* There is a location constraint (allow-rsc1) containing a rsc
attribute and one top-level rule.
* There is a location constraint (allow-rsc2) containing a rsc
attribute and one top-level rule with two nested rules.
* There is a location constraint (ban-rsc3-rsc4-node1-node2) containing
two resource_set elements (with id attributes), two top-level
rules, and two rule elements (with id attributes) within a lifetime
element.
* There is a location constraint (ban-rsc3-rsc4-node1-node2) containing
two resource_set elements (with id-ref attributes), two top-level
rules, and two rule elements (with id-ref attributes) within a
lifetime element.
In this situation:
* ban-rsc1 should be replaced by two new location constraints, each
containing one of the original rules.
* allow-rsc1 and allow-rsc2 should be unmodified.
* ban-rsc3-rsc4-node1-node2 should be replaced by two new location
constraints, each containing one of the original rules. The first of
the new constraints should contain the original resource_set and
lifetime rule elements, while the second should contain id-refs to
them.
* ban-rsc3-rsc4-node3-node4 should be replaced by two new location
constraints, each containing one of the original rules. Both of the
new constraints should contain the original resource_set and lifetime
rule elements, which are id-refs to resource sets defined in
ban-rsc3-rsc4-node1-node2.
* The rules within a lifetime element should be converted to an "or"
rule set nested alongside an "and" rule set containing the other
top-level rule.
-->
<crm_config/>
<nodes>
<node id="node1" uname="node1" type="member"/>
<node id="node2" uname="node2" type="member"/>
<node id="node3" uname="node3" type="member"/>
<node id="node4" uname="node3" type="member"/>
</nodes>
<resources>
<primitive id="rsc1" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc2" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc3" class="ocf" type="Dummy" provider="pacemaker"/>
<primitive id="rsc4" class="ocf" type="Dummy" provider="pacemaker"/>
</resources>
<constraints>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc1-1" rsc="rsc1">
<rule id="ban-rsc1-rule1" score="-INFINITY">
<expression id="ban-rsc1-rule1-expr" attribute="#uname" operation="eq" value="node1"/>
</rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc1-2" rsc="rsc1">
<rule id="ban-rsc1-rule2" score="-INFINITY">
<expression id="ban-rsc1-rule2-expr" attribute="#uname" operation="eq" value="node2"/>
</rule>
</rsc_location>
<rsc_location id="allow-rsc1" rsc="rsc1">
<rule id="allow-rsc1-rule" score="INFINITY">
<expression id="allow-rsc1-rule-expr" attribute="#uname" operation="eq" value="node3"/>
</rule>
</rsc_location>
<rsc_location id="allow-rsc2" rsc="rsc2">
<rule id="allow-rsc2-rule" score="INFINITY" boolean-op="or">
<rule id="allow-rsc2-rule-subrule1">
<expression id="allow-rsc2-rule-subrule1-expr" attribute="#uname" operation="eq" value="node1"/>
</rule>
<rule id="allow-rsc2-rule-subrule2">
<expression id="allow-rsc2-rule-subrule2-expr" attribute="#uname" operation="eq" value="node2"/>
</rule>
</rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1">
<resource_set id="ban-rsc3-rsc4-node1-node2-set1">
<resource_ref id="rsc3"/>
</resource_set>
<resource_set id="ban-rsc3-rsc4-node1-node2-set2">
<resource_ref id="rsc4"/>
</resource_set>
- <rule id="ban-rsc3-rsc4-node1-node2-rule1" score="-INFINITY">
- <expression id="ban-rsc3-rsc4-node1-node2-rule1-expr" attribute="#uname" operation="eq" value="node1"/>
- </rule>
- <lifetime>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node1-node2-rule1" score="-INFINITY">
+ <expression id="ban-rsc3-rsc4-node1-node2-rule1-expr" attribute="#uname" operation="eq" value="node1"/>
</rule>
- <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2">
- <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-1-lifetime-or-rule" boolean-op="or">
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule1">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule1-expr" operation="in_range" start="2004-001"/>
+ </rule>
+ <rule id="ban-rsc3-rsc4-node1-node2-lifetime-rule2">
+ <date_expression id="ban-rsc3-rsc4-node1-node2-lifetime-rule2-expr" operation="in_range" end="2005-001"/>
+ </rule>
</rule>
- </lifetime>
+ </rule>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2">
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set1"/>
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set2"/>
- <rule id="ban-rsc3-rsc4-node1-node2-rule2" score="-INFINITY">
- <expression id="ban-rsc3-rsc4-node1-node2-rule2-expr" attribute="#uname" operation="eq" value="node2"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node1-node2-rule2" score="-INFINITY">
+ <expression id="ban-rsc3-rsc4-node1-node2-rule2-expr" attribute="#uname" operation="eq" value="node2"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node1-node2-2-lifetime-or-rule" boolean-op="or">
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
+ </rule>
</rule>
- <lifetime>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
- </lifetime>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1">
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set1"/>
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set2"/>
- <rule id="ban-rsc3-rsc4-node3-node4-rule1" score="-INFINITY">
- <expression id="ban-rsc3-rsc4-node3-node4-rule1-expr" attribute="#uname" operation="eq" value="node3"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node3-node4-rule1" score="-INFINITY">
+ <expression id="ban-rsc3-rsc4-node3-node4-rule1-expr" attribute="#uname" operation="eq" value="node3"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-1-lifetime-or-rule" boolean-op="or">
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
+ </rule>
</rule>
- <lifetime>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
- </lifetime>
</rsc_location>
<rsc_location id="pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2">
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set1"/>
<resource_set id-ref="ban-rsc3-rsc4-node1-node2-set2"/>
- <rule id="ban-rsc3-rsc4-node3-node4-rule2" score="-INFINITY">
- <expression id="ban-rsc3-rsc4-node3-node4-rule2-expr" attribute="#uname" operation="eq" value="node4"/>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2-lifetime-and-rule" boolean-op="and">
+ <rule id="ban-rsc3-rsc4-node3-node4-rule2" score="-INFINITY">
+ <expression id="ban-rsc3-rsc4-node3-node4-rule2-expr" attribute="#uname" operation="eq" value="node4"/>
+ </rule>
+ <rule id="pcmk__3_10_upgrade-pcmk__3_10_upgrade-ban-rsc3-rsc4-node3-node4-2-lifetime-or-rule" boolean-op="or">
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
+ <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
+ </rule>
</rule>
- <lifetime>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule1"/>
- <rule id-ref="ban-rsc3-rsc4-node1-node2-lifetime-rule2"/>
- </lifetime>
</rsc_location>
</constraints>
</configuration>
<status/>
</cib>
diff --git a/lib/pacemaker/pcmk_sched_constraints.c b/lib/pacemaker/pcmk_sched_constraints.c
index 8cefce8752..8ce17198dc 100644
--- a/lib/pacemaker/pcmk_sched_constraints.c
+++ b/lib/pacemaker/pcmk_sched_constraints.c
@@ -1,477 +1,478 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <sys/param.h>
#include <sys/types.h>
#include <stdbool.h>
#include <regex.h>
#include <glib.h>
#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/common/scheduler.h>
#include <crm/common/xml.h>
#include <crm/common/xml_internal.h>
#include <crm/common/iso8601.h>
#include <crm/pengine/status.h>
#include <crm/pengine/internal.h>
#include <crm/pengine/rules.h>
#include <pacemaker-internal.h>
#include "libpacemaker_private.h"
static bool
evaluate_lifetime(xmlNode *lifetime, pcmk_scheduler_t *scheduler)
{
bool result = false;
crm_time_t *next_change = crm_time_new_undefined();
pcmk_rule_input_t rule_input = {
.now = scheduler->priv->now,
};
result = (pcmk__evaluate_rules(lifetime, &rule_input,
next_change) == pcmk_rc_ok);
if (crm_time_is_defined(next_change)) {
time_t recheck = (time_t) crm_time_get_seconds_since_epoch(next_change);
pe__update_recheck_time(recheck, scheduler, "constraint lifetime");
}
crm_time_free(next_change);
return result;
}
/*!
* \internal
* \brief Unpack constraints from XML
*
* Given scheduler data, unpack all constraints from its input XML into
* data structures.
*
* \param[in,out] scheduler Scheduler data
*/
void
pcmk__unpack_constraints(pcmk_scheduler_t *scheduler)
{
xmlNode *xml_constraints = pcmk_find_cib_element(scheduler->input,
PCMK_XE_CONSTRAINTS);
for (xmlNode *xml_obj = pcmk__xe_first_child(xml_constraints, NULL, NULL,
NULL);
xml_obj != NULL; xml_obj = pcmk__xe_next(xml_obj)) {
xmlNode *lifetime = NULL;
const char *id = crm_element_value(xml_obj, PCMK_XA_ID);
const char *tag = (const char *) xml_obj->name;
if (id == NULL) {
pcmk__config_err("Ignoring <%s> constraint without "
PCMK_XA_ID, tag);
continue;
}
crm_trace("Unpacking %s constraint '%s'", tag, id);
lifetime = pcmk__xe_first_child(xml_obj, PCMK__XE_LIFETIME, NULL, NULL);
if (lifetime != NULL) {
+ // @COMPAT Not possible with schema validation enabled
pcmk__config_warn("Support for '" PCMK__XE_LIFETIME "' element "
"(in %s) is deprecated and will be dropped "
"in a later release", id);
}
if ((lifetime != NULL) && !evaluate_lifetime(lifetime, scheduler)) {
crm_info("Constraint %s %s is not active", tag, id);
} else if (pcmk__str_eq(PCMK_XE_RSC_ORDER, tag, pcmk__str_none)) {
pcmk__unpack_ordering(xml_obj, scheduler);
} else if (pcmk__str_eq(PCMK_XE_RSC_COLOCATION, tag, pcmk__str_none)) {
pcmk__unpack_colocation(xml_obj, scheduler);
} else if (pcmk__str_eq(PCMK_XE_RSC_LOCATION, tag, pcmk__str_none)) {
pcmk__unpack_location(xml_obj, scheduler);
} else if (pcmk__str_eq(PCMK_XE_RSC_TICKET, tag, pcmk__str_none)) {
pcmk__unpack_rsc_ticket(xml_obj, scheduler);
} else {
pcmk__config_err("Unsupported constraint type: %s", tag);
}
}
}
pcmk_resource_t *
pcmk__find_constraint_resource(GList *rsc_list, const char *id)
{
if (id == NULL) {
return NULL;
}
for (GList *iter = rsc_list; iter != NULL; iter = iter->next) {
pcmk_resource_t *parent = iter->data;
pcmk_resource_t *match = NULL;
match = parent->priv->fns->find_rsc(parent, id, NULL,
pcmk_rsc_match_history);
if (match != NULL) {
if (!pcmk__str_eq(match->id, id, pcmk__str_none)) {
/* We found an instance of a clone instead */
match = uber_parent(match);
crm_debug("Found %s for %s", match->id, id);
}
return match;
}
}
crm_trace("No match for %s", id);
return NULL;
}
/*!
* \internal
* \brief Check whether an ID references a resource tag
*
* \param[in] scheduler Scheduler data
* \param[in] id Tag ID to search for
* \param[out] tag Where to store tag, if found
*
* \return true if ID refers to a tagged resource or resource set template,
* otherwise false
*/
static bool
find_constraint_tag(const pcmk_scheduler_t *scheduler, const char *id,
pcmk__idref_t **tag)
{
*tag = NULL;
// Check whether id refers to a resource set template
if (g_hash_table_lookup_extended(scheduler->priv->templates, id,
NULL, (gpointer *) tag)) {
if (*tag == NULL) {
crm_notice("No resource is derived from template '%s'", id);
return false;
}
return true;
}
// If not, check whether id refers to a tag
if (g_hash_table_lookup_extended(scheduler->priv->tags, id,
NULL, (gpointer *) tag)) {
if (*tag == NULL) {
crm_notice("No resource is tagged with '%s'", id);
return false;
}
return true;
}
pcmk__config_warn("No resource, template, or tag named '%s'", id);
return false;
}
/*!
* \internal
* \brief Parse a role attribute from a constraint
*
* This is like pcmk_parse_role() except that started is treated as
* pcmk_role_unknown (indicating any role), and the return value is
* pcmk_rc_unpack_error for invalid specifications.
*
* \param[in] id ID of constraint being parsed (for logging only)
* \param[in] role_spec Role specification
* \param[in] role Where to store parsed role
*
* \return Standard Pacemaker return code
*/
int
pcmk__parse_constraint_role(const char *id, const char *role_spec,
enum rsc_role_e *role)
{
*role = pcmk_parse_role(role_spec);
switch (*role) {
case pcmk_role_unknown:
if (role_spec != NULL) {
pcmk__config_err("Ignoring constraint %s: Invalid role '%s'",
id, role_spec);
return pcmk_rc_unpack_error;
}
break;
case pcmk_role_started:
*role = pcmk_role_unknown;
break;
default:
break;
}
return pcmk_rc_ok;
}
/*!
* \brief
* \internal Check whether an ID refers to a valid resource or tag
*
* \param[in] scheduler Scheduler data
* \param[in] id ID to search for
* \param[out] rsc Where to store resource, if found
* (or NULL to skip searching resources)
* \param[out] tag Where to store tag, if found
* (or NULL to skip searching tags)
*
* \return true if id refers to a resource (possibly indirectly via a tag)
*/
bool
pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id,
pcmk_resource_t **rsc, pcmk__idref_t **tag)
{
if (rsc != NULL) {
*rsc = pcmk__find_constraint_resource(scheduler->priv->resources, id);
if (*rsc != NULL) {
return true;
}
}
if ((tag != NULL) && find_constraint_tag(scheduler, id, tag)) {
return true;
}
return false;
}
/*!
* \internal
* \brief Replace any resource tags with equivalent \C PCMK_XE_RESOURCE_REF
* entries
*
* If a given constraint has resource sets, check each set for
* \c PCMK_XE_RESOURCE_REF entries that list tags rather than resource IDs, and
* replace any found with \c PCMK_XE_RESOURCE_REF entries for the corresponding
* resource IDs.
*
* \param[in,out] xml_obj Constraint XML
* \param[in] scheduler Scheduler data
*
* \return Equivalent XML with resource tags replaced (or NULL if none)
* \note It is the caller's responsibility to free the return value with
* \c pcmk__xml_free().
*/
xmlNode *
pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
{
xmlNode *new_xml = NULL;
bool any_refs = false;
// Short-circuit if there are no sets
if (pcmk__xe_first_child(xml_obj, PCMK_XE_RESOURCE_SET, NULL,
NULL) == NULL) {
return NULL;
}
new_xml = pcmk__xml_copy(NULL, xml_obj);
for (xmlNode *set = pcmk__xe_first_child(new_xml, PCMK_XE_RESOURCE_SET,
NULL, NULL);
set != NULL; set = pcmk__xe_next_same(set)) {
GList *tag_refs = NULL;
GList *iter = NULL;
for (xmlNode *xml_rsc = pcmk__xe_first_child(set, PCMK_XE_RESOURCE_REF,
NULL, NULL);
xml_rsc != NULL; xml_rsc = pcmk__xe_next_same(xml_rsc)) {
pcmk_resource_t *rsc = NULL;
pcmk__idref_t *tag = NULL;
if (!pcmk__valid_resource_or_tag(scheduler, pcmk__xe_id(xml_rsc),
&rsc, &tag)) {
pcmk__config_err("Ignoring resource sets for constraint '%s' "
"because '%s' is not a valid resource or tag",
pcmk__xe_id(xml_obj), pcmk__xe_id(xml_rsc));
pcmk__xml_free(new_xml);
return NULL;
} else if (rsc) {
continue;
} else if (tag) {
/* PCMK_XE_RESOURCE_REF under PCMK_XE_RESOURCE_SET references
* template or tag
*/
xmlNode *last_ref = xml_rsc;
/* For example, given the original XML:
*
* <resource_set id="tag1-colocation-0" sequential="true">
* <resource_ref id="rsc1"/>
* <resource_ref id="tag1"/>
* <resource_ref id="rsc4"/>
* </resource_set>
*
* If rsc2 and rsc3 are tagged with tag1, we add them after it:
*
* <resource_set id="tag1-colocation-0" sequential="true">
* <resource_ref id="rsc1"/>
* <resource_ref id="tag1"/>
* <resource_ref id="rsc2"/>
* <resource_ref id="rsc3"/>
* <resource_ref id="rsc4"/>
* </resource_set>
*/
for (iter = tag->refs; iter != NULL; iter = iter->next) {
const char *obj_ref = iter->data;
xmlNode *new_rsc_ref = NULL;
new_rsc_ref = xmlNewDocRawNode(set->doc, NULL,
(pcmkXmlStr)
PCMK_XE_RESOURCE_REF,
NULL);
crm_xml_add(new_rsc_ref, PCMK_XA_ID, obj_ref);
xmlAddNextSibling(last_ref, new_rsc_ref);
last_ref = new_rsc_ref;
}
any_refs = true;
/* Freeing the resource_ref now would break the XML child
* iteration, so just remember it for freeing later.
*/
tag_refs = g_list_append(tag_refs, xml_rsc);
}
}
/* Now free '<resource_ref id="tag1"/>', and finally get:
<resource_set id="tag1-colocation-0" sequential="true">
<resource_ref id="rsc1"/>
<resource_ref id="rsc2"/>
<resource_ref id="rsc3"/>
<resource_ref id="rsc4"/>
</resource_set>
*/
for (iter = tag_refs; iter != NULL; iter = iter->next) {
xmlNode *tag_ref = iter->data;
pcmk__xml_free(tag_ref);
}
g_list_free(tag_refs);
}
if (!any_refs) {
pcmk__xml_free(new_xml);
new_xml = NULL;
}
return new_xml;
}
/*!
* \internal
* \brief Convert a tag into a resource set of tagged resources
*
* \param[in,out] xml_obj Constraint XML
* \param[out] rsc_set Where to store resource set XML
* \param[in] attr Name of XML attribute with resource or tag ID
* \param[in] convert_rsc If true, convert to set even if \p attr
* references a resource
* \param[in] scheduler Scheduler data
*/
bool
pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr,
bool convert_rsc, const pcmk_scheduler_t *scheduler)
{
const char *cons_id = NULL;
const char *id = NULL;
pcmk_resource_t *rsc = NULL;
pcmk__idref_t *tag = NULL;
*rsc_set = NULL;
CRM_CHECK((xml_obj != NULL) && (attr != NULL), return false);
cons_id = pcmk__xe_id(xml_obj);
if (cons_id == NULL) {
pcmk__config_err("Ignoring <%s> constraint without " PCMK_XA_ID,
xml_obj->name);
return false;
}
id = crm_element_value(xml_obj, attr);
if (id == NULL) {
return true;
}
if (!pcmk__valid_resource_or_tag(scheduler, id, &rsc, &tag)) {
pcmk__config_err("Ignoring constraint '%s' because '%s' is not a "
"valid resource or tag", cons_id, id);
return false;
} else if (tag) {
/* The "attr" attribute (for a resource in a constraint) specifies a
* template or tag. Add the corresponding PCMK_XE_RESOURCE_SET
* containing the resources derived from or tagged with it.
*/
*rsc_set = pcmk__xe_create(xml_obj, PCMK_XE_RESOURCE_SET);
crm_xml_add(*rsc_set, PCMK_XA_ID, id);
for (GList *iter = tag->refs; iter != NULL; iter = iter->next) {
const char *obj_ref = iter->data;
xmlNode *rsc_ref = NULL;
rsc_ref = pcmk__xe_create(*rsc_set, PCMK_XE_RESOURCE_REF);
crm_xml_add(rsc_ref, PCMK_XA_ID, obj_ref);
}
// Set PCMK_XA_SEQUENTIAL=PCMK_VALUE_FALSE for the PCMK_XE_RESOURCE_SET
pcmk__xe_set_bool_attr(*rsc_set, PCMK_XA_SEQUENTIAL, false);
} else if ((rsc != NULL) && convert_rsc) {
/* Even if a regular resource is referenced by "attr", convert it into a
* PCMK_XE_RESOURCE_SET, because the other resource reference in the
* constraint could be a template or tag.
*/
xmlNode *rsc_ref = NULL;
*rsc_set = pcmk__xe_create(xml_obj, PCMK_XE_RESOURCE_SET);
crm_xml_add(*rsc_set, PCMK_XA_ID, id);
rsc_ref = pcmk__xe_create(*rsc_set, PCMK_XE_RESOURCE_REF);
crm_xml_add(rsc_ref, PCMK_XA_ID, id);
} else {
return true;
}
/* Remove the "attr" attribute referencing the template/tag */
if (*rsc_set != NULL) {
pcmk__xe_remove_attr(xml_obj, attr);
}
return true;
}
/*!
* \internal
* \brief Create constraints inherent to resource types
*
* \param[in,out] scheduler Scheduler data
*/
void
pcmk__create_internal_constraints(pcmk_scheduler_t *scheduler)
{
crm_trace("Create internal constraints");
for (GList *iter = scheduler->priv->resources;
iter != NULL; iter = iter->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
rsc->priv->cmds->internal_constraints(rsc);
}
}
diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c
index fe962239fc..f0d216b80d 100644
--- a/tools/crm_resource_print.c
+++ b/tools/crm_resource_print.c
@@ -1,927 +1,927 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <stdint.h>
#include <crm_resource.h>
#include <crm/common/lists_internal.h>
#include <crm/common/output.h>
#include <crm/common/results.h>
#define cons_string(x) x?x:"NA"
static int
print_constraint(xmlNode *xml_obj, void *userdata)
{
pcmk_scheduler_t *scheduler = (pcmk_scheduler_t *) userdata;
pcmk__output_t *out = scheduler->priv->out;
xmlNode *lifetime = NULL;
const char *id = crm_element_value(xml_obj, PCMK_XA_ID);
pcmk_rule_input_t rule_input = {
.now = scheduler->priv->now,
};
if (id == NULL) {
return pcmk_rc_ok;
}
- // @COMPAT PCMK__XE_LIFETIME is deprecated
+ // @COMPAT Not possible with schema validation enabled
lifetime = pcmk__xe_first_child(xml_obj, PCMK__XE_LIFETIME, NULL, NULL);
if (pcmk__evaluate_rules(lifetime, &rule_input, NULL) != pcmk_rc_ok) {
return pcmk_rc_ok;
}
if (!pcmk__xe_is(xml_obj, PCMK_XE_RSC_COLOCATION)) {
return pcmk_rc_ok;
}
out->info(out, "Constraint %s %s %s %s %s %s %s",
xml_obj->name,
cons_string(crm_element_value(xml_obj, PCMK_XA_ID)),
cons_string(crm_element_value(xml_obj, PCMK_XA_RSC)),
cons_string(crm_element_value(xml_obj, PCMK_XA_WITH_RSC)),
cons_string(crm_element_value(xml_obj, PCMK_XA_SCORE)),
cons_string(crm_element_value(xml_obj, PCMK_XA_RSC_ROLE)),
cons_string(crm_element_value(xml_obj, PCMK_XA_WITH_RSC_ROLE)));
return pcmk_rc_ok;
}
void
cli_resource_print_cts_constraints(pcmk_scheduler_t *scheduler)
{
pcmk__xe_foreach_child(pcmk_find_cib_element(scheduler->input,
PCMK_XE_CONSTRAINTS),
NULL, print_constraint, scheduler);
}
void
cli_resource_print_cts(pcmk_resource_t *rsc, pcmk__output_t *out)
{
const char *host = NULL;
bool needs_quorum = TRUE;
const char *rtype = crm_element_value(rsc->priv->xml, PCMK_XA_TYPE);
const char *rprov = crm_element_value(rsc->priv->xml, PCMK_XA_PROVIDER);
const char *rclass = crm_element_value(rsc->priv->xml, PCMK_XA_CLASS);
pcmk_node_t *node = pcmk__current_node(rsc);
if (pcmk_is_set(rsc->flags, pcmk__rsc_fence_device)) {
needs_quorum = FALSE;
} else {
// @TODO check requires in resource meta-data and rsc_defaults
}
if (node != NULL) {
host = node->priv->name;
}
out->info(out, "Resource: %s %s %s %s %s %s %s %s %d %lld %#.16llx",
rsc->priv->xml->name, rsc->id,
pcmk__s(rsc->priv->history_id, rsc->id),
((rsc->priv->parent == NULL)? "NA" : rsc->priv->parent->id),
rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags,
rsc->flags);
g_list_foreach(rsc->priv->children, (GFunc) cli_resource_print_cts, out);
}
// \return Standard Pacemaker return code
int
cli_resource_print_operations(const char *rsc_id, const char *host_uname,
bool active, pcmk_scheduler_t *scheduler)
{
pcmk__output_t *out = scheduler->priv->out;
int rc = pcmk_rc_no_output;
GList *ops = find_operations(rsc_id, host_uname, active, scheduler);
if (!ops) {
return rc;
}
out->begin_list(out, NULL, NULL, "Resource Operations");
rc = pcmk_rc_ok;
for (GList *lpc = ops; lpc != NULL; lpc = lpc->next) {
xmlNode *xml_op = (xmlNode *) lpc->data;
out->message(out, "node-and-op", scheduler, xml_op);
}
out->end_list(out);
return rc;
}
// \return Standard Pacemaker return code
int
cli_resource_print(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler,
bool expanded)
{
pcmk__output_t *out = scheduler->priv->out;
uint32_t show_opts = pcmk_show_pending;
GList *all = NULL;
all = g_list_prepend(all, (gpointer) "*");
out->begin_list(out, NULL, NULL, "Resource Config");
out->message(out, pcmk__map_element_name(rsc->priv->xml), show_opts, rsc,
all, all);
out->message(out, "resource-config", rsc, !expanded);
out->end_list(out);
g_list_free(all);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-changed", "attr_update_data_t *")
static int
attribute_changed_default(pcmk__output_t *out, va_list args)
{
attr_update_data_t *ud = va_arg(args, attr_update_data_t *);
out->info(out, "Set '%s' option: "
PCMK_XA_ID "=%s%s%s%s%s value=%s",
ud->given_rsc_id, ud->found_attr_id,
((ud->attr_set_id == NULL)? "" : " " PCMK__XA_SET "="),
pcmk__s(ud->attr_set_id, ""),
((ud->attr_name == NULL)? "" : " " PCMK_XA_NAME "="),
pcmk__s(ud->attr_name, ""), ud->attr_value);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-changed", "attr_update_data_t *")
static int
attribute_changed_xml(pcmk__output_t *out, va_list args)
{
attr_update_data_t *ud = va_arg(args, attr_update_data_t *);
pcmk__output_xml_create_parent(out,
(const char *) ud->rsc->priv->xml->name,
PCMK_XA_ID, ud->rsc->id,
NULL);
pcmk__output_xml_create_parent(out, ud->attr_set_type,
PCMK_XA_ID, ud->attr_set_id,
NULL);
pcmk__output_create_xml_node(out, PCMK_XE_NVPAIR,
PCMK_XA_ID, ud->found_attr_id,
PCMK_XA_VALUE, ud->attr_value,
PCMK_XA_NAME, ud->attr_name,
NULL);
pcmk__output_xml_pop_parent(out);
pcmk__output_xml_pop_parent(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-changed-list", "GList *")
static int
attribute_changed_list_default(pcmk__output_t *out, va_list args)
{
GList *results = va_arg(args, GList *);
if (results == NULL) {
return pcmk_rc_no_output;
}
for (GList *iter = results; iter != NULL; iter = iter->next) {
attr_update_data_t *ud = iter->data;
out->message(out, "attribute-changed", ud);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-changed-list", "GList *")
static int
attribute_changed_list_xml(pcmk__output_t *out, va_list args)
{
GList *results = va_arg(args, GList *);
if (results == NULL) {
return pcmk_rc_no_output;
}
pcmk__output_xml_create_parent(out, PCMK__XE_RESOURCE_SETTINGS, NULL);
for (GList *iter = results; iter != NULL; iter = iter->next) {
attr_update_data_t *ud = iter->data;
out->message(out, "attribute-changed", ud);
}
pcmk__output_xml_pop_parent(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-list", "pcmk_resource_t *", "const char *",
"const char *")
static int
attribute_list_default(pcmk__output_t *out, va_list args) {
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
const char *attr = va_arg(args, char *);
const char *value = va_arg(args, const char *);
if (value != NULL) {
out->begin_list(out, NULL, NULL, "Attributes");
out->list_item(out, attr, "%s", value);
out->end_list(out);
return pcmk_rc_ok;
} else {
out->err(out, "Attribute '%s' not found for '%s'", attr, rsc->id);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
"const char *", "const char *", "crm_exit_t", "const char *")
static int
agent_status_default(pcmk__output_t *out, va_list args) {
int status = va_arg(args, int);
const char *action = va_arg(args, const char *);
const char *name = va_arg(args, const char *);
const char *class = va_arg(args, const char *);
const char *provider = va_arg(args, const char *);
const char *type = va_arg(args, const char *);
crm_exit_t rc = va_arg(args, crm_exit_t);
const char *exit_reason = va_arg(args, const char *);
if (status == PCMK_EXEC_DONE) {
/* Operation <action> [for <resource>] (<class>[:<provider>]:<agent>)
* returned <exit-code> (<exit-description>[: <exit-reason>])
*/
out->info(out, "Operation %s%s%s (%s%s%s:%s) returned %d (%s%s%s)",
action,
((name == NULL)? "" : " for "), ((name == NULL)? "" : name),
class,
((provider == NULL)? "" : ":"),
((provider == NULL)? "" : provider),
type, (int) rc, services_ocf_exitcode_str((int) rc),
((exit_reason == NULL)? "" : ": "),
((exit_reason == NULL)? "" : exit_reason));
} else {
/* Operation <action> [for <resource>] (<class>[:<provider>]:<agent>)
* could not be executed (<execution-status>[: <exit-reason>])
*/
out->err(out,
"Operation %s%s%s (%s%s%s:%s) could not be executed (%s%s%s)",
action,
((name == NULL)? "" : " for "), ((name == NULL)? "" : name),
class,
((provider == NULL)? "" : ":"),
((provider == NULL)? "" : provider),
type, pcmk_exec_status_str(status),
((exit_reason == NULL)? "" : ": "),
((exit_reason == NULL)? "" : exit_reason));
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
"const char *", "const char *", "crm_exit_t", "const char *")
static int
agent_status_xml(pcmk__output_t *out, va_list args) {
int status = va_arg(args, int);
const char *action G_GNUC_UNUSED = va_arg(args, const char *);
const char *name G_GNUC_UNUSED = va_arg(args, const char *);
const char *class G_GNUC_UNUSED = va_arg(args, const char *);
const char *provider G_GNUC_UNUSED = va_arg(args, const char *);
const char *type G_GNUC_UNUSED = va_arg(args, const char *);
crm_exit_t rc = va_arg(args, crm_exit_t);
const char *exit_reason = va_arg(args, const char *);
char *exit_s = pcmk__itoa(rc);
const char *message = services_ocf_exitcode_str((int) rc);
char *status_s = pcmk__itoa(status);
const char *execution_message = pcmk_exec_status_str(status);
pcmk__output_create_xml_node(out, PCMK_XE_AGENT_STATUS,
PCMK_XA_CODE, exit_s,
PCMK_XA_MESSAGE, message,
PCMK_XA_EXECUTION_CODE, status_s,
PCMK_XA_EXECUTION_MESSAGE, execution_message,
PCMK_XA_REASON, exit_reason,
NULL);
free(exit_s);
free(status_s);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("attribute-list", "pcmk_resource_t *", "const char *",
"const char *")
static int
attribute_list_text(pcmk__output_t *out, va_list args) {
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
const char *attr = va_arg(args, char *);
const char *value = va_arg(args, const char *);
if (value != NULL) {
pcmk__formatted_printf(out, "%s\n", value);
return pcmk_rc_ok;
} else {
out->err(out, "Attribute '%s' not found for '%s'", attr, rsc->id);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
static int
override_default(pcmk__output_t *out, va_list args) {
const char *rsc_name = va_arg(args, const char *);
const char *name = va_arg(args, const char *);
const char *value = va_arg(args, const char *);
if (rsc_name == NULL) {
out->list_item(out, NULL, "Overriding the cluster configuration with '%s' = '%s'",
name, value);
} else {
out->list_item(out, NULL, "Overriding the cluster configuration for '%s' with '%s' = '%s'",
rsc_name, name, value);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
static int
override_xml(pcmk__output_t *out, va_list args) {
const char *rsc_name = va_arg(args, const char *);
const char *name = va_arg(args, const char *);
const char *value = va_arg(args, const char *);
xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_OVERRIDE,
PCMK_XA_NAME, name,
PCMK_XA_VALUE, value,
NULL);
if (rsc_name != NULL) {
crm_xml_add(node, PCMK_XA_RSC, rsc_name);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("property-list", "pcmk_resource_t *", "const char *")
static int
property_list_default(pcmk__output_t *out, va_list args) {
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
const char *attr = va_arg(args, char *);
const char *value = crm_element_value(rsc->priv->xml, attr);
if (value != NULL) {
out->begin_list(out, NULL, NULL, "Properties");
out->list_item(out, attr, "%s", value);
out->end_list(out);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("property-list", "pcmk_resource_t *", "const char *")
static int
property_list_text(pcmk__output_t *out, va_list args) {
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
const char *attr = va_arg(args, const char *);
const char *value = crm_element_value(rsc->priv->xml, attr);
if (value != NULL) {
pcmk__formatted_printf(out, "%s\n", value);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
"const char *", "const char *", "const char *", "GHashTable *",
"crm_exit_t", "int", "const char *", "const char *", "const char *")
static int
resource_agent_action_default(pcmk__output_t *out, va_list args) {
int verbose = va_arg(args, int);
const char *class = va_arg(args, const char *);
const char *provider = va_arg(args, const char *);
const char *type = va_arg(args, const char *);
const char *rsc_name = va_arg(args, const char *);
const char *action = va_arg(args, const char *);
GHashTable *overrides = va_arg(args, GHashTable *);
crm_exit_t rc = va_arg(args, crm_exit_t);
int status = va_arg(args, int);
const char *exit_reason = va_arg(args, const char *);
const char *stdout_data = va_arg(args, const char *);
const char *stderr_data = va_arg(args, const char *);
if (overrides) {
GHashTableIter iter;
const char *name = NULL;
const char *value = NULL;
out->begin_list(out, NULL, NULL, PCMK_XE_OVERRIDES);
g_hash_table_iter_init(&iter, overrides);
while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
out->message(out, "override", rsc_name, name, value);
}
out->end_list(out);
}
out->message(out, "agent-status", status, action, rsc_name, class, provider,
type, rc, exit_reason);
/* hide output for validate-all if not in verbose */
if ((verbose == 0)
&& pcmk__str_eq(action, PCMK_ACTION_VALIDATE_ALL, pcmk__str_casei)) {
return pcmk_rc_ok;
}
if (stdout_data || stderr_data) {
xmlNodePtr doc = NULL;
if (stdout_data != NULL) {
doc = pcmk__xml_parse(stdout_data);
}
if (doc != NULL) {
out->output_xml(out, PCMK_XE_COMMAND, stdout_data);
xmlFreeNode(doc);
} else {
out->subprocess_output(out, rc, stdout_data, stderr_data);
}
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
"const char *", "const char *", "const char *", "GHashTable *",
"crm_exit_t", "int", "const char *", "const char *", "const char *")
static int
resource_agent_action_xml(pcmk__output_t *out, va_list args) {
int verbose G_GNUC_UNUSED = va_arg(args, int);
const char *class = va_arg(args, const char *);
const char *provider = va_arg(args, const char *);
const char *type = va_arg(args, const char *);
const char *rsc_name = va_arg(args, const char *);
const char *action = va_arg(args, const char *);
GHashTable *overrides = va_arg(args, GHashTable *);
crm_exit_t rc = va_arg(args, crm_exit_t);
int status = va_arg(args, int);
const char *exit_reason = va_arg(args, const char *);
const char *stdout_data = va_arg(args, const char *);
const char *stderr_data = va_arg(args, const char *);
xmlNodePtr node = NULL;
node = pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCE_AGENT_ACTION,
PCMK_XA_ACTION, action,
PCMK_XA_CLASS, class,
PCMK_XA_TYPE, type,
NULL);
if (rsc_name) {
crm_xml_add(node, PCMK_XA_RSC, rsc_name);
}
crm_xml_add(node, PCMK_XA_PROVIDER, provider);
if (overrides) {
GHashTableIter iter;
const char *name = NULL;
const char *value = NULL;
out->begin_list(out, NULL, NULL, PCMK_XE_OVERRIDES);
g_hash_table_iter_init(&iter, overrides);
while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
out->message(out, "override", rsc_name, name, value);
}
out->end_list(out);
}
out->message(out, "agent-status", status, action, rsc_name, class, provider,
type, rc, exit_reason);
if (stdout_data || stderr_data) {
xmlNodePtr doc = NULL;
if (stdout_data != NULL) {
doc = pcmk__xml_parse(stdout_data);
}
if (doc != NULL) {
out->output_xml(out, PCMK_XE_COMMAND, stdout_data);
xmlFreeNode(doc);
} else {
out->subprocess_output(out, rc, stdout_data, stderr_data);
}
}
pcmk__output_xml_pop_parent(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
static int
resource_check_list_default(pcmk__output_t *out, va_list args) {
resource_checks_t *checks = va_arg(args, resource_checks_t *);
const pcmk_resource_t *parent = pe__const_top_resource(checks->rsc, false);
const pcmk_scheduler_t *scheduler = checks->rsc->priv->scheduler;
if (checks->flags == 0) {
return pcmk_rc_no_output;
}
out->begin_list(out, NULL, NULL, "Resource Checks");
if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
out->list_item(out, "check", "Configuration specifies '%s' should remain stopped",
parent->id);
}
if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
out->list_item(out, "check", "Configuration specifies '%s' should not be promoted",
parent->id);
}
if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
out->list_item(out, "check", "Configuration prevents cluster from stopping or starting unmanaged '%s'",
parent->id);
}
if (pcmk_is_set(checks->flags, rsc_locked)) {
out->list_item(out, "check", "'%s' is locked to node %s due to shutdown",
parent->id, checks->lock_node);
}
if (pcmk_is_set(checks->flags, rsc_node_health)) {
out->list_item(out, "check",
"'%s' cannot run on unhealthy nodes due to "
PCMK_OPT_NODE_HEALTH_STRATEGY "='%s'",
parent->id,
pcmk__cluster_option(scheduler->priv->options,
PCMK_OPT_NODE_HEALTH_STRATEGY));
}
out->end_list(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
static int
resource_check_list_xml(pcmk__output_t *out, va_list args) {
resource_checks_t *checks = va_arg(args, resource_checks_t *);
const pcmk_resource_t *parent = pe__const_top_resource(checks->rsc, false);
xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_CHECK,
PCMK_XA_ID, parent->id,
NULL);
if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
pcmk__xe_set_bool_attr(node, PCMK_XA_REMAIN_STOPPED, true);
}
if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
pcmk__xe_set_bool_attr(node, PCMK_XA_PROMOTABLE, false);
}
if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
pcmk__xe_set_bool_attr(node, PCMK_XA_UNMANAGED, true);
}
if (pcmk_is_set(checks->flags, rsc_locked)) {
crm_xml_add(node, PCMK_XA_LOCKED_TO_HYPHEN, checks->lock_node);
}
if (pcmk_is_set(checks->flags, rsc_node_health)) {
pcmk__xe_set_bool_attr(node, PCMK_XA_UNHEALTHY, true);
}
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "const gchar *")
static int
resource_search_list_default(pcmk__output_t *out, va_list args)
{
GList *nodes = va_arg(args, GList *);
const gchar *requested_name = va_arg(args, const gchar *);
bool printed = false;
int rc = pcmk_rc_no_output;
if (!out->is_quiet(out) && nodes == NULL) {
out->err(out, "resource %s is NOT running", requested_name);
return rc;
}
for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
node_info_t *ni = (node_info_t *) lpc->data;
if (!printed) {
out->begin_list(out, NULL, NULL, "Nodes");
printed = true;
rc = pcmk_rc_ok;
}
if (out->is_quiet(out)) {
out->list_item(out, "node", "%s", ni->node_name);
} else {
const char *role_text = "";
if (ni->promoted) {
role_text = " " PCMK_ROLE_PROMOTED;
}
out->list_item(out, "node", "resource %s is running on: %s%s",
requested_name, ni->node_name, role_text);
}
}
if (printed) {
out->end_list(out);
}
return rc;
}
PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "const gchar *")
static int
resource_search_list_xml(pcmk__output_t *out, va_list args)
{
GList *nodes = va_arg(args, GList *);
const gchar *requested_name = va_arg(args, const gchar *);
pcmk__output_xml_create_parent(out, PCMK_XE_NODES,
PCMK_XA_RESOURCE, requested_name,
NULL);
for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
node_info_t *ni = (node_info_t *) lpc->data;
xmlNodePtr sub_node = pcmk__output_create_xml_text_node(out,
PCMK_XE_NODE,
ni->node_name);
if (ni->promoted) {
crm_xml_add(sub_node, PCMK_XA_STATE, "promoted");
}
}
pcmk__output_xml_pop_parent(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-reasons-list", "GList *", "pcmk_resource_t *",
"pcmk_node_t *")
static int
resource_reasons_list_default(pcmk__output_t *out, va_list args)
{
GList *resources = va_arg(args, GList *);
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
pcmk_node_t *node = va_arg(args, pcmk_node_t *);
const char *host_uname = (node == NULL)? NULL : node->priv->name;
out->begin_list(out, NULL, NULL, "Resource Reasons");
if ((rsc == NULL) && (host_uname == NULL)) {
GList *lpc = NULL;
GList *hosts = NULL;
for (lpc = resources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
rsc->priv->fns->location(rsc, &hosts, pcmk__rsc_node_current);
if (hosts == NULL) {
out->list_item(out, "reason", "Resource %s is not running", rsc->id);
} else {
out->list_item(out, "reason", "Resource %s is running", rsc->id);
}
cli_resource_check(out, rsc, NULL);
g_list_free(hosts);
hosts = NULL;
}
} else if ((rsc != NULL) && (host_uname != NULL)) {
if (resource_is_running_on(rsc, host_uname)) {
out->list_item(out, "reason", "Resource %s is running on host %s",
rsc->id, host_uname);
} else {
out->list_item(out, "reason", "Resource %s is not running on host %s",
rsc->id, host_uname);
}
cli_resource_check(out, rsc, node);
} else if ((rsc == NULL) && (host_uname != NULL)) {
const char* host_uname = node->priv->name;
GList *allResources = node->priv->assigned_resources;
GList *activeResources = node->details->running_rsc;
GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
GList *lpc = NULL;
for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
out->list_item(out, "reason", "Resource %s is running on host %s",
rsc->id, host_uname);
cli_resource_check(out, rsc, node);
}
for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
out->list_item(out, "reason", "Resource %s is assigned to host %s but not running",
rsc->id, host_uname);
cli_resource_check(out, rsc, node);
}
g_list_free(allResources);
g_list_free(activeResources);
g_list_free(unactiveResources);
} else if ((rsc != NULL) && (host_uname == NULL)) {
GList *hosts = NULL;
rsc->priv->fns->location(rsc, &hosts, pcmk__rsc_node_current);
out->list_item(out, "reason", "Resource %s is %srunning",
rsc->id, (hosts? "" : "not "));
cli_resource_check(out, rsc, NULL);
g_list_free(hosts);
}
out->end_list(out);
return pcmk_rc_ok;
}
PCMK__OUTPUT_ARGS("resource-reasons-list", "GList *", "pcmk_resource_t *",
"pcmk_node_t *")
static int
resource_reasons_list_xml(pcmk__output_t *out, va_list args)
{
GList *resources = va_arg(args, GList *);
pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *);
pcmk_node_t *node = va_arg(args, pcmk_node_t *);
const char *host_uname = (node == NULL)? NULL : node->priv->name;
xmlNodePtr xml_node = pcmk__output_xml_create_parent(out, PCMK_XE_REASON,
NULL);
if ((rsc == NULL) && (host_uname == NULL)) {
GList *lpc = NULL;
GList *hosts = NULL;
pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCES, NULL);
for (lpc = resources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
const char *running = NULL;
rsc->priv->fns->location(rsc, &hosts, pcmk__rsc_node_current);
running = pcmk__btoa(hosts != NULL);
pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCE,
PCMK_XA_ID, rsc->id,
PCMK_XA_RUNNING, running,
NULL);
cli_resource_check(out, rsc, NULL);
pcmk__output_xml_pop_parent(out);
g_list_free(hosts);
hosts = NULL;
}
pcmk__output_xml_pop_parent(out);
} else if ((rsc != NULL) && (host_uname != NULL)) {
if (resource_is_running_on(rsc, host_uname)) {
crm_xml_add(xml_node, PCMK_XA_RUNNING_ON, host_uname);
}
cli_resource_check(out, rsc, node);
} else if ((rsc == NULL) && (host_uname != NULL)) {
const char* host_uname = node->priv->name;
GList *allResources = node->priv->assigned_resources;
GList *activeResources = node->details->running_rsc;
GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
GList *lpc = NULL;
pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCES, NULL);
for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCE,
PCMK_XA_ID, rsc->id,
PCMK_XA_RUNNING, PCMK_VALUE_TRUE,
PCMK_XA_HOST, host_uname,
NULL);
cli_resource_check(out, rsc, node);
pcmk__output_xml_pop_parent(out);
}
for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data;
pcmk__output_xml_create_parent(out, PCMK_XE_RESOURCE,
PCMK_XA_ID, rsc->id,
PCMK_XA_RUNNING, PCMK_VALUE_FALSE,
PCMK_XA_HOST, host_uname,
NULL);
cli_resource_check(out, rsc, node);
pcmk__output_xml_pop_parent(out);
}
pcmk__output_xml_pop_parent(out);
g_list_free(allResources);
g_list_free(activeResources);
g_list_free(unactiveResources);
} else if ((rsc != NULL) && (host_uname == NULL)) {
GList *hosts = NULL;
rsc->priv->fns->location(rsc, &hosts, pcmk__rsc_node_current);
crm_xml_add(xml_node, PCMK_XA_RUNNING, pcmk__btoa(hosts != NULL));
cli_resource_check(out, rsc, NULL);
g_list_free(hosts);
}
pcmk__output_xml_pop_parent(out);
return pcmk_rc_ok;
}
static void
add_resource_name(pcmk_resource_t *rsc, pcmk__output_t *out)
{
if (rsc->priv->children == NULL) {
/* Sometimes PCMK_XE_RESOURCE might act as a PCMK_XA_NAME instead of an
* XML element name, depending on whether pcmk__output_enable_list_element
* was called.
*/
out->list_item(out, PCMK_XE_RESOURCE, "%s", rsc->id);
} else {
g_list_foreach(rsc->priv->children, (GFunc) add_resource_name, out);
}
}
PCMK__OUTPUT_ARGS("resource-names-list", "GList *")
static int
resource_names(pcmk__output_t *out, va_list args) {
GList *resources = va_arg(args, GList *);
if (resources == NULL) {
out->err(out, "NO resources configured\n");
return pcmk_rc_no_output;
}
out->begin_list(out, NULL, NULL, "Resource Names");
g_list_foreach(resources, (GFunc) add_resource_name, out);
out->end_list(out);
return pcmk_rc_ok;
}
static pcmk__message_entry_t fmt_functions[] = {
{ "agent-status", "default", agent_status_default },
{ "agent-status", "xml", agent_status_xml },
{ "attribute-changed", "default", attribute_changed_default },
{ "attribute-changed", "xml", attribute_changed_xml },
{ "attribute-changed-list", "default", attribute_changed_list_default },
{ "attribute-changed-list", "xml", attribute_changed_list_xml },
{ "attribute-list", "default", attribute_list_default },
{ "attribute-list", "text", attribute_list_text },
{ "override", "default", override_default },
{ "override", "xml", override_xml },
{ "property-list", "default", property_list_default },
{ "property-list", "text", property_list_text },
{ "resource-agent-action", "default", resource_agent_action_default },
{ "resource-agent-action", "xml", resource_agent_action_xml },
{ "resource-check-list", "default", resource_check_list_default },
{ "resource-check-list", "xml", resource_check_list_xml },
{ "resource-search-list", "default", resource_search_list_default },
{ "resource-search-list", "xml", resource_search_list_xml },
{ "resource-reasons-list", "default", resource_reasons_list_default },
{ "resource-reasons-list", "xml", resource_reasons_list_xml },
{ "resource-names-list", "default", resource_names },
{ NULL, NULL, NULL }
};
void
crm_resource_register_messages(pcmk__output_t *out) {
pcmk__register_messages(out, fmt_functions);
}
diff --git a/xml/constraints-4.0.rng b/xml/constraints-4.0.rng
index d43557f09f..7128842b5b 100644
--- a/xml/constraints-4.0.rng
+++ b/xml/constraints-4.0.rng
@@ -1,281 +1,248 @@
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<ref name="element-constraints"/>
</start>
<define name="element-constraints">
<element name="constraints">
<zeroOrMore>
<choice>
<ref name="element-location"/>
<ref name="element-colocation"/>
<ref name="element-order"/>
<ref name="element-rsc_ticket"/>
</choice>
</zeroOrMore>
</element>
</define>
<define name="element-location">
<element name="rsc_location">
<attribute name="id"><data type="ID"/></attribute>
<choice>
<group>
<choice>
<attribute name="rsc"><data type="IDREF"/></attribute>
<attribute name="rsc-pattern"><text/></attribute>
</choice>
<optional>
<attribute name="role">
<ref name="attribute-roles"/>
</attribute>
</optional>
</group>
<oneOrMore>
<ref name="element-resource-set"/>
</oneOrMore>
</choice>
<choice>
<group>
<externalRef href="score.rng"/>
<attribute name="node"><text/></attribute>
</group>
<grammar>
<include href="rule-4.0.rng">
<start>
<ref name="element-rule-location"/>
</start>
</include>
</grammar>
</choice>
-
- <!-- @COMPAT: The lifetime element is deprecated -->
- <optional>
- <ref name="element-lifetime"/>
- </optional>
-
<optional>
<attribute name="resource-discovery">
<ref name="attribute-discovery"/>
</attribute>
</optional>
</element>
</define>
<define name="element-resource-set">
<element name="resource_set">
<choice>
<attribute name="id-ref"><data type="IDREF"/></attribute>
<group>
<attribute name="id"><data type="ID"/></attribute>
<optional>
<attribute name="sequential"><data type="boolean"/></attribute>
</optional>
<optional>
<attribute name="require-all"><data type="boolean"/></attribute>
</optional>
<optional>
<attribute name="ordering">
<choice>
<value>group</value>
<value>listed</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="action">
<ref name="attribute-actions"/>
</attribute>
</optional>
<optional>
<attribute name="role">
<ref name="attribute-roles"/>
</attribute>
</optional>
<optional>
<choice>
<externalRef href="score.rng"/>
<attribute name="kind">
<ref name="order-types"/>
</attribute>
</choice>
</optional>
<oneOrMore>
<element name="resource_ref">
<attribute name="id"><data type="IDREF"/></attribute>
</element>
</oneOrMore>
</group>
</choice>
</element>
</define>
<define name="element-colocation">
<element name="rsc_colocation">
<attribute name="id"><data type="ID"/></attribute>
<optional>
<externalRef href="score.rng"/>
</optional>
<optional>
<attribute name="influence"><text/></attribute>
</optional>
-
- <!-- @COMPAT: The lifetime element is deprecated -->
- <optional>
- <ref name="element-lifetime"/>
- </optional>
-
<choice>
<oneOrMore>
<ref name="element-resource-set"/>
</oneOrMore>
<group>
<attribute name="rsc"><data type="IDREF"/></attribute>
<attribute name="with-rsc"><data type="IDREF"/></attribute>
<optional>
<attribute name="node-attribute"><text/></attribute>
</optional>
<optional>
<attribute name="rsc-role">
<ref name="attribute-roles"/>
</attribute>
</optional>
<optional>
<attribute name="with-rsc-role">
<ref name="attribute-roles"/>
</attribute>
</optional>
</group>
</choice>
</element>
</define>
<define name="element-order">
<element name="rsc_order">
<attribute name="id"><data type="ID"/></attribute>
-
- <!-- @COMPAT: The lifetime element is deprecated -->
- <optional>
- <ref name="element-lifetime"/>
- </optional>
-
<optional>
<attribute name="symmetrical"><data type="boolean"/></attribute>
</optional>
<optional>
<attribute name="require-all"><data type="boolean"/></attribute>
</optional>
<optional>
<choice>
<externalRef href="score.rng"/>
<attribute name="kind">
<ref name="order-types"/>
</attribute>
</choice>
</optional>
<choice>
<oneOrMore>
<ref name="element-resource-set"/>
</oneOrMore>
<group>
<attribute name="first"><data type="IDREF"/></attribute>
<attribute name="then"><data type="IDREF"/></attribute>
<optional>
<attribute name="first-action">
<ref name="attribute-actions"/>
</attribute>
</optional>
<optional>
<attribute name="then-action">
<ref name="attribute-actions"/>
</attribute>
</optional>
</group>
</choice>
</element>
</define>
<define name="element-rsc_ticket">
<element name="rsc_ticket">
<attribute name="id"><data type="ID"/></attribute>
<choice>
<oneOrMore>
<ref name="element-resource-set"/>
</oneOrMore>
<group>
<attribute name="rsc"><data type="IDREF"/></attribute>
<optional>
<attribute name="rsc-role">
<ref name="attribute-roles"/>
</attribute>
</optional>
</group>
</choice>
<attribute name="ticket"><text/></attribute>
<optional>
<attribute name="loss-policy">
<choice>
<value>stop</value>
<value>demote</value>
<value>fence</value>
<value>freeze</value>
</choice>
</attribute>
</optional>
</element>
</define>
<define name="attribute-discovery">
<choice>
<value>always</value>
<value>never</value>
<value>exclusive</value>
</choice>
</define>
<define name="attribute-actions">
<choice>
<value>start</value>
<value>promote</value>
<value>demote</value>
<value>stop</value>
</choice>
</define>
<define name="attribute-roles">
<choice>
<value>Stopped</value>
<value>Started</value>
<value>Promoted</value>
<value>Unpromoted</value>
<value>Master</value>
<value>Slave</value>
</choice>
</define>
<define name="order-types">
<choice>
<value>Optional</value>
<value>Mandatory</value>
<value>Serialize</value>
</choice>
</define>
- <!-- @COMPAT: The lifetime element is deprecated -->
- <define name="element-lifetime">
- <element name="lifetime">
- <oneOrMore>
- <grammar>
- <include href="rule-3.10.rng">
- <start>
- <ref name="element-rule-location"/>
- </start>
- </include>
- </grammar>
- </oneOrMore>
- </element>
- </define>
-
</grammar>
diff --git a/xml/upgrade-3.10-3.xsl b/xml/upgrade-3.10-3.xsl
index 76e8d5f9fa..ccf37c2d18 100644
--- a/xml/upgrade-3.10-3.xsl
+++ b/xml/upgrade-3.10-3.xsl
@@ -1,23 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Use comments liberally as future maintainers may be unfamiliar with XSLT.
-->
<!--
upgrade-3.10-3.xsl
Guarantees after this transformation:
+ * There are no lifetime elements.
+ * If a lifetime element existed in a location constraint prior to this
+ transformation, we drop it. If the lifetime element had multiple top-level
+ rules, we nest them inside a single "or" rule; otherwise, we keep the
+ top-level lifetime rule as-is. Then we do the following with it:
+ * If the constraint did not have a top-level rule, the lifetime-based rule
+ becomes the constraint's top-level rule.
+ * If the constraint already had a top-level rule, we create a new "and"
+ top-level constraint rule, containing the existing top-level constraint
+ rule and the lifetime-based rule.
+ * If a lifetime element existed in a colocation or order constraint prior to
+ this transformation, its rules are in a new location constraint that does
+ not apply to any resources. This is in case some other rule references
+ them. A rule in a lifetime element may contain a node attribute expression,
+ which is now allowed only within a location constraint rule.
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="upgrade-3.10-common.xsl"/>
+<xsl:key name='rule_id' match="rule" use="@id"/>
+
<!-- Copy everything unaltered by default -->
<xsl:template match="/|@*|node()">
<xsl:call-template name="identity"/>
</xsl:template>
+
+<!-- Constraints -->
+
+<!--
+ Create a new location constraint that doesn't match any resources, to hold the
+ defined rules from deleted lifetime elements in colocation and order
+ constraints that are still referenced elsewhere (if any)
+ -->
+<xsl:template match="constraints">
+ <!-- All colocation and ordering constraints -->
+ <xsl:variable name="coloc_order" select="rsc_colocation|rsc_order"/>
+
+ <!--
+ All rules originally defined in colocation/ordering lifetime elements
+ -->
+ <xsl:variable name="co_lifetime_rules"
+ select="$coloc_order/lifetime/rule
+ [boolean(number(@original))]"/>
+
+ <!--
+ Rule IDs from $co_lifetime_rule_ids that will still be referenced somewhere
+ after dropping colocation/ordering lifetime elements
+ -->
+ <xsl:variable name="co_lifetime_live_rules"
+ select="$co_lifetime_rules
+ [count(key('rule_id', @id)/ancestor::lifetime
+ [parent::rsc_colocation or parent::rsc_order])
+ != count(key('rule_id', @id))]"/>
+
+ <!--
+ The rules in $co_lifetime_live_rules are referenced elsewhere, so they need
+ definitions. The end of the transformation pipeline would ensure that the
+ first remaining occurrence of the rule remains a definition while the rest
+ become references. However, a lifetime rule may contain a node attribute
+ expression, so its definition should go inside a rsc_location, the last
+ remaining element type that supports rules with node attribute expressions.
+
+ It is likely a mistake if some context besides a location constraint or a
+ lifetime element references a rule with a node attribute expression in a
+ lifetime element. However, it is allowed by the pacemaker-3.10 schema, and
+ we want to ensure the upgraded CIB still validates against the
+ pacemaker-4.0 schema provided the input CIB validates against the
+ pacemaker-3.10 schema.
+ -->
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+
+ <xsl:if test="$co_lifetime_live_rules">
+ <xsl:variable name="location_id"
+ select="concat($upgrade_prefix,
+ 'coloc-order-lifetime-rules')"/>
+
+ <!-- New location constraint to hold rules: matches no resources -->
+ <xsl:element name="rsc_location">
+ <xsl:attribute name="id">
+ <xsl:value-of select="$location_id"/>
+ </xsl:attribute>
+
+ <!-- Nothing can come before the beginning-of-string anchor -->
+ <xsl:attribute name="rsc-pattern">a^</xsl:attribute>
+
+ <!-- Top-level wrapper rule: score and boolean-op don't matter -->
+ <xsl:element name="rule">
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($location_id, '-rule')"/>
+ </xsl:attribute>
+ <xsl:attribute name="score">-INFINITY</xsl:attribute>
+
+ <xsl:apply-templates select="$co_lifetime_live_rules"/>
+ </xsl:element>
+ </xsl:element>
+ </xsl:if>
+ </xsl:copy>
+</xsl:template>
+
+<!--
+ Generate an equivalent rule from a constraint's node and score attributes.
+
+ The context node is assumed to be a location constraint with node and score
+ attributes.
+ -->
+<xsl:template name="node_score_rule">
+ <xsl:variable name="rule_id"
+ select="concat($upgrade_prefix, @id, '-node-score-rule')"/>
+
+ <xsl:element name="rule">
+ <xsl:attribute name="id">
+ <xsl:value-of select="$rule_id"/>
+ </xsl:attribute>
+ <xsl:apply-templates select="@score"/>
+
+ <xsl:element name="expression">
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($rule_id, '-expr')"/>
+ </xsl:attribute>
+ <xsl:attribute name="attribute">#uname</xsl:attribute>
+ <xsl:attribute name="operation">eq</xsl:attribute>
+ <xsl:attribute name="value">
+ <xsl:value-of select="@node"/>
+ </xsl:attribute>
+ </xsl:element>
+ </xsl:element>
+</xsl:template>
+
+<!--
+ For a lifetime element in a location constraint, nest its rules (joined into
+ an "or" rule if there are multiple) inside a top-level rule of the
+ constraint.
+ * If there was already a top-level rule, nest it alongside the lifetime-based
+ rule in a new top-level "and" rule.
+ * Otherwise, create a new rule equivalent to the node and score XML attributes,
+ and nest it alongside the lifetime-based rule in a new top-level "and" rule.
+
+ For the constraint to apply, at least one of the lifetime rules must apply, and
+ either the node XML attribute must match or the existing top-level rule must be
+ satisfied.
+ -->
+<xsl:template match="rsc_location[lifetime]">
+ <xsl:copy>
+ <!-- Existing attributes (except node and score) and resource sets -->
+ <xsl:apply-templates select="@*[(local-name() != 'node')
+ and (local-name() != 'score')]
+ |resource_set"/>
+
+ <xsl:element name="rule">
+ <!--
+ Set a probably-unique ID for the new wrapper rule, based on the
+ rsc_location ID
+ -->
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($upgrade_prefix, @id,
+ '-lifetime-and-rule')"/>
+ </xsl:attribute>
+ <xsl:attribute name="boolean-op">and</xsl:attribute>
+
+ <!-- Include existing top-level rule or node/score attributes -->
+ <xsl:choose>
+ <xsl:when test="rule">
+ <!-- Existing top-level rule -->
+ <xsl:apply-templates select="rule"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- New rule from node and score attributes -->
+ <xsl:call-template name="node_score_rule"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!--
+ Lifetime element's rules (either singleton or nested in a new "or"
+ rule)
+ -->
+ <xsl:apply-templates select="lifetime"/>
+ </xsl:element>
+ </xsl:copy>
+</xsl:template>
+
+<!--
+ For a lifetime element with multiple rules within a location constraint, nest
+ the rules within an "or" wrapper and drop the lifetime element.
+ -->
+<xsl:template match="rsc_location/lifetime[count(rule) > 1]">
+ <xsl:element name="rule">
+ <!--
+ Set a probably-unique ID for the new wrapper rule, based on the
+ rsc_location ID
+ -->
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($upgrade_prefix, ../@id,
+ '-lifetime-or-rule')"/>
+ </xsl:attribute>
+ <xsl:attribute name="boolean-op">or</xsl:attribute>
+ <xsl:apply-templates select="rule"/>
+ </xsl:element>
+</xsl:template>
+
+<!--
+ For a lifetime element with only one rule within a location constraint, simply
+ drop the lifetime element and keep the rule.
+ -->
+<xsl:template match="rsc_location/lifetime[count(rule) = 1]">
+ <xsl:apply-templates select="rule"/>
+</xsl:template>
+
+<!-- Drop lifetime elements within colocation and order constraints -->
+<xsl:template match="rsc_colocation/lifetime"/>
+<xsl:template match="rsc_order/lifetime"/>
+
</xsl:stylesheet>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:23 PM (12 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002617
Default Alt Text
(117 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment