Bug 1397714

Summary: pcs constraint location foo rule --force should be able to ignore that "foo" does not exist yet (if pacemaker validations are turned off)
Product: Red Hat Enterprise Linux 7 Reporter: Michele Baldessari <michele>
Component: pcsAssignee: Tomas Jelinek <tojeline>
Status: CLOSED WONTFIX QA Contact: cluster-qe <cluster-qe>
Severity: high Docs Contact:
Priority: high    
Version: 7.3CC: abeekhof, cfeist, cluster-maint, idevat, jpokorny, omular, tojeline
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-12-13 12:49:20 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Michele Baldessari 2016-11-23 08:54:17 UTC
Description of problem:
The reason for this unusual request is simple: I need to manage constraints and resources with puppet and puppet is horribly bad at managing the same resource in multiple states. So it is rather hard to do the following sequence:
pcs resource create foo --disabled
pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller
pcs resource enable foo

So what I would love to achieve is basically the following:
pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller --force
pcs resource create foo

Now what I tried (after discussing it with Andrew) is the following:
1) Disable validation:
cibadmin --modify --xml-text '<cib validate-with="none"/>' (I plan to re-enable it right after I add the location rule with the non existing resource)
2) pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller --force

The problem is that pcs does its own internal validation and will barf about the missing resource. With the following patch I am able to achieve what I want:
--- constraint.py.orig  2016-11-23 09:42:47.867168506 +0100
+++ constraint.py       2016-11-23 09:45:56.701428923 +0100
@@ -1066,7 +1066,7 @@
         = utils.validate_constraint_resource(utils.get_cib_dom(), res_name)
     if "--autocorrect" in utils.pcs_options and correct_id:
         res_name = correct_id
-    elif not resource_valid:
+    elif not resource_valid and "--force" not in utils.pcs_options:
         utils.err(resource_error)
 
     argv.pop(0) # pop "rule"
@@ -1076,7 +1076,8 @@
     # If resource-discovery is specified, we use it with the rsc_location
     # element not the rule
     if "resource-discovery" in options and options["resource-discovery"]:
-        utils.checkAndUpgradeCIB(2,2,0)
+        if "--force" not in utils.pcs_options:
+           utils.checkAndUpgradeCIB(2,2,0)
         cib, constraints = getCurrentConstraints(utils.get_cib_dom())
         lc = cib.createElement("rsc_location")
         lc.setAttribute("resource-discovery", options.pop("resource-discovery"))


So with the above applied I can do this:
1) cibadmin --modify --xml-text '<cib validate-with="none"/>' 
2) pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller --force
3) pcs resource create foo ocf:heartbeat:Delay
4) cibadmin --modify --xml-text '<cib validate-with="pacemaker-2.3"/>' 


Now the million dollar question is: Are there any chances to get something along the above lines in pcs? :)

Comment 1 Jan Pokorný [poki] 2016-11-23 09:36:45 UTC
Please, do not circumvent validation logic.  There's enough
possibly harmful "forces" in pcs already, and doing so just
to temporarily put the world upside down doesn't seem to be
a good idea.  What if something bad happens and you are stuck
in some interim state you definitely don't want to keep for
long?  It's better to avoid such interim states completely
(e.g., using accumulate-and-push model for CIB which pcs
supports).

What's the problem with puppet and the original sequence?

Comment 2 Tomas Jelinek 2016-11-23 09:42:54 UTC
I really do not think this is a good idea. We should not break pcs just to work around issues in other tools (puppet in this case). If we allow to create invalid CIB it will only bite users later.

Have you tried using editing CIB in file? Something like this:
  pcs cluster cib > cib.xml
  pcs -f cib.xml resource create foo
  pcs -f cib.xml constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller
  pcs cluster cib-push cib.xml

Also I do not get how this is hard to do in puppet:
  pcs resource create foo --disabled
  pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller
  pcs resource enable foo
and this is not:
  cibadmin --modify --xml-text '<cib validate-with="none"/>' 
  pcs constraint location foo rule resource-discovery=exclusive score=0 osprole eq controller --force
  pcs resource create foo ocf:heartbeat:Delay
  cibadmin --modify --xml-text '<cib validate-with="pacemaker-2.3"/>'

Maybe if you elaborate on your issue details we can figure out how to solve it without actually breaking things.

Comment 3 Michele Baldessari 2016-11-23 09:51:18 UTC
(In reply to Tomas Jelinek from comment #2)
> I really do not think this is a good idea. 
I know I know :) I fully realize that. I am trying to gauge all my options here basically.

> We should not break pcs just to
> work around issues in other tools (puppet in this case). If we allow to
> create invalid CIB it will only bite users later.
> 
> Have you tried using editing CIB in file? Something like this:
>   pcs cluster cib > cib.xml
>   pcs -f cib.xml resource create foo
>   pcs -f cib.xml constraint location foo rule resource-discovery=exclusive
> score=0 osprole eq controller
>   pcs cluster cib-push cib.xml
> 
> Also I do not get how this is hard to do in puppet:
>   pcs resource create foo --disabled
>   pcs constraint location foo rule resource-discovery=exclusive score=0
> osprole eq controller
>   pcs resource enable foo
> and this is not:
>   cibadmin --modify --xml-text '<cib validate-with="none"/>' 
>   pcs constraint location foo rule resource-discovery=exclusive score=0
> osprole eq controller --force
>   pcs resource create foo ocf:heartbeat:Delay
>   cibadmin --modify --xml-text '<cib validate-with="pacemaker-2.3"/>'
> 
> Maybe if you elaborate on your issue details we can figure out how to solve
> it without actually breaking things.

The reason this is hard has to do with redefining the same resource foo with different attributes because this breaks idempotency (I.e. if I rerun the manifest it might disable and reenable the resource, which is not what I want). Right now I kind of workaround it via a ruby hack. 
I guess I need to figure out where the hack is the least painful to achieve this.

Thanks Tomas and Poki for the feedback. I'll leave this BZ open a bit more just to bounce off an idea or two if needed and close it afterwards.

Comment 4 Andrew Beekhof 2016-11-23 11:05:02 UTC
(In reply to Jan Pokorný from comment #1)
> Please, do not circumvent validation logic.

In this case, it would be the least worse option