#!/bin/sh
# Copyright 2017 Red Hat, Inc.
# Part of clufter project
# Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt)

# Depending on the usage, quick sanity check or just the prologue for run-tests

s="${0}"
[ $# -gt 0 ] && {
    case "${1}" in
    -*) ;;
    *) s="${1}"; shift ;;
    esac
}

PATH="${PATH:+${PATH}:}$(
  dirname "$(pwd)/$(
    ls -l "$(echo "${s}" | sed 's|\./||')" | cut -d'>' -f2 | awk '{print $NF}'
  )"
)"
unset s

: ${PYTHONEXEC:="python -Es"}

echo "Current path: ${PATH}"
which ccs_flatten 2>/dev/null || (
    cd __root__ 2>/dev/null || :
    ${PYTHONEXEC} setup.py pkg_prepare --build-develop
    # can drop the latter when reasonably recent coreutils spread around (8.22?)
    ln -frs -- ccs-flatten/*.metadata build 2>/dev/null \
    || ( cd build; ln -fs -- ../ccs-flatten/*.metadata . )
    ln -fs -- build/ccs_flatten .
    #make -C ccs-flatten symlink
) || { ret=$?; echo "ccs_flatten missing, cannot be built"; exit ${ret}; }

run_check_ccs2pcs() {
    testcib="$(mktemp)" testcoro="$(mktemp)"
    { { ${PYTHONEXEC} run-dev --sys linux --dist redhat,7.1,Maipo \
                              ccs2pcs "${@}" -- - - "${testcib}" \
        | grep -Ev 'key: _NOT_SECRET--' > "${testcoro}"; } \
    && echo "TEST: execution OK" \
    || { echo "TEST: execution FAIL"; ret=20; }; }<<EOF
<?xml version="1.0"?>
<cluster name="one" config_version="6">
  <logging debug="on"/>
  <clusternodes>
    <clusternode name="rhel6-node1" votes="1" nodeid="1">
      <fence>
        <method name="single">
          <device name="xvm" domain="rhel6-node1"/>
        </method>
      </fence>
    </clusternode>
    <clusternode name="rhel6-node2" votes="1" nodeid="2">
      <fence>
        <method name="single">
          <device name="xvm" domain="rhel6-node2"/>
        </method>
      </fence>
    </clusternode>
  </clusternodes>
  <fencedevices>
    <fencedevice name="xvm" agent="fence_xvm"/>
  </fencedevices>
  <quorumd label="qdisk"/>
  <rm central_processing="1">
    <failoverdomains>
      <failoverdomain name="failover_domain1" ordered="1" restricted="1" nofailback="1">
        <failoverdomainnode name="rhel6-node1" priority="1"/>
        <failoverdomainnode name="rhel6-node2" priority="1"/>
      </failoverdomain>
    </failoverdomains>
    <resources>
      <ip address="192.168.0.128" monitor_link="1"/>
    </resources>
    <service autostart="1" name="mm" domain="failover_domain1">
    <!-- service exclusive="0" autostart="1" name="mm" -->
      <ip ref="192.168.0.128"/>
    </service>
  </rm>
</cluster>
EOF
    { diff -u -- - "${testcib}" \
      && echo "TEST: cib diff OK" \
      || { echo "TEST: cib diff FAIL"; ret=21; }; }<<EOF
<cib validate-with="pacemaker-1.2" admin_epoch="0" epoch="0" num_updates="0" update-client="$(${PYTHONEXEC} run-dev --version | head -n1)">
  <configuration>
    <crm_config/>
    <nodes>
      <node id="1" uname="rhel6-node1" type="member"/>
      <node id="2" uname="rhel6-node2" type="member"/>
    </nodes>
    <resources>
      <!-- FENCING/STONITH (+ POSSIBLY TOPOLOGY BELOW) -->
      <primitive id="FENCEDEV-xvm" class="stonith" type="fence_xvm">
        <instance_attributes id="FENCEDEV-xvm-ATTRS">
          <nvpair id="FENCEDEV-xvm-ATTRS-pcmk_host_map" name="pcmk_host_map" value="rhel6-node1:rhel6-node1,rhel6-node2:rhel6-node2"/>
        </instance_attributes>
      </primitive>
      <!-- RESOURCES+ARRANGEMENT -->
      <group id="SERVICE-mm-GROUP">
        <primitive id="RESOURCE-ip-192.168.0.128" description="natively converted from ip RA" class="ocf" provider="heartbeat" type="IPaddr2">
          <instance_attributes id="RESOURCE-ip-192.168.0.128-ATTRS">
            <nvpair id="RESOURCE-ip-192.168.0.128-ATTRS-ip" name="ip" value="192.168.0.128"/>
          </instance_attributes>
          <operations>
            <op id="RESOURCE-ip-192.168.0.128-OP-monitor" name="monitor" interval="20s"/>
          </operations>
        </primitive>
        <!-- mimic NOFAILBACK failoverdomain (FAILOVERDOMAIN-failover_domain1)-->
        <meta_attributes id="SERVICE-mm-META-ATTRS-nofailback">
          <rule id="SERVICE-mm-META-RULE-stickiness" score="0" boolean-op="or">
            <expression id="STICKINESS-SERVICE-mm-rhel6-node1" attribute="#uname" operation="eq" value="rhel6-node1"/>
            <expression id="STICKINESS-SERVICE-mm-rhel6-node2" attribute="#uname" operation="eq" value="rhel6-node2"/>
          </rule>
          <nvpair id="SERVICE-mm-META-ATTRS-nofailback-pair" name="resource-stickiness" value="INFINITY"/>
        </meta_attributes>
      </group>
    </resources>
    <constraints>
      <rsc_location id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP" rsc="SERVICE-mm-GROUP">
        <!-- mimic failoverdomain (failover_domain1) for SERVICE-mm -->
        <rule id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node1" score="INFINITY">
          <expression id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node1-expr" attribute="#uname" operation="eq" value="rhel6-node1"/>
        </rule>
        <rule id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node2" score="INFINITY">
          <expression id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node2-expr" attribute="#uname" operation="eq" value="rhel6-node2"/>
        </rule>
        <!-- mimic RESTRICTED failoverdomain (failover_domain1) for SERVICE-mm -->
        <rule id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-RESTRICTED" boolean-op="and" score="-INFINITY">
          <expression id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-RESTRICTED-rhel6-node1-expr" attribute="#uname" operation="ne" value="rhel6-node1"/>
          <expression id="CONSTRAINT-LOCATION-SERVICE-mm-GROUP-RESTRICTED-rhel6-node2-expr" attribute="#uname" operation="ne" value="rhel6-node2"/>
        </rule>
      </rsc_location>
    </constraints>
  </configuration>
  <status/>
</cib>
EOF
    { diff -u -- - "${testcoro}" \
      && echo "TEST: coro diff OK" \
      || { echo "TEST: coro diff FAIL"; ret=22; }; }<<EOF
nodelist {
	node {
		nodeid: 1
		ring0_addr: rhel6-node1
	}
	node {
		nodeid: 2
		ring0_addr: rhel6-node2
	}
}
quorum {
	provider: corosync_votequorum
}
logging {
	debug: on
}
totem {
	cluster_name: one
	consensus: 12000
	join: 60
	token: 10000
	version: 2
}
EOF
    rm -f -- "${testcib}" "${testcoro}"
    unset testcib testcoro
    return ${ret}
}

run_check_ccs2pcscmd() {
    testcmd="$(mktemp)"
    { ${PYTHONEXEC} run-dev --sys linux --dist redhat,7.1,Maipo \
                            ccs2pcscmd "${@}" \
			    --text-width=72 --silent --noguidance \
			    -- - - \
			    | sed '1,5d;7d' > "${testcmd}" \
      && echo "TEST: execution OK" \
      || { echo "TEST: execution FAIL"; ret=20; }; }<<EOF
<?xml version="1.0"?>
<cluster name="one" config_version="6">
  <logging debug="on"/>
  <clusternodes>
    <clusternode name="rhel6-node1" votes="1" nodeid="1">
      <fence>
        <method name="single">
          <device name="xvm" domain="rhel6-node1"/>
        </method>
      </fence>
    </clusternode>
    <clusternode name="rhel6-node2" votes="1" nodeid="2">
      <fence>
        <method name="single">
          <device name="xvm" domain="rhel6-node2"/>
        </method>
      </fence>
    </clusternode>
  </clusternodes>
  <fencedevices>
    <fencedevice name="xvm" agent="fence_xvm"/>
  </fencedevices>
  <quorumd label="qdisk"/>
  <rm central_processing="1">
    <failoverdomains>
      <failoverdomain name="failover_domain1" ordered="1" restricted="1" nofailback="1">
        <failoverdomainnode name="rhel6-node1" priority="1"/>
        <failoverdomainnode name="rhel6-node2" priority="1"/>
      </failoverdomain>
    </failoverdomains>
    <resources>
      <ip address="192.168.0.128" monitor_link="1"/>
    </resources>
    <service autostart="1" name="mm" domain="failover_domain1">
    <!-- service exclusive="0" autostart="1" name="mm" -->
      <ip ref="192.168.0.128"/>
    </service>
  </rm>
</cluster>
EOF
    { diff -u -- - "${testcmd}" \
      && echo "TEST: cmd diff OK" \
      || { echo "TEST: cmd diff FAIL"; ret=21; }; }<<EOF
# targeting system: ('linux', 'redhat', '7.1', 'Maipo')
pcs cluster auth rhel6-node1 rhel6-node2 <> /dev/tty
pcs cluster setup --name one rhel6-node1 rhel6-node2 --join 60 \\
  --token 10000 --consensus 12000
pcs cluster start --all && sleep 60
pcs cluster cib tmp-cib.xml
pcs -f tmp-cib.xml stonith create FENCEDEV-xvm fence_xvm \\
  pcmk_host_map=rhel6-node1:rhel6-node1,rhel6-node2:rhel6-node2
pcs -f tmp-cib.xml \\
  resource create RESOURCE-ip-192.168.0.128 ocf:heartbeat:IPaddr2 \\
  ip=192.168.0.128 op monitor interval=20s
pcs -f tmp-cib.xml \\
  resource group add SERVICE-mm-GROUP RESOURCE-ip-192.168.0.128
pcs -f tmp-cib.xml \\
  constraint location SERVICE-mm-GROUP rule \\
  id=CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node1 \\
  constraint-id=CONSTRAINT-LOCATION-SERVICE-mm-GROUP score=INFINITY \\
  '#uname' eq rhel6-node1
pcs -f tmp-cib.xml \\
  constraint rule add CONSTRAINT-LOCATION-SERVICE-mm-GROUP \\
  id=CONSTRAINT-LOCATION-SERVICE-mm-GROUP-rhel6-node2 score=INFINITY \\
  '#uname' eq rhel6-node2
pcs -f tmp-cib.xml \\
  constraint rule add CONSTRAINT-LOCATION-SERVICE-mm-GROUP \\
  id=CONSTRAINT-LOCATION-SERVICE-mm-GROUP-RESTRICTED score=-INFINITY \\
  '#uname' ne rhel6-node1 and '#uname' ne rhel6-node2
pcs cluster cib-push tmp-cib.xml --config
EOF
    rm -f -- "${testcmd}"
    unset testcmd
    return ${ret}
}

run_check_cib2pcscmd() {
    # config borrowed from: pacemaker.git/pengine/test10/bug-cl-5212.xml
    # (but subsequently extended: acls, bundle)
    testcmd="$(mktemp)"
    { ${PYTHONEXEC} run-dev --sys linux --dist rhel,7.4 \
                            cib2pcscmd "${@}" \
			    --text-width=72 --silent -- - - \
			    | sed '1,4d;6d' > "${testcmd}" \
      && echo "TEST: execution OK" \
      || { echo "TEST: execution FAIL"; ret=20; }; }<<EOF
<cib validate-with="pacemaker-2.0" epoch="4" num_updates="46" admin_epoch="0">
  <configuration>
    <crm_config>
      <cluster_property_set id="cib-bootstrap-options">
        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.1.11-f0f09b8"/>
        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
        <nvpair name="no-quorum-policy" value="freeze" id="cib-bootstrap-options-no-quorum-policy"/>
        <nvpair name="stonith-enabled" value="true" id="cib-bootstrap-options-stonith-enabled"/>
      </cluster_property_set>
    </crm_config>
    <nodes>
      <node id="3232238300" uname="srv03"/>
      <node id="3232238280" uname="srv01"/>
      <node id="3232238290" uname="srv02"/>
    </nodes>
    <resources>
      <group id="grpStonith1">
        <!--### Group Configuration ###-->
        <primitive id="prmStonith1-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith1-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith1-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv01" id="prmStonith1-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith1-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith1-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith1-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <group id="grpStonith2">
        <primitive id="prmStonith2-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith2-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith2-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv02" id="prmStonith2-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith2-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith2-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith2-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <group id="grpStonith3">
        <primitive id="prmStonith3-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith3-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith3-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv03" id="prmStonith3-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith3-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith3-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith3-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <master id="msPostgresql">
        <!--### Master/Slave Configuration ###-->
        <meta_attributes id="msPostgresql-meta_attributes">
          <nvpair name="master-max" value="1" id="msPostgresql-meta_attributes-master-max"/>
          <nvpair name="master-node-max" value="1" id="msPostgresql-meta_attributes-master-node-max"/>
          <nvpair name="clone-max" value="3" id="msPostgresql-meta_attributes-clone-max"/>
          <nvpair name="clone-node-max" value="1" id="msPostgresql-meta_attributes-clone-node-max"/>
          <nvpair name="notify" value="true" id="msPostgresql-meta_attributes-notify"/>
        </meta_attributes>
        <primitive id="pgsql" class="ocf" provider="pacemaker" type="Stateful">
          <operations>
            <op name="start" interval="0s" timeout="300s" on-fail="restart" id="pgsql-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="pgsql-monitor-10s"/>
            <op name="monitor" role="Master" interval="9s" timeout="60s" on-fail="restart" id="pgsql-monitor-9s"/>
            <op name="promote" interval="0s" timeout="300s" on-fail="restart" id="pgsql-promote-0s"/>
            <op name="demote" interval="0s" timeout="300s" on-fail="fence" id="pgsql-demote-0s"/>
            <op name="notify" interval="0s" timeout="60s" id="pgsql-notify-0s"/>
            <op name="stop" interval="0s" timeout="300s" on-fail="fence" id="pgsql-stop-0s"/>
          </operations>
        </primitive>
      </master>
      <clone id="clnPingd">
        <!--### Clone Configuration ###-->
        <primitive id="prmPingd" class="ocf" provider="pacemaker" type="ping">
          <instance_attributes id="prmPingd-instance_attributes">
            <nvpair name="name" value="default_ping_set" id="prmPingd-instance_attributes-name"/>
            <nvpair name="host_list" value="192.168.40.1" id="prmPingd-instance_attributes-host_list"/>
            <nvpair name="multiplier" value="100" id="prmPingd-instance_attributes-multiplier"/>
            <nvpair name="attempts" value="2" id="prmPingd-instance_attributes-attempts"/>
            <nvpair name="timeout" value="2" id="prmPingd-instance_attributes-timeout"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmPingd-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmPingd-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmPingd-stop-0s"/>
          </operations>
        </primitive>
      </clone>
      <bundle id="httpd-bundle">
        <docker image="pcmktest:http" replicas="3" options="--log-driver=journald" />
        <network ip-range-start="192.168.122.131" host-interface="eth0" host-netmask="24">
          <port-mapping id="httpd-port" port="80"/>
        </network>
        <storage>
          <storage-mapping id="httpd-root"
            source-dir-root="/var/local/containers"
            target-dir="/var/www/html"
            options="rw"/>
          <storage-mapping id="httpd-logs"
            source-dir-root="/var/log/pacemaker/bundles"
            target-dir="/etc/httpd/logs"
            options="rw"/>
        </storage>
        <primitive class="ocf" id="httpd" provider="heartbeat" type="apache"/>
      </bundle>
    </resources>
    <constraints>
      <rsc_location id="rsc_location-grpStonith1" rsc="grpStonith1">
        <!--### Resource Location ###-->
        <rule score="-INFINITY" id="rsc_location-grpStonith1-rule">
          <expression attribute="#uname" operation="eq" value="srv01" id="rsc_location-grpStonith1-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-grpStonith2" rsc="grpStonith2">
        <rule score="-INFINITY" id="rsc_location-grpStonith2-rule">
          <expression attribute="#uname" operation="eq" value="srv02" id="rsc_location-grpStonith2-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-grpStonith3" rsc="grpStonith3">
        <rule score="-INFINITY" id="rsc_location-grpStonith3-rule">
          <expression attribute="#uname" operation="eq" value="srv03" id="rsc_location-grpStonith3-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-msPostgresql-1" rsc="msPostgresql">
        <rule role="master" score="300" id="rsc_location-msPostgresql-1-rule">
          <expression attribute="#uname" operation="eq" value="srv01" id="rsc_location-msPostgresql-1-expression"/>
        </rule>
        <rule role="master" score="200" id="rsc_location-msPostgresql-1-rule-0">
          <expression attribute="#uname" operation="eq" value="srv02" id="rsc_location-msPostgresql-1-expression-0"/>
        </rule>
        <rule role="master" score="100" id="rsc_location-msPostgresql-1-rule-1">
          <expression attribute="#uname" operation="eq" value="srv03" id="rsc_location-msPostgresql-1-expression-1"/>
        </rule>
      </rsc_location>
      <rsc_colocation id="rsc_colocation-msPostgresql-clnPingd-1" score="INFINITY" rsc="msPostgresql" rsc-role="Master" with-rsc="clnPingd">
        <!--### Resource Colocation ###-->
      </rsc_colocation>
      <rsc_order id="rsc_order-clnPingd-msPostgresql-1" score="0" first="clnPingd" then="msPostgresql" symmetrical="false">
        <!--### Resource Order ###-->
      </rsc_order>
    </constraints>
    <fencing-topology>
      <!--### Fencing Topology ###-->
      <fencing-level target="srv01" devices="prmStonith1-1" index="1" id="fencing"/>
      <fencing-level target="srv02" devices="prmStonith2-1" index="1" id="fencing-0"/>
      <fencing-level target="srv03" devices="prmStonith3-1" index="1" id="fencing-1"/>
    </fencing-topology>
    <rsc_defaults>
      <meta_attributes id="rsc-options">
        <!--### Resource Defaults ###-->
        <nvpair name="resource-stickiness" value="INFINITY" id="rsc-options-resource-stickiness"/>
        <nvpair name="migration-threshold" value="1" id="rsc-options-migration-threshold"/>
      </meta_attributes>
    </rsc_defaults>
  </configuration>
</cib>
EOF
    { diff -u -- - "${testcmd}" \
      && echo "TEST: cmd diff OK" \
      || { echo "TEST: cmd diff FAIL"; ret=21; }; }<<EOF
# targeting system: ('linux', 'redhat', '7.4')
pcs cluster cib tmp-cib.xml
cp tmp-cib.xml tmp-cib.xml.deltasrc
pcs -f tmp-cib.xml property set no-quorum-policy=freeze
pcs -f tmp-cib.xml property set stonith-enabled=true
pcs -f tmp-cib.xml \\
  resource defaults resource-stickiness=INFINITY migration-threshold=1
pcs -f tmp-cib.xml stonith create prmStonith1-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv01 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith1-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith1-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith1-1-stop-0s
pcs -f tmp-cib.xml stonith create prmStonith2-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv02 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith2-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith2-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith2-1-stop-0s
pcs -f tmp-cib.xml stonith create prmStonith3-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv03 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith3-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith3-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith3-1-stop-0s
pcs -f tmp-cib.xml resource bundle create httpd-bundle \\
  container docker image=pcmktest:http replicas=3 \\
  options=--log-driver=journald \\
  network ip-range-start=192.168.122.131 host-interface=eth0 \\
  host-netmask=24 port-map id=httpd-port port=80 \\
  storage-map id=httpd-root source-dir-root=/var/local/containers \\
  target-dir=/var/www/html options=rw \\
  storage-map id=httpd-logs source-dir-root=/var/log/pacemaker/bundles \\
  target-dir=/etc/httpd/logs options=rw
pcs -f tmp-cib.xml resource create pgsql ocf:pacemaker:Stateful \\
  op start interval=0s timeout=300s on-fail=restart monitor interval=10s \\
  timeout=60s on-fail=restart monitor role=Master interval=9s \\
  timeout=60s on-fail=restart promote interval=0s timeout=300s \\
  on-fail=restart demote interval=0s timeout=300s on-fail=fence notify \\
  interval=0s timeout=60s stop interval=0s timeout=300s on-fail=fence
pcs -f tmp-cib.xml resource create prmPingd ocf:pacemaker:ping \\
  name=default_ping_set host_list=192.168.40.1 multiplier=100 attempts=2 \\
  timeout=2 \\
  op start interval=0s timeout=60s on-fail=restart monitor \\
  interval=10s timeout=60s on-fail=restart stop interval=0s \\
  timeout=60s on-fail=ignore
pcs -f tmp-cib.xml resource create httpd ocf:heartbeat:apache \\
  bundle httpd-bundle
pcs -f tmp-cib.xml resource group add grpStonith1 prmStonith1-1
pcs -f tmp-cib.xml resource group add grpStonith2 prmStonith2-1
pcs -f tmp-cib.xml resource group add grpStonith3 prmStonith3-1
pcs -f tmp-cib.xml resource clone prmPingd
pcs -f tmp-cib.xml \\
  resource master msPostgresql pgsql master-max=1 master-node-max=1 \\
  clone-max=3 clone-node-max=1 notify=true
pcs -f tmp-cib.xml \\
  constraint location grpStonith1 rule id=rsc_location-grpStonith1-rule \\
  constraint-id=rsc_location-grpStonith1 score=-INFINITY '#uname' eq \\
  srv01
pcs -f tmp-cib.xml \\
  constraint location grpStonith2 rule id=rsc_location-grpStonith2-rule \\
  constraint-id=rsc_location-grpStonith2 score=-INFINITY '#uname' eq \\
  srv02
pcs -f tmp-cib.xml \\
  constraint location grpStonith3 rule id=rsc_location-grpStonith3-rule \\
  constraint-id=rsc_location-grpStonith3 score=-INFINITY '#uname' eq \\
  srv03
pcs -f tmp-cib.xml \\
  constraint location msPostgresql rule \\
  id=rsc_location-msPostgresql-1-rule \\
  constraint-id=rsc_location-msPostgresql-1 master score=300 '#uname' \\
  eq srv01
pcs -f tmp-cib.xml \\
  constraint rule add rsc_location-msPostgresql-1 \\
  id=rsc_location-msPostgresql-1-rule-0 master score=200 '#uname' eq \\
  srv02
pcs -f tmp-cib.xml \\
  constraint rule add rsc_location-msPostgresql-1 \\
  id=rsc_location-msPostgresql-1-rule-1 master score=100 '#uname' eq \\
  srv03
pcs -f tmp-cib.xml \\
  constraint colocation add master msPostgresql with clnPingd \\
  id=rsc_colocation-msPostgresql-clnPingd-1
pcs -f tmp-cib.xml constraint order clnPingd \\
  then msPostgresql score=0 symmetrical=false \\
  id=rsc_order-clnPingd-msPostgresql-1
pcs -f tmp-cib.xml stonith level add 1 srv01 prmStonith1-1
pcs -f tmp-cib.xml stonith level add 1 srv02 prmStonith2-1
pcs -f tmp-cib.xml stonith level add 1 srv03 prmStonith3-1
pcs cluster cib-push tmp-cib.xml diff-against=tmp-cib.xml.deltasrc
EOF
    rm -f -- "${testcmd}"
    unset testcmd
    return ${ret}
}

# as run_check_cib2pcscmd but enforce internal 1.2 -> 2.0+ format upgrade
run_check_cib2pcscmd_impl_conv() {
    # config borrowed from: pacemaker.git/pengine/test10/bug-cl-5212.xml
    testcmd="$(mktemp)"
    { ${PYTHONEXEC} run-dev --sys linux --dist rhel,7.4 \
                            cib2pcscmd "${@}" \
			    --text-width=72 --silent -- - - \
			    | sed '1,4d;6d' > "${testcmd}" \
      && echo "TEST: execution OK" \
      || { echo "TEST: execution FAIL"; ret=20; }; }<<EOF
<cib validate-with="pacemaker-1.2" epoch="4" num_updates="46" admin_epoch="0">
  <configuration>
    <crm_config>
      <cluster_property_set id="cib-bootstrap-options">
        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.1.11-f0f09b8"/>
        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
        <nvpair name="enable-acl" value="true" id="cib-bootstrap-options-enable-acl"/>
        <nvpair name="no-quorum-policy" value="freeze" id="cib-bootstrap-options-no-quorum-policy"/>
        <nvpair name="stonith-enabled" value="true" id="cib-bootstrap-options-stonith-enabled"/>
      </cluster_property_set>
    </crm_config>
    <nodes>
      <node id="3232238300" uname="srv03"/>
      <node id="3232238280" uname="srv01"/>
      <node id="3232238290" uname="srv02"/>
    </nodes>
    <resources>
      <group id="grpStonith1">
        <!--### Group Configuration ###-->
        <primitive id="prmStonith1-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith1-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith1-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv01" id="prmStonith1-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith1-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith1-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith1-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <group id="grpStonith2">
        <primitive id="prmStonith2-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith2-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith2-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv02" id="prmStonith2-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith2-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith2-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith2-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <group id="grpStonith3">
        <primitive id="prmStonith3-1" class="stonith" type="external/ssh">
          <instance_attributes id="prmStonith3-1-instance_attributes">
            <nvpair name="pcmk_reboot_timeout" value="60s" id="prmStonith3-1-instance_attributes-pcmk_reboot_timeout"/>
            <nvpair name="hostlist" value="srv03" id="prmStonith3-1-instance_attributes-hostlist"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmStonith3-1-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmStonith3-1-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmStonith3-1-stop-0s"/>
          </operations>
        </primitive>
      </group>
      <master id="msPostgresql">
        <!--### Master/Slave Configuration ###-->
        <meta_attributes id="msPostgresql-meta_attributes">
          <nvpair name="master-max" value="1" id="msPostgresql-meta_attributes-master-max"/>
          <nvpair name="master-node-max" value="1" id="msPostgresql-meta_attributes-master-node-max"/>
          <nvpair name="clone-max" value="3" id="msPostgresql-meta_attributes-clone-max"/>
          <nvpair name="clone-node-max" value="1" id="msPostgresql-meta_attributes-clone-node-max"/>
          <nvpair name="notify" value="true" id="msPostgresql-meta_attributes-notify"/>
        </meta_attributes>
        <primitive id="pgsql" class="ocf" provider="pacemaker" type="Stateful">
          <operations>
            <op name="start" interval="0s" timeout="300s" on-fail="restart" id="pgsql-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="pgsql-monitor-10s"/>
            <op name="monitor" role="Master" interval="9s" timeout="60s" on-fail="restart" id="pgsql-monitor-9s"/>
            <op name="promote" interval="0s" timeout="300s" on-fail="restart" id="pgsql-promote-0s"/>
            <op name="demote" interval="0s" timeout="300s" on-fail="fence" id="pgsql-demote-0s"/>
            <op name="notify" interval="0s" timeout="60s" id="pgsql-notify-0s"/>
            <op name="stop" interval="0s" timeout="300s" on-fail="fence" id="pgsql-stop-0s"/>
          </operations>
        </primitive>
      </master>
      <clone id="clnPingd">
        <!--### Clone Configuration ###-->
        <primitive id="prmPingd" class="ocf" provider="pacemaker" type="ping">
          <instance_attributes id="prmPingd-instance_attributes">
            <nvpair name="name" value="default_ping_set" id="prmPingd-instance_attributes-name"/>
            <nvpair name="host_list" value="192.168.40.1" id="prmPingd-instance_attributes-host_list"/>
            <nvpair name="multiplier" value="100" id="prmPingd-instance_attributes-multiplier"/>
            <nvpair name="attempts" value="2" id="prmPingd-instance_attributes-attempts"/>
            <nvpair name="timeout" value="2" id="prmPingd-instance_attributes-timeout"/>
          </instance_attributes>
          <operations>
            <op name="start" interval="0s" timeout="60s" on-fail="restart" id="prmPingd-start-0s"/>
            <op name="monitor" interval="10s" timeout="60s" on-fail="restart" id="prmPingd-monitor-10s"/>
            <op name="stop" interval="0s" timeout="60s" on-fail="ignore" id="prmPingd-stop-0s"/>
          </operations>
        </primitive>
      </clone>
    </resources>
    <constraints>
      <rsc_location id="rsc_location-grpStonith1" rsc="grpStonith1">
        <!--### Resource Location ###-->
        <rule score="-INFINITY" id="rsc_location-grpStonith1-rule">
          <expression attribute="#uname" operation="eq" value="srv01" id="rsc_location-grpStonith1-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-grpStonith2" rsc="grpStonith2">
        <rule score="-INFINITY" id="rsc_location-grpStonith2-rule">
          <expression attribute="#uname" operation="eq" value="srv02" id="rsc_location-grpStonith2-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-grpStonith3" rsc="grpStonith3">
        <rule score="-INFINITY" id="rsc_location-grpStonith3-rule">
          <expression attribute="#uname" operation="eq" value="srv03" id="rsc_location-grpStonith3-expression"/>
        </rule>
      </rsc_location>
      <rsc_location id="rsc_location-msPostgresql-1" rsc="msPostgresql">
        <rule role="master" score="300" id="rsc_location-msPostgresql-1-rule">
          <expression attribute="#uname" operation="eq" value="srv01" id="rsc_location-msPostgresql-1-expression"/>
        </rule>
        <rule role="master" score="200" id="rsc_location-msPostgresql-1-rule-0">
          <expression attribute="#uname" operation="eq" value="srv02" id="rsc_location-msPostgresql-1-expression-0"/>
        </rule>
        <rule role="master" score="100" id="rsc_location-msPostgresql-1-rule-1">
          <expression attribute="#uname" operation="eq" value="srv03" id="rsc_location-msPostgresql-1-expression-1"/>
        </rule>
      </rsc_location>
      <rsc_colocation id="rsc_colocation-msPostgresql-clnPingd-1" score="INFINITY" rsc="msPostgresql" rsc-role="Master" with-rsc="clnPingd">
        <!--### Resource Colocation ###-->
      </rsc_colocation>
      <rsc_order id="rsc_order-clnPingd-msPostgresql-1" score="0" first="clnPingd" then="msPostgresql" symmetrical="false">
        <!--### Resource Order ###-->
      </rsc_order>
    </constraints>
    <fencing-topology>
      <!--### Fencing Topology ###-->
      <fencing-level target="srv01" devices="prmStonith1-1" index="1" id="fencing"/>
      <fencing-level target="srv02" devices="prmStonith2-1" index="1" id="fencing-0"/>
      <fencing-level target="srv03" devices="prmStonith3-1" index="1" id="fencing-1"/>
    </fencing-topology>
    <rsc_defaults>
      <meta_attributes id="rsc-options">
        <!--### Resource Defaults ###-->
        <nvpair name="resource-stickiness" value="INFINITY" id="rsc-options-resource-stickiness"/>
        <nvpair name="migration-threshold" value="1" id="rsc-options-migration-threshold"/>
      </meta_attributes>
    </rsc_defaults>
    <acls>
      <acl_user id="fixer">
        <write id="fixer_write_options" ref="cib-bootstrap-options"/>
        <deny id="fixer_deny_aclenabled" ref="cib-bootstrap-options-enable-acl"/>
        <deny id="fixer_deny_stonith" ref="cib-bootstrap-options-stonith-enabled"/>
        <deny id="fixer_deny_noquorum" ref="cib-bootstrap-options-no-quorum-policy"/>
      </acl_user>
    </acls>
  </configuration>
</cib>
EOF
    { diff -u -- - "${testcmd}" \
      && echo "TEST: cmd diff OK" \
      || { echo "TEST: cmd diff FAIL"; ret=21; }; }<<EOF
# targeting system: ('linux', 'redhat', '7.4')
pcs cluster cib tmp-cib.xml
cp tmp-cib.xml tmp-cib.xml.deltasrc
pcs -f tmp-cib.xml property set no-quorum-policy=freeze
pcs -f tmp-cib.xml property set stonith-enabled=true
pcs -f tmp-cib.xml \\
  resource defaults resource-stickiness=INFINITY migration-threshold=1
pcs -f tmp-cib.xml stonith create prmStonith1-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv01 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith1-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith1-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith1-1-stop-0s
pcs -f tmp-cib.xml stonith create prmStonith2-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv02 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith2-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith2-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith2-1-stop-0s
pcs -f tmp-cib.xml stonith create prmStonith3-1 external/ssh \\
  pcmk_reboot_timeout=60s hostlist=srv03 \\
  op start name=start interval=0s timeout=60s on-fail=restart \\
  id=prmStonith3-1-start-0s monitor name=monitor interval=10s \\
  timeout=60s on-fail=restart id=prmStonith3-1-monitor-10s stop \\
  name=stop interval=0s timeout=60s on-fail=ignore \\
  id=prmStonith3-1-stop-0s
pcs -f tmp-cib.xml resource create pgsql ocf:pacemaker:Stateful \\
  op start interval=0s timeout=300s on-fail=restart monitor interval=10s \\
  timeout=60s on-fail=restart monitor role=Master interval=9s \\
  timeout=60s on-fail=restart promote interval=0s timeout=300s \\
  on-fail=restart demote interval=0s timeout=300s on-fail=fence notify \\
  interval=0s timeout=60s stop interval=0s timeout=300s on-fail=fence
pcs -f tmp-cib.xml resource create prmPingd ocf:pacemaker:ping \\
  name=default_ping_set host_list=192.168.40.1 multiplier=100 attempts=2 \\
  timeout=2 \\
  op start interval=0s timeout=60s on-fail=restart monitor \\
  interval=10s timeout=60s on-fail=restart stop interval=0s \\
  timeout=60s on-fail=ignore
pcs -f tmp-cib.xml resource group add grpStonith1 prmStonith1-1
pcs -f tmp-cib.xml resource group add grpStonith2 prmStonith2-1
pcs -f tmp-cib.xml resource group add grpStonith3 prmStonith3-1
pcs -f tmp-cib.xml resource clone prmPingd
pcs -f tmp-cib.xml \\
  resource master msPostgresql pgsql master-max=1 master-node-max=1 \\
  clone-max=3 clone-node-max=1 notify=true
pcs -f tmp-cib.xml \\
  constraint location grpStonith1 rule id=rsc_location-grpStonith1-rule \\
  constraint-id=rsc_location-grpStonith1 score=-INFINITY '#uname' eq \\
  srv01
pcs -f tmp-cib.xml \\
  constraint location grpStonith2 rule id=rsc_location-grpStonith2-rule \\
  constraint-id=rsc_location-grpStonith2 score=-INFINITY '#uname' eq \\
  srv02
pcs -f tmp-cib.xml \\
  constraint location grpStonith3 rule id=rsc_location-grpStonith3-rule \\
  constraint-id=rsc_location-grpStonith3 score=-INFINITY '#uname' eq \\
  srv03
pcs -f tmp-cib.xml \\
  constraint location msPostgresql rule \\
  id=rsc_location-msPostgresql-1-rule \\
  constraint-id=rsc_location-msPostgresql-1 master score=300 '#uname' \\
  eq srv01
pcs -f tmp-cib.xml \\
  constraint rule add rsc_location-msPostgresql-1 \\
  id=rsc_location-msPostgresql-1-rule-0 master score=200 '#uname' eq \\
  srv02
pcs -f tmp-cib.xml \\
  constraint rule add rsc_location-msPostgresql-1 \\
  id=rsc_location-msPostgresql-1-rule-1 master score=100 '#uname' eq \\
  srv03
pcs -f tmp-cib.xml \\
  constraint colocation add master msPostgresql with clnPingd \\
  id=rsc_colocation-msPostgresql-clnPingd-1
pcs -f tmp-cib.xml constraint order clnPingd \\
  then msPostgresql score=0 symmetrical=false \\
  id=rsc_order-clnPingd-msPostgresql-1
pcs -f tmp-cib.xml stonith level add 1 srv01 prmStonith1-1
pcs -f tmp-cib.xml stonith level add 1 srv02 prmStonith2-1
pcs -f tmp-cib.xml stonith level add 1 srv03 prmStonith3-1
pcs -f tmp-cib.xml acl role create auto-fixer write \\
  id cib-bootstrap-options deny \\
  id cib-bootstrap-options-enable-acl deny \\
  id cib-bootstrap-options-stonith-enabled deny \\
  id cib-bootstrap-options-no-quorum-policy
pcs -f tmp-cib.xml acl user create fixer auto-fixer
pcs -f tmp-cib.xml property set enable-acl=true
pcs cluster cib-push tmp-cib.xml diff-against=tmp-cib.xml.deltasrc
EOF
    rm -f -- "${testcmd}"
    unset testcmd
    return ${ret}
}

run_checks() {
    ret=0
    run_check_ccs2pcs "${@}"; ret=$((ret+$?))
    run_check_ccs2pcscmd "${@}"; ret=$((ret+$?))
    run_check_cib2pcscmd "${@}"; ret=$((ret+$?))
    run_check_cib2pcscmd_impl_conv "${@}"; ret=$((ret+$?))
    return ${ret}
}

[ "${NORUN:-0}" -ne 0 ] || run_checks "${@}"
