parent
0efe61c521
commit
ae378fe2ae
@ -1,21 +1,21 @@
|
||||
SOURCES/backports-3.23.0.gem
|
||||
SOURCES/childprocess-4.1.0.gem
|
||||
SOURCES/dacite-1.6.0.tar.gz
|
||||
SOURCES/daemons-1.4.1.gem
|
||||
SOURCES/ethon-0.15.0.gem
|
||||
SOURCES/ethon-0.16.0.gem
|
||||
SOURCES/eventmachine-1.2.7.gem
|
||||
SOURCES/ffi-1.15.5.gem
|
||||
SOURCES/mustermann-2.0.2.gem
|
||||
SOURCES/open4-1.3.4-1.gem
|
||||
SOURCES/pcs-0.11.3.tar.gz
|
||||
SOURCES/pcs-web-ui-0.1.14.1.tar.gz
|
||||
SOURCES/pcs-web-ui-node-modules-0.1.14.1.tar.xz
|
||||
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/pyagentx-0.4.pcs.2.tar.gz
|
||||
SOURCES/rack-2.2.6.2.gem
|
||||
SOURCES/rack-protection-2.2.4.gem
|
||||
SOURCES/rack-test-1.1.0.gem
|
||||
SOURCES/rack-2.2.5.gem
|
||||
SOURCES/rack-protection-3.0.5.gem
|
||||
SOURCES/rack-test-2.0.2.gem
|
||||
SOURCES/ruby2_keywords-0.0.5.gem
|
||||
SOURCES/sinatra-2.2.4.gem
|
||||
SOURCES/sinatra-3.0.5.gem
|
||||
SOURCES/thin-1.8.1.gem
|
||||
SOURCES/tilt-2.0.11.gem
|
||||
SOURCES/tornado-6.1.0.tar.gz
|
||||
SOURCES/tornado-6.2.0.tar.gz
|
||||
SOURCES/webrick-1.7.0.gem
|
||||
|
@ -1,21 +1,21 @@
|
||||
0e11246385a9e0a4bc122b74fb74fe536a234f81 SOURCES/backports-3.23.0.gem
|
||||
81639c8886342e01d189c10a6beab6ad0526dc4e SOURCES/childprocess-4.1.0.gem
|
||||
31546c37fbdc6270d5097687619e9c0db6f1c05c SOURCES/dacite-1.6.0.tar.gz
|
||||
4795a8962cc1608bfec0d91fa4d438c7cfe90c62 SOURCES/daemons-1.4.1.gem
|
||||
29697a34b8cd9df4a77c650e2a38d0a36cdeee8b SOURCES/ethon-0.15.0.gem
|
||||
5b56a68268708c474bef04550639ded3add5e946 SOURCES/ethon-0.16.0.gem
|
||||
7a5b2896e210fac9759c786ee4510f265f75b481 SOURCES/eventmachine-1.2.7.gem
|
||||
97632b7975067266c0b39596de0a4c86d9330658 SOURCES/ffi-1.15.5.gem
|
||||
f5f804366823c1126791dfefd98dd0539563785c SOURCES/mustermann-2.0.2.gem
|
||||
41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
|
||||
c16c4623928ba85b0b94b8cbdec6396be85d3672 SOURCES/pcs-0.11.3.tar.gz
|
||||
8230681464db03850ce69ba54bcb8ecad67e409d SOURCES/pcs-web-ui-0.1.14.1.tar.gz
|
||||
5594665cf6dd3c8cfff579f91f7ef82ae5a338bd SOURCES/pcs-web-ui-node-modules-0.1.14.1.tar.xz
|
||||
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
|
||||
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||
872e3dadb596908640d003c55073590dd78f77c5 SOURCES/rack-2.2.6.2.gem
|
||||
5347315a7283f0b04443e924ed4eaa17807432c8 SOURCES/rack-protection-2.2.4.gem
|
||||
b80bc5ca38a885e747271675ba91dd3d02136bf1 SOURCES/rack-test-1.1.0.gem
|
||||
3ad7b27b68d5dd893ce91f216bb2685ae6c9846a SOURCES/rack-2.2.5.gem
|
||||
b311f9d60fc3ac0e20078a5aca7c51efa404727c SOURCES/rack-protection-3.0.5.gem
|
||||
3c669527ecbcb9f915a83983ec89320c356e1fe3 SOURCES/rack-test-2.0.2.gem
|
||||
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
|
||||
fa6a6c98f885e93f54c23dd0454cae906e82c31b SOURCES/sinatra-2.2.4.gem
|
||||
2a2fb3c121c6e5adc6f29d7e06cef66cdda303f1 SOURCES/sinatra-3.0.5.gem
|
||||
1ac6292a98e17247b7bb847a35ff868605256f7b SOURCES/thin-1.8.1.gem
|
||||
360d77c80d2851a538fb13d43751093115c34712 SOURCES/tilt-2.0.11.gem
|
||||
c23c617c7a0205e465bebad5b8cdf289ae8402a2 SOURCES/tornado-6.1.0.tar.gz
|
||||
9e809453db3a3347b7c0e7837a189833247e0828 SOURCES/tornado-6.2.0.tar.gz
|
||||
10ba51035928541b7713415f1f2e3a41114972fc SOURCES/webrick-1.7.0.gem
|
||||
|
@ -0,0 +1,215 @@
|
||||
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
|
||||
|
@ -0,0 +1,30 @@
|
||||
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
|
||||
|
@ -1,46 +0,0 @@
|
||||
From f863c38497eb716141c9e585ddb418191e9fc2a4 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Jelinek <tojeline@redhat.com>
|
||||
Date: Fri, 15 Jul 2022 15:55:57 +0200
|
||||
Subject: [PATCH 3/3] booth sync: check whether /etc/booth exists
|
||||
|
||||
---
|
||||
pcsd/pcsd_file.rb | 6 +-----
|
||||
pcsd/remote.rb | 4 ++++
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/pcsd/pcsd_file.rb b/pcsd/pcsd_file.rb
|
||||
index d82b55d2..394db59a 100644
|
||||
--- a/pcsd/pcsd_file.rb
|
||||
+++ b/pcsd/pcsd_file.rb
|
||||
@@ -112,12 +112,8 @@ module PcsdFile
|
||||
end
|
||||
end
|
||||
|
||||
- def dir()
|
||||
- return BOOTH_CONFIG_DIR
|
||||
- end
|
||||
-
|
||||
def full_file_name()
|
||||
- @full_file_name ||= File.join(self.dir, @file[:name])
|
||||
+ @full_file_name ||= File.join(BOOTH_CONFIG_DIR, @file[:name])
|
||||
end
|
||||
end
|
||||
|
||||
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
||||
index 854674eb..144d25f3 100644
|
||||
--- a/pcsd/remote.rb
|
||||
+++ b/pcsd/remote.rb
|
||||
@@ -2090,6 +2090,10 @@ def booth_set_config(params, request, auth_user)
|
||||
check_permissions(auth_user, Permissions::WRITE)
|
||||
data = check_request_data_for_json(params, auth_user)
|
||||
|
||||
+ if not File.directory?(BOOTH_CONFIG_DIR)
|
||||
+ raise "Configuration directory for booth '/etc/booth' is missing. Is booth installed?"
|
||||
+ end
|
||||
+
|
||||
PcsdExchangeFormat::validate_item_map_is_Hash('files', data)
|
||||
PcsdExchangeFormat::validate_item_is_Hash('file', :config, data[:config])
|
||||
if data[:authfile]
|
||||
--
|
||||
2.35.3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,126 +0,0 @@
|
||||
From de4845ea2d22c7dd9f4539360b44a900b1cea193 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Jelinek <tojeline@redhat.com>
|
||||
Date: Thu, 14 Jul 2022 16:46:33 +0200
|
||||
Subject: [PATCH 2/3] make booth ticket mode value case insensitive
|
||||
|
||||
---
|
||||
pcs/lib/booth/config_validators.py | 10 ++++++++
|
||||
pcs/lib/commands/booth.py | 14 +++++++++---
|
||||
pcs_test/tier0/lib/commands/test_booth.py | 28 ++++++++++++++++-------
|
||||
3 files changed, 41 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/pcs/lib/booth/config_validators.py b/pcs/lib/booth/config_validators.py
|
||||
index 99badc46..6c4a4ddc 100644
|
||||
--- a/pcs/lib/booth/config_validators.py
|
||||
+++ b/pcs/lib/booth/config_validators.py
|
||||
@@ -100,6 +100,16 @@ def remove_ticket(conf_facade, ticket_name):
|
||||
return []
|
||||
|
||||
|
||||
+def ticket_options_normalization() -> validate.TypeNormalizeFunc:
|
||||
+ return validate.option_value_normalization(
|
||||
+ {
|
||||
+ "mode": (
|
||||
+ lambda value: value.lower() if isinstance(value, str) else value
|
||||
+ )
|
||||
+ }
|
||||
+ )
|
||||
+
|
||||
+
|
||||
def validate_ticket_name(ticket_name: str) -> reports.ReportItemList:
|
||||
if not __TICKET_NAME_RE.search(ticket_name):
|
||||
return [
|
||||
diff --git a/pcs/lib/commands/booth.py b/pcs/lib/commands/booth.py
|
||||
index e7891fbe..fc1454ce 100644
|
||||
--- a/pcs/lib/commands/booth.py
|
||||
+++ b/pcs/lib/commands/booth.py
|
||||
@@ -23,7 +23,10 @@ from pcs.common.reports.item import (
|
||||
)
|
||||
from pcs.common.services.errors import ManageServiceError
|
||||
from pcs.common.str_tools import join_multilines
|
||||
-from pcs.lib import tools
|
||||
+from pcs.lib import (
|
||||
+ tools,
|
||||
+ validate,
|
||||
+)
|
||||
from pcs.lib.booth import (
|
||||
config_files,
|
||||
config_validators,
|
||||
@@ -329,17 +332,22 @@ def config_ticket_add(
|
||||
booth_env = env.get_booth_env(instance_name)
|
||||
try:
|
||||
booth_conf = booth_env.config.read_to_facade()
|
||||
+ options_pairs = validate.values_to_pairs(
|
||||
+ options, config_validators.ticket_options_normalization()
|
||||
+ )
|
||||
report_processor.report_list(
|
||||
config_validators.add_ticket(
|
||||
booth_conf,
|
||||
ticket_name,
|
||||
- options,
|
||||
+ options_pairs,
|
||||
allow_unknown_options=allow_unknown_options,
|
||||
)
|
||||
)
|
||||
if report_processor.has_errors:
|
||||
raise LibraryError()
|
||||
- booth_conf.add_ticket(ticket_name, options)
|
||||
+ booth_conf.add_ticket(
|
||||
+ ticket_name, validate.pairs_to_values(options_pairs)
|
||||
+ )
|
||||
booth_env.config.write_facade(booth_conf, can_overwrite=True)
|
||||
except RawFileError as e:
|
||||
report_processor.report(raw_file_error_report(e))
|
||||
diff --git a/pcs_test/tier0/lib/commands/test_booth.py b/pcs_test/tier0/lib/commands/test_booth.py
|
||||
index 2b20a199..12b169c2 100644
|
||||
--- a/pcs_test/tier0/lib/commands/test_booth.py
|
||||
+++ b/pcs_test/tier0/lib/commands/test_booth.py
|
||||
@@ -1194,7 +1194,7 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
|
||||
},
|
||||
)
|
||||
|
||||
- def test_success_ticket_options(self):
|
||||
+ def assert_success_ticket_options(self, options_command, options_config):
|
||||
self.config.raw_file.read(
|
||||
file_type_codes.BOOTH_CONFIG,
|
||||
self.fixture_cfg_path(),
|
||||
@@ -1203,17 +1203,29 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
|
||||
self.config.raw_file.write(
|
||||
file_type_codes.BOOTH_CONFIG,
|
||||
self.fixture_cfg_path(),
|
||||
- self.fixture_cfg_content(
|
||||
- ticket_list=[
|
||||
- ["ticketA", [("retries", "10"), ("timeout", "20")]]
|
||||
- ]
|
||||
- ),
|
||||
+ self.fixture_cfg_content(ticket_list=[["ticketA", options_config]]),
|
||||
can_overwrite=True,
|
||||
)
|
||||
commands.config_ticket_add(
|
||||
- self.env_assist.get_env(),
|
||||
- "ticketA",
|
||||
+ self.env_assist.get_env(), "ticketA", options_command
|
||||
+ )
|
||||
+
|
||||
+ def test_success_ticket_options(self):
|
||||
+ self.assert_success_ticket_options(
|
||||
{"timeout": "20", "retries": "10"},
|
||||
+ [("retries", "10"), ("timeout", "20")],
|
||||
+ )
|
||||
+
|
||||
+ def test_success_ticket_options_mode(self):
|
||||
+ self.assert_success_ticket_options(
|
||||
+ {"timeout": "20", "retries": "10", "mode": "manual"},
|
||||
+ [("mode", "manual"), ("retries", "10"), ("timeout", "20")],
|
||||
+ )
|
||||
+
|
||||
+ def test_success_ticket_options_mode_case_insensitive(self):
|
||||
+ self.assert_success_ticket_options(
|
||||
+ {"timeout": "20", "retries": "10", "mode": "MaNuAl"},
|
||||
+ [("mode", "manual"), ("retries", "10"), ("timeout", "20")],
|
||||
)
|
||||
|
||||
def test_ticket_already_exists(self):
|
||||
--
|
||||
2.35.3
|
||||
|
@ -1,24 +0,0 @@
|
||||
From eeeaac9a46f3568e0a116048068ff99d0dccf25c Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Jelinek <tojeline@redhat.com>
|
||||
Date: Thu, 30 Jun 2022 14:49:16 +0200
|
||||
Subject: [PATCH] fix 'pcs resource restart' traceback
|
||||
|
||||
---
|
||||
pcs/resource.py | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/pcs/resource.py b/pcs/resource.py
|
||||
index eb59d703..8d402c22 100644
|
||||
--- a/pcs/resource.py
|
||||
+++ b/pcs/resource.py
|
||||
@@ -2596,7 +2596,6 @@ def resource_restart(
|
||||
Options:
|
||||
* --wait
|
||||
"""
|
||||
- del lib
|
||||
modifiers.ensure_only_supported("--wait")
|
||||
if not argv:
|
||||
utils.err("You must specify a resource to restart")
|
||||
--
|
||||
2.35.3
|
||||
|
@ -1,46 +0,0 @@
|
||||
From efd5edbfc96a2d85ee0575beca8b163b4ab9179f Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Jelinek <tojeline@redhat.com>
|
||||
Date: Wed, 10 Aug 2022 14:47:53 +0200
|
||||
Subject: [PATCH] fix ruby socket permissions
|
||||
|
||||
---
|
||||
pcsd/rserver.rb | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/pcsd/rserver.rb b/pcsd/rserver.rb
|
||||
index e2c5e2a1..4fde639e 100644
|
||||
--- a/pcsd/rserver.rb
|
||||
+++ b/pcsd/rserver.rb
|
||||
@@ -7,6 +7,29 @@ require 'thin'
|
||||
|
||||
require 'settings.rb'
|
||||
|
||||
+# Replace Thin::Backends::UnixServer:connect
|
||||
+# The only change is 'File.umask(0o777)' instead of 'File.umask(0)' to properly
|
||||
+# set python-ruby socket permissions
|
||||
+module Thin
|
||||
+ module Backends
|
||||
+ class UnixServer < Base
|
||||
+ def connect
|
||||
+ at_exit { remove_socket_file } # In case it crashes
|
||||
+ old_umask = File.umask(0o077)
|
||||
+ begin
|
||||
+ EventMachine.start_unix_domain_server(@socket, UnixConnection, &method(:initialize_connection))
|
||||
+ # HACK EventMachine.start_unix_domain_server doesn't return the connection signature
|
||||
+ # so we have to go in the internal stuff to find it.
|
||||
+ @signature = EventMachine.instance_eval{@acceptors.keys.first}
|
||||
+ ensure
|
||||
+ File.umask(old_umask)
|
||||
+ end
|
||||
+ end
|
||||
+ end
|
||||
+ end
|
||||
+end
|
||||
+
|
||||
+
|
||||
def pack_response(response)
|
||||
return [200, {}, [response.to_json.to_str]]
|
||||
end
|
||||
--
|
||||
2.37.3
|
||||
|
@ -0,0 +1,40 @@
|
||||
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
|
||||
|
@ -0,0 +1,755 @@
|
||||
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
|
||||
|
@ -0,0 +1,506 @@
|
||||
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
@ -0,0 +1,311 @@
|
||||
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
|
||||
|
@ -0,0 +1,67 @@
|
||||
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
|
||||
|
Loading…
Reference in new issue