RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 2163953 - [RFE] Provide means to export configured constraints as pcs commands
Summary: [RFE] Provide means to export configured constraints as pcs commands
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 9
Classification: Red Hat
Component: pcs
Version: 9.3
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: rc
: 9.3
Assignee: Ondrej Mular
QA Contact: cluster-qe
Steven J. Levine
URL:
Whiteboard:
Depends On: 1423473 2166294
Blocks: 2166291
TreeView+ depends on / blocked
 
Reported: 2023-01-24 14:06 UTC by Tomas Jelinek
Modified: 2023-11-07 09:00 UTC (History)
9 users (show)

Fixed In Version: pcs-0.11.6-2.el9
Doc Type: Enhancement
Doc Text:
.Displaying the `pcs` commands for re-creating configured resource constraints You can now display the `pcs constraint` commands that can be used to re-create configured resource constraints on a different system by using the `pcs constraint` command with the new `--output-format=cmd` option. The default output format is plain text, as in previous releases, which you can specify with the `--output-format=text` option. The plain text format has been changed slightly to make it consistent with the output format of other `pcs` commands.
Clone Of:
: 2166291 (view as bug list)
Environment:
Last Closed: 2023-11-07 08:23:10 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
additional fix (64.39 KB, patch)
2023-07-11 15:02 UTC, Tomas Jelinek
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker CLUSTERQE-6631 0 None None None 2023-04-19 22:23:18 UTC
Red Hat Issue Tracker RHELPLAN-146184 0 None None None 2023-01-24 14:10:31 UTC
Red Hat Product Errata RHSA-2023:6316 0 None None None 2023-11-07 08:24:03 UTC

Description Tomas Jelinek 2023-01-24 14:06:13 UTC
This is a part of a long term goal to export the whole cluster configuration in form of pcs commands which, when run, recreate the same configuration.

This particular BZ is focused on resource constraints configuration.

Comment 3 Ondrej Mular 2023-03-30 11:04:40 UTC
Upstream patch: https://github.com/ClusterLabs/pcs/commit/ff1d564830b3ab922249a796ecfc4a63925ec4c8

Test:
[root@rhel92-node1 pcs]# pcs constraint --output-format=cmd --all
pcs -- constraint location add location-D1-non-existing-node--10000 resource%D1 non-existing-node -10000;
pcs -- constraint location add location-D1-another-one--INFINITY resource%D1 another-one -INFINITY;
pcs -- constraint location add location-D1-localhost-INFINITY resource%D1 localhost INFINITY;
pcs -- constraint location add location-D2-localhost-INFINITY resource%D2 localhost INFINITY;
pcs -- constraint location add location-D-localhost-INFINITY 'regexp%D*' localhost INFINITY;
pcs -- constraint location resource%D3 rule \
  id=loc_constr_wiht_expired_rule-rule constraint-id=loc_constr_wiht_expired_rule score=500 \
  date lt 2000-01-01;
pcs -- constraint rule add loc_constr_wiht_expired_rule \
  id=loc_constr_wiht_expired_rule-rule-1 role=Unpromoted score=123 \
  date lt 2000-01-02;
pcs -- constraint location resource%D4 rule \
  id=loc_constr_with_not_expired_rule-rule constraint-id=loc_constr_with_not_expired_rule score=500 \
  date gt 2000-01-01;
pcs -- constraint rule add loc_constr_with_not_expired_rule \
  id=loc_constr_with_not_expired_rule-rule-1 role=Promoted score-attribute=test-attr \
  date gt 2010-12-31;
pcs -- constraint location resource%D1 rule \
  id=location-D1-rule constraint-id=location-D1 role=Promoted score=INFINITY \
  date gt 2000-01-01;
pcs -- constraint colocation add Promoted S1-clone with Stopped D4 -100 \
  id=colocation-S1-clone-D4--100;
pcs -- constraint colocation \
  set D1 D2 role=Started \
  set D3 D4 sequential=0 \
  setoptions id=colocation_set_D1D2D3 score=-1;
pcs -- constraint order stop D1 then stop D2 \
  id=order-D1-D2-mandatory symmetrical=0 require-all=0;
pcs -- constraint order start D2 then start D3 \
  id=order-D2-D3-Optional kind=Optional;
pcs -- constraint order \
  set D3 D4 require-all=0 action=stop \
  set S1-clone sequential=0 action=promote \
  setoptions id=order_set_D3D4Se kind=Optional;
pcs -- constraint ticket add custom-ticket1 Promoted S1-clone \
  id=ticket-custom-ticket1-S1-clone-Promoted loss-policy=demote;
