import CS pcs-0.11.6-3.el9

This commit is contained in:
eabdullin 2023-09-21 19:50:55 +00:00
parent 9cce3ea39e
commit 186ac077d4
17 changed files with 1964 additions and 3661 deletions

28
.gitignore vendored
View File

@ -1,21 +1,19 @@
SOURCES/backports-3.23.0.gem
SOURCES/backports-3.24.1.gem
SOURCES/childprocess-4.1.0.gem
SOURCES/dacite-1.6.0.tar.gz
SOURCES/daemons-1.4.1.gem
SOURCES/dacite-1.8.1.tar.gz
SOURCES/ethon-0.16.0.gem
SOURCES/eventmachine-1.2.7.gem
SOURCES/ffi-1.15.5.gem
SOURCES/mustermann-3.0.0.gem
SOURCES/pcs-0.11.4.tar.gz
SOURCES/pcs-web-ui-0.1.16.tar.gz
SOURCES/pcs-web-ui-node-modules-0.1.16.tar.xz
SOURCES/nio4r-2.5.9.gem
SOURCES/pcs-0.11.6.tar.gz
SOURCES/pcs-web-ui-0.1.17.tar.gz
SOURCES/pcs-web-ui-node-modules-0.1.17.tar.xz
SOURCES/puma-6.3.0.gem
SOURCES/pyagentx-0.4.pcs.2.tar.gz
SOURCES/rack-2.2.5.gem
SOURCES/rack-protection-3.0.5.gem
SOURCES/rack-test-2.0.2.gem
SOURCES/rack-2.2.7.gem
SOURCES/rack-protection-3.0.6.gem
SOURCES/rack-test-2.1.0.gem
SOURCES/ruby2_keywords-0.0.5.gem
SOURCES/sinatra-3.0.5.gem
SOURCES/thin-1.8.1.gem
SOURCES/tilt-2.0.11.gem
SOURCES/tornado-6.2.0.tar.gz
SOURCES/webrick-1.7.0.gem
SOURCES/sinatra-3.0.6.gem
SOURCES/tilt-2.2.0.gem
SOURCES/tornado-6.3.2.tar.gz

View File

@ -1,21 +1,19 @@
0e11246385a9e0a4bc122b74fb74fe536a234f81 SOURCES/backports-3.23.0.gem
0ef72a288913e220695ad62718aeb75171924028 SOURCES/backports-3.24.1.gem
81639c8886342e01d189c10a6beab6ad0526dc4e SOURCES/childprocess-4.1.0.gem
31546c37fbdc6270d5097687619e9c0db6f1c05c SOURCES/dacite-1.6.0.tar.gz
4795a8962cc1608bfec0d91fa4d438c7cfe90c62 SOURCES/daemons-1.4.1.gem
07b26abbf7ff0dcba5c7f9e814ff7eebafefb058 SOURCES/dacite-1.8.1.tar.gz
5b56a68268708c474bef04550639ded3add5e946 SOURCES/ethon-0.16.0.gem
7a5b2896e210fac9759c786ee4510f265f75b481 SOURCES/eventmachine-1.2.7.gem
97632b7975067266c0b39596de0a4c86d9330658 SOURCES/ffi-1.15.5.gem
e892678aaf02ccb27f3a6cd58482cda00aea6ce8 SOURCES/mustermann-3.0.0.gem
b7aecf2f71777395b2b3bb79012de3e658383d4e SOURCES/pcs-0.11.4.tar.gz
62565f6f573d40a733662f5b9274caa4d275b0de SOURCES/pcs-web-ui-0.1.16.tar.gz
c079fc5427f91afcefec34c3dc5597eba916effc SOURCES/pcs-web-ui-node-modules-0.1.16.tar.xz
2f65d371f5f37460ad74afcedcb97d2b41a46806 SOURCES/nio4r-2.5.9.gem
18622c035d84535340ff004083170497f8cb5414 SOURCES/pcs-0.11.6.tar.gz
2d6a9f30b5c14351fc6c68d9a5519dc9f756c6ec SOURCES/pcs-web-ui-0.1.17.tar.gz
2b799265059e4c2008187ca32233cf4e04a9a2fb SOURCES/pcs-web-ui-node-modules-0.1.17.tar.xz
77e706abd5f50cc4b6e175931dda25e902c46018 SOURCES/puma-6.3.0.gem
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
3ad7b27b68d5dd893ce91f216bb2685ae6c9846a SOURCES/rack-2.2.5.gem
b311f9d60fc3ac0e20078a5aca7c51efa404727c SOURCES/rack-protection-3.0.5.gem
3c669527ecbcb9f915a83983ec89320c356e1fe3 SOURCES/rack-test-2.0.2.gem
f60fea8846d18d6389fe22ef431fac9e9a8d796d SOURCES/rack-2.2.7.gem
c212026bdfdb35923d1e46fed2c2c5ac1fd8faa1 SOURCES/rack-protection-3.0.6.gem
ae09ea83748b55875edc3708fffba90db180cb8e SOURCES/rack-test-2.1.0.gem
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
2a2fb3c121c6e5adc6f29d7e06cef66cdda303f1 SOURCES/sinatra-3.0.5.gem
1ac6292a98e17247b7bb847a35ff868605256f7b SOURCES/thin-1.8.1.gem
360d77c80d2851a538fb13d43751093115c34712 SOURCES/tilt-2.0.11.gem
9e809453db3a3347b7c0e7837a189833247e0828 SOURCES/tornado-6.2.0.tar.gz
10ba51035928541b7713415f1f2e3a41114972fc SOURCES/webrick-1.7.0.gem
71fb81a5bad00452c5fdaeacf74e053415a7c2e5 SOURCES/sinatra-3.0.6.gem
6a06f99324246b8d4c443ce596789e64a0c05fe4 SOURCES/tilt-2.2.0.gem
877e6035bee39ed749f2b05bffb515fc772101e3 SOURCES/tornado-6.3.2.tar.gz

View File

@ -1,215 +0,0 @@
From 2f1b9d7f225530dfc88af57d364547d9ad425172 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Thu, 24 Nov 2022 15:10:20 +0100
Subject: [PATCH] smoke test improvements
---
.gitignore | 1 +
.gitlab-ci.yml | 1 +
configure.ac | 2 +-
pcs/Makefile.am | 1 -
pcs/api_v2_client.in | 22 --------------------
pcs_test/Makefile.am | 1 +
pcs_test/api_v2_client.in | 20 +++++++++++++++++++
{pcs => pcs_test}/api_v2_client.py | 0
pcs_test/smoke.sh.in | 32 +++++++++++++++++++-----------
9 files changed, 44 insertions(+), 36 deletions(-)
delete mode 100644 pcs/api_v2_client.in
create mode 100644 pcs_test/api_v2_client.in
rename {pcs => pcs_test}/api_v2_client.py (100%)
diff --git a/.gitignore b/.gitignore
index b368a048..8dd3d5be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ requirements.txt
setup.py
setup.cfg
pcs/api_v2_client
+pcs_test/api_v2_client
pcs/pcs
pcs/pcs_internal
pcs/settings.py
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d4e0074d..3d797729 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -126,6 +126,7 @@ python_smoke_tests:
- ./autogen.sh
- ./configure --enable-local-build
- make
+ - rm -rf pcs
- pcs_test/smoke.sh
artifacts:
paths:
diff --git a/configure.ac b/configure.ac
index bc8abb39..b61c1b25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -578,10 +578,10 @@ AC_CONFIG_FILES([Makefile
pcsd/settings.rb
pcsd/logrotate/pcsd])
-AC_CONFIG_FILES([pcs/api_v2_client], [chmod +x pcs/api_v2_client])
AC_CONFIG_FILES([pcs/pcs], [chmod +x pcs/pcs])
AC_CONFIG_FILES([pcs/pcs_internal], [chmod +x pcs/pcs_internal])
AC_CONFIG_FILES([pcs/snmp/pcs_snmp_agent], [chmod +x pcs/snmp/pcs_snmp_agent])
+AC_CONFIG_FILES([pcs_test/api_v2_client], [chmod +x pcs_test/api_v2_client])
AC_CONFIG_FILES([pcs_test/smoke.sh], [chmod +x pcs_test/smoke.sh])
AC_CONFIG_FILES([pcs_test/pcs_for_tests], [chmod +x pcs_test/pcs_for_tests])
AC_CONFIG_FILES([pcs_test/suite], [chmod +x pcs_test/suite])
diff --git a/pcs/Makefile.am b/pcs/Makefile.am
index 5c5104b4..f562b32c 100644
--- a/pcs/Makefile.am
+++ b/pcs/Makefile.am
@@ -20,7 +20,6 @@ EXTRA_DIST = \
acl.py \
alert.py \
app.py \
- api_v2_client.py \
cli/booth/command.py \
cli/booth/env.py \
cli/booth/__init__.py \
diff --git a/pcs/api_v2_client.in b/pcs/api_v2_client.in
deleted file mode 100644
index 93336c31..00000000
--- a/pcs/api_v2_client.in
+++ /dev/null
@@ -1,22 +0,0 @@
-#!@PYTHON@
-
-import os.path
-import sys
-
-CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
-
-# We prevent to import some module from this dir instead of e.g. standard module.
-# There is no reason to import anything from this module.
-sys.path.remove(CURRENT_DIR)
-
-# Add pcs package.
-PACKAGE_DIR = os.path.dirname(CURRENT_DIR)
-BUNDLED_PACKAGES_DIR = os.path.join(
- PACKAGE_DIR, "@PCS_BUNDLED_DIR_LOCAL@", "packages"
-)
-sys.path.insert(0, BUNDLED_PACKAGES_DIR)
-sys.path.insert(0, PACKAGE_DIR)
-
-from pcs import api_v2_client
-
-api_v2_client.main()
diff --git a/pcs_test/Makefile.am b/pcs_test/Makefile.am
index 89a23e05..6f497a0e 100644
--- a/pcs_test/Makefile.am
+++ b/pcs_test/Makefile.am
@@ -57,6 +57,7 @@ EXTRA_DIST = \
resources/transitions01.xml \
resources/transitions02.xml \
suite.py \
+ api_v2_client.py \
tier0/cli/booth/__init__.py \
tier0/cli/booth/test_env.py \
tier0/cli/cluster/__init__.py \
diff --git a/pcs_test/api_v2_client.in b/pcs_test/api_v2_client.in
new file mode 100644
index 00000000..73a22324
--- /dev/null
+++ b/pcs_test/api_v2_client.in
@@ -0,0 +1,20 @@
+#!@PYTHON@
+import os.path
+import sys
+
+CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
+
+TEST_INSTALLED = os.environ.get("PCS_TEST.TEST_INSTALLED", "0") == "1"
+
+if TEST_INSTALLED:
+ BUNDLED_PACKAGES_DIR = os.path.join("@PCS_BUNDLED_DIR@", "packages")
+else:
+ PACKAGE_DIR = os.path.dirname(CURRENT_DIR)
+ sys.path.insert(0, PACKAGE_DIR)
+ BUNDLED_PACKAGES_DIR = os.path.join(PACKAGE_DIR, "@PCS_BUNDLED_DIR_LOCAL@", "packages")
+
+sys.path.insert(0, BUNDLED_PACKAGES_DIR)
+
+from api_v2_client import main
+
+main()
diff --git a/pcs/api_v2_client.py b/pcs_test/api_v2_client.py
similarity index 100%
rename from pcs/api_v2_client.py
rename to pcs_test/api_v2_client.py
diff --git a/pcs_test/smoke.sh.in b/pcs_test/smoke.sh.in
index 42321777..b845b6d6 100755
--- a/pcs_test/smoke.sh.in
+++ b/pcs_test/smoke.sh.in
@@ -1,6 +1,8 @@
#!@BASH@
set -ex
+SCRIPT_DIR="$(dirname -- "$(realpath -- "$0")")"
+
cluster_user=hacluster
cluster_user_password=qa57Jk27eP
pcsd_socket_path="@LOCALSTATEDIR@/run/pcsd.socket"
@@ -15,13 +17,15 @@ if pidof systemd | grep "\b1\b"; then
pcs cluster setup cluster-name localhost --debug
fi
+output_file=$(mktemp)
+token_file=$(mktemp)
+
# Sanity check of API V0
token=$(python3 -c "import json; print(json.load(open('@LOCALSTATEDIR@/lib/pcsd/known-hosts'))['known_hosts']['localhost']['token']);")
-curl -kb "token=${token}" https://localhost:2224/remote/cluster_status_plaintext -d 'data_json={}' > output.json
-cat output.json; echo ""
-python3 -c "import json; import sys; json.load(open('output.json'))['status'] == 'exception' and (sys.exit(1))";
+curl -kb "token=${token}" https://localhost:2224/remote/cluster_status_plaintext -d 'data_json={}' > "${output_file}"
+cat "${output_file}"; echo ""
+python3 -c "import json; import sys; json.load(open('${output_file}'))['status'] == 'exception' and (sys.exit(1))";
-token_file=$(mktemp)
dd if=/dev/urandom bs=32 count=1 status=none | base64 > "${token_file}"
custom_localhost_node_name="custom-node-name"
@@ -30,24 +34,28 @@ pcs pcsd accept_token "${token_file}"
pcs pcsd status "${custom_localhost_node_name}" | grep "${custom_localhost_node_name}: Online"
# Sanity check of API V1
-curl -kb "token=${token}" https://localhost:2224/api/v1/resource-agent-get-agents-list/v1 --data '{}' > output.json
-cat output.json; echo ""
-python3 -c "import json; import sys; json.load(open('output.json'))['status'] != 'success' and (sys.exit(1))";
+curl -kb "token=${token}" https://localhost:2224/api/v1/resource-agent-get-agents-list/v1 --data '{}' > "${output_file}"
+cat "${output_file}"; echo ""
+python3 -c "import json; import sys; json.load(open('${output_file}'))['status'] != 'success' and (sys.exit(1))";
# Sanity check of API V2
# async
-pcs/api_v2_client resource_agent.get_agent_metadata '{"agent_name":{"standard":"ocf","provider":"pacemaker","type":"Dummy"}}'
+env "PCS_TEST.TEST_INSTALLED=1" ${SCRIPT_DIR}/api_v2_client resource_agent.get_agent_metadata '{"agent_name":{"standard":"ocf","provider":"pacemaker","type":"Dummy"}}'
# sync
-pcs/api_v2_client --sync resource_agent.get_agent_metadata '{"agent_name":{"standard":"ocf","provider":"pacemaker","type":"Stateful"}}'
+env "PCS_TEST.TEST_INSTALLED=1" ${SCRIPT_DIR}/api_v2_client --sync resource_agent.get_agent_metadata '{"agent_name":{"standard":"ocf","provider":"pacemaker","type":"Stateful"}}'
# unix socket test
-curl --unix-socket "${pcsd_socket_path}" http:/something/api/v1/resource-agent-get-agents-list/v1 --data '{}' > output.json
-cat output.json; echo ""
-python3 -c "import json; import sys; json.load(open('output.json'))['status'] != 'success' and (sys.exit(1))";
+curl --unix-socket "${pcsd_socket_path}" http:/something/api/v1/resource-agent-get-agents-list/v1 --data '{}' > "${output_file}"
+cat "${output_file}"; echo ""
+python3 -c "import json; import sys; json.load(open('${output_file}'))['status'] != 'success' and (sys.exit(1))";
# make sure socket is not accessible by all users
useradd testuser
su testuser
! curl --unix-socket "${pcsd_socket_path}" http:/something/api/v1/resource-agent-get-agents-list/v1 --data '{}'
+
+# cleanup
+rm "${token_file}"
+rm "${output_file}"
exit 0
--
2.38.1