pcs -- constraint ticket \
  set D1 D3 D2 role=Stopped \
  setoptions id=ticket_set_D1D3D2 ticket=ticket2;
pcs -- constraint ticket \
  set D1 D3 role=Stopped \
  set D2 \
  setoptions id=ticket_set_D1D3D2-1 ticket=ticket2

Comment 5 Michal Pospisil 2023-05-26 09:41:29 UTC
DevTestResults:

[root@r09-03-a ~]# rpm -q pcs
pcs-0.11.5-1.el9.x86_64

[root@r09-03-a ~]# pcs constraint --output-format=cmd --all
pcs -- constraint location add location-r1-r09-03-b.vm-INFINITY resource%r1 r09-03-b.vm INFINITY;
pcs -- constraint location resource%r2 rule \
 id=location-r2-rule constraint-id=location-r2 score=INFINITY \
 #uname eq r09-03-a.vm

Comment 9 Michal Mazourek 2023-06-28 09:50:24 UTC
A couple of things needs adjustment: 

1. Fix escaping in dates with space and special characters

[root@virt-558 ~]# pcs constraint location d2 rule date lt "2024-06-27 17:50:00"
[root@virt-558 ~]# pcs constraint config --output-format cmd
pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27 17:50:00
[root@virt-558 ~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: score=INFINITY (id: location-d2-rule)
        Expression: date lt 2024-06-27 17:50:00 (id: location-d2-rule-expr)
[root@virt-558 ~]# pcs constraint delete location-d2-rule
[root@virt-558 ~]# pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27 17:50:00
Error: 'date lt 2024-06-27 17:50:00' is not a valid rule expression: unexpected '17:50:00'
[root@virt-558 ~]# echo $?
1


2. Omit unsupported constraints from the generated output of commands, which can be confusing with a large amount of constraints and can re-create unexpected configuration

[root@virt-540 ~]# pcs resource ban d2 virt-542
Warning: Creating location constraint 'cli-ban-d2-on-virt-542' with a score of -INFINITY for resource d2 on virt-542.
	This will prevent d2 from running on virt-542 until the constraint is removed
	This will be the case even if virt-542 is the last node in the cluster
[root@virt-540 ~]# pcs constraint --full > config_before

# there is warning that the constraint is not supported, but the command for its re-creation is still present
[root@virt-540 ~]# pcs constraint config --output-format cmd
Warning: Resource role 'Started' detected in constraint 'cli-ban-d2-on-virt-542' but not supported by this command.
pcs -- constraint location add cli-ban-d2-on-virt-542 resource%d2 virt-542 -INFINITY
[root@virt-540 ~]# pcs constraint delete cli-ban-d2-on-virt-542
[root@virt-540 ~]# pcs -- constraint location add cli-ban-d2-on-virt-542 resource%d2 virt-542 -INFINITY
[root@virt-540 ~]# pcs constraint --full > config_after
[root@virt-540 ~]# diff config_before config_after 
2,3c2,3
<   Started resource 'd2' avoids node 'virt-542' with score INFINITY (id: cli-
<       ban-d2-on-virt-542)
---
>   resource 'd2' avoids node 'virt-542' with score INFINITY (id: cli-ban-d2-on-
>       virt-542)

Comment 14 Tomas Jelinek 2023-07-11 15:02:21 UTC
Created attachment 1975179 [details]
additional fix

1. Escape space and special characters in rules

Space is not allowed as a delimiter in ISO 8601 dates. Therefore pcs normalizes ISO 8601 dates when exporting them:
- all spaces around delimiters are removed
- the first space is replaced with 'T', which is a delimiter between date and time
This results in valid dates being exported as a single string with no spaces.

Using spaces in dates is now deprecated.

Special characters are now quoted.

Test:
[root@rh92-node1:~]# pcs constraint location d2 rule \#uname eq rh92-node1 and date lt "2024-06-27 17:50:00"
Deprecation Warning: Using spaces in date values is deprecated and will be removed. Use 'T' as a delimiter between date and time.
[root@rh92-node1:~]# pcs constraint config --output-format cmd
pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  '#uname' eq rh92-node1 and date lt 2024-06-27T17:50:00
[root@rh92-node1:~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: boolean-op=and score=INFINITY (id: location-d2-rule)
        Expression: #uname eq rh92-node1 (id: location-d2-rule-expr)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr-1)
[root@rh92-node1:~]# pcs constraint delete location-d2
[root@rh92-node1:~]# pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  '#uname' eq rh92-node1 and date lt 2024-06-27T17:50:00
[root@rh92-node1:~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: boolean-op=and score=INFINITY (id: location-d2-rule)
        Expression: #uname eq rh92-node1 (id: location-d2-rule-expr)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr-1)



2. Omit constraints with unsupported settings

Test:
See pcs_test.tier1.constraint.test_config.ConstraintConfigCmdUnsupported for a test and a list of unsupported settings being detected. Corresponding CIB file is pcs_test/resources/cib-unexportable-constraints.xml.

Comment 15 Michal Pospisil 2023-07-14 09:57:33 UTC
DevTestResults:

[root@r09-03-b ~]# rpm -q pcs
pcs-0.11.6-2.el9.x86_64

[root@r09-03-b pcs]# pcs_test/suite pcs_test.tier1.constraint.test_config.ConstraintConfigCmdUnsupported
pcs_test.tier1.constraint.test_config.ConstraintConfigCmdUnsupported.test_dont_export_unsupported_constraints (subunit.RemotedTestCase)
pcs_test.tier1.constraint.test_config.ConstraintConfigCmdUnsupported.test_dont_export_unsupported_constraints ... ok
----------------------------------------------------------------------
Ran 1 test in 0.958s

OK

Comment 25 Michal Mazourek 2023-08-16 15:07:01 UTC
AFTER:
======

[root@virt-537 ~]# rpm -q pcs
pcs-0.11.6-3.el9.x86_64


## Checking pcs constraint usage 

[root@virt-537 ~]# pcs constraint config --help | grep output-format -B 1
Usage: pcs constraint [constraints]...
    [config] [--all] [--full] [--output-format text|cmd|json]
--
    location [config [resources [<resource reference>...]] | [nodes [<node>...]]]
            [--all] [--full] [--output-format text|cmd|json]
--

    order [config] [--full] [--output-format text|cmd|json]
--

    colocation [config] [--full] [--output-format text|cmd|json]
--

    ticket [config] [--full] [--output-format text|cmd|json]

> OK: New --output-format is present in usage with config for every constraint


[root@virt-537 ~]# pcs constraint config --help | grep "3 formats" -A 4 -m 1
        There are 3 formats of output available: 'cmd', 'json' and 'text',
        default is 'text'. Format 'text' is a human friendly output. Format
        'cmd' prints pcs commands which can be used to recreate the same
        configuration. Format 'json' is a machine oriented output of the
        configuration.

> OK: This hint is present with every config containing --output-format


## Preparing environment 

[root@virt-537 ~]# pcs resource create d1 ocf:heartbeat:Dummy
[root@virt-537 ~]# pcs resource create d2 ocf:pacemaker:Dummy
[root@virt-537 ~]# pcs resource create d3 ocf:pacemaker:Stateful promotable
[root@virt-537 ~]# pcs resource create d4 ocf:heartbeat:Dummy
[root@virt-537 ~]# pcs resource create d5 ocf:heartbeat:Dummy
[root@virt-537 ~]# pcs resource
  * Clone Set: locking-clone [locking]:
    * Started: [ virt-537 virt-538 ]
  * d1	(ocf:heartbeat:Dummy):	 Started virt-537
  * d2	(ocf:pacemaker:Dummy):	 Started virt-538
  * Clone Set: d3-clone [d3] (promotable):
    * Promoted: [ virt-537 ]
    * Unpromoted: [ virt-538 ]
  * d4	(ocf:heartbeat:Dummy):	 Started virt-537
  * d5	(ocf:heartbeat:Dummy):	 Started virt-538

[root@virt-537 ~]# pcs constraint config
[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint config --all
[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint config --full
[root@virt-537 ~]# echo $?
0


## Checking that --output-format is empty when no constraint is set

[root@virt-537 ~]# pcs constraint config --output-format=text
[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint config --output-format=cmd

[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint config --output-format=json
{
  "location": [],
  "location_set": [],
  "colocation": [],
  "colocation_set": [],
  "order": [],
  "order_set": [],
  "ticket": [],
  "ticket_set": []
}
[root@virt-537 ~]# echo $?
0

> OK


## Creating constraints

# location prefers with <resource_id>, node and a score
[root@virt-537 ~]# pcs constraint location d1 prefers virt-537=10
[root@virt-537 ~]# echo $?
0

# location avoids with %<resource_id>, node and a score
[root@virt-537 ~]# pcs constraint location %d2 avoids virt-538=5
[root@virt-537 ~]# echo $?
0

# location rule with resource%<resource_id>, rule id, role, constraint-id, score, expression 
[root@virt-537 ~]# pcs constraint location resource%d3-clone rule id=rule_1 role=Promoted constraint-id=rule_constraint_1 score=15 date gt 2023-01-01
[root@virt-537 ~]# echo $?
0

# order with <resource id>, action and 'kind' option
[root@virt-537 ~]# pcs constraint order start d1 then promote d3-clone kind=Optional
Adding d1 d3-clone (kind: Optional) (Options: first-action=start then-action=promote)
[root@virt-537 ~]# echo $?
0

# colocation with role, <source resource id>, <target resource id>, score, id 
[root@virt-537 ~]# pcs constraint colocation add Started d2 with Started d1 score=10 id=colocation_1
[root@virt-537 ~]# echo $?
0

# ticket with role, ticket, <resource id>, loss-policy and id
[root@virt-537 ~]# pcs constraint ticket add ticketA Started d4 loss-policy=stop id=ticket_constraint_1
[root@virt-537 ~]# echo $?
0

# constraint created by ban with <resource id>, node, lifetime
[root@virt-537 ~]# pcs resource ban d2 virt-538 lifetime=P100Y
Migration will take effect until: 2123-06-26 12:12:12 +02:00
Warning: Creating location constraint 'cli-ban-d2-on-virt-538' with a score of -INFINITY for resource d2 on virt-538.
	This will prevent d2 from running on virt-538 until the constraint is removed
	This will be the case even if virt-538 is the last node in the cluster
[root@virt-537 ~]# echo $?
0

# constraint created by move with <resource id>, destination node
[root@virt-537 ~]# pcs resource move-with-constraint d4 virt-537
Warning: A move constraint has been created and the resource 'd4' may or may not move depending on other configuration
[root@virt-537 ~]# echo $?
0

# colocation set with 2 resources, role and id
[root@virt-537 ~]# pcs constraint colocation set d4 d5 role=Stopped setoptions id=colocation_set_1
[root@virt-537 ~]# echo $?
0

# ticket set with 2 resources, ticket and loss-policy
[root@virt-537 ~]# pcs constraint ticket set d4 d5 setoptions ticket=ticketB loss-policy=stop
[root@virt-537 ~]# echo $?
0

# order set with 3 resources, action and id
[root@virt-537 ~]# pcs constraint order set d1 d2 d3-clone action=start setoptions id=order_set_1
[root@virt-537 ~]# echo $?
0


## Checking all created constraints and save it to file to diff it later

[root@virt-537 ~]# pcs constraint config 
Location Constraints:
  resource 'd1' prefers node 'virt-537' with score 10
  resource 'd2' avoids node 'virt-538' with score 5
  resource 'd3-clone'
    Rules:
      Rule: role=Promoted score=15
        Expression: date gt 2023-01-01
  Started resource 'd2'
    Rules:
      Rule: boolean-op=and score=-INFINITY
        Expression: #uname eq string virt-538
        Expression: date lt 2123-06-26 16:32:02 +02:00
  Started resource 'd4' prefers node 'virt-537' with score INFINITY
Colocation Constraints:
  Started resource 'd2' with Started resource 'd1'
    score=10
Colocation Set Constraints:
  Set Constraint:
    score=INFINITY
    Resource Set:
      Resources: 'd4', 'd5'
      role=Stopped
Order Constraints:
  start resource 'd1' then promote resource 'd3-clone'
    kind=Optional
Order Set Constraints:
  Set Constraint:
    Resource Set:
      Resources: 'd1', 'd2', 'd3-clone'
      action=start
Ticket Constraints:
  Started resource 'd4' depends on ticket 'ticketA'
    loss-policy=stop
Ticket Set Constraints:
  Set Constraint:
    ticket=ticketB loss-policy=stop
    Resource Set:
      Resources: 'd4', 'd5'

[root@virt-537 ~]# pcs constraint config > config_before


## Checking all created constraints with --full flag to see ids

[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd1' prefers node 'virt-537' with score 10 (id: location-d1-virt-537-10)
  resource 'd2' avoids node 'virt-538' with score 5 (id: location-d2-virt-538--5)
  resource 'd3-clone' (id: rule_constraint_1)
    Rules:
      Rule: role=Promoted score=15 (id: rule_1)
        Expression: date gt 2023-01-01 (id: rule_1-expr)
  Started resource 'd2' (id: cli-ban-d2-on-virt-538)
    Rules:
      Rule: boolean-op=and score=-INFINITY (id: cli-ban-d2-on-virt-538-rule)
        Expression: #uname eq string virt-538 (id: cli-ban-d2-on-virt-538-expr)
        Expression: date lt 2123-06-26 16:32:02 +02:00 (id: cli-ban-d2-on-virt-538-lifetime)
  Started resource 'd4' prefers node 'virt-537' with score INFINITY (id: cli-prefer-d4)
Colocation Constraints:
  Started resource 'd2' with Started resource 'd1' (id: colocation_1)
    score=10
Colocation Set Constraints:
  Set Constraint: colocation_set_1
    score=INFINITY
    Resource Set: colocation_set_1_set
      Resources: 'd4', 'd5'
      role=Stopped
Order Constraints:
  start resource 'd1' then promote resource 'd3-clone' (id: order-d1-d3-clone-Optional)
    kind=Optional
Order Set Constraints:
  Set Constraint: order_set_1
    Resource Set: order_set_1_set
      Resources: 'd1', 'd2', 'd3-clone'
      action=start
Ticket Constraints:
  Started resource 'd4' depends on ticket 'ticketA' (id: ticket_constraint_1)
    loss-policy=stop
Ticket Set Constraints:
  Set Constraint: ticket_set_d4d5
    ticket=ticketB loss-policy=stop
    Resource Set: ticket_set_d4d5_set
      Resources: 'd4', 'd5'


## Checking state of resources (d1, d2 and promoted of d3-clone should be running on virt-537, d4 and d5 should be stopped)

[root@virt-537 ~]# pcs resource
  * Clone Set: locking-clone [locking]:
    * Started: [ virt-537 virt-538 ]
  * d1	(ocf:heartbeat:Dummy):	 Started virt-537
  * d2	(ocf:pacemaker:Dummy):	 Started virt-537
  * Clone Set: d3-clone [d3] (promotable):
    * Promoted: [ virt-537 ]
    * Unpromoted: [ virt-538 ]
  * d4	(ocf:heartbeat:Dummy):	 Stopped
  * d5	(ocf:heartbeat:Dummy):	 Stopped

> OK


## Checking output formats for all created constraints

# text (default)

[root@virt-537 ~]# pcs constraint config --output-format text
Location Constraints:
  resource 'd1' prefers node 'virt-537' with score 10
  resource 'd2' avoids node 'virt-538' with score 5
  resource 'd3-clone'
    Rules:
      Rule: role=Promoted score=15
        Expression: date gt 2023-01-01
  Started resource 'd2'
    Rules:
      Rule: boolean-op=and score=-INFINITY
        Expression: #uname eq string virt-538
        Expression: date lt 2123-06-26 16:32:02 +02:00
  Started resource 'd4' prefers node 'virt-537' with score INFINITY
Colocation Constraints:
  Started resource 'd2' with Started resource 'd1'
    score=10
Colocation Set Constraints:
  Set Constraint:
    score=INFINITY
    Resource Set:
      Resources: 'd4', 'd5'
      role=Stopped
Order Constraints:
  start resource 'd1' then promote resource 'd3-clone'
    kind=Optional
Order Set Constraints:
  Set Constraint:
    Resource Set:
      Resources: 'd1', 'd2', 'd3-clone'
      action=start
Ticket Constraints:
  Started resource 'd4' depends on ticket 'ticketA'
    loss-policy=stop
Ticket Set Constraints:
  Set Constraint:
    ticket=ticketB loss-policy=stop
    Resource Set:
      Resources: 'd4', 'd5'
[root@virt-537 ~]# pcs constraint config --output-format text > config_before_as_text
[root@virt-537 ~]# diff config_before config_before_as_text 
[root@virt-537 ~]# echo $?
0

> OK: The 'pcs constraint config --output-format text' is the same as 'pcs constraint config'

# json

[root@virt-537 ~]# pcs constraint config --output-format json
{
  "location": [
    {
      "resource_id": "d1",
      "resource_pattern": null,
      "role": null,
      "attributes": {
        "constraint_id": "location-d1-virt-537-10",
        "score": "10",
        "node": "virt-537",
        "rules": [],
        "lifetime": [],
        "resource_discovery": null
      }
    },
    {
      "resource_id": "d2",
      "resource_pattern": null,
      "role": null,
      "attributes": {
        "constraint_id": "location-d2-virt-538--5",
        "score": "-5",
        "node": "virt-538",
        "rules": [],
        "lifetime": [],
        "resource_discovery": null
      }
    },
    {
      "resource_id": "d3-clone",
      "resource_pattern": null,
      "role": null,
      "attributes": {
        "constraint_id": "rule_constraint_1",
        "score": null,
        "node": null,
        "rules": [
          {
            "id": "rule_1",
            "type": "RULE",
            "in_effect": "IN_EFFECT",
            "options": {
              "role": "Promoted",
              "score": "15"
            },
            "date_spec": null,
            "duration": null,
            "expressions": [
              {
                "id": "rule_1-expr",
                "type": "DATE_EXPRESSION",
                "in_effect": "UNKNOWN",
                "options": {
                  "operation": "gt",
                  "start": "2023-01-01"
                },
                "date_spec": null,
                "duration": null,
                "expressions": [],
                "as_string": "date gt 2023-01-01"
              }
            ],
            "as_string": "date gt 2023-01-01"
          }
        ],
        "lifetime": [],
        "resource_discovery": null
      }
    },
    {
      "resource_id": "d2",
      "resource_pattern": null,
      "role": "Started",
      "attributes": {
        "constraint_id": "cli-ban-d2-on-virt-538",
        "score": null,
        "node": null,
        "rules": [
          {
            "id": "cli-ban-d2-on-virt-538-rule",
            "type": "RULE",
            "in_effect": "IN_EFFECT",
            "options": {
              "score": "-INFINITY",
              "boolean-op": "and"
            },
            "date_spec": null,
            "duration": null,
            "expressions": [
              {
                "id": "cli-ban-d2-on-virt-538-expr",
                "type": "EXPRESSION",
                "in_effect": "UNKNOWN",
                "options": {
                  "attribute": "#uname",
                  "operation": "eq",
                  "value": "virt-538",
                  "type": "string"
                },
                "date_spec": null,
                "duration": null,
                "expressions": [],
                "as_string": "#uname eq string virt-538"
              },
              {
                "id": "cli-ban-d2-on-virt-538-lifetime",
                "type": "DATE_EXPRESSION",
                "in_effect": "UNKNOWN",
                "options": {
                  "operation": "lt",
                  "end": "2123-06-26 16:32:02 +02:00"
                },
                "date_spec": null,
                "duration": null,
                "expressions": [],
                "as_string": "date lt 2123-06-26 16:32:02 +02:00"
              }
            ],
            "as_string": "#uname eq string virt-538 and date lt 2123-06-26 16:32:02 +02:00"
          }
        ],
        "lifetime": [],
        "resource_discovery": null
      }
    },
    {
      "resource_id": "d4",
      "resource_pattern": null,
      "role": "Started",
      "attributes": {
        "constraint_id": "cli-prefer-d4",
        "score": "INFINITY",
        "node": "virt-537",
        "rules": [],
        "lifetime": [],
        "resource_discovery": null
      }
    }
  ],
  "location_set": [],
  "colocation": [
    {
      "resource_id": "d2",
      "with_resource_id": "d1",
      "node_attribute": null,
      "resource_role": "Started",
      "with_resource_role": "Started",
      "resource_instance": null,
      "with_resource_instance": null,
      "attributes": {
        "constraint_id": "colocation_1",
        "score": "10",
        "influence": null,
        "lifetime": []
      }
    }
  ],
  "colocation_set": [
    {
      "resource_sets": [
        {
          "set_id": "colocation_set_1_set",
          "sequential": null,
          "require_all": null,
          "ordering": null,
          "action": null,
          "role": "Stopped",
          "score": null,
          "kind": null,
          "resources_ids": [
            "d4",
            "d5"
          ]
        }
      ],
      "attributes": {
        "constraint_id": "colocation_set_1",
        "score": "INFINITY",
        "influence": null,
        "lifetime": []
      }
    }
  ],
  "order": [
    {
      "first_resource_id": "d1",
      "then_resource_id": "d3-clone",
      "first_action": "start",
      "then_action": "promote",
      "first_resource_instance": null,
      "then_resource_instance": null,
      "attributes": {
        "constraint_id": "order-d1-d3-clone-Optional",
        "symmetrical": null,
        "require_all": null,
        "score": null,
        "kind": "Optional"
      }
    }
  ],
  "order_set": [
    {
      "resource_sets": [
        {
          "set_id": "order_set_1_set",
          "sequential": null,
          "require_all": null,
          "ordering": null,
          "action": "start",
          "role": null,
          "score": null,
          "kind": null,
          "resources_ids": [
            "d1",
            "d2",
            "d3-clone"
          ]
        }
      ],
      "attributes": {
        "constraint_id": "order_set_1",
        "symmetrical": null,
        "require_all": null,
        "score": null,
        "kind": null
      }
    }
  ],
  "ticket": [
    {
      "resource_id": "d4",
      "role": "Started",
      "attributes": {
        "constraint_id": "ticket_constraint_1",
        "ticket": "ticketA",
        "loss_policy": "stop"
      }
    }
  ],
  "ticket_set": [
    {
      "resource_sets": [
        {
          "set_id": "ticket_set_d4d5_set",
          "sequential": null,
          "require_all": null,
          "ordering": null,
          "action": null,
          "role": null,
          "score": null,
          "kind": null,
          "resources_ids": [
            "d4",
            "d5"
          ]
        }
      ],
      "attributes": {
        "constraint_id": "ticket_set_d4d5",
        "ticket": "ticketB",
        "loss_policy": "stop"
      }
    }
  ]
}

> OK

# cmd

[root@virt-537 ~]# pcs constraint config --output-format cmd
Warning: Resource role detected in constraint 'cli-ban-d2-on-virt-538' but not supported by this command. Command for creating the constraint is omitted.
Warning: Resource role detected in constraint 'cli-prefer-d4' but not supported by this command. Command for creating the constraint is omitted.
pcs -- constraint location add location-d1-virt-537-10 resource%d1 virt-537 10;
pcs -- constraint location add location-d2-virt-538--5 resource%d2 virt-538 -5;
pcs -- constraint location resource%d3-clone rule \
  id=rule_1 constraint-id=rule_constraint_1 role=Promoted score=15 \
  date gt 2023-01-01;
pcs -- constraint colocation add Started d2 with Started d1 10 \
  id=colocation_1;
pcs -- constraint colocation \
  set d4 d5 role=Stopped \
  setoptions id=colocation_set_1 score=INFINITY;
pcs -- constraint order start d1 then promote d3-clone \
  id=order-d1-d3-clone-Optional kind=Optional;
pcs -- constraint order \
  set d1 d2 d3-clone action=start \
  setoptions id=order_set_1;
pcs -- constraint ticket add ticketA Started d4 \
  id=ticket_constraint_1 loss-policy=stop;
pcs -- constraint ticket \
  set d4 d5 \
  setoptions id=ticket_set_d4d5 loss-policy=stop ticket=ticketB

> OK: The 'output-format cmd' generates commands to recreate the configuration. There are warning messages for all constraints that are not supported by this command. As mentioned in comment 9, these constraints are now omitted. 


## Deleting all constraints

[root@virt-537 ~]# pcs constraint delete location-d1-virt-537-10 location-d2-virt-538--5 rule_constraint_1 cli-ban-d2-on-virt-538 cli-prefer-d4 colocation_1 colocation_set_1 order-d1-d3-clone-Optional order_set_1 ticket_constraint_1 ticket_set_d4d5
[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint
[root@virt-537 ~]# echo $?
0


## Trying to re-create the configuration with the ouput of '--output-format cmd' 

[root@virt-537 ~]# pcs -- constraint location add location-d1-virt-537-10 resource%d1 virt-537 10;
pcs -- constraint location add location-d2-virt-538--5 resource%d2 virt-538 -5;
pcs -- constraint location resource%d3-clone rule \
  id=rule_1 constraint-id=rule_constraint_1 role=Promoted score=15 \
  date gt 2023-01-01;
pcs -- constraint colocation add Started d2 with Started d1 10 \
  id=colocation_1;
pcs -- constraint colocation \
  set d4 d5 role=Stopped \
  setoptions id=colocation_set_1 score=INFINITY;
pcs -- constraint order start d1 then promote d3-clone \
  id=order-d1-d3-clone-Optional kind=Optional;
pcs -- constraint order \
  set d1 d2 d3-clone action=start \
  setoptions id=order_set_1;
pcs -- constraint ticket add ticketA Started d4 \
  id=ticket_constraint_1 loss-policy=stop;
pcs -- constraint ticket \
  set d4 d5 \
  setoptions id=ticket_set_d4d5 loss-policy=stop ticket=ticketB
Adding d1 d3-clone (kind: Optional) (Options: id=order-d1-d3-clone-Optional first-action=start then-action=promote)
[root@virt-537 ~]# echo $?
0

> OK: The constraints were created.


## Comparing the constraints configuration created manually and the new configuration created by the output-format cmd

[root@virt-537 ~]# pcs constraint
Location Constraints:
  resource 'd1' prefers node 'virt-537' with score 10
  resource 'd2' avoids node 'virt-538' with score 5
  resource 'd3-clone'
    Rules:
      Rule: role=Promoted score=15
        Expression: date gt 2023-01-01
Colocation Constraints:
  Started resource 'd2' with Started resource 'd1'
    score=10
Colocation Set Constraints:
  Set Constraint:
    score=INFINITY
    Resource Set:
      Resources: 'd4', 'd5'
      role=Stopped
Order Constraints:
  start resource 'd1' then promote resource 'd3-clone'
    kind=Optional
Order Set Constraints:
  Set Constraint:
    Resource Set:
      Resources: 'd1', 'd2', 'd3-clone'
      action=start
Ticket Constraints:
  Started resource 'd4' depends on ticket 'ticketA'
    loss-policy=stop
Ticket Set Constraints:
  Set Constraint:
    ticket=ticketB loss-policy=stop
    Resource Set:
      Resources: 'd4', 'd5'


[root@virt-537 ~]# pcs constraint > config_after
[root@virt-537 ~]# diff config_before config_after
8,13d7
<   Started resource 'd2'
<     Rules:
<       Rule: boolean-op=and score=-INFINITY
<         Expression: #uname eq string virt-538
<         Expression: date lt 2123-08-16T14:27:41+02:00
<   Started resource 'd4' prefers node 'virt-537' with score INFINITY

> OK: Unsupported constraints were omitted, the rest of the configuration was recreated without an issue


[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd1' prefers node 'virt-537' with score 10 (id: location-d1-virt-537-10)
  resource 'd2' avoids node 'virt-538' with score 5 (id: location-d2-virt-538--5)
  resource 'd3-clone' (id: rule_constraint_1)
    Rules:
      Rule: role=Promoted score=15 (id: rule_1)
        Expression: date gt 2023-01-01 (id: rule_1-expr)
Colocation Constraints:
  Started resource 'd2' with Started resource 'd1' (id: colocation_1)
    score=10
Colocation Set Constraints:
  Set Constraint: colocation_set_1
    score=INFINITY
    Resource Set: colocation_set_1_set
      Resources: 'd4', 'd5'
      role=Stopped
Order Constraints:
  start resource 'd1' then promote resource 'd3-clone' (id: order-d1-d3-clone-Optional)
    kind=Optional
Order Set Constraints:
  Set Constraint: order_set_1
    Resource Set: order_set_1_set
      Resources: 'd1', 'd2', 'd3-clone'
      action=start
Ticket Constraints:
  Started resource 'd4' depends on ticket 'ticketA' (id: ticket_constraint_1)
    loss-policy=stop
Ticket Set Constraints:
  Set Constraint: ticket_set_d4d5
    ticket=ticketB loss-policy=stop
    Resource Set: ticket_set_d4d5_set
      Resources: 'd4', 'd5'

[root@virt-537 ~]# pcs resource
  * Clone Set: locking-clone [locking]:
    * Started: [ virt-537 virt-538 ]
  * d1	(ocf:heartbeat:Dummy):	 Started virt-537
  * d2	(ocf:pacemaker:Dummy):	 Started virt-537
  * Clone Set: d3-clone [d3] (promotable):
    * Promoted: [ virt-537 ]
    * Unpromoted: [ virt-538 ]
  * d4	(ocf:heartbeat:Dummy):	 Stopped
  * d5	(ocf:heartbeat:Dummy):	 Stopped

> OK


[root@virt-537 ~]# pcs constraint delete location-d1-virt-537-10 location-d2-virt-538--5 rule_constraint_1 colocation_1 colocation_set_1 order-d1-d3-clone-Optional order_set_1 ticket_constraint_1 ticket_set_d4d5


## Escaping in dates with space and special characters (see comment 9)

[root@virt-537 ~]# pcs constraint location d2 rule date lt "2024-06-27 17:50:00"
Deprecation Warning: Using spaces in date values is deprecated and will be removed. Use 'T' as a delimiter between date and time.
[root@virt-537 ~]# pcs constraint config --output-format cmd
pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27T17:50:00
[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: score=INFINITY (id: location-d2-rule)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr)
[root@virt-537 ~]# pcs constraint delete location-d2-rule
[root@virt-537 ~]# pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27T17:50:00
[root@virt-537 ~]# echo $?
0
[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: score=INFINITY (id: location-d2-rule)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr)

> OK

# With the 'T' delimiter
[root@virt-537 ~]# pcs constraint location d2 rule date lt 2024-06-27T17:50:00
[root@virt-537 ~]# pcs constraint config --output-format cmd
pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27T17:50:00
[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: score=INFINITY (id: location-d2-rule)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr)
[root@virt-537 ~]# pcs constraint delete location-d2-rule
[root@virt-537 ~]# pcs constraint config --output-format cmd
pcs -- constraint location resource%d2 rule \
  id=location-d2-rule constraint-id=location-d2 score=INFINITY \
  date lt 2024-06-27T17:50:00
[root@virt-537 ~]# pcs constraint --full
Location Constraints:
  resource 'd2' (id: location-d2)
    Rules:
      Rule: score=INFINITY (id: location-d2-rule)
        Expression: date lt 2024-06-27T17:50:00 (id: location-d2-rule-expr)

> OK


Marking as VERIFIED for pcs-0.11.6-3.el9.

Comment 30 errata-xmlrpc 2023-11-07 08:23:10 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Low: pcs security, bug fix, and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2023:6316


Note You need to log in before you can comment on or make changes to this bug.