View File

@ -1,30 +0,0 @@
From 4692f1032b7954d56f76f243283d519e8453ff58 Mon Sep 17 00:00:00 2001
From: Miroslav Lisik <mlisik@redhat.com>
Date: Tue, 29 Nov 2022 17:46:08 +0100
Subject: [PATCH 1/3] fix smoke test
---
pcs_test/smoke.sh.in | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pcs_test/smoke.sh.in b/pcs_test/smoke.sh.in
index b845b6d6..e9466efd 100755
--- a/pcs_test/smoke.sh.in
+++ b/pcs_test/smoke.sh.in
@@ -52,10 +52,11 @@ python3 -c "import json; import sys; json.load(open('${output_file}'))['status']
# make sure socket is not accessible by all users
useradd testuser
-su testuser
-! curl --unix-socket "${pcsd_socket_path}" http:/something/api/v1/resource-agent-get-agents-list/v1 --data '{}'
+su testuser -c '! curl --unix-socket '"${pcsd_socket_path}"' http:/something/api/v1/resource-agent-get-agents-list/v1 --data '\''{}'\'''
# cleanup
rm "${token_file}"
rm "${output_file}"
+pcs cluster destroy --force
+userdel -r testuser
exit 0
--
2.38.1

View File

@ -1,40 +0,0 @@
From d486d9c9bafbfc13be7ff86c0ae781feed184d52 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Thu, 24 Nov 2022 08:15:13 +0100
Subject: [PATCH 1/2] fix graceful termination of pcsd via systemd
---
CHANGELOG.md | 5 +++++
pcsd/pcsd.service.in | 1 +
2 files changed, 6 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d3d606b..7927eae6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Change Log
+## [Unreleased]
+
+### Fixed
+- Graceful stopping pcsd service using `systemctl stop pcsd` command
+
## [0.11.4] - 2022-11-21
### Security
diff --git a/pcsd/pcsd.service.in b/pcsd/pcsd.service.in
index 8591e750..dca5052d 100644
--- a/pcsd/pcsd.service.in
+++ b/pcsd/pcsd.service.in
@@ -11,6 +11,7 @@ After=pcsd-ruby.service
EnvironmentFile=@CONF_DIR@/pcsd
ExecStart=@SBINDIR@/pcsd
Type=notify
+KillMode=mixed
[Install]
WantedBy=multi-user.target
--
2.38.1

View File

@ -1,145 +0,0 @@
From 1edf85bdabadf10708f63c0767991c7f4150e842 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Wed, 7 Dec 2022 15:53:25 +0100
Subject: [PATCH 3/3] fix displaying bool and integer values in `pcs resource
config` command
---
CHANGELOG.md | 4 ++++
pcs/cli/resource/output.py | 18 +++++++++---------
pcs_test/resources/cib-resources.xml | 2 +-
pcs_test/tier1/legacy/test_resource.py | 3 ++-
pcs_test/tools/resources_dto.py | 4 ++--
5 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed2083af..378cca50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,11 @@
### Fixed
- Graceful stopping pcsd service using `systemctl stop pcsd` command
+- Displaying bool and integer values in `pcs resource config` command
+ ([rhbz#2151164], [ghissue#604])
+[ghissue#604]: https://github.com/ClusterLabs/pcs/issues/604
+[rhbz#2151164]: https://bugzilla.redhat.com/show_bug.cgi?id=2151164
[rhbz#2151524]: https://bugzilla.redhat.com/show_bug.cgi?id=2151524
diff --git a/pcs/cli/resource/output.py b/pcs/cli/resource/output.py
index daa713a0..dbdf009f 100644
--- a/pcs/cli/resource/output.py
+++ b/pcs/cli/resource/output.py
@@ -69,9 +69,9 @@ def _resource_operation_to_pairs(
pairs.append(("interval-origin", operation_dto.interval_origin))
if operation_dto.timeout:
pairs.append(("timeout", operation_dto.timeout))
- if operation_dto.enabled:
+ if operation_dto.enabled is not None:
pairs.append(("enabled", _bool_to_cli_value(operation_dto.enabled)))
- if operation_dto.record_pending:
+ if operation_dto.record_pending is not None:
pairs.append(
("record-pending", _bool_to_cli_value(operation_dto.record_pending))
)
@@ -474,13 +474,13 @@ def _resource_bundle_container_options_to_pairs(
options: CibResourceBundleContainerRuntimeOptionsDto,
) -> List[Tuple[str, str]]:
option_list = [("image", options.image)]
- if options.replicas:
+ if options.replicas is not None:
option_list.append(("replicas", str(options.replicas)))
- if options.replicas_per_host:
+ if options.replicas_per_host is not None:
option_list.append(
("replicas-per-host", str(options.replicas_per_host))
)
- if options.promoted_max:
+ if options.promoted_max is not None:
option_list.append(("promoted-max", str(options.promoted_max)))
if options.run_command:
option_list.append(("run-command", options.run_command))
@@ -505,7 +505,7 @@ def _resource_bundle_network_options_to_pairs(
network_options.append(
("ip-range-start", bundle_network_dto.ip_range_start)
)
- if bundle_network_dto.control_port:
+ if bundle_network_dto.control_port is not None:
network_options.append(
("control-port", str(bundle_network_dto.control_port))
)
@@ -513,7 +513,7 @@ def _resource_bundle_network_options_to_pairs(
network_options.append(
("host-interface", bundle_network_dto.host_interface)
)
- if bundle_network_dto.host_netmask:
+ if bundle_network_dto.host_netmask is not None:
network_options.append(
("host-netmask", str(bundle_network_dto.host_netmask))
)
@@ -528,9 +528,9 @@ def _resource_bundle_port_mapping_to_pairs(
bundle_net_port_mapping_dto: CibResourceBundlePortMappingDto,
) -> List[Tuple[str, str]]:
mapping = []
- if bundle_net_port_mapping_dto.port:
+ if bundle_net_port_mapping_dto.port is not None:
mapping.append(("port", str(bundle_net_port_mapping_dto.port)))
- if bundle_net_port_mapping_dto.internal_port:
+ if bundle_net_port_mapping_dto.internal_port is not None:
mapping.append(
("internal-port", str(bundle_net_port_mapping_dto.internal_port))
)
diff --git a/pcs_test/resources/cib-resources.xml b/pcs_test/resources/cib-resources.xml
index 1e256b42..9242fd4a 100644
--- a/pcs_test/resources/cib-resources.xml
+++ b/pcs_test/resources/cib-resources.xml
@@ -53,7 +53,7 @@
</instance_attributes>
</op>
<op name="migrate_from" timeout="20s" interval="0s" id="R7-migrate_from-interval-0s"/>
- <op name="migrate_to" timeout="20s" interval="0s" id="R7-migrate_to-interval-0s"/>
+ <op name="migrate_to" timeout="20s" interval="0s" id="R7-migrate_to-interval-0s" enabled="false" record-pending="false"/>
<op name="monitor" timeout="20s" interval="10s" id="R7-monitor-interval-10s"/>
<op name="reload" timeout="20s" interval="0s" id="R7-reload-interval-0s"/>
<op name="reload-agent" timeout="20s" interval="0s" id="R7-reload-agent-interval-0s"/>
diff --git a/pcs_test/tier1/legacy/test_resource.py b/pcs_test/tier1/legacy/test_resource.py
index c097a937..3ba32ec7 100644
--- a/pcs_test/tier1/legacy/test_resource.py
+++ b/pcs_test/tier1/legacy/test_resource.py
@@ -774,7 +774,7 @@ Error: moni=tor does not appear to be a valid operation action
o, r = pcs(
self.temp_cib.name,
- "resource create --no-default-ops OPTest ocf:heartbeat:Dummy op monitor interval=30s OCF_CHECK_LEVEL=1 op monitor interval=25s OCF_CHECK_LEVEL=1".split(),
+ "resource create --no-default-ops OPTest ocf:heartbeat:Dummy op monitor interval=30s OCF_CHECK_LEVEL=1 op monitor interval=25s OCF_CHECK_LEVEL=1 enabled=0".split(),
)
ac(o, "")
assert r == 0
@@ -791,6 +791,7 @@ Error: moni=tor does not appear to be a valid operation action
OCF_CHECK_LEVEL=1
monitor: OPTest-monitor-interval-25s
interval=25s
+ enabled=0
OCF_CHECK_LEVEL=1
"""
),
diff --git a/pcs_test/tools/resources_dto.py b/pcs_test/tools/resources_dto.py
index e010037e..af0b4ac3 100644
--- a/pcs_test/tools/resources_dto.py
+++ b/pcs_test/tools/resources_dto.py
@@ -236,8 +236,8 @@ PRIMITIVE_R7 = CibResourcePrimitiveDto(
start_delay=None,
interval_origin=None,
timeout="20s",
- enabled=None,
- record_pending=None,
+ enabled=False,
+ record_pending=False,
role=None,
on_fail=None,
meta_attributes=[],
--
2.38.1

View File

@ -1,755 +0,0 @@
From e292dd4de2504da09901133fdab7ace5a97f9d73 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Wed, 7 Dec 2022 11:33:25 +0100
Subject: [PATCH 2/3] add warning when updating a misconfigured resource
---
CHANGELOG.md | 8 ++
pcs/common/reports/codes.py | 3 +
pcs/common/reports/messages.py | 19 +++++
pcs/lib/cib/resource/primitive.py | 84 ++++++++++++++-----
pcs/lib/pacemaker/live.py | 38 ++-------
.../tier0/common/reports/test_messages.py | 16 ++++
.../cib/resource/test_primitive_validate.py | 56 +++++++------
pcs_test/tier0/lib/pacemaker/test_live.py | 78 +++++------------
pcs_test/tier1/legacy/test_stonith.py | 5 +-
9 files changed, 169 insertions(+), 138 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7927eae6..ed2083af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,17 @@
## [Unreleased]
+### Added
+- Warning to `pcs resource|stonith update` commands about not using agent
+ self-validation feature when the resource is already misconfigured
+ ([rhbz#2151524])
+
### Fixed
- Graceful stopping pcsd service using `systemctl stop pcsd` command
+[rhbz#2151524]: https://bugzilla.redhat.com/show_bug.cgi?id=2151524
+
+
## [0.11.4] - 2022-11-21
### Security
diff --git a/pcs/common/reports/codes.py b/pcs/common/reports/codes.py
index 76963733..90609f47 100644
--- a/pcs/common/reports/codes.py
+++ b/pcs/common/reports/codes.py
@@ -44,6 +44,9 @@ AGENT_NAME_GUESS_FOUND_MORE_THAN_ONE = M("AGENT_NAME_GUESS_FOUND_MORE_THAN_ONE")
AGENT_NAME_GUESS_FOUND_NONE = M("AGENT_NAME_GUESS_FOUND_NONE")
AGENT_NAME_GUESSED = M("AGENT_NAME_GUESSED")
AGENT_SELF_VALIDATION_INVALID_DATA = M("AGENT_SELF_VALIDATION_INVALID_DATA")
+AGENT_SELF_VALIDATION_SKIPPED_UPDATED_RESOURCE_MISCONFIGURED = M(
+ "AGENT_SELF_VALIDATION_SKIPPED_UPDATED_RESOURCE_MISCONFIGURED"
+)
AGENT_SELF_VALIDATION_RESULT = M("AGENT_SELF_VALIDATION_RESULT")
BAD_CLUSTER_STATE_FORMAT = M("BAD_CLUSTER_STATE_FORMAT")
BOOTH_ADDRESS_DUPLICATION = M("BOOTH_ADDRESS_DUPLICATION")
diff --git a/pcs/common/reports/messages.py b/pcs/common/reports/messages.py
index ba748eb2..fbc4de62 100644
--- a/pcs/common/reports/messages.py
+++ b/pcs/common/reports/messages.py
@@ -7494,6 +7494,25 @@ class AgentSelfValidationInvalidData(ReportItemMessage):
return f"Invalid validation data from agent: {self.reason}"
+@dataclass(frozen=True)
+class AgentSelfValidationSkippedUpdatedResourceMisconfigured(ReportItemMessage):
+ """
+ Agent self validation is skipped when updating a resource as it is
+ misconfigured in its current state.
+ """
+
+ result: str
+ _code = codes.AGENT_SELF_VALIDATION_SKIPPED_UPDATED_RESOURCE_MISCONFIGURED
+
+ @property
+ def message(self) -> str:
+ return (
+ "The resource was misconfigured before the update, therefore agent "
+ "self-validation will not be run for the updated configuration. "
+ "Validation output of the original configuration:\n{result}"
+ ).format(result="\n".join(indent(self.result.splitlines())))
+
+
@dataclass(frozen=True)
class ResourceCloneIncompatibleMetaAttributes(ReportItemMessage):
"""
diff --git a/pcs/lib/cib/resource/primitive.py b/pcs/lib/cib/resource/primitive.py
index d9940e9d..f9d52b9b 100644
--- a/pcs/lib/cib/resource/primitive.py
+++ b/pcs/lib/cib/resource/primitive.py
@@ -357,6 +357,31 @@ def _is_ocf_or_stonith_agent(resource_agent_name: ResourceAgentName) -> bool:
return resource_agent_name.standard in ("stonith", "ocf")
+def _get_report_from_agent_self_validation(
+ is_valid: Optional[bool],
+ reason: str,
+ report_severity: reports.ReportItemSeverity,
+) -> reports.ReportItemList:
+ report_items = []
+ if is_valid is None:
+ report_items.append(
+ reports.ReportItem(
+ report_severity,
+ reports.messages.AgentSelfValidationInvalidData(reason),
+ )
+ )
+ elif not is_valid or reason:
+ if is_valid:
+ report_severity = reports.ReportItemSeverity.warning()
+ report_items.append(
+ reports.ReportItem(
+ report_severity,
+ reports.messages.AgentSelfValidationResult(reason),
+ )
+ )
+ return report_items
+
+
def validate_resource_instance_attributes_create(
cmd_runner: CommandRunner,
resource_agent: ResourceAgentFacade,
@@ -405,16 +430,16 @@ def validate_resource_instance_attributes_create(
for report_item in report_items
)
):
- (
- dummy_is_valid,
- agent_validation_reports,
- ) = validate_resource_instance_attributes_via_pcmk(
- cmd_runner,
- agent_name,
- instance_attributes,
- reports.get_severity(reports.codes.FORCE, force),
+ report_items.extend(
+ _get_report_from_agent_self_validation(
+ *validate_resource_instance_attributes_via_pcmk(
+ cmd_runner,
+ agent_name,
+ instance_attributes,
+ ),
+ reports.get_severity(reports.codes.FORCE, force),
+ )
)
- report_items.extend(agent_validation_reports)
return report_items
@@ -508,25 +533,40 @@ def validate_resource_instance_attributes_update(
)
):
(
- is_valid,
- dummy_reports,
+ original_is_valid,
+ original_reason,
) = validate_resource_instance_attributes_via_pcmk(
cmd_runner,
agent_name,
current_instance_attrs,
- reports.ReportItemSeverity.error(),
)
- if is_valid:
- (
- dummy_is_valid,
- agent_validation_reports,
- ) = validate_resource_instance_attributes_via_pcmk(
- cmd_runner,
- resource_agent.metadata.name,
- final_attrs,
- reports.get_severity(reports.codes.FORCE, force),
+ if original_is_valid:
+ report_items.extend(
+ _get_report_from_agent_self_validation(
+ *validate_resource_instance_attributes_via_pcmk(
+ cmd_runner,
+ resource_agent.metadata.name,
+ final_attrs,
+ ),
+ reports.get_severity(reports.codes.FORCE, force),
+ )
+ )
+ elif original_is_valid is None:
+ report_items.append(
+ reports.ReportItem.warning(
+ reports.messages.AgentSelfValidationInvalidData(
+ original_reason
+ )
+ )
+ )
+ else:
+ report_items.append(
+ reports.ReportItem.warning(
+ reports.messages.AgentSelfValidationSkippedUpdatedResourceMisconfigured(
+ original_reason
+ )
+ )
)
- report_items.extend(agent_validation_reports)
return report_items
diff --git a/pcs/lib/pacemaker/live.py b/pcs/lib/pacemaker/live.py
index 6dab613e..fb1e0a4a 100644
--- a/pcs/lib/pacemaker/live.py
+++ b/pcs/lib/pacemaker/live.py
@@ -884,8 +884,7 @@ def _validate_stonith_instance_attributes_via_pcmk(
cmd_runner: CommandRunner,
agent_name: ResourceAgentName,
instance_attributes: Mapping[str, str],
- not_valid_severity: reports.ReportItemSeverity,
-) -> tuple[Optional[bool], reports.ReportItemList]:
+) -> tuple[Optional[bool], str]:
cmd = [
settings.stonith_admin,
"--validate",
@@ -899,7 +898,6 @@ def _validate_stonith_instance_attributes_via_pcmk(
cmd,
"./validate/command/output",
instance_attributes,
- not_valid_severity,
)
@@ -907,8 +905,7 @@ def _validate_resource_instance_attributes_via_pcmk(
cmd_runner: CommandRunner,
agent_name: ResourceAgentName,
instance_attributes: Mapping[str, str],
- not_valid_severity: reports.ReportItemSeverity,
-) -> tuple[Optional[bool], reports.ReportItemList]:
+) -> tuple[Optional[bool], str]:
cmd = [
settings.crm_resource_binary,
"--validate",
@@ -926,7 +923,6 @@ def _validate_resource_instance_attributes_via_pcmk(
cmd,
"./resource-agent-action/command/output",
instance_attributes,
- not_valid_severity,
)
@@ -935,8 +931,7 @@ def _handle_instance_attributes_validation_via_pcmk(
cmd: StringSequence,
data_xpath: str,
instance_attributes: Mapping[str, str],
- not_valid_severity: reports.ReportItemSeverity,
-) -> tuple[Optional[bool], reports.ReportItemList]:
+) -> tuple[Optional[bool], str]:
full_cmd = list(cmd)
for key, value in sorted(instance_attributes.items()):
full_cmd.extend(["--option", f"{key}={value}"])
@@ -945,12 +940,7 @@ def _handle_instance_attributes_validation_via_pcmk(
# dom = _get_api_result_dom(stdout)
dom = xml_fromstring(stdout)
except (etree.XMLSyntaxError, etree.DocumentInvalid) as e:
- return None, [
- reports.ReportItem(
- not_valid_severity,
- reports.messages.AgentSelfValidationInvalidData(str(e)),
- )
- ]
+ return None, str(e)
result = "\n".join(
"\n".join(
line.strip() for line in item.text.split("\n") if line.strip()
@@ -958,38 +948,22 @@ def _handle_instance_attributes_validation_via_pcmk(
for item in dom.iterfind(data_xpath)
if item.get("source") == "stderr" and item.text
).strip()
- if return_value == 0:
- if result:
- return True, [
- reports.ReportItem.warning(
- reports.messages.AgentSelfValidationResult(result)
- )
- ]
- return True, []
- return False, [
- reports.ReportItem(
- not_valid_severity,
- reports.messages.AgentSelfValidationResult(result),
- )
- ]
+ return return_value == 0, result
def validate_resource_instance_attributes_via_pcmk(
cmd_runner: CommandRunner,
resource_agent_name: ResourceAgentName,
instance_attributes: Mapping[str, str],
- not_valid_severity: reports.ReportItemSeverity,
-) -> tuple[Optional[bool], reports.ReportItemList]:
+) -> tuple[Optional[bool], str]:
if resource_agent_name.is_stonith:
return _validate_stonith_instance_attributes_via_pcmk(
cmd_runner,
resource_agent_name,
instance_attributes,
- not_valid_severity,
)
return _validate_resource_instance_attributes_via_pcmk(
cmd_runner,
resource_agent_name,
instance_attributes,
- not_valid_severity,
)
diff --git a/pcs_test/tier0/common/reports/test_messages.py b/pcs_test/tier0/common/reports/test_messages.py
index 64e74daa..b1e009ce 100644
--- a/pcs_test/tier0/common/reports/test_messages.py
+++ b/pcs_test/tier0/common/reports/test_messages.py
@@ -5525,6 +5525,22 @@ class AgentSelfValidationInvalidData(NameBuildTest):
)
+class AgentSelfValidationSkippedUpdatedResourceMisconfigured(NameBuildTest):
+ def test_message(self):
+ lines = list(f"line #{i}" for i in range(3))
+ self.assert_message_from_report(
+ (
+ "The resource was misconfigured before the update, therefore "
+ "agent self-validation will not be run for the updated "
+ "configuration. Validation output of the original "
+ "configuration:\n {}"
+ ).format("\n ".join(lines)),
+ reports.AgentSelfValidationSkippedUpdatedResourceMisconfigured(
+ "\n".join(lines)
+ ),
+ )
+
+
class ResourceCloneIncompatibleMetaAttributes(NameBuildTest):
def test_with_provider(self):
attr = "attr_name"
diff --git a/pcs_test/tier0/lib/cib/resource/test_primitive_validate.py b/pcs_test/tier0/lib/cib/resource/test_primitive_validate.py
index 8b52314f..7a4e5c8f 100644
--- a/pcs_test/tier0/lib/cib/resource/test_primitive_validate.py
+++ b/pcs_test/tier0/lib/cib/resource/test_primitive_validate.py
@@ -660,7 +660,6 @@ class ValidateResourceInstanceAttributesCreateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
)
def test_force(self):
@@ -680,15 +679,14 @@ class ValidateResourceInstanceAttributesCreateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
attributes,
- reports.ReportItemSeverity.warning(),
)
def test_failure(self):
attributes = {"required": "value"}
facade = _fixture_ocf_agent()
- failure_reports = ["report1", "report2"]
- self.agent_self_validation_mock.return_value = False, failure_reports
- self.assertEqual(
+ failure_reason = "failure reason"
+ self.agent_self_validation_mock.return_value = False, failure_reason
+ assert_report_item_list_equal(
primitive.validate_resource_instance_attributes_create(
self.cmd_runner,
facade,
@@ -696,13 +694,18 @@ class ValidateResourceInstanceAttributesCreateSelfValidation(TestCase):
etree.Element("resources"),
force=False,
),
- failure_reports,
+ [
+ fixture.error(
+ reports.codes.AGENT_SELF_VALIDATION_RESULT,
+ result=failure_reason,
+ force_code=reports.codes.FORCE,
+ )
+ ],
)
self.agent_self_validation_mock.assert_called_once_with(
self.cmd_runner,
facade.metadata.name,
attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
)
def test_stonith_check(self):
@@ -722,7 +725,6 @@ class ValidateResourceInstanceAttributesCreateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
)
def test_nonexisting_agent(self):
@@ -1346,13 +1348,11 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
old_attributes,
- reports.ReportItemSeverity.error(),
),
mock.call(
self.cmd_runner,
facade.metadata.name,
new_attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
),
],
)
@@ -1379,13 +1379,11 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
old_attributes,
- reports.ReportItemSeverity.error(),
),
mock.call(
self.cmd_runner,
facade.metadata.name,
new_attributes,
- reports.ReportItemSeverity.warning(),
),
],
)
@@ -1393,13 +1391,13 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
def test_failure(self):
old_attributes = {"required": "old_value"}
new_attributes = {"required": "new_value"}
- failure_reports = ["report1", "report2"]
+ failure_reason = "failure reason"
facade = _fixture_ocf_agent()
self.agent_self_validation_mock.side_effect = (
- (True, []),
- (False, failure_reports),
+ (True, ""),
+ (False, failure_reason),
)
- self.assertEqual(
+ assert_report_item_list_equal(
primitive.validate_resource_instance_attributes_update(
self.cmd_runner,
facade,
@@ -1408,7 +1406,13 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self._fixture_resources(old_attributes),
force=False,
),
- failure_reports,
+ [
+ fixture.error(
+ reports.codes.AGENT_SELF_VALIDATION_RESULT,
+ result=failure_reason,
+ force_code=reports.codes.FORCE,
+ )
+ ],
)
self.assertEqual(
self.agent_self_validation_mock.mock_calls,
@@ -1417,13 +1421,11 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
old_attributes,
- reports.ReportItemSeverity.error(),
),
mock.call(
self.cmd_runner,
facade.metadata.name,
new_attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
),
],
)
@@ -1450,13 +1452,11 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
old_attributes,
- reports.ReportItemSeverity.error(),
),
mock.call(
self.cmd_runner,
facade.metadata.name,
new_attributes,
- reports.ReportItemSeverity.error(reports.codes.FORCE),
),
],
)
@@ -1522,10 +1522,10 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
def test_current_attributes_failure(self):
old_attributes = {"required": "old_value"}
new_attributes = {"required": "new_value"}
- failure_reports = ["report1", "report2"]
+ failure_reason = "failure reason"
facade = _fixture_ocf_agent()
- self.agent_self_validation_mock.return_value = False, failure_reports
- self.assertEqual(
+ self.agent_self_validation_mock.return_value = False, failure_reason
+ assert_report_item_list_equal(
primitive.validate_resource_instance_attributes_update(
self.cmd_runner,
facade,
@@ -1534,7 +1534,12 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self._fixture_resources(old_attributes),
force=False,
),
- [],
+ [
+ fixture.warn(
+ reports.codes.AGENT_SELF_VALIDATION_SKIPPED_UPDATED_RESOURCE_MISCONFIGURED,
+ result=failure_reason,
+ )
+ ],
)
self.assertEqual(
self.agent_self_validation_mock.mock_calls,
@@ -1543,7 +1548,6 @@ class ValidateResourceInstanceAttributesUpdateSelfValidation(TestCase):
self.cmd_runner,
facade.metadata.name,
old_attributes,
- reports.ReportItemSeverity.error(),
),
],
)
diff --git a/pcs_test/tier0/lib/pacemaker/test_live.py b/pcs_test/tier0/lib/pacemaker/test_live.py
index 1f37d759..c1363a65 100644
--- a/pcs_test/tier0/lib/pacemaker/test_live.py
+++ b/pcs_test/tier0/lib/pacemaker/test_live.py
@@ -1706,16 +1706,15 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertTrue(is_valid)
- self.assertEqual(report_list, [])
+ self.assertEqual(reason, "")
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
)
@@ -1725,23 +1724,17 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertIsNone(is_valid)
- assert_report_item_list_equal(
- report_list,
- [
- fixture.info(
- report_codes.AGENT_SELF_VALIDATION_INVALID_DATA,
- reason="Start tag expected, '<' not found, line 1, column 1 (<string>, line 1)",
- )
- ],
+ self.assertEqual(
+ reason,
+ "Start tag expected, '<' not found, line 1, column 1 (<string>, line 1)",
)
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
@@ -1760,19 +1753,15 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertTrue(is_valid)
- assert_report_item_list_equal(
- report_list,
- [],
- )
+ self.assertEqual(reason, "")
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
)
@@ -1791,23 +1780,15 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertFalse(is_valid)
- assert_report_item_list_equal(
- report_list,
- [
- fixture.info(
- report_codes.AGENT_SELF_VALIDATION_RESULT, result=""
- )
- ],
- )
+ self.assertEqual(reason, "")
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
)
@@ -1835,23 +1816,17 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertFalse(is_valid)
- assert_report_item_list_equal(
- report_list,
- [
- fixture.info(
- report_codes.AGENT_SELF_VALIDATION_RESULT,
- result="first line\nImportant output\nand another line",
- )
- ],
+ self.assertEqual(
+ reason,
+ "first line\nImportant output\nand another line",
)
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
@@ -1879,23 +1854,17 @@ class HandleInstanceAttributesValidateViaPcmkTest(TestCase):
base_cmd = ["some", "command"]
(
is_valid,
- report_list,
+ reason,
) = lib._handle_instance_attributes_validation_via_pcmk(
runner,
base_cmd,
"result/output",
{"attr1": "val1", "attr2": "val2"},
- not_valid_severity=Severity.info(),
)
self.assertTrue(is_valid)
- assert_report_item_list_equal(
- report_list,
- [
- fixture.warn(
- report_codes.AGENT_SELF_VALIDATION_RESULT,
- result="first line\nImportant output\nand another line",
- )
- ],
+ self.assertEqual(
+ reason,
+ "first line\nImportant output\nand another line",
)
runner.run.assert_called_once_with(
base_cmd + ["--option", "attr1=val1", "--option", "attr2=val2"]
@@ -1907,7 +1876,6 @@ class ValidateResourceInstanceAttributesViaPcmkTest(TestCase):
def setUp(self):
self.runner = mock.Mock()
self.attrs = dict(attra="val1", attrb="val2")
- self.severity = Severity.info()
patcher = mock.patch(
"pcs.lib.pacemaker.live._handle_instance_attributes_validation_via_pcmk"
)
@@ -1921,7 +1889,7 @@ class ValidateResourceInstanceAttributesViaPcmkTest(TestCase):
)
self.assertEqual(
lib._validate_resource_instance_attributes_via_pcmk(
- self.runner, agent, self.attrs, self.severity
+ self.runner, agent, self.attrs
),
self.ret_val,
)
@@ -1941,7 +1909,6 @@ class ValidateResourceInstanceAttributesViaPcmkTest(TestCase):
],
"./resource-agent-action/command/output",
self.attrs,
- self.severity,
)
def test_without_provider(self):
@@ -1950,7 +1917,7 @@ class ValidateResourceInstanceAttributesViaPcmkTest(TestCase):
)
self.assertEqual(
lib._validate_resource_instance_attributes_via_pcmk(
- self.runner, agent, self.attrs, self.severity
+ self.runner, agent, self.attrs
),
self.ret_val,
)
@@ -1968,7 +1935,6 @@ class ValidateResourceInstanceAttributesViaPcmkTest(TestCase):
],
"./resource-agent-action/command/output",
self.attrs,
- self.severity,
)
@@ -1978,7 +1944,6 @@ class ValidateStonithInstanceAttributesViaPcmkTest(TestCase):
def setUp(self):
self.runner = mock.Mock()
self.attrs = dict(attra="val1", attrb="val2")
- self.severity = Severity.info()
patcher = mock.patch(
"pcs.lib.pacemaker.live._handle_instance_attributes_validation_via_pcmk"
)
@@ -1992,7 +1957,7 @@ class ValidateStonithInstanceAttributesViaPcmkTest(TestCase):
)
self.assertEqual(
lib._validate_stonith_instance_attributes_via_pcmk(
- self.runner, agent, self.attrs, self.severity
+ self.runner, agent, self.attrs
),
self.ret_val,
)
@@ -2008,5 +1973,4 @@ class ValidateStonithInstanceAttributesViaPcmkTest(TestCase):
],
"./validate/command/output",
self.attrs,
- self.severity,
)
diff --git a/pcs_test/tier1/legacy/test_stonith.py b/pcs_test/tier1/legacy/test_stonith.py
index 8b31094b..7e7ec030 100644
--- a/pcs_test/tier1/legacy/test_stonith.py
+++ b/pcs_test/tier1/legacy/test_stonith.py
@@ -1291,7 +1291,10 @@ class StonithTest(TestCase, AssertPcsMixin):
),
)
- self.assert_pcs_success("stonith update test3 username=testA".split())
+ self.assert_pcs_success(
+ "stonith update test3 username=testA".split(),
+ stdout_start="Warning: ",
+ )
self.assert_pcs_success(
"stonith config test2".split(),
--
2.38.1

View File

@ -1,506 +0,0 @@
From bbf53f713189eb2233efa03bf3aa9c96eb79ba82 Mon Sep 17 00:00:00 2001
From: Miroslav Lisik <mlisik@redhat.com>
Date: Thu, 5 Jan 2023 16:21:44 +0100
Subject: [PATCH 2/2] Fix stonith-watchdog-timeout validation
---
CHANGELOG.md | 2 +
pcs/lib/cluster_property.py | 25 ++++-
pcs/lib/sbd.py | 15 ++-
.../lib/commands/test_cluster_property.py | 50 ++++++++--
pcs_test/tier0/lib/test_cluster_property.py | 98 ++++++++++++++-----
pcs_test/tier1/test_cluster_property.py | 14 ++-
6 files changed, 159 insertions(+), 45 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47212f00..0945d727 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
- Graceful stopping pcsd service using `systemctl stop pcsd` command
- Displaying bool and integer values in `pcs resource config` command
([rhbz#2151164], [ghissue#604])
+- Allow time values in stonith-watchdog-time property ([rhbz#2158790])
### Changed
- Resource/stonith agent self-validation of instance attributes is now
@@ -22,6 +23,7 @@
[rhbz#2151164]: https://bugzilla.redhat.com/show_bug.cgi?id=2151164
[rhbz#2151524]: https://bugzilla.redhat.com/show_bug.cgi?id=2151524
[rhbz#2159454]: https://bugzilla.redhat.com/show_bug.cgi?id=2159454
+[rhbz#2158790]: https://bugzilla.redhat.com/show_bug.cgi?id=2158790
## [0.11.4] - 2022-11-21
diff --git a/pcs/lib/cluster_property.py b/pcs/lib/cluster_property.py
index 3bbc093d..d3c8a896 100644
--- a/pcs/lib/cluster_property.py
+++ b/pcs/lib/cluster_property.py
@@ -7,6 +7,7 @@ from lxml.etree import _Element
from pcs.common import reports
from pcs.common.services.interfaces import ServiceManagerInterface
+from pcs.common.tools import timeout_to_seconds
from pcs.common.types import StringSequence
from pcs.lib import (
sbd,
@@ -37,8 +38,21 @@ def _validate_stonith_watchdog_timeout_property(
force: bool = False,
) -> reports.ReportItemList:
report_list: reports.ReportItemList = []
+ original_value = value
+ # if value is not empty, try to convert time interval string
+ if value:
+ seconds = timeout_to_seconds(value)
+ if seconds is None:
+ # returns empty list because this should be reported by
+ # ValueTimeInterval validator
+ return report_list
+ value = str(seconds)
if sbd.is_sbd_enabled(service_manager):
- report_list.extend(sbd.validate_stonith_watchdog_timeout(value, force))
+ report_list.extend(
+ sbd.validate_stonith_watchdog_timeout(
+ validate.ValuePair(original_value, value), force
+ )
+ )
else:
if value not in ["", "0"]:
report_list.append(
@@ -123,9 +137,6 @@ def validate_set_cluster_properties(
# unknow properties are reported by NamesIn validator
continue
property_metadata = possible_properties_dict[property_name]
- if property_metadata.name == "stonith-watchdog-timeout":
- # needs extra validation
- continue
if property_metadata.type == "boolean":
validators.append(
validate.ValuePcmkBoolean(
@@ -153,9 +164,13 @@ def validate_set_cluster_properties(
)
)
elif property_metadata.type == "time":
+ # make stonith-watchdog-timeout value not forcable
validators.append(
validate.ValueTimeInterval(
- property_metadata.name, severity=severity
+ property_metadata.name,
+ severity=severity
+ if property_metadata.name != "stonith-watchdog-timeout"
+ else reports.ReportItemSeverity.error(),
)
)
report_list.extend(
diff --git a/pcs/lib/sbd.py b/pcs/lib/sbd.py
index 1e3cfb37..38cd8767 100644
--- a/pcs/lib/sbd.py
+++ b/pcs/lib/sbd.py
@@ -1,6 +1,9 @@
import re
from os import path
-from typing import Optional
+from typing import (
+ Optional,
+ Union,
+)
from pcs import settings
from pcs.common import reports
@@ -392,7 +395,10 @@ def _get_local_sbd_watchdog_timeout() -> int:
def validate_stonith_watchdog_timeout(
- stonith_watchdog_timeout: str, force: bool = False
+ stonith_watchdog_timeout: Union[
+ validate.TypeOptionValue, validate.ValuePair
+ ],
+ force: bool = False,
) -> reports.ReportItemList:
"""
Check sbd status and config when user is setting stonith-watchdog-timeout
@@ -401,6 +407,7 @@ def validate_stonith_watchdog_timeout(
stonith_watchdog_timeout -- value to be validated
"""
+ stonith_watchdog_timeout = validate.ValuePair.get(stonith_watchdog_timeout)
severity = reports.get_severity(reports.codes.FORCE, force)
if _is_device_set_local():
return (
@@ -412,11 +419,11 @@ def validate_stonith_watchdog_timeout(
),
)
]
- if stonith_watchdog_timeout not in ["", "0"]
+ if stonith_watchdog_timeout.normalized not in ["", "0"]
else []
)
- if stonith_watchdog_timeout in ["", "0"]:
+ if stonith_watchdog_timeout.normalized in ["", "0"]:
return [
reports.ReportItem(
severity,
diff --git a/pcs_test/tier0/lib/commands/test_cluster_property.py b/pcs_test/tier0/lib/commands/test_cluster_property.py
index 94c0938a..781222ab 100644
--- a/pcs_test/tier0/lib/commands/test_cluster_property.py
+++ b/pcs_test/tier0/lib/commands/test_cluster_property.py
@@ -120,6 +120,34 @@ class StonithWatchdogTimeoutMixin(LoadMetadataMixin):
)
self.env_assist.assert_reports([])
+ def _set_invalid_value(self, forced=False):
+ self.config.remove("services.is_enabled")
+ self.env_assist.assert_raise_library_error(
+ lambda: cluster_property.set_properties(
+ self.env_assist.get_env(),
+ {"stonith-watchdog-timeout": "15x"},
+ [] if not forced else [reports.codes.FORCE],
+ )
+ )
+ self.env_assist.assert_reports(
+ [
+ fixture.error(
+ reports.codes.INVALID_OPTION_VALUE,
+ option_name="stonith-watchdog-timeout",
+ option_value="15x",
+ allowed_values="time interval (e.g. 1, 2s, 3m, 4h, ...)",
+ cannot_be_empty=False,
+ forbidden_characters=None,
+ ),
+ ]
+ )
+
+ def test_set_invalid_value(self):
+ self._set_invalid_value(forced=False)
+
+ def test_set_invalid_value_forced(self):
+ self._set_invalid_value(forced=True)
+
class TestSetStonithWatchdogTimeoutSBDIsDisabled(
StonithWatchdogTimeoutMixin, TestCase
@@ -132,6 +160,9 @@ class TestSetStonithWatchdogTimeoutSBDIsDisabled(
def test_set_zero(self):
self._set_success({"stonith-watchdog-timeout": "0"})
+ def test_set_zero_time_suffix(self):
+ self._set_success({"stonith-watchdog-timeout": "0s"})
+
def test_set_not_zero_or_empty(self):
self.env_assist.assert_raise_library_error(
lambda: cluster_property.set_properties(
@@ -231,12 +262,12 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledWatchdogOnly(
def test_set_zero_forced(self):
self.config.env.push_cib(
crm_config=fixture_crm_config_properties(
- [("cib-bootstrap-options", {"stonith-watchdog-timeout": "0"})]
+ [("cib-bootstrap-options", {"stonith-watchdog-timeout": "0s"})]
)
)
cluster_property.set_properties(
self.env_assist.get_env(),
- {"stonith-watchdog-timeout": "0"},
+ {"stonith-watchdog-timeout": "0s"},
[reports.codes.FORCE],
)
self.env_assist.assert_reports(
@@ -271,7 +302,7 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledWatchdogOnly(
self.env_assist.assert_raise_library_error(
lambda: cluster_property.set_properties(
self.env_assist.get_env(),
- {"stonith-watchdog-timeout": "9"},
+ {"stonith-watchdog-timeout": "9s"},
[],
)
)
@@ -281,7 +312,7 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledWatchdogOnly(
reports.codes.STONITH_WATCHDOG_TIMEOUT_TOO_SMALL,
force_code=reports.codes.FORCE,
cluster_sbd_watchdog_timeout=10,
- entered_watchdog_timeout="9",
+ entered_watchdog_timeout="9s",
)
]
)
@@ -289,12 +320,12 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledWatchdogOnly(
def test_too_small_forced(self):
self.config.env.push_cib(
crm_config=fixture_crm_config_properties(
- [("cib-bootstrap-options", {"stonith-watchdog-timeout": "9"})]
+ [("cib-bootstrap-options", {"stonith-watchdog-timeout": "9s"})]
)
)
cluster_property.set_properties(
self.env_assist.get_env(),
- {"stonith-watchdog-timeout": "9"},
+ {"stonith-watchdog-timeout": "9s"},
[reports.codes.FORCE],
)
self.env_assist.assert_reports(
@@ -302,13 +333,13 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledWatchdogOnly(
fixture.warn(
reports.codes.STONITH_WATCHDOG_TIMEOUT_TOO_SMALL,
cluster_sbd_watchdog_timeout=10,
- entered_watchdog_timeout="9",
+ entered_watchdog_timeout="9s",
)
]
)
def test_more_than_timeout(self):
- self._set_success({"stonith-watchdog-timeout": "11"})
+ self._set_success({"stonith-watchdog-timeout": "11s"})
@mock.patch("pcs.lib.sbd.get_local_sbd_device_list", lambda: ["dev1", "dev2"])
@@ -323,6 +354,9 @@ class TestSetStonithWatchdogTimeoutSBDIsEnabledSharedDevices(
def test_set_to_zero(self):
self._set_success({"stonith-watchdog-timeout": "0"})
+ def test_set_to_zero_time_suffix(self):
+ self._set_success({"stonith-watchdog-timeout": "0min"})
+
def test_set_not_zero_or_empty(self):
self.env_assist.assert_raise_library_error(
lambda: cluster_property.set_properties(
diff --git a/pcs_test/tier0/lib/test_cluster_property.py b/pcs_test/tier0/lib/test_cluster_property.py
index 2feb728d..8d6f90b1 100644
--- a/pcs_test/tier0/lib/test_cluster_property.py
+++ b/pcs_test/tier0/lib/test_cluster_property.py
@@ -83,6 +83,7 @@ FIXTURE_VALID_OPTIONS_DICT = {
"integer_param": "10",
"percentage_param": "20%",
"select_param": "s3",
+ "stonith-watchdog-timeout": "0",
"time_param": "5min",
}
@@ -96,6 +97,8 @@ FIXTURE_INVALID_OPTIONS_DICT = {
"have-watchdog": "100",
}
+STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES = ["", "0", "0s"]
+
def _fixture_parameter(name, param_type, default, enum_values):
return ResourceAgentParameter(
@@ -239,6 +242,7 @@ class TestValidateSetClusterProperties(TestCase):
sbd_enabled=False,
sbd_devices=False,
force=False,
+ valid_value=True,
):
self.mock_is_sbd_enabled.return_value = sbd_enabled
self.mock_sbd_devices.return_value = ["devices"] if sbd_devices else []
@@ -254,9 +258,13 @@ class TestValidateSetClusterProperties(TestCase):
),
expected_report_list,
)
- if "stonith-watchdog-timeout" in new_properties and (
- new_properties["stonith-watchdog-timeout"]
- or "stonith-watchdog-timeout" in configured_properties
+ if (
+ "stonith-watchdog-timeout" in new_properties
+ and (
+ new_properties["stonith-watchdog-timeout"]
+ or "stonith-watchdog-timeout" in configured_properties
+ )
+ and valid_value
):
self.mock_is_sbd_enabled.assert_called_once_with(
self.mock_service_manager
@@ -266,7 +274,10 @@ class TestValidateSetClusterProperties(TestCase):
if sbd_devices:
self.mock_sbd_timeout.assert_not_called()
else:
- if new_properties["stonith-watchdog-timeout"] in ["", "0"]:
+ if (
+ new_properties["stonith-watchdog-timeout"]
+ in STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES
+ ):
self.mock_sbd_timeout.assert_not_called()
else:
self.mock_sbd_timeout.assert_called_once_with()
@@ -280,6 +291,8 @@ class TestValidateSetClusterProperties(TestCase):
self.mock_sbd_timeout.assert_not_called()
self.mock_is_sbd_enabled.reset_mock()
+ self.mock_sbd_devices.reset_mock()
+ self.mock_sbd_timeout.reset_mock()
def test_no_properties_to_set_or_unset(self):
self.assert_validate_set(
@@ -328,7 +341,7 @@ class TestValidateSetClusterProperties(TestCase):
)
def test_unset_stonith_watchdog_timeout_sbd_disabled(self):
- for value in ["0", ""]:
+ for value in STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES:
with self.subTest(value=value):
self.assert_validate_set(
["stonith-watchdog-timeout"],
@@ -349,22 +362,27 @@ class TestValidateSetClusterProperties(TestCase):
)
def test_set_ok_stonith_watchdog_timeout_sbd_enabled_without_devices(self):
- self.assert_validate_set(
- [], {"stonith-watchdog-timeout": "15"}, [], sbd_enabled=True
- )
+ for value in ["15", "15s"]:
+ with self.subTest(value=value):
+ self.assert_validate_set(
+ [],
+ {"stonith-watchdog-timeout": value},
+ [],
+ sbd_enabled=True,
+ )
def test_set_small_stonith_watchdog_timeout_sbd_enabled_without_devices(
self,
):
self.assert_validate_set(
[],
- {"stonith-watchdog-timeout": "9"},
+ {"stonith-watchdog-timeout": "9s"},
[
fixture.error(
reports.codes.STONITH_WATCHDOG_TIMEOUT_TOO_SMALL,
force_code=reports.codes.FORCE,
cluster_sbd_watchdog_timeout=10,
- entered_watchdog_timeout="9",
+ entered_watchdog_timeout="9s",
)
],
sbd_enabled=True,
@@ -387,28 +405,54 @@ class TestValidateSetClusterProperties(TestCase):
force=True,
)
- def test_set_not_a_number_stonith_watchdog_timeout_sbd_enabled_without_devices(
+ def _set_invalid_value_stonith_watchdog_timeout(
+ self, sbd_enabled=False, sbd_devices=False
+ ):
+ for value in ["invalid", "10x"]:
+ with self.subTest(value=value):
+ self.assert_validate_set(
+ [],
+ {"stonith-watchdog-timeout": value},
+ [
+ fixture.error(
+ reports.codes.INVALID_OPTION_VALUE,
+ option_name="stonith-watchdog-timeout",
+ option_value=value,
+ allowed_values="time interval (e.g. 1, 2s, 3m, 4h, ...)",
+ cannot_be_empty=False,
+ forbidden_characters=None,
+ )
+ ],
+ sbd_enabled=sbd_enabled,
+ sbd_devices=sbd_devices,
+ valid_value=False,
+ )
+
+ def test_set_invalid_value_stonith_watchdog_timeout_sbd_enabled_without_devices(
self,
):
+ self._set_invalid_value_stonith_watchdog_timeout(
+ sbd_enabled=True, sbd_devices=False
+ )
- self.assert_validate_set(
- [],
- {"stonith-watchdog-timeout": "invalid"},
- [
- fixture.error(
- reports.codes.STONITH_WATCHDOG_TIMEOUT_TOO_SMALL,
- force_code=reports.codes.FORCE,
- cluster_sbd_watchdog_timeout=10,
- entered_watchdog_timeout="invalid",
- )
- ],
- sbd_enabled=True,
+ def test_set_invalid_value_stonith_watchdog_timeout_sbd_enabled_with_devices(
+ self,
+ ):
+ self._set_invalid_value_stonith_watchdog_timeout(
+ sbd_enabled=True, sbd_devices=True
+ )
+
+ def test_set_invalid_value_stonith_watchdog_timeout_sbd_disabled(
+ self,
+ ):
+ self._set_invalid_value_stonith_watchdog_timeout(
+ sbd_enabled=False, sbd_devices=False
)
def test_unset_stonith_watchdog_timeout_sbd_enabled_without_devices(
self,
):
- for value in ["0", ""]:
+ for value in STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES:
with self.subTest(value=value):
self.assert_validate_set(
["stonith-watchdog-timeout"],
@@ -426,7 +470,7 @@ class TestValidateSetClusterProperties(TestCase):
def test_unset_stonith_watchdog_timeout_sbd_enabled_without_devices_forced(
self,
):
- for value in ["0", ""]:
+ for value in STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES:
with self.subTest(value=value):
self.assert_validate_set(
["stonith-watchdog-timeout"],
@@ -459,7 +503,7 @@ class TestValidateSetClusterProperties(TestCase):
def test_set_stonith_watchdog_timeout_sbd_enabled_with_devices_forced(self):
self.assert_validate_set(
[],
- {"stonith-watchdog-timeout": 15},
+ {"stonith-watchdog-timeout": "15s"},
[
fixture.warn(
reports.codes.STONITH_WATCHDOG_TIMEOUT_CANNOT_BE_SET,
@@ -472,7 +516,7 @@ class TestValidateSetClusterProperties(TestCase):
)
def test_unset_stonith_watchdog_timeout_sbd_enabled_with_devices(self):
- for value in ["0", ""]:
+ for value in STONITH_WATCHDOG_TIMEOUT_UNSET_VALUES:
with self.subTest(value=value):
self.assert_validate_set(
["stonith-watchdog-timeout"],
diff --git a/pcs_test/tier1/test_cluster_property.py b/pcs_test/tier1/test_cluster_property.py
index 39d70b9d..cb2d8f5c 100644
--- a/pcs_test/tier1/test_cluster_property.py
+++ b/pcs_test/tier1/test_cluster_property.py
@@ -169,7 +169,7 @@ class TestPropertySet(PropertyMixin, TestCase):
def test_set_stonith_watchdog_timeout(self):
self.assert_pcs_fail(
- "property set stonith-watchdog-timeout=5".split(),
+ "property set stonith-watchdog-timeout=5s".split(),
stderr_full=(
"Error: stonith-watchdog-timeout can only be unset or set to 0 "
"while SBD is disabled\n"
@@ -179,6 +179,18 @@ class TestPropertySet(PropertyMixin, TestCase):
)
self.assert_resources_xml_in_cib(UNCHANGED_CRM_CONFIG)
+ def test_set_stonith_watchdog_timeout_invalid_value(self):
+ self.assert_pcs_fail(
+ "property set stonith-watchdog-timeout=5x".split(),
+ stderr_full=(
+ "Error: '5x' is not a valid stonith-watchdog-timeout value, use"
+ " time interval (e.g. 1, 2s, 3m, 4h, ...)\n"
+ "Error: Errors have occurred, therefore pcs is unable to "
+ "continue\n"
+ ),
+ )
+ self.assert_resources_xml_in_cib(UNCHANGED_CRM_CONFIG)
+
class TestPropertyUnset(PropertyMixin, TestCase):
def test_success(self):
--
2.39.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,311 +0,0 @@
From 166fd04bb5505f29463088080044689f15635018 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Tue, 31 Jan 2023 17:44:16 +0100
Subject: [PATCH] fix update of stonith-watchdog-timeout when cluster is not
running
---
pcs/lib/communication/sbd.py | 4 +-
.../lib/commands/sbd/test_disable_sbd.py | 10 ++--
.../tier0/lib/commands/sbd/test_enable_sbd.py | 49 ++++++++++---------
pcsd/pcs.rb | 17 +++++--
4 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/pcs/lib/communication/sbd.py b/pcs/lib/communication/sbd.py
index f31bf16f..83d912b2 100644
--- a/pcs/lib/communication/sbd.py
+++ b/pcs/lib/communication/sbd.py
@@ -98,8 +98,8 @@ class StonithWatchdogTimeoutAction(
)
if report_item is None:
self._on_success()
- return []
- self._report(report_item)
+ else:
+ self._report(report_item)
return self._get_next_list()
diff --git a/pcs_test/tier0/lib/commands/sbd/test_disable_sbd.py b/pcs_test/tier0/lib/commands/sbd/test_disable_sbd.py
index 13135fb2..f8f165bf 100644
--- a/pcs_test/tier0/lib/commands/sbd/test_disable_sbd.py
+++ b/pcs_test/tier0/lib/commands/sbd/test_disable_sbd.py
@@ -19,7 +19,7 @@ class DisableSbd(TestCase):
self.config.corosync_conf.load(filename=self.corosync_conf_name)
self.config.http.host.check_auth(node_labels=self.node_list)
self.config.http.pcmk.set_stonith_watchdog_timeout_to_zero(
- node_labels=self.node_list[:1]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.disable_sbd(node_labels=self.node_list)
disable_sbd(self.env_assist.get_env())
@@ -56,7 +56,7 @@ class DisableSbd(TestCase):
self.config.corosync_conf.load(filename=self.corosync_conf_name)
self.config.http.host.check_auth(node_labels=self.node_list)
self.config.http.pcmk.set_stonith_watchdog_timeout_to_zero(
- node_labels=self.node_list[:1]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.disable_sbd(node_labels=self.node_list)
@@ -158,7 +158,9 @@ class DisableSbd(TestCase):
]
)
self.config.http.pcmk.set_stonith_watchdog_timeout_to_zero(
- node_labels=online_nodes_list[:1]
+ communication_list=[
+ [dict(label=node)] for node in self.node_list[1:]
+ ],
)
self.config.http.sbd.disable_sbd(node_labels=online_nodes_list)
disable_sbd(self.env_assist.get_env(), ignore_offline_nodes=True)
@@ -291,7 +293,7 @@ class DisableSbd(TestCase):
self.config.corosync_conf.load(filename=self.corosync_conf_name)
self.config.http.host.check_auth(node_labels=self.node_list)
self.config.http.pcmk.set_stonith_watchdog_timeout_to_zero(
- node_labels=self.node_list[:1]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.disable_sbd(
communication_list=[
diff --git a/pcs_test/tier0/lib/commands/sbd/test_enable_sbd.py b/pcs_test/tier0/lib/commands/sbd/test_enable_sbd.py
index be479a34..77863d5e 100644
--- a/pcs_test/tier0/lib/commands/sbd/test_enable_sbd.py
+++ b/pcs_test/tier0/lib/commands/sbd/test_enable_sbd.py
@@ -130,7 +130,7 @@ class OddNumOfNodesSuccess(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -164,7 +164,7 @@ class OddNumOfNodesSuccess(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -218,7 +218,7 @@ class OddNumOfNodesDefaultsSuccess(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -248,7 +248,7 @@ class OddNumOfNodesDefaultsSuccess(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -351,7 +351,7 @@ class WatchdogValidations(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -407,7 +407,7 @@ class EvenNumOfNodes(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -443,7 +443,7 @@ class EvenNumOfNodes(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -480,7 +480,7 @@ class EvenNumOfNodes(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -513,7 +513,7 @@ class EvenNumOfNodes(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
self.config.http.sbd.enable_sbd(node_labels=self.node_list)
enable_sbd(
@@ -604,7 +604,9 @@ class OfflineNodes(TestCase):
node_labels=self.online_node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.online_node_list[0]]
+ communication_list=[
+ [dict(label=node)] for node in self.online_node_list
+ ],
)
self.config.http.sbd.enable_sbd(node_labels=self.online_node_list)
enable_sbd(
@@ -644,7 +646,9 @@ class OfflineNodes(TestCase):
node_labels=self.online_node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.online_node_list[0]]
+ communication_list=[
+ [dict(label=node)] for node in self.online_node_list
+ ],
)
self.config.http.sbd.enable_sbd(node_labels=self.online_node_list)
enable_sbd(
@@ -1228,7 +1232,7 @@ class FailureHandling(TestCase):
node_labels=self.node_list,
)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
- node_labels=[self.node_list[0]]
+ communication_list=[[dict(label=node)] for node in self.node_list],
)
def _remove_calls(self, count):
@@ -1304,7 +1308,8 @@ class FailureHandling(TestCase):
)
def test_removing_stonith_wd_timeout_failure(self):
- self._remove_calls(2)
+ self._remove_calls(len(self.node_list) + 1)
+
self.config.http.pcmk.remove_stonith_watchdog_timeout(
communication_list=[
self.communication_list_failure[:1],
@@ -1333,7 +1338,7 @@ class FailureHandling(TestCase):
)
def test_removing_stonith_wd_timeout_not_connected(self):
- self._remove_calls(2)
+ self._remove_calls(len(self.node_list) + 1)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
communication_list=[
self.communication_list_not_connected[:1],
@@ -1362,7 +1367,7 @@ class FailureHandling(TestCase):
)
def test_removing_stonith_wd_timeout_complete_failure(self):
- self._remove_calls(2)
+ self._remove_calls(len(self.node_list) + 1)
self.config.http.pcmk.remove_stonith_watchdog_timeout(
communication_list=[
self.communication_list_not_connected[:1],
@@ -1408,7 +1413,7 @@ class FailureHandling(TestCase):
)
def test_set_sbd_config_failure(self):
- self._remove_calls(4)
+ self._remove_calls(len(self.node_list) + 1 + 2)
self.config.http.sbd.set_sbd_config(
communication_list=[
dict(
@@ -1455,7 +1460,7 @@ class FailureHandling(TestCase):
)
def test_set_corosync_conf_failed(self):
- self._remove_calls(5)
+ self._remove_calls(len(self.node_list) + 1 + 3)
self.config.env.push_corosync_conf(
corosync_conf_text=_get_corosync_conf_text_with_atb(
self.corosync_conf_name
@@ -1479,7 +1484,7 @@ class FailureHandling(TestCase):
)
def test_check_sbd_invalid_data_format(self):
- self._remove_calls(7)
+ self._remove_calls(len(self.node_list) + 1 + 5)
self.config.http.sbd.check_sbd(
communication_list=[
dict(
@@ -1518,7 +1523,7 @@ class FailureHandling(TestCase):
)
def test_check_sbd_failure(self):
- self._remove_calls(7)
+ self._remove_calls(len(self.node_list) + 1 + 5)
self.config.http.sbd.check_sbd(
communication_list=[
dict(
@@ -1560,7 +1565,7 @@ class FailureHandling(TestCase):
)
def test_check_sbd_not_connected(self):
- self._remove_calls(7)
+ self._remove_calls(len(self.node_list) + 1 + 5)
self.config.http.sbd.check_sbd(
communication_list=[
dict(
@@ -1603,7 +1608,7 @@ class FailureHandling(TestCase):
)
def test_get_online_targets_failed(self):
- self._remove_calls(9)
+ self._remove_calls(len(self.node_list) + 1 + 7)
self.config.http.host.check_auth(
communication_list=self.communication_list_failure
)
@@ -1628,7 +1633,7 @@ class FailureHandling(TestCase):
)
def test_get_online_targets_not_connected(self):
- self._remove_calls(9)
+ self._remove_calls(len(self.node_list) + 1 + 7)
self.config.http.host.check_auth(
communication_list=self.communication_list_not_connected
)
diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb
index 6d8669d1..d79c863b 100644
--- a/pcsd/pcs.rb
+++ b/pcsd/pcs.rb
@@ -1642,13 +1642,22 @@ end
def set_cluster_prop_force(auth_user, prop, val)
cmd = ['property', 'set', "#{prop}=#{val}"]
flags = ['--force']
+ sig_file = "#{CIB_PATH}.sig"
+ retcode = 0
+
if pacemaker_running?
- user = auth_user
+ _, _, retcode = run_cmd(auth_user, PCS, *flags, "--", *cmd)
else
- user = PCSAuth.getSuperuserAuth()
- flags += ['-f', CIB_PATH]
+ if File.exist?(CIB_PATH)
+ flags += ['-f', CIB_PATH]
+ _, _, retcode = run_cmd(PCSAuth.getSuperuserAuth(), PCS, *flags, "--", *cmd)
+ begin
+ File.delete(sig_file)
+ rescue => e
+ $logger.debug("Cannot delete file '#{sig_file}': #{e.message}")
+ end
+ end
end
- _, _, retcode = run_cmd(user, PCS, *flags, "--", *cmd)
return (retcode == 0)
end
--
2.39.0

View File

@ -1,67 +0,0 @@
From c51faf31a1abc08e26e5ccb4492c1a46f101a22a Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 13 Dec 2022 12:58:00 +0100
Subject: [PATCH] fix agents filter in resource/fence device create
---
.../cluster/fenceDevices/task/create/NameTypeTypeSelect.tsx | 4 ++--
.../view/cluster/resources/task/create/NameTypeTypeSelect.tsx | 4 ++--
src/app/view/share/form/Select.tsx | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/app/view/cluster/fenceDevices/task/create/NameTypeTypeSelect.tsx b/src/app/view/cluster/fenceDevices/task/create/NameTypeTypeSelect.tsx
index 80327801..8d623e2b 100644
--- a/src/app/view/cluster/fenceDevices/task/create/NameTypeTypeSelect.tsx
+++ b/src/app/view/cluster/fenceDevices/task/create/NameTypeTypeSelect.tsx
@@ -38,13 +38,13 @@ export const NameTypeTypeSelect = ({
return (
<Select
variant="typeahead"
- typeAheadAriaLabel="Select a fence device"
+ typeAheadAriaLabel="Select a fence device agent"
+ placeholderText="Select a fence device agent"
onSelect={onSelect}
onClear={onClear}
onFilter={onFilter}
selections={agentName}
isGrouped
- hasInlineFilter
customBadgeText={agentName.length > 0 ? agentName : undefined}
optionsValues={filteredFenceAgentList}
data-test="fence-device-agent"
diff --git a/src/app/view/cluster/resources/task/create/NameTypeTypeSelect.tsx b/src/app/view/cluster/resources/task/create/NameTypeTypeSelect.tsx
index bd7807d8..b531e825 100644
--- a/src/app/view/cluster/resources/task/create/NameTypeTypeSelect.tsx
+++ b/src/app/view/cluster/resources/task/create/NameTypeTypeSelect.tsx
@@ -52,13 +52,13 @@ export const NameTypeTypeSelect = ({
return (
<Select
variant="typeahead"
- typeAheadAriaLabel="Select a state"
+ typeAheadAriaLabel="Select a resource agent"
+ placeholderText="Select a resource agent"
onSelect={onSelect}
onClear={onClear}
onFilter={onFilter}
selections={agentName}
isGrouped
- hasInlineFilter
customBadgeText={agentName.length > 0 ? agentName : undefined}
data-test="resource-agent"
>
diff --git a/src/app/view/share/form/Select.tsx b/src/app/view/share/form/Select.tsx
index d73f126c..e2b81ce2 100644
--- a/src/app/view/share/form/Select.tsx
+++ b/src/app/view/share/form/Select.tsx
@@ -31,7 +31,7 @@ export const Select = (
const filter = onFilter
? (_event: React.ChangeEvent<HTMLInputElement> | null, value: string) => {
onFilter(value);
- return null as unknown as React.ReactElement[];
+ return undefined;
}
: null;
--
2.39.0

View File

@ -0,0 +1,302 @@
From 24a8e84e3f81fc846a8d60dc636c9d42fc7a0cd8 Mon Sep 17 00:00:00 2001
From: Miroslav Lisik <mlisik@redhat.com>
Date: Tue, 4 Jul 2023 21:43:38 +0200
Subject: [PATCH 2/3] fix displaying duplicate records in property commands
---
pcs/cli/cluster_property/output.py | 65 +++++++++----------
.../cli/cluster_property/test_command.py | 15 +++++
.../tier0/cli/cluster_property/test_output.py | 31 ++++++---
.../lib/commands/test_cluster_property.py | 28 ++++++++
4 files changed, 93 insertions(+), 46 deletions(-)
diff --git a/pcs/cli/cluster_property/output.py b/pcs/cli/cluster_property/output.py
index c538c5c1..c9c46d1c 100644
--- a/pcs/cli/cluster_property/output.py
+++ b/pcs/cli/cluster_property/output.py
@@ -31,21 +31,15 @@ class PropertyConfigurationFacade:
readonly_properties: StringCollection,
) -> None:
self._properties = properties
+ self._first_nvpair_set = (
+ self._properties[0].nvpairs if self._properties else []
+ )
self._properties_metadata = properties_metadata
self._readonly_properties = readonly_properties
- self._defaults_map = {
- metadata.name: metadata.default
- for metadata in self._properties_metadata
- if metadata.default is not None
+ self._defaults_map = self.get_defaults(include_advanced=True)
+ self._name_nvpair_dto_map = {
+ nvpair_dto.name: nvpair_dto for nvpair_dto in self._first_nvpair_set
}
- self._name_nvpair_dto_map = (
- {
- nvpair_dto.name: nvpair_dto
- for nvpair_dto in self._properties[0].nvpairs
- }
- if self._properties
- else {}
- )
@classmethod
def from_properties_dtos(
@@ -105,17 +99,6 @@ class PropertyConfigurationFacade:
return value
return self._defaults_map.get(property_name, custom_default)
- @staticmethod
- def _filter_names_advanced(
- metadata: ResourceAgentParameterDto,
- property_names: Optional[StringSequence] = None,
- include_advanced: bool = False,
- ) -> bool:
- return bool(
- (not property_names and (include_advanced or not metadata.advanced))
- or (property_names and metadata.name in property_names)
- )
-
def get_defaults(
self,
property_names: Optional[StringSequence] = None,
@@ -123,11 +106,10 @@ class PropertyConfigurationFacade:
) -> dict[str, str]:
return {
metadata.name: metadata.default
- for metadata in self._properties_metadata
- if metadata.default is not None
- and self._filter_names_advanced(
- metadata, property_names, include_advanced
+ for metadata in self.get_properties_metadata(
+ property_names, include_advanced
)
+ if metadata.default is not None
}
def get_properties_metadata(
@@ -135,23 +117,34 @@ class PropertyConfigurationFacade:
property_names: Optional[StringSequence] = None,
include_advanced: bool = False,
) -> Sequence[ResourceAgentParameterDto]:
- return [
- metadata
- for metadata in self._properties_metadata
- if self._filter_names_advanced(
- metadata, property_names, include_advanced
- )
- ]
+ if property_names:
+ filtered_metadata = [
+ metadata
+ for metadata in self._properties_metadata
+ if metadata.name in property_names
+ ]
+ else:
+ filtered_metadata = [
+ metadata
+ for metadata in self._properties_metadata
+ if include_advanced or not metadata.advanced
+ ]
+ deduplicated_metadata = {
+ metadata.name: metadata for metadata in filtered_metadata
+ }
+ return list(deduplicated_metadata.values())
def get_name_value_default_list(self) -> list[tuple[str, str, bool]]:
name_value_default_list = [
(nvpair_dto.name, nvpair_dto.value, False)
- for nvpair_dto in self._name_nvpair_dto_map.values()
+ for nvpair_dto in self._first_nvpair_set
]
name_value_default_list.extend(
[
(metadata_dto.name, metadata_dto.default, True)
- for metadata_dto in self._properties_metadata
+ for metadata_dto in self.get_properties_metadata(
+ include_advanced=True
+ )
if metadata_dto.name not in self._name_nvpair_dto_map
and metadata_dto.default is not None
]
diff --git a/pcs_test/tier0/cli/cluster_property/test_command.py b/pcs_test/tier0/cli/cluster_property/test_command.py
index b54d0e58..f8cc2afa 100644
--- a/pcs_test/tier0/cli/cluster_property/test_command.py
+++ b/pcs_test/tier0/cli/cluster_property/test_command.py
@@ -21,6 +21,21 @@ from pcs_test.tools.misc import dict_to_modifiers
FIXTURE_PROPERTY_METADATA = ClusterPropertyMetadataDto(
properties_metadata=[
+ ResourceAgentParameterDto(
+ name="property_name",
+ shortdesc="Duplicate property",
+ longdesc=None,
+ type="string",
+ default="duplicate_default",
+ enum_values=None,
+ required=False,
+ advanced=False,
+ deprecated=False,
+ deprecated_by=[],
+ deprecated_desc=None,
+ unique_group=None,
+ reloadable=False,
+ ),
ResourceAgentParameterDto(
name="property_name",
shortdesc=None,
diff --git a/pcs_test/tier0/cli/cluster_property/test_output.py b/pcs_test/tier0/cli/cluster_property/test_output.py
index 0ce8f6a8..59d33466 100644
--- a/pcs_test/tier0/cli/cluster_property/test_output.py
+++ b/pcs_test/tier0/cli/cluster_property/test_output.py
@@ -21,6 +21,7 @@ FIXTURE_TWO_PROPERTY_SETS = [
CibNvpairDto(id="", name="readonly2", value="ro_val2"),
CibNvpairDto(id="", name="property2", value="val2"),
CibNvpairDto(id="", name="property1", value="val1"),
+ CibNvpairDto(id="", name="property1", value="duplicate_val1"),
],
),
CibNvsetDto(
@@ -39,6 +40,7 @@ FIXTURE_READONLY_PROPERTIES_LIST = ["readonly1", "readonly2"]
FIXTURE_TEXT_OUTPUT_FIRST_SET = dedent(
"""\
Cluster Properties: id1 score=150
+ property1=duplicate_val1
property1=val1
property2=val2
readonly1=ro_val1
@@ -75,6 +77,7 @@ def fixture_property_metadata(
FIXTURE_PROPERTY_METADATA_LIST = [
+ fixture_property_metadata(name="property1", default="duplicate_default1"),
fixture_property_metadata(name="property1", default="default1"),
fixture_property_metadata(name="property2", default="default2"),
fixture_property_metadata(
@@ -136,7 +139,7 @@ class TestPropertyConfigurationFacadeGetPropertyValue(TestCase):
)
def test_property_value_from_first_set(self):
- self.assertEqual(self.facade.get_property_value("property1"), "val1")
+ self.assertEqual(self.facade.get_property_value("property2"), "val2")
def test_property_value_from_second_set(self):
self.assertEqual(self.facade.get_property_value("property3"), None)
@@ -152,6 +155,11 @@ class TestPropertyConfigurationFacadeGetPropertyValue(TestCase):
"custom",
)
+ def test_property_with_multiple_values(self):
+ self.assertEqual(
+ self.facade.get_property_value("property1"), "duplicate_val1"
+ )
+
class TestPropertyConfigurationFacadeGetPropertyValueOrDefault(TestCase):
def setUp(self):
@@ -163,7 +171,7 @@ class TestPropertyConfigurationFacadeGetPropertyValueOrDefault(TestCase):
def test_property_value_from_first_set(self):
self.assertEqual(
- self.facade.get_property_value_or_default("property1"), "val1"
+ self.facade.get_property_value_or_default("property2"), "val2"
)
def test_property_value_not_in_set(self):
@@ -239,21 +247,22 @@ class TestPropertyConfigurationFacadeGetPropertiesMetadata(TestCase):
)
def test_metadata_without_advanced(self):
- metadata = FIXTURE_PROPERTY_METADATA_LIST[0:2]
- self.assertEqual(self.facade.get_properties_metadata(), metadata)
+ metadata = FIXTURE_PROPERTY_METADATA_LIST[1:3]
+ self.assertCountEqual(self.facade.get_properties_metadata(), metadata)
def test_metadata_with_advanced(self):
- metadata = FIXTURE_PROPERTY_METADATA_LIST
- self.assertEqual(
- self.facade.get_properties_metadata(include_advanced=True), metadata
+ metadata = FIXTURE_PROPERTY_METADATA_LIST[1:]
+ self.assertCountEqual(
+ self.facade.get_properties_metadata(include_advanced=True),
+ metadata,
)
def test_metadata_specified(self):
metadata = (
- FIXTURE_PROPERTY_METADATA_LIST[0:1]
+ FIXTURE_PROPERTY_METADATA_LIST[1:2]
+ FIXTURE_PROPERTY_METADATA_LIST[-1:]
)
- self.assertEqual(
+ self.assertCountEqual(
self.facade.get_properties_metadata(
property_names=["property4", "property1"]
),
@@ -275,6 +284,7 @@ class TestPropertyConfigurationFacadeGetNameValueDefaultList(TestCase):
("readonly2", "ro_val2", False),
("property2", "val2", False),
("property1", "val1", False),
+ ("property1", "duplicate_val1", False),
("property3", "default3", True),
("property4", "default4", True),
]
@@ -503,7 +513,8 @@ class TestPropertiesToCmd(TestCase):
"""\
pcs property set --force -- \\
property2=val2 \\
- property1=val1
+ property1=val1 \\
+ property1=duplicate_val1
"""
)
self.assert_lines(facade, output)
diff --git a/pcs_test/tier0/lib/commands/test_cluster_property.py b/pcs_test/tier0/lib/commands/test_cluster_property.py
index c7cb7ae5..c02761a0 100644
--- a/pcs_test/tier0/lib/commands/test_cluster_property.py
+++ b/pcs_test/tier0/lib/commands/test_cluster_property.py
@@ -911,6 +911,10 @@ class TestGetProperties(TestCase):
)
self.env_assist.assert_reports([])
+ @mock.patch(
+ "pcs.lib.cib.rule.in_effect.has_rule_in_effect_status_tool",
+ lambda: True,
+ )
def test_evaluate_expired_but_no_set_rule(self):
self.config.runner.cib.load(
crm_config=fixture_crm_config_properties([("set_id", {})])
@@ -924,6 +928,30 @@ class TestGetProperties(TestCase):
),
)
+ @mock.patch(
+ "pcs.lib.cib.rule.in_effect.has_rule_in_effect_status_tool",
+ lambda: False,
+ )
+ def test_evaluate_expired_no_status_tool(self):
+ self.config.runner.cib.load(
+ crm_config=fixture_crm_config_properties([("set_id", {})])
+ )
+ self.assertEqual(
+ self.command(evaluate_expired=True),
+ ListCibNvsetDto(
+ nvsets=[
+ CibNvsetDto(id="set_id", options={}, rule=None, nvpairs=[])
+ ]
+ ),
+ )
+ self.env_assist.assert_reports(
+ [
+ fixture.warn(
+ reports.codes.RULE_IN_EFFECT_STATUS_DETECTION_NOT_SUPPORTED,
+ )
+ ]
+ )
+
class TestGetPropertiesMetadata(MetadataErrorMixin, TestCase):
_load_cib_when_metadata_error = False
--
2.41.0

View File

@ -0,0 +1,55 @@
From e47799cbdd588649872efd24d6bcfa78acb23ecb Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Tue, 11 Jul 2023 14:09:17 +0200
Subject: [PATCH 3/3] use a filter when extracting a config backup tarball
---
pcs/config.py | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/pcs/config.py b/pcs/config.py
index 56c49aae..d750f52f 100644
--- a/pcs/config.py
+++ b/pcs/config.py
@@ -488,14 +488,36 @@ def config_restore_local(infile_name, infile_obj):
if "rename" in extract_info and extract_info["rename"]:
if tmp_dir is None:
tmp_dir = tempfile.mkdtemp()
- tarball.extractall(tmp_dir, [tar_member_info])
+ if hasattr(tarfile, "data_filter"):
+ # Safe way of extraction is available since Python 3.12,
+ # hasattr above checks if it's available.
+ # It's also backported to 3.11.4, 3.10.12, 3.9.17.
+ # It may be backported to older versions in downstream.
+ tarball.extractall(
+ tmp_dir, [tar_member_info], filter="data"
+ )
+ else:
+ # Unsafe way of extraction
+ # Remove once we don't support Python 3.8 and older
+ tarball.extractall(tmp_dir, [tar_member_info])
path_full = extract_info["path"]
shutil.move(
os.path.join(tmp_dir, tar_member_info.name), path_full
)
else:
dir_path = os.path.dirname(extract_info["path"])
- tarball.extractall(dir_path, [tar_member_info])
+ if hasattr(tarfile, "data_filter"):
+ # Safe way of extraction is available since Python 3.12,
+ # hasattr above checks if it's available.
+ # It's also backported to 3.11.4, 3.10.12, 3.9.17.
+ # It may be backported to older versions in downstream.
+ tarball.extractall(
+ dir_path, [tar_member_info], filter="data"
+ )
+ else:
+ # Unsafe way of extracting
+ # Remove once we don't support Python 3.8 and older
+ tarball.extractall(dir_path, [tar_member_info])
path_full = os.path.join(dir_path, tar_member_info.name)
file_attrs = extract_info["attrs"]
os.chmod(path_full, file_attrs["mode"])
--
2.41.0

View File

@ -0,0 +1,53 @@
From 074e24f039a5bdfa81d17feb390dd342eda5ba73 Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Fri, 14 Jul 2023 14:44:20 +0200
Subject: [PATCH] fix assets url (relative -> absolute)
---
.bin/build.sh | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/.bin/build.sh b/.bin/build.sh
index 2113eaae..c7f0b4a0 100755
--- a/.bin/build.sh
+++ b/.bin/build.sh
@@ -74,10 +74,15 @@ inject_built_assets() {
}
fix_asset_paths() {
- # All assets in index.html uses absolute path. This function makes them
- # relative. The index.html is also used by development server which needs
- # absolute paths. There is no copy/edit phase in development server, so it is
- # done here.
+ # All assets in index.html uses absolute path. The index.html is also used by
+ # development server which needs absolute paths. There is no copy/edit phase
+ # in development server, so it is done here.
+ # Here is the absolute path prefixed according to pcsd url namespace for
+ # webui.
+ # WARNING: Don't use relative path. It works well in dashboard but in the
+ # cluster detail the resulting url contains word "cluster" inside, so instead
+ # of "/ui/static/..." we get "/ui/cluster/static" and asset loading fails.
+ # see: https://bugzilla.redhat.com/show_bug.cgi?id=2222788
html=$1
path_prefix=$2
js_path="$3/"
@@ -130,6 +135,7 @@ adapt_for_environment() {
}
use_current_node_modules=${BUILD_USE_CURRENT_NODE_MODULES:-"false"}
+url_prefix=${PCSD_BUILD_URL_PREFIX:-"/ui"}
node_modules=$(get_path "appNodeModules")
node_modules_backup="${node_modules}.build-backup"
export BUILD_DIR="${BUILD_DIR:-$(realpath "$(dirname "$0")"/../build)}"
@@ -155,7 +161,7 @@ adapt_for_environment \
static/js/adapterCockpit.js \
"${PCSD_UINIX_SOCKET:-"/var/run/pcsd.socket"}"
-fix_asset_paths "$BUILD_DIR"/index.html "." \
+fix_asset_paths "$BUILD_DIR"/index.html "$url_prefix" \
static/js \
static/css \
manifest.json \
--
2.41.0

View File

@ -1,4 +1,4 @@
From c7b8c999f796cee4899df578944b239e1db29cb5 Mon Sep 17 00:00:00 2001
From 948eb79f2f4057ac8143242b29e8c164ee4516ed Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 20 Nov 2018 15:03:56 +0100
Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL9
@ -9,10 +9,10 @@ Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL9
2 files changed, 3 insertions(+)
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
index 7bbd1ae2..53bfebb4 100644
index 2baf0009..9b2f7388 100644
--- a/pcs/pcs.8.in
+++ b/pcs/pcs.8.in
@@ -457,6 +457,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
@@ -479,6 +479,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
Transports udp and udpu:
.br
@ -22,10 +22,10 @@ index 7bbd1ae2..53bfebb4 100644
.br
Transport options are: ip_version, netmtu
diff --git a/pcs/usage.py b/pcs/usage.py
index 073e2b1e..91ceb787 100644
index df149e5b..c915b513 100644
--- a/pcs/usage.py
+++ b/pcs/usage.py
@@ -1431,6 +1431,7 @@ Commands:
@@ -1486,6 +1486,7 @@ Commands:
hash=sha256. To disable encryption, set cipher=none and hash=none.
Transports udp and udpu:
@ -34,5 +34,5 @@ index 073e2b1e..91ceb787 100644
support traffic encryption nor compression.
Transport options are:
--
2.38.1
2.41.0

View File

@ -1,53 +1,51 @@
Name: pcs
Version: 0.11.4
Release: 6%{?dist}
Version: 0.11.6
Release: 3%{?dist}
# https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
# https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses
# GPL-2.0-only: pcs
# Apache-2.0: tornado
# MIT: backports, childprocess, dacite, daemons, ethon, mustermann, rack,
# MIT: backports, childprocess, dacite, ethon, mustermann, rack,
# rack-protection, rack-test, sinatra, tilt
# GPL-2.0-only or Ruby: eventmachine
# (GPL-2.0-only or Ruby) and BSD-2-Clause: thin
# BSD-2-Clause or Ruby: ruby2_keywords, webrick
# MIT and (BSD-2-Clause or GPL-2.0-or-later): nio4r
# BSD-2-Clause or Ruby: ruby2_keywords
# BSD-3-Clause: puma
# BSD-3-Clause and MIT: ffi
License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (GPL-2.0-only OR Ruby) AND BSD-2-Clause AND (BSD-2-Clause OR Ruby)
License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later)
URL: https://github.com/ClusterLabs/pcs
Group: System Environment/Base
Summary: Pacemaker Configuration System
Summary: Pacemaker/Corosync Configuration System
#building only for architectures with pacemaker and corosync available
ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
# When specifying a commit, use its long hash
%global version_or_commit %{version}
# %%global version_or_commit %%{version}.206-f51f
# %%global version_or_commit 3e479bdb68dc900523a743e7dcb759b501385555
%global pcs_source_name %{name}-%{version_or_commit}
# ui_commit can be determined by hash, tag or branch
%global ui_commit 0.1.16
%global ui_modules_version 0.1.16
%global ui_commit 0.1.17
%global ui_modules_version 0.1.17
%global ui_src_name pcs-web-ui-%{ui_commit}
%global pcs_snmp_pkg_name pcs-snmp
%global pyagentx_version 0.4.pcs.2
%global tornado_version 6.2.0
%global dacite_version 1.6.0
%global version_rubygem_backports 3.23.0
%global tornado_version 6.3.2
%global dacite_version 1.8.1
%global version_rubygem_backports 3.24.1
%global version_rubygem_childprocess 4.1.0
%global version_rubygem_daemons 1.4.1
%global version_rubygem_ethon 0.16.0
%global version_rubygem_eventmachine 1.2.7
%global version_rubygem_ffi 1.15.5
%global version_rubygem_mustermann 3.0.0
%global version_rubygem_rack 2.2.5
%global version_rubygem_rack_protection 3.0.5
%global version_rubygem_rack_test 2.0.2
%global version_rubygem_nio4r 2.5.9
%global version_rubygem_puma 6.3.0
%global version_rubygem_rack 2.2.7
%global version_rubygem_rack_protection 3.0.6
%global version_rubygem_rack_test 2.1.0
%global version_rubygem_ruby2_keywords 0.0.5
%global version_rubygem_sinatra 3.0.5
%global version_rubygem_thin 1.8.1
%global version_rubygem_tilt 2.0.11
%global version_rubygem_webrick 1.7.0
%global version_rubygem_sinatra 3.0.6
%global version_rubygem_tilt 2.2.0
%global required_pacemaker_version 2.1.0
@ -71,7 +69,13 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
# /usr/bin/python will be removed or switched to Python 3 in the future.
%global __python %{__python3}
Source0: %{url}/archive/%{version_or_commit}/%{pcs_source_name}.tar.gz
# prepend v for folder in GitHub link when using tagged tarball
%if "%{version}" == "%{version_or_commit}"
%global v_prefix v
%endif
# part after the last slash is recognized as filename in look-aside cache
Source0: %{url}/archive/%{?v_prefix}%{version_or_commit}/%{pcs_source_name}.tar.gz
Source41: https://github.com/ondrejmular/pyagentx/archive/v%{pyagentx_version}/pyagentx-%{pyagentx_version}.tar.gz
Source42: https://github.com/tornadoweb/tornado/archive/v%{tornado_version}/tornado-%{tornado_version}.tar.gz
@ -80,6 +84,8 @@ Source44: https://github.com/konradhalas/dacite/archive/v%{dacite_version}/dacit
Source81: https://rubygems.org/downloads/backports-%{version_rubygem_backports}.gem
Source82: https://rubygems.org/downloads/ethon-%{version_rubygem_ethon}.gem
Source83: https://rubygems.org/downloads/ffi-%{version_rubygem_ffi}.gem
Source84: https://rubygems.org/downloads/nio4r-%{version_rubygem_nio4r}.gem
Source85: https://rubygems.org/downloads/puma-%{version_rubygem_puma}.gem
Source86: https://rubygems.org/downloads/mustermann-%{version_rubygem_mustermann}.gem
Source87: https://rubygems.org/downloads/childprocess-%{version_rubygem_childprocess}.gem
Source88: https://rubygems.org/downloads/rack-%{version_rubygem_rack}.gem
@ -87,41 +93,25 @@ Source89: https://rubygems.org/downloads/rack-protection-%{version_rubygem_rack_
Source90: https://rubygems.org/downloads/rack-test-%{version_rubygem_rack_test}.gem
Source91: https://rubygems.org/downloads/sinatra-%{version_rubygem_sinatra}.gem
Source92: https://rubygems.org/downloads/tilt-%{version_rubygem_tilt}.gem
Source93: https://rubygems.org/downloads/eventmachine-%{version_rubygem_eventmachine}.gem
Source94: https://rubygems.org/downloads/daemons-%{version_rubygem_daemons}.gem
Source95: https://rubygems.org/downloads/thin-%{version_rubygem_thin}.gem
Source96: https://rubygems.org/downloads/ruby2_keywords-%{version_rubygem_ruby2_keywords}.gem
Source97: https://rubygems.org/downloads/webrick-%{version_rubygem_webrick}.gem
Source93: https://rubygems.org/downloads/ruby2_keywords-%{version_rubygem_ruby2_keywords}.gem
Source100: https://github.com/ClusterLabs/pcs-web-ui/archive/%{ui_commit}/%{ui_src_name}.tar.gz
Source101: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_commit}/pcs-web-ui-node-modules-%{ui_modules_version}.tar.xz
# Patches from upstream.
# They should come before downstream patches to avoid unnecessary conflicts.
# Z-streams are exception here: they can come from upstream but should be
# applied at the end to keep z-stream changes as straightforward as possible.
# Patch1: bzNUMBER-01-name.patch
# Downstream patches do not come from upstream. They adapt pcs for specific
# RHEL needs.
# pcs patches: <= 200
Patch1: do-not-support-cluster-setup-with-udp-u-transport.patch
Patch2: bz2148124-01-pcsd-systemd-killmode.patch
Patch3: 01-smoke-test-fix.patch
Patch4: 02-smoke-test-fix.patch
Patch5: bz2151524-01-add-warning-when-updating-a-misconfigured-resource.patch
Patch6: bz2151164-01-fix-displaying-bool-and-integer-values.patch
Patch7: bz2159454-01-add-agent-validation-option.patch
Patch8: bz2158790-01-fix-stonith-watchdog-timeout-validation.patch
Patch9: bz2166249-01-fix-stonith-watchdog-timeout-offline-update.patch
# Patch0: bzNUMBER-01-name.patch
Patch0: do-not-support-cluster-setup-with-udp-u-transport.patch
Patch1: bz2163953-01-constraint-fixes.patch
Patch2: bz2217850-01-fix-exporting-location-constraints-with-rules.patch
Patch3: bz2219407-01-use-a-filter-when-extracting-a-config-backup-tarball.patch
# ui patches: >200
Patch201: bz2167471-01-fix-broken-typeahead-component.patch
# Patch201: bzNUMBER-01-name.patch
Patch201: bz2222788-01-fix-assets-url-relative-absolute.patch
# git for patches
BuildRequires: git-core
#printf from coreutils is used in makefile
# printf from coreutils is used in makefile, head is used in spec
BuildRequires: coreutils
# python for pcs
BuildRequires: python3 >= 3.9
@ -170,6 +160,10 @@ BuildRequires: fence-agents-common
BuildRequires: pacemaker-libs-devel >= %{required_pacemaker_version}
BuildRequires: resource-agents
BuildRequires: sbd
# for working with qdevice certificates (certutil) - used in configure.ac
BuildRequires: nss-tools
# for generating MiniDebugInfo with find-debuginfo
BuildRequires: debugedit
# python and libraries for pcs, setuptools for pcs entrypoint
Requires: python3 >= 3.9
@ -205,24 +199,24 @@ Requires: pam
Requires: redhat-logos
# needs logrotate for /etc/logrotate.d/pcsd
Requires: logrotate
# for working with qdevice certificates (certutil)
Requires: nss-tools
Provides: bundled(tornado) = %{tornado_version}
Provides: bundled(dacite) = %{dacite_version}
Provides: bundled(backports) = %{version_rubygem_backports}
Provides: bundled(daemons) = %{version_rubygem_daemons}
Provides: bundled(childprocess) = %{version_rubygem_childprocess}
Provides: bundled(ethon) = %{version_rubygem_ethon}
Provides: bundled(eventmachine) = %{version_rubygem_eventmachine}
Provides: bundled(ffi) = %{version_rubygem_ffi}
Provides: bundled(mustermann) = %{version_rubygem_mustermann}
Provides: bundled(childprocess) = %{version_rubygem_childprocess}
Provides: bundled(nio4r) = %{version_rubygem_nio4r}
Provides: bundled(puma) = %{version_rubygem_puma}
Provides: bundled(rack) = %{version_rubygem_rack}
Provides: bundled(rack_protection) = %{version_rubygem_rack_protection}
Provides: bundled(rack_test) = %{version_rubygem_rack_test}
Provides: bundled(ruby2_keywords) = %{version_rubygem_ruby2_keywords}
Provides: bundled(sinatra) = %{version_rubygem_sinatra}
Provides: bundled(thin) = %{version_rubygem_thin}
Provides: bundled(tilt) = %{version_rubygem_tilt}
Provides: bundled(webrick) = %{version_rubygem_webrick}
%description
pcs is a corosync and pacemaker configuration tool. It permits users to
@ -238,7 +232,7 @@ Summary: Pacemaker cluster SNMP agent
License: GPL-2.0-only and BSD-2-Clause
URL: https://github.com/ClusterLabs/pcs
# tar for unpacking pyagetx source tar ball
# tar for unpacking pyagentx source tarball
BuildRequires: tar
Requires: pcs = %{version}-%{release}
@ -296,20 +290,23 @@ update_times_patch(){
# patch web-ui sources
%autosetup -D -T -b 100 -a 101 -S git -n %{ui_src_name} -N
%autopatch -p1 -m 201
# update_times_patch %%{PATCH201}
update_times_patch %{PATCH201}
# patch pcs sources
%autosetup -S git -n %{pcs_source_name} -N
%autopatch -p1 -M 200
# update_times_patch %%{PATCH0}
update_times_patch %{PATCH0}
update_times_patch %{PATCH1}
update_times_patch %{PATCH2}
update_times_patch %{PATCH3}
update_times_patch %{PATCH4}
update_times_patch %{PATCH5}
update_times_patch %{PATCH6}
update_times_patch %{PATCH7}
update_times_patch %{PATCH8}
update_times_patch %{PATCH9}
# generate .tarball-version if building from an untagged commit, not a released version
# autogen uses git-version-gen which uses .tarball-version for generating version number
%if "%{version}" != "%{version_or_commit}"
echo "%version+$(echo "%{version_or_commit}" | head -c 8)" > %{_builddir}/%{pcs_source_name}/.tarball-version
%endif
# prepare dirs/files necessary for building all bundles
# -----------------------------------------------------
@ -319,6 +316,8 @@ mkdir -p %{rubygem_cache_dir}
cp -f %SOURCE81 %{rubygem_cache_dir}
cp -f %SOURCE82 %{rubygem_cache_dir}
cp -f %SOURCE83 %{rubygem_cache_dir}
cp -f %SOURCE84 %{rubygem_cache_dir}
cp -f %SOURCE85 %{rubygem_cache_dir}
cp -f %SOURCE86 %{rubygem_cache_dir}
cp -f %SOURCE87 %{rubygem_cache_dir}
cp -f %SOURCE88 %{rubygem_cache_dir}
@ -327,10 +326,6 @@ cp -f %SOURCE90 %{rubygem_cache_dir}
cp -f %SOURCE91 %{rubygem_cache_dir}
cp -f %SOURCE92 %{rubygem_cache_dir}
cp -f %SOURCE93 %{rubygem_cache_dir}
cp -f %SOURCE94 %{rubygem_cache_dir}
cp -f %SOURCE95 %{rubygem_cache_dir}
cp -f %SOURCE96 %{rubygem_cache_dir}
cp -f %SOURCE97 %{rubygem_cache_dir}
# 2) prepare python bundles
@ -347,7 +342,7 @@ cp -f %SOURCE44 rpm/
make all
# build pcs-web-ui
make -C %{_builddir}/%{ui_src_name} build BUILD_USE_EXISTING_NODE_MODULES=true
BUILD_USE_CURRENT_NODE_MODULES=true make -C %{_builddir}/%{ui_src_name} build
%install
rm -rf $RPM_BUILD_ROOT
@ -359,28 +354,27 @@ pwd
cp -r %{_builddir}/%{ui_src_name}/build ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui
# symlink favicon into pcsd directories
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/images/
ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/images/favicon.png
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media
ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media/favicon.png
# prepare license files
# some rubygems do not have a license file (thin)
mv %{rubygem_bundle_dir}/gems/backports-%{version_rubygem_backports}/LICENSE.txt backports_LICENSE.txt
mv %{rubygem_bundle_dir}/gems/daemons-%{version_rubygem_daemons}/LICENSE daemons_LICENSE
mv %{rubygem_bundle_dir}/gems/childprocess-%{version_rubygem_childprocess}/LICENSE childprocess_LICENSE
mv %{rubygem_bundle_dir}/gems/ethon-%{version_rubygem_ethon}/LICENSE ethon_LICENSE
mv %{rubygem_bundle_dir}/gems/eventmachine-%{version_rubygem_eventmachine}/LICENSE eventmachine_LICENSE
mv %{rubygem_bundle_dir}/gems/eventmachine-%{version_rubygem_eventmachine}/GNU eventmachine_GNU
mv %{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/COPYING ffi_COPYING
mv %{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/LICENSE ffi_LICENSE
mv %{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/LICENSE.SPECS ffi_LICENSE.SPECS
mv %{rubygem_bundle_dir}/gems/mustermann-%{version_rubygem_mustermann}/LICENSE mustermann_LICENSE
mv %{rubygem_bundle_dir}/gems/childprocess-%{version_rubygem_childprocess}/LICENSE childprocess_LICENSE
mv %{rubygem_bundle_dir}/gems/nio4r-%{version_rubygem_nio4r}/license.md nio4r_license.md
mv %{rubygem_bundle_dir}/gems/nio4r-%{version_rubygem_nio4r}/ext/libev/LICENSE nio4r_libev_LICENSE
mv %{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/LICENSE puma_LICENSE
mv %{rubygem_bundle_dir}/gems/rack-%{version_rubygem_rack}/MIT-LICENSE rack_MIT-LICENSE
mv %{rubygem_bundle_dir}/gems/rack-protection-%{version_rubygem_rack_protection}/License rack-protection_License
mv %{rubygem_bundle_dir}/gems/rack-test-%{version_rubygem_rack_test}/MIT-LICENSE.txt rack-test_MIT-LICENSE.txt
mv %{rubygem_bundle_dir}/gems/ruby2_keywords-%{version_rubygem_ruby2_keywords}/LICENSE ruby2_keywords_LICENSE
mv %{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/LICENSE sinatra_LICENSE
mv %{rubygem_bundle_dir}/gems/tilt-%{version_rubygem_tilt}/COPYING tilt_COPYING
mv %{rubygem_bundle_dir}/gems/webrick-%{version_rubygem_webrick}/LICENSE.txt webrick_LICENSE.txt
cp %{pcs_bundled_dir}/src/pyagentx-*/LICENSE.txt pyagentx_LICENSE.txt
cp %{pcs_bundled_dir}/src/pyagentx-*/CONTRIBUTORS.txt pyagentx_CONTRIBUTORS.txt
@ -395,19 +389,19 @@ cp %{pcs_bundled_dir}/src/dacite-*/README.md dacite_README.md
# We are not building debug package for pcs but we need to add MiniDebuginfo
# to the bundled shared libraries from rubygem extensions in order to satisfy
# rpmdiff's binary stripping checker.
# Therefore we call find-debuginfo.sh script manually in order to strip
# Therefore we call find-debuginfo from debugedit manually in order to strip
# binaries and add MiniDebugInfo with .gnu_debugdata section
/usr/lib/rpm/find-debuginfo.sh -j2 -m -i -S debugsourcefiles.list
# find-debuginfo.sh generated some files into /usr/lib/debug and
find-debuginfo -j2 -m -i -S debugsourcefiles.list
# find-debuginfo generated some files into /usr/lib/debug and
# /usr/src/debug/ that we don't want in the package
rm -rf $RPM_BUILD_ROOT%{_libdir}/debug
rm -rf $RPM_BUILD_ROOT/usr/lib/debug
rm -rf $RPM_BUILD_ROOT%{_prefix}/src/debug
# We can remove files required for gem compilation
rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/eventmachine-%{version_rubygem_eventmachine}/ext
rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/ext
rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/thin-%{version_rubygem_thin}/ext
rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/nio4r-%{version_rubygem_nio4r}/ext
rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/ext
%check
# In the building environment LC_CTYPE is set to C which causes tests to fail
@ -489,21 +483,20 @@ run_all_tests
# rubygem licenses
%license backports_LICENSE.txt
%license childprocess_LICENSE
%license daemons_LICENSE
%license ethon_LICENSE
%license eventmachine_LICENSE
%license eventmachine_GNU
%license ffi_COPYING
%license ffi_LICENSE
%license ffi_LICENSE.SPECS
%license mustermann_LICENSE
%license nio4r_license.md
%license nio4r_libev_LICENSE
%license puma_LICENSE
%license rack_MIT-LICENSE
%license rack-protection_License
%license rack-test_MIT-LICENSE.txt
%license ruby2_keywords_LICENSE
%license sinatra_LICENSE
%license tilt_COPYING
%license webrick_LICENSE.txt
%{python3_sitelib}/*
%{_sbindir}/pcs
%{_sbindir}/pcsd
@ -544,6 +537,45 @@ run_all_tests
%license pyagentx_LICENSE.txt
%changelog
* Fri Jul 14 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.6-3
- Refreshing any page in pcs-web-ui no longer causes it to display a blank page
- Resolves: rhbz#2222788
* Mon Jul 10 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.6-2
- Added BuildRequires: debugedit - for generating MiniDebugInfo - triggered by removing find-debuginfo.sh from rpm
- Make use of filters when extracting tarballs to enhance security if provided by Python (pcs config restore command)
- Exporting constraints with rules in form of pcs commands now escapes # and fixes spaces in dates to make the commands valid
- Constraints containing options unsupported by pcs are not exported and a warning is printed instead
- Using spaces in dates in location constraint rules is deprecated
- Resolves: rhbz#2163953 rhbz#2216434 rhbz#2217850 rhbz#2219407
* Tue Jun 20 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.6-1
- Rebased to the latest upstream sources (see CHANGELOG.md)
- Updated bundled rubygems: puma, tilt
- Resolves: rhbz#1465829 rhbz#2163440 rhbz#2168155
* Wed May 31 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.5-2
- Fixed a regression causing crash in `pcs resource move` command (broken since pcs-0.11.5)
- Resolves: rhbz#2210855
* Mon May 22 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.5-1
- Rebased to the latest upstream sources (see CHANGELOG.md)
- Updated pcs-web-ui
- Updated bundled dependencies: tornado, dacite
- Added bundled rubygems: nio4r, puma
- Removed bundled rubygems: daemons, eventmachine, thin, webrick
- Updated bundled rubygems: backports, rack, rack-protection, rack-test, sinatra, tilt
- Added dependency nss-tools - for working with qdevice certificates
- Resolves: rhbz#1423473 rhbz#1860626 rhbz#2160664 rhbz#2163440 rhbz#2163914 rhbz#2163953 rhbz#2168155 rhbz#2168617 rhbz#2174735 rhbz#2174829 rhbz#2175881 rhbz#2177996 rhbz#2178701 rhbz#2178714 rhbz#2179902 rhbz#2180379 rhbz#2182810
* Tue Mar 28 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.4-7
- Fix displaying differences between configuration checkpoints in “pcs config checkpoint diff” command
- Fix “pcs stonith update-scsi-devices” command which was broken since Pacemaker-2.1.5-rc1
- Fixed loading of cluster status in the web interface when fencing levels are configured
- Fixed a vulnerability in pcs-web-ui-node-modules
- Updated bundled rubygem rack
- Resolves: rhbz#2179901 rhbz#2180697 rhbz#2180704 rhbz#2180708 rhbz#2180978 rhbz#2183180
* Mon Feb 13 2023 Michal Pospisil <mpospisi@redhat.com> - 0.11.4-6
- Fixed broken filtering in create resource/fence device wizards in the web interface
- Added BuildRequires: pam - needed for tier0 tests during build