import pcs-0.10.14-5.el8
This commit is contained in:
parent
8f0d21c4aa
commit
6d25dd9016
22
.gitignore
vendored
22
.gitignore
vendored
@ -1,25 +1,25 @@
|
|||||||
SOURCES/HAM-logo.png
|
SOURCES/HAM-logo.png
|
||||||
SOURCES/backports-3.17.2.gem
|
SOURCES/backports-3.23.0.gem
|
||||||
SOURCES/dacite-1.6.0.tar.gz
|
SOURCES/dacite-1.6.0.tar.gz
|
||||||
SOURCES/daemons-1.3.1.gem
|
SOURCES/daemons-1.4.1.gem
|
||||||
SOURCES/dataclasses-0.8.tar.gz
|
SOURCES/dataclasses-0.8.tar.gz
|
||||||
SOURCES/ethon-0.12.0.gem
|
SOURCES/ethon-0.15.0.gem
|
||||||
SOURCES/eventmachine-1.2.7.gem
|
SOURCES/eventmachine-1.2.7.gem
|
||||||
SOURCES/ffi-1.13.1.gem
|
SOURCES/ffi-1.15.5.gem
|
||||||
SOURCES/json-2.3.0.gem
|
SOURCES/json-2.6.2.gem
|
||||||
SOURCES/mustermann-1.1.1.gem
|
SOURCES/mustermann-1.1.1.gem
|
||||||
SOURCES/open4-1.3.4-1.gem
|
SOURCES/open4-1.3.4-1.gem
|
||||||
SOURCES/pcs-0.10.12.tar.gz
|
SOURCES/pcs-0.10.14.tar.gz
|
||||||
SOURCES/pcs-web-ui-0.1.12.tar.gz
|
SOURCES/pcs-web-ui-0.1.13.tar.gz
|
||||||
SOURCES/pcs-web-ui-node-modules-0.1.12.tar.xz
|
SOURCES/pcs-web-ui-node-modules-0.1.13.tar.xz
|
||||||
SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||||
SOURCES/python-dateutil-2.8.1.tar.gz
|
SOURCES/python-dateutil-2.8.1.tar.gz
|
||||||
SOURCES/rack-2.2.3.gem
|
SOURCES/rack-2.2.3.1.gem
|
||||||
SOURCES/rack-protection-2.2.0.gem
|
SOURCES/rack-protection-2.2.0.gem
|
||||||
SOURCES/rack-test-1.1.0.gem
|
SOURCES/rack-test-1.1.0.gem
|
||||||
SOURCES/rexml-3.2.5.gem
|
SOURCES/rexml-3.2.5.gem
|
||||||
SOURCES/ruby2_keywords-0.0.2.gem
|
SOURCES/ruby2_keywords-0.0.5.gem
|
||||||
SOURCES/sinatra-2.2.0.gem
|
SOURCES/sinatra-2.2.0.gem
|
||||||
SOURCES/thin-1.7.2.gem
|
SOURCES/thin-1.8.1.gem
|
||||||
SOURCES/tilt-2.0.10.gem
|
SOURCES/tilt-2.0.10.gem
|
||||||
SOURCES/tornado-6.1.0.tar.gz
|
SOURCES/tornado-6.1.0.tar.gz
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
679a4ce22a33ffd4d704261a17c00cff98d9499a SOURCES/HAM-logo.png
|
679a4ce22a33ffd4d704261a17c00cff98d9499a SOURCES/HAM-logo.png
|
||||||
28b63a742124da6c9575a1c5e7d7331ef93600b2 SOURCES/backports-3.17.2.gem
|
0e11246385a9e0a4bc122b74fb74fe536a234f81 SOURCES/backports-3.23.0.gem
|
||||||
31546c37fbdc6270d5097687619e9c0db6f1c05c SOURCES/dacite-1.6.0.tar.gz
|
31546c37fbdc6270d5097687619e9c0db6f1c05c SOURCES/dacite-1.6.0.tar.gz
|
||||||
e28c1e78d1a6e34e80f4933b494f1e0501939dd3 SOURCES/daemons-1.3.1.gem
|
4795a8962cc1608bfec0d91fa4d438c7cfe90c62 SOURCES/daemons-1.4.1.gem
|
||||||
8b7598273d2ae6dad2b88466aefac55071a41926 SOURCES/dataclasses-0.8.tar.gz
|
8b7598273d2ae6dad2b88466aefac55071a41926 SOURCES/dataclasses-0.8.tar.gz
|
||||||
921ef1be44583a7644ee7f20fe5f26f21d018a04 SOURCES/ethon-0.12.0.gem
|
29697a34b8cd9df4a77c650e2a38d0a36cdeee8b SOURCES/ethon-0.15.0.gem
|
||||||
7a5b2896e210fac9759c786ee4510f265f75b481 SOURCES/eventmachine-1.2.7.gem
|
7a5b2896e210fac9759c786ee4510f265f75b481 SOURCES/eventmachine-1.2.7.gem
|
||||||
cfa25e7a3760c3ec16723cb8263d9b7a52d0eadf SOURCES/ffi-1.13.1.gem
|
97632b7975067266c0b39596de0a4c86d9330658 SOURCES/ffi-1.15.5.gem
|
||||||
0230e8c5a37f1543982e5b04be503dd5f9004b47 SOURCES/json-2.3.0.gem
|
86c10824191e8f351da3fe0a0b6db94a813ada3a SOURCES/json-2.6.2.gem
|
||||||
50a4e37904485810cb05e27d75c9783e5a8f3402 SOURCES/mustermann-1.1.1.gem
|
50a4e37904485810cb05e27d75c9783e5a8f3402 SOURCES/mustermann-1.1.1.gem
|
||||||
41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
|
41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
|
||||||
1937b826a36bb8396da227361d13f4c25830929c SOURCES/pcs-0.10.12.tar.gz
|
825eab03553c98465e1de265c151ece149ddba04 SOURCES/pcs-0.10.14.tar.gz
|
||||||
a29bfd22130ac978c5d4a6a82108ce37ad2a5db9 SOURCES/pcs-web-ui-0.1.12.tar.gz
|
f7455776936492ce7b241f9801d6bbc946b0461a SOURCES/pcs-web-ui-0.1.13.tar.gz
|
||||||
c9723466d7bfb353899307a5700177f47e7e6cff SOURCES/pcs-web-ui-node-modules-0.1.12.tar.xz
|
bd18d97d611233914828719c97b4d98d079913d2 SOURCES/pcs-web-ui-node-modules-0.1.13.tar.xz
|
||||||
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||||
bd26127e57f83a10f656b62c46524c15aeb844dd SOURCES/python-dateutil-2.8.1.tar.gz
|
bd26127e57f83a10f656b62c46524c15aeb844dd SOURCES/python-dateutil-2.8.1.tar.gz
|
||||||
345b7169d4d2d62176a225510399963bad62b68f SOURCES/rack-2.2.3.gem
|
be609467c819d263c138c417548431b81f8da216 SOURCES/rack-2.2.3.1.gem
|
||||||
21cfac2453436c6856da31e741bbfa59da4973e1 SOURCES/rack-protection-2.2.0.gem
|
21cfac2453436c6856da31e741bbfa59da4973e1 SOURCES/rack-protection-2.2.0.gem
|
||||||
b80bc5ca38a885e747271675ba91dd3d02136bf1 SOURCES/rack-test-1.1.0.gem
|
b80bc5ca38a885e747271675ba91dd3d02136bf1 SOURCES/rack-test-1.1.0.gem
|
||||||
e7f48fa5fb2d92e6cb21d6b1638fe41a5a7c4287 SOURCES/rexml-3.2.5.gem
|
e7f48fa5fb2d92e6cb21d6b1638fe41a5a7c4287 SOURCES/rexml-3.2.5.gem
|
||||||
0be571aacb5d6a212a30af3f322a7000d8af1ef9 SOURCES/ruby2_keywords-0.0.2.gem
|
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
|
||||||
5f0d7e63f9d8683f39ad23afe7e00b99602b87cc SOURCES/sinatra-2.2.0.gem
|
5f0d7e63f9d8683f39ad23afe7e00b99602b87cc SOURCES/sinatra-2.2.0.gem
|
||||||
41395e86322ffd31f3a7aef1f697bda3e1e2d6b9 SOURCES/thin-1.7.2.gem
|
1ac6292a98e17247b7bb847a35ff868605256f7b SOURCES/thin-1.8.1.gem
|
||||||
d265c822a6b228392d899e9eb5114613d65e6967 SOURCES/tilt-2.0.10.gem
|
d265c822a6b228392d899e9eb5114613d65e6967 SOURCES/tilt-2.0.10.gem
|
||||||
c23c617c7a0205e465bebad5b8cdf289ae8402a2 SOURCES/tornado-6.1.0.tar.gz
|
c23c617c7a0205e465bebad5b8cdf289ae8402a2 SOURCES/tornado-6.1.0.tar.gz
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
From e5fc48f45a60228a82980dcd6d68ca01cf447eac Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Mular <omular@redhat.com>
|
|
||||||
Date: Tue, 7 Dec 2021 11:58:09 +0100
|
|
||||||
Subject: [PATCH 2/3] fix rsc update cmd when unable to get agent metadata
|
|
||||||
|
|
||||||
`resource update` command failed with a traceback when updating a
|
|
||||||
resource with a non-existing resource agent
|
|
||||||
---
|
|
||||||
pcs/resource.py | 14 ++++++++------
|
|
||||||
pcs_test/tier1/legacy/test_resource.py | 21 +++++++++++++++++++++
|
|
||||||
2 files changed, 29 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/pcs/resource.py b/pcs/resource.py
|
|
||||||
index c0e8b0d9..4514338d 100644
|
|
||||||
--- a/pcs/resource.py
|
|
||||||
+++ b/pcs/resource.py
|
|
||||||
@@ -1049,13 +1049,15 @@ def resource_update(lib, args, modifiers, deal_with_guest_change=True):
|
|
||||||
if report_list:
|
|
||||||
process_library_reports(report_list)
|
|
||||||
except lib_ra.ResourceAgentError as e:
|
|
||||||
- severity = (
|
|
||||||
- reports.ReportItemSeverity.WARNING
|
|
||||||
- if modifiers.get("--force")
|
|
||||||
- else reports.ReportItemSeverity.ERROR
|
|
||||||
- )
|
|
||||||
process_library_reports(
|
|
||||||
- [lib_ra.resource_agent_error_to_report_item(e, severity)]
|
|
||||||
+ [
|
|
||||||
+ lib_ra.resource_agent_error_to_report_item(
|
|
||||||
+ e,
|
|
||||||
+ reports.get_severity(
|
|
||||||
+ reports.codes.FORCE, modifiers.get("--force")
|
|
||||||
+ ),
|
|
||||||
+ )
|
|
||||||
+ ]
|
|
||||||
)
|
|
||||||
except LibraryError as e:
|
|
||||||
process_library_reports(e.args)
|
|
||||||
diff --git a/pcs_test/tier1/legacy/test_resource.py b/pcs_test/tier1/legacy/test_resource.py
|
|
||||||
index 3f0e08b9..bae0587a 100644
|
|
||||||
--- a/pcs_test/tier1/legacy/test_resource.py
|
|
||||||
+++ b/pcs_test/tier1/legacy/test_resource.py
|
|
||||||
@@ -4879,6 +4879,27 @@ class UpdateInstanceAttrs(
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
+ def test_nonexisting_agent(self):
|
|
||||||
+ agent = "ocf:pacemaker:nonexistent"
|
|
||||||
+ message = (
|
|
||||||
+ f"Agent '{agent}' is not installed or does "
|
|
||||||
+ "not provide valid metadata: Metadata query for "
|
|
||||||
+ f"{agent} failed: Input/output error"
|
|
||||||
+ )
|
|
||||||
+ self.assert_pcs_success(
|
|
||||||
+ f"resource create --force D0 {agent}".split(),
|
|
||||||
+ f"Warning: {message}\n",
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ self.assert_pcs_fail(
|
|
||||||
+ "resource update D0 test=testA".split(),
|
|
||||||
+ f"Error: {message}, use --force to override\n",
|
|
||||||
+ )
|
|
||||||
+ self.assert_pcs_success(
|
|
||||||
+ "resource update --force D0 test=testA".split(),
|
|
||||||
+ f"Warning: {message}\n",
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
def test_update_existing(self):
|
|
||||||
xml = """
|
|
||||||
<resources>
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
2491
SOURCES/bz1786964-01-code-formatting.patch
Normal file
2491
SOURCES/bz1786964-01-code-formatting.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,126 @@
|
|||||||
|
From d6258ba9643b4d7528ceff65d433024104942a4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tomas Jelinek <tojeline@redhat.com>
|
||||||
|
Date: Thu, 14 Jul 2022 16:46:05 +0200
|
||||||
|
Subject: [PATCH 2/4] 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
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 7e44b3cd51a3a5079d0d42d91a3445f3b8ae9d17 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/4] 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 9bf96db9..b7bee7e6 100644
|
||||||
|
--- a/pcsd/remote.rb
|
||||||
|
+++ b/pcsd/remote.rb
|
||||||
|
@@ -2622,6 +2622,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,94 +0,0 @@
|
|||||||
From f0342f110bdb4a7421532b85ca0f49070c7e5c1e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
|
||||||
Date: Thu, 13 Jan 2022 17:32:38 +0100
|
|
||||||
Subject: [PATCH 4/5] fix creating empty cib
|
|
||||||
|
|
||||||
---
|
|
||||||
pcs/utils.py | 21 +++++++++++----------
|
|
||||||
pcs_test/tier1/test_misc.py | 25 ++++++++++++++++++++++++-
|
|
||||||
2 files changed, 35 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/pcs/utils.py b/pcs/utils.py
|
|
||||||
index ad2d4452..423ffc43 100644
|
|
||||||
--- a/pcs/utils.py
|
|
||||||
+++ b/pcs/utils.py
|
|
||||||
@@ -2067,16 +2067,17 @@ def write_empty_cib(cibfile):
|
|
||||||
"""
|
|
||||||
Commandline options: no options
|
|
||||||
"""
|
|
||||||
- empty_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
-<cib admin_epoch="0" epoch="1" num_updates="1" validate-with="pacemaker-1.2">
|
|
||||||
- <configuration>
|
|
||||||
- <crm_config/>
|
|
||||||
- <nodes/>
|
|
||||||
- <resources/>
|
|
||||||
- <constraints/>
|
|
||||||
- </configuration>
|
|
||||||
- <status/>
|
|
||||||
-</cib>"""
|
|
||||||
+ empty_xml = """
|
|
||||||
+ <cib admin_epoch="0" epoch="1" num_updates="1" validate-with="pacemaker-3.1">
|
|
||||||
+ <configuration>
|
|
||||||
+ <crm_config/>
|
|
||||||
+ <nodes/>
|
|
||||||
+ <resources/>
|
|
||||||
+ <constraints/>
|
|
||||||
+ </configuration>
|
|
||||||
+ <status/>
|
|
||||||
+ </cib>
|
|
||||||
+ """
|
|
||||||
with open(cibfile, "w") as f:
|
|
||||||
f.write(empty_xml)
|
|
||||||
|
|
||||||
diff --git a/pcs_test/tier1/test_misc.py b/pcs_test/tier1/test_misc.py
|
|
||||||
index 29ca6a71..6e6f72fb 100644
|
|
||||||
--- a/pcs_test/tier1/test_misc.py
|
|
||||||
+++ b/pcs_test/tier1/test_misc.py
|
|
||||||
@@ -1,8 +1,10 @@
|
|
||||||
+import os
|
|
||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
from pcs_test.tools.assertions import AssertPcsMixin
|
|
||||||
from pcs_test.tools.misc import (
|
|
||||||
get_test_resource as rc,
|
|
||||||
+ get_tmp_dir,
|
|
||||||
get_tmp_file,
|
|
||||||
outdent,
|
|
||||||
write_file_to_tmpfile,
|
|
||||||
@@ -19,7 +21,7 @@ class ParseArgvDashDash(TestCase, AssertPcsMixin):
|
|
||||||
cmd = "constraint colocation add R1 with R2".split()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
- self.temp_cib = get_tmp_file("tier1_misc")
|
|
||||||
+ self.temp_cib = get_tmp_file("tier1_misc_dashdash")
|
|
||||||
write_file_to_tmpfile(rc("cib-empty.xml"), self.temp_cib)
|
|
||||||
self.pcs_runner = PcsRunner(self.temp_cib.name)
|
|
||||||
self.allowed_roles = format_list(const.PCMK_ROLES)
|
|
||||||
@@ -89,3 +91,24 @@ class ParseArgvDashDash(TestCase, AssertPcsMixin):
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class EmptyCibIsPcmk2Compatible(TestCase, AssertPcsMixin):
|
|
||||||
+ # This test verifies that a default empty CIB created by pcs when -f points
|
|
||||||
+ # to an empty file conforms to minimal schema version supported by
|
|
||||||
+ # pacemaker 2.0. If pcs prints a message that CIB schema has been upgraded,
|
|
||||||
+ # then the test fails and shows there is a bug. Bundle with promoted-max
|
|
||||||
+ # requires CIB compliant with schema 3.1, which was introduced in pacemaker
|
|
||||||
+ # 2.0.0.
|
|
||||||
+ def setUp(self):
|
|
||||||
+ self.cib_dir = get_tmp_dir("tier1_misc_empty_cib")
|
|
||||||
+ self.pcs_runner = PcsRunner(os.path.join(self.cib_dir.name, "cib.xml"))
|
|
||||||
+
|
|
||||||
+ def tearDown(self):
|
|
||||||
+ self.cib_dir.cleanup()
|
|
||||||
+
|
|
||||||
+ def test_success(self):
|
|
||||||
+ self.assert_pcs_success(
|
|
||||||
+ "resource bundle create b container docker image=my.img promoted-max=1".split(),
|
|
||||||
+ "",
|
|
||||||
+ )
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
From 6b4b0c0026e5077044e4e908d093cb613ae2e94e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
|
||||||
Date: Mon, 6 Dec 2021 16:06:31 +0100
|
|
||||||
Subject: [PATCH 1/3] fix enabling corosync-qdevice
|
|
||||||
|
|
||||||
---
|
|
||||||
pcsd/remote.rb | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
|
||||||
index c49db116..3574d665 100644
|
|
||||||
--- a/pcsd/remote.rb
|
|
||||||
+++ b/pcsd/remote.rb
|
|
||||||
@@ -2515,7 +2515,7 @@ def qdevice_client_enable(param, request, auth_user)
|
|
||||||
unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
|
|
||||||
return 403, 'Permission denied'
|
|
||||||
end
|
|
||||||
- if not ServiceChecker.new('corosync', enabled: true).is_enabled?('corosync')
|
|
||||||
+ if not ServiceChecker.new(['corosync'], enabled: true).is_enabled?('corosync')
|
|
||||||
return pcsd_success('corosync is not enabled, skipping')
|
|
||||||
elsif enable_service('corosync-qdevice')
|
|
||||||
return pcsd_success('corosync-qdevice enabled')
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
|||||||
From 082bded126151e4f4b4667a1d8337db741828da6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Miroslav Lisik <mlisik@redhat.com>
|
|
||||||
Date: Thu, 16 Dec 2021 14:12:58 +0100
|
|
||||||
Subject: [PATCH 1/5] skip checking of scsi devices to be removed before
|
|
||||||
unfencing to be added devices
|
|
||||||
|
|
||||||
---
|
|
||||||
pcs/lib/commands/scsi.py | 3 ++-
|
|
||||||
pcs_test/tier0/lib/commands/test_scsi.py | 21 +++++++++++++++++----
|
|
||||||
2 files changed, 19 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/pcs/lib/commands/scsi.py b/pcs/lib/commands/scsi.py
|
|
||||||
index ff20a563..ab732805 100644
|
|
||||||
--- a/pcs/lib/commands/scsi.py
|
|
||||||
+++ b/pcs/lib/commands/scsi.py
|
|
||||||
@@ -31,7 +31,8 @@ def unfence_node(
|
|
||||||
return
|
|
||||||
fence_scsi_bin = os.path.join(settings.fence_agent_binaries, "fence_scsi")
|
|
||||||
fenced_devices = []
|
|
||||||
- for device in original_devices:
|
|
||||||
+ # do not check devices being removed
|
|
||||||
+ for device in sorted(set(original_devices) & set(updated_devices)):
|
|
||||||
stdout, stderr, return_code = env.cmd_runner().run(
|
|
||||||
[
|
|
||||||
fence_scsi_bin,
|
|
||||||
diff --git a/pcs_test/tier0/lib/commands/test_scsi.py b/pcs_test/tier0/lib/commands/test_scsi.py
|
|
||||||
index 8ef9836a..bc2357a9 100644
|
|
||||||
--- a/pcs_test/tier0/lib/commands/test_scsi.py
|
|
||||||
+++ b/pcs_test/tier0/lib/commands/test_scsi.py
|
|
||||||
@@ -13,10 +13,13 @@ class TestUnfenceNode(TestCase):
|
|
||||||
self.old_devices = ["device1", "device3"]
|
|
||||||
self.new_devices = ["device3", "device0", "device2"]
|
|
||||||
self.added_devices = set(self.new_devices) - set(self.old_devices)
|
|
||||||
+ self.check_devices = sorted(
|
|
||||||
+ set(self.old_devices) & set(self.new_devices)
|
|
||||||
+ )
|
|
||||||
self.node = "node1"
|
|
||||||
|
|
||||||
def test_success_devices_to_unfence(self):
|
|
||||||
- for old_dev in self.old_devices:
|
|
||||||
+ for old_dev in self.check_devices:
|
|
||||||
self.config.runner.scsi.get_status(
|
|
||||||
self.node, old_dev, name=f"runner.scsi.is_fenced.{old_dev}"
|
|
||||||
)
|
|
||||||
@@ -38,9 +41,19 @@ class TestUnfenceNode(TestCase):
|
|
||||||
)
|
|
||||||
self.env_assist.assert_reports([])
|
|
||||||
|
|
||||||
+ def test_success_replace_unavailable_device(self):
|
|
||||||
+ self.config.runner.scsi.unfence_node(self.node, {"device2"})
|
|
||||||
+ scsi.unfence_node(
|
|
||||||
+ self.env_assist.get_env(),
|
|
||||||
+ self.node,
|
|
||||||
+ {"device1"},
|
|
||||||
+ {"device2"},
|
|
||||||
+ )
|
|
||||||
+ self.env_assist.assert_reports([])
|
|
||||||
+
|
|
||||||
def test_unfencing_failure(self):
|
|
||||||
err_msg = "stderr"
|
|
||||||
- for old_dev in self.old_devices:
|
|
||||||
+ for old_dev in self.check_devices:
|
|
||||||
self.config.runner.scsi.get_status(
|
|
||||||
self.node, old_dev, name=f"runner.scsi.is_fenced.{old_dev}"
|
|
||||||
)
|
|
||||||
@@ -98,7 +111,7 @@ class TestUnfenceNode(TestCase):
|
|
||||||
|
|
||||||
def test_unfencing_skipped_devices_are_fenced(self):
|
|
||||||
stdout_off = "Status: OFF"
|
|
||||||
- for old_dev in self.old_devices:
|
|
||||||
+ for old_dev in self.check_devices:
|
|
||||||
self.config.runner.scsi.get_status(
|
|
||||||
self.node,
|
|
||||||
old_dev,
|
|
||||||
@@ -116,7 +129,7 @@ class TestUnfenceNode(TestCase):
|
|
||||||
[
|
|
||||||
fixture.info(
|
|
||||||
report_codes.STONITH_UNFENCING_SKIPPED_DEVICES_FENCED,
|
|
||||||
- devices=sorted(self.old_devices),
|
|
||||||
+ devices=sorted(self.check_devices),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From 46b079a93d1817f9c1d6a7403c70b30f59d19c20 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
|
||||||
Date: Tue, 4 Jan 2022 12:56:56 +0100
|
|
||||||
Subject: [PATCH 2/5] Make ocf:linbit:drbd agent pass OCF validation
|
|
||||||
|
|
||||||
---
|
|
||||||
data/ocf-1.0.rng | 18 ++++++++----------
|
|
||||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/data/ocf-1.0.rng b/data/ocf-1.0.rng
|
|
||||||
index 36ba4611..1e14a83b 100644
|
|
||||||
--- a/data/ocf-1.0.rng
|
|
||||||
+++ b/data/ocf-1.0.rng
|
|
||||||
@@ -169,16 +169,14 @@ RNGs. Thank you.
|
|
||||||
<optional>
|
|
||||||
<element name="content">
|
|
||||||
<choice>
|
|
||||||
- <attribute name="type">
|
|
||||||
- <choice>
|
|
||||||
- <value>boolean</value>
|
|
||||||
- <value>string</value>
|
|
||||||
- <value>integer</value>
|
|
||||||
- <value>second</value><!-- used by fence agents -->
|
|
||||||
- <value>int</value><!-- used by fence agents intead of integer -->
|
|
||||||
- <value>time</value><!-- used by pacemaker metadata -->
|
|
||||||
- </choice>
|
|
||||||
- </attribute>
|
|
||||||
+ <!--
|
|
||||||
+ OCF 1.0 allows values: boolean, integer, string. Agents, however,
|
|
||||||
+ quite often use other values: int (fence agents), numeric
|
|
||||||
+ (ocf:linbit:drbd), second (fence agents), time (pacemaker
|
|
||||||
+ metadata). Since pcs doesn't actually care about the type, we
|
|
||||||
+ allow any type to keep compatibility with existing agents.
|
|
||||||
+ -->
|
|
||||||
+ <attribute name="type" />
|
|
||||||
<group>
|
|
||||||
<!--
|
|
||||||
used by fence agents and processed by pcs even though it is not
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
From fa75f40361bc39cbd645b8014713e4c0ad0cda18 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ivan Devat <idevat@redhat.com>
|
|
||||||
Date: Mon, 24 Jan 2022 14:08:54 +0100
|
|
||||||
Subject: [PATCH 2/2] fix backend parameter "all" in cluster destroy
|
|
||||||
|
|
||||||
---
|
|
||||||
src/app/backend/calls/destroyCluster.ts | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/app/backend/calls/destroyCluster.ts b/src/app/backend/calls/destroyCluster.ts
|
|
||||||
index b6e83a41..cf41ea42 100644
|
|
||||||
--- a/src/app/backend/calls/destroyCluster.ts
|
|
||||||
+++ b/src/app/backend/calls/destroyCluster.ts
|
|
||||||
@@ -4,5 +4,5 @@ const { url } = endpoints.destroyCluster;
|
|
||||||
|
|
||||||
export const destroyCluster = (clusterName: string): CallResult =>
|
|
||||||
http.post(url({ clusterName }), {
|
|
||||||
- params: [["--all", "1"]],
|
|
||||||
+ params: [["all", "1"]],
|
|
||||||
});
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
From 68aa09a89804084e2764b06f0ae37f56cc609bda Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Valentin=20Vidi=C4=87?= <vvidic@valentin-vidic.from.hr>
|
|
||||||
Date: Wed, 15 Dec 2021 20:32:26 +0100
|
|
||||||
Subject: [PATCH 1/2] Fix snmp client
|
|
||||||
|
|
||||||
Required constant is missing causing the command to fail on startup and breaking the pcs_snmp_agent service.
|
|
||||||
---
|
|
||||||
pcsd/pcsd-cli-main.rb | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/pcsd/pcsd-cli-main.rb b/pcsd/pcsd-cli-main.rb
|
|
||||||
index 29b9006d..be72d543 100644
|
|
||||||
--- a/pcsd/pcsd-cli-main.rb
|
|
||||||
+++ b/pcsd/pcsd-cli-main.rb
|
|
||||||
@@ -10,6 +10,7 @@ require 'remote.rb'
|
|
||||||
|
|
||||||
|
|
||||||
PCS = get_pcs_path()
|
|
||||||
+PCS_INTERNAL = get_pcs_internal_path()
|
|
||||||
$logger_device = StringIO.new
|
|
||||||
$logger = Logger.new($logger_device)
|
|
||||||
early_log($logger)
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
@ -1,934 +0,0 @@
|
|||||||
From ae3435418f0af6e5f22f463871aa90a5c5b2d15f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
|
||||||
Date: Fri, 4 Feb 2022 16:23:18 +0100
|
|
||||||
Subject: [PATCH 1/3] process invalid OCF agents as if they complied with OCF
|
|
||||||
1.0
|
|
||||||
|
|
||||||
---
|
|
||||||
pcs/common/reports/codes.py | 4 +-
|
|
||||||
pcs/common/reports/messages.py | 13 +-
|
|
||||||
pcs/lib/commands/resource.py | 3 +-
|
|
||||||
pcs/lib/commands/resource_agent.py | 4 +-
|
|
||||||
pcs/lib/commands/stonith.py | 3 +-
|
|
||||||
pcs/lib/resource_agent/__init__.py | 1 -
|
|
||||||
pcs/lib/resource_agent/error.py | 14 --
|
|
||||||
pcs/lib/resource_agent/facade.py | 37 ++-
|
|
||||||
pcs/lib/resource_agent/xml.py | 15 +-
|
|
||||||
.../tier0/common/reports/test_messages.py | 18 +-
|
|
||||||
.../tier0/lib/resource_agent/test_facade.py | 47 ++++
|
|
||||||
pcs_test/tier0/lib/resource_agent/test_xml.py | 226 ++++++++----------
|
|
||||||
12 files changed, 201 insertions(+), 184 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/pcs/common/reports/codes.py b/pcs/common/reports/codes.py
|
|
||||||
index 3e0512d9..e8dee00f 100644
|
|
||||||
--- a/pcs/common/reports/codes.py
|
|
||||||
+++ b/pcs/common/reports/codes.py
|
|
||||||
@@ -36,8 +36,8 @@ ADD_REMOVE_CANNOT_SPECIFY_ADJACENT_ITEM_WITHOUT_ITEMS_TO_ADD = M(
|
|
||||||
"ADD_REMOVE_CANNOT_SPECIFY_ADJACENT_ITEM_WITHOUT_ITEMS_TO_ADD"
|
|
||||||
)
|
|
||||||
AGENT_GENERIC_ERROR = M("AGENT_GENERIC_ERROR")
|
|
||||||
-AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION = M(
|
|
||||||
- "AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION"
|
|
||||||
+AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION_ASSUMED_VERSION = M(
|
|
||||||
+ "AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION_ASSUMED_VERSION"
|
|
||||||
)
|
|
||||||
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")
|
|
||||||
diff --git a/pcs/common/reports/messages.py b/pcs/common/reports/messages.py
|
|
||||||
index 9d665e73..7df1e1eb 100644
|
|
||||||
--- a/pcs/common/reports/messages.py
|
|
||||||
+++ b/pcs/common/reports/messages.py
|
|
||||||
@@ -3789,9 +3789,9 @@ class AgentNameGuessFoundNone(ReportItemMessage):
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
-class AgentImplementsUnsupportedOcfVersion(ReportItemMessage):
|
|
||||||
+class AgentImplementsUnsupportedOcfVersionAssumedVersion(ReportItemMessage):
|
|
||||||
"""
|
|
||||||
- Specified agent implements OCF version not supported by pcs
|
|
||||||
+ Specified agent implements OCF version not supported by pcs, assumed OCF 1.0
|
|
||||||
|
|
||||||
agent -- name of the agent
|
|
||||||
ocf_version -- OCF version implemented by the agent
|
|
||||||
@@ -3801,7 +3801,8 @@ class AgentImplementsUnsupportedOcfVersion(ReportItemMessage):
|
|
||||||
agent: str
|
|
||||||
ocf_version: str
|
|
||||||
supported_versions: List[str]
|
|
||||||
- _code = codes.AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION
|
|
||||||
+ assumed_version: str
|
|
||||||
+ _code = codes.AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION_ASSUMED_VERSION
|
|
||||||
|
|
||||||
@property
|
|
||||||
def message(self) -> str:
|
|
||||||
@@ -3809,9 +3810,9 @@ class AgentImplementsUnsupportedOcfVersion(ReportItemMessage):
|
|
||||||
_is = format_plural(self.supported_versions, "is")
|
|
||||||
_version_list = format_list(self.supported_versions)
|
|
||||||
return (
|
|
||||||
- f"Unable to process agent '{self.agent}' as it implements "
|
|
||||||
- f"unsupported OCF version '{self.ocf_version}', supported "
|
|
||||||
- f"{_version} {_is}: {_version_list}"
|
|
||||||
+ f"Agent '{self.agent}' implements unsupported OCF version "
|
|
||||||
+ f"'{self.ocf_version}', supported {_version} {_is}: "
|
|
||||||
+ f"{_version_list}; assumed version '{self.assumed_version}'"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/pcs/lib/commands/resource.py b/pcs/lib/commands/resource.py
|
|
||||||
index 82ce73e0..c4b6252c 100644
|
|
||||||
--- a/pcs/lib/commands/resource.py
|
|
||||||
+++ b/pcs/lib/commands/resource.py
|
|
||||||
@@ -84,7 +84,6 @@ from pcs.lib.resource_agent import (
|
|
||||||
ResourceAgentName,
|
|
||||||
split_resource_agent_name,
|
|
||||||
UnableToGetAgentMetadata,
|
|
||||||
- UnsupportedOcfVersion,
|
|
||||||
)
|
|
||||||
from pcs.lib.tools import get_tmp_cib
|
|
||||||
from pcs.lib.validate import ValueTimeInterval
|
|
||||||
@@ -162,7 +161,7 @@ def _get_agent_facade(
|
|
||||||
else find_one_resource_agent_by_type(runner, report_processor, name)
|
|
||||||
)
|
|
||||||
return factory.facade_from_parsed_name(split_name)
|
|
||||||
- except (UnableToGetAgentMetadata, UnsupportedOcfVersion) as e:
|
|
||||||
+ except UnableToGetAgentMetadata as e:
|
|
||||||
if allow_absent_agent:
|
|
||||||
report_processor.report(
|
|
||||||
resource_agent_error_to_report_item(
|
|
||||||
diff --git a/pcs/lib/commands/resource_agent.py b/pcs/lib/commands/resource_agent.py
|
|
||||||
index e6167b13..4a1831c0 100644
|
|
||||||
--- a/pcs/lib/commands/resource_agent.py
|
|
||||||
+++ b/pcs/lib/commands/resource_agent.py
|
|
||||||
@@ -139,7 +139,9 @@ def _complete_agent_list(
|
|
||||||
try:
|
|
||||||
split_name = split_resource_agent_name(name)
|
|
||||||
metadata = (
|
|
||||||
- agent_factory.facade_from_parsed_name(split_name).metadata
|
|
||||||
+ agent_factory.facade_from_parsed_name(
|
|
||||||
+ split_name, report_warnings=False
|
|
||||||
+ ).metadata
|
|
||||||
if describe
|
|
||||||
else name_to_void_metadata(split_name)
|
|
||||||
)
|
|
||||||
diff --git a/pcs/lib/commands/stonith.py b/pcs/lib/commands/stonith.py
|
|
||||||
index 093f5be9..2aa299d7 100644
|
|
||||||
--- a/pcs/lib/commands/stonith.py
|
|
||||||
+++ b/pcs/lib/commands/stonith.py
|
|
||||||
@@ -45,7 +45,6 @@ from pcs.lib.resource_agent import (
|
|
||||||
ResourceAgentFacadeFactory,
|
|
||||||
ResourceAgentName,
|
|
||||||
UnableToGetAgentMetadata,
|
|
||||||
- UnsupportedOcfVersion,
|
|
||||||
)
|
|
||||||
from pcs.lib.validate import validate_add_remove_items
|
|
||||||
from pcs.lib.xml_tools import get_root
|
|
||||||
@@ -62,7 +61,7 @@ def _get_agent_facade(
|
|
||||||
raise InvalidResourceAgentName(name)
|
|
||||||
full_name = ResourceAgentName("stonith", None, name)
|
|
||||||
return factory.facade_from_parsed_name(full_name)
|
|
||||||
- except (UnableToGetAgentMetadata, UnsupportedOcfVersion) as e:
|
|
||||||
+ except UnableToGetAgentMetadata as e:
|
|
||||||
if allow_absent_agent:
|
|
||||||
report_processor.report(
|
|
||||||
resource_agent_error_to_report_item(
|
|
||||||
diff --git a/pcs/lib/resource_agent/__init__.py b/pcs/lib/resource_agent/__init__.py
|
|
||||||
index 4548017f..c6086331 100644
|
|
||||||
--- a/pcs/lib/resource_agent/__init__.py
|
|
||||||
+++ b/pcs/lib/resource_agent/__init__.py
|
|
||||||
@@ -10,7 +10,6 @@ from .error import (
|
|
||||||
ResourceAgentError,
|
|
||||||
resource_agent_error_to_report_item,
|
|
||||||
UnableToGetAgentMetadata,
|
|
||||||
- UnsupportedOcfVersion,
|
|
||||||
)
|
|
||||||
from .facade import ResourceAgentFacade, ResourceAgentFacadeFactory
|
|
||||||
from .list import (
|
|
||||||
diff --git a/pcs/lib/resource_agent/error.py b/pcs/lib/resource_agent/error.py
|
|
||||||
index d4178333..f1dd7f3d 100644
|
|
||||||
--- a/pcs/lib/resource_agent/error.py
|
|
||||||
+++ b/pcs/lib/resource_agent/error.py
|
|
||||||
@@ -2,8 +2,6 @@ from typing import Iterable
|
|
||||||
|
|
||||||
from pcs.common import reports
|
|
||||||
|
|
||||||
-from . import const
|
|
||||||
-
|
|
||||||
|
|
||||||
class ResourceAgentError(Exception):
|
|
||||||
def __init__(self, agent_name: str):
|
|
||||||
@@ -37,12 +35,6 @@ class UnableToGetAgentMetadata(ResourceAgentError):
|
|
||||||
self.message = message
|
|
||||||
|
|
||||||
|
|
||||||
-class UnsupportedOcfVersion(ResourceAgentError):
|
|
||||||
- def __init__(self, agent_name: str, ocf_version: str):
|
|
||||||
- super().__init__(agent_name)
|
|
||||||
- self.ocf_version = ocf_version
|
|
||||||
-
|
|
||||||
-
|
|
||||||
def resource_agent_error_to_report_item(
|
|
||||||
e: ResourceAgentError,
|
|
||||||
severity: reports.ReportItemSeverity = reports.ReportItemSeverity.error(),
|
|
||||||
@@ -69,10 +61,4 @@ def resource_agent_error_to_report_item(
|
|
||||||
message = reports.messages.UnableToGetAgentMetadata(
|
|
||||||
e.agent_name, e.message
|
|
||||||
)
|
|
||||||
- elif isinstance(e, UnsupportedOcfVersion):
|
|
||||||
- message = reports.messages.AgentImplementsUnsupportedOcfVersion(
|
|
||||||
- e.agent_name,
|
|
||||||
- e.ocf_version,
|
|
||||||
- sorted(const.SUPPORTED_OCF_VERSIONS),
|
|
||||||
- )
|
|
||||||
return reports.ReportItem(severity, message)
|
|
||||||
diff --git a/pcs/lib/resource_agent/facade.py b/pcs/lib/resource_agent/facade.py
|
|
||||||
index 4dbb59b8..dea59a1a 100644
|
|
||||||
--- a/pcs/lib/resource_agent/facade.py
|
|
||||||
+++ b/pcs/lib/resource_agent/facade.py
|
|
||||||
@@ -188,18 +188,32 @@ class ResourceAgentFacadeFactory:
|
|
||||||
self._fenced_metadata = None
|
|
||||||
|
|
||||||
def facade_from_parsed_name(
|
|
||||||
- self, name: ResourceAgentName
|
|
||||||
+ self, name: ResourceAgentName, report_warnings=True
|
|
||||||
) -> ResourceAgentFacade:
|
|
||||||
"""
|
|
||||||
Create ResourceAgentFacade based on specified agent name
|
|
||||||
|
|
||||||
name -- agent name to get a facade for
|
|
||||||
"""
|
|
||||||
- return self._facade_from_metadata(
|
|
||||||
- ocf_version_to_ocf_unified(
|
|
||||||
- parse_metadata(name, load_metadata(self._runner, name))
|
|
||||||
- )
|
|
||||||
+ metadata, raw_ocf_version = parse_metadata(
|
|
||||||
+ name,
|
|
||||||
+ load_metadata(self._runner, name),
|
|
||||||
)
|
|
||||||
+ if (
|
|
||||||
+ report_warnings
|
|
||||||
+ and raw_ocf_version not in const.SUPPORTED_OCF_VERSIONS
|
|
||||||
+ ):
|
|
||||||
+ self._report_processor.report(
|
|
||||||
+ reports.ReportItem.warning(
|
|
||||||
+ reports.messages.AgentImplementsUnsupportedOcfVersionAssumedVersion(
|
|
||||||
+ name.full_name,
|
|
||||||
+ raw_ocf_version,
|
|
||||||
+ sorted(const.SUPPORTED_OCF_VERSIONS),
|
|
||||||
+ const.OCF_1_0,
|
|
||||||
+ )
|
|
||||||
+ )
|
|
||||||
+ )
|
|
||||||
+ return self._facade_from_metadata(ocf_version_to_ocf_unified(metadata))
|
|
||||||
|
|
||||||
def void_facade_from_parsed_name(
|
|
||||||
self, name: ResourceAgentName
|
|
||||||
@@ -232,15 +246,12 @@ class ResourceAgentFacadeFactory:
|
|
||||||
const.FAKE_AGENT_STANDARD, None, const.PACEMAKER_FENCED
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
+ metadata, _ = parse_metadata(
|
|
||||||
+ agent_name,
|
|
||||||
+ load_fake_agent_metadata(self._runner, agent_name.type),
|
|
||||||
+ )
|
|
||||||
self._fenced_metadata = ocf_unified_to_pcs(
|
|
||||||
- ocf_version_to_ocf_unified(
|
|
||||||
- parse_metadata(
|
|
||||||
- agent_name,
|
|
||||||
- load_fake_agent_metadata(
|
|
||||||
- self._runner, agent_name.type
|
|
||||||
- ),
|
|
||||||
- )
|
|
||||||
- )
|
|
||||||
+ ocf_version_to_ocf_unified(metadata)
|
|
||||||
)
|
|
||||||
except ResourceAgentError as e:
|
|
||||||
# If pcs is unable to load fenced metadata, cache an empty
|
|
||||||
diff --git a/pcs/lib/resource_agent/xml.py b/pcs/lib/resource_agent/xml.py
|
|
||||||
index 82f8fbfa..1ba97216 100644
|
|
||||||
--- a/pcs/lib/resource_agent/xml.py
|
|
||||||
+++ b/pcs/lib/resource_agent/xml.py
|
|
||||||
@@ -8,7 +8,7 @@ from pcs.common.tools import xml_fromstring
|
|
||||||
from pcs.lib.external import CommandRunner
|
|
||||||
|
|
||||||
from . import const
|
|
||||||
-from .error import UnableToGetAgentMetadata, UnsupportedOcfVersion
|
|
||||||
+from .error import UnableToGetAgentMetadata
|
|
||||||
from .types import (
|
|
||||||
FakeAgentName,
|
|
||||||
ResourceAgentActionOcf1_0,
|
|
||||||
@@ -137,8 +137,11 @@ def load_fake_agent_metadata(
|
|
||||||
|
|
||||||
|
|
||||||
def parse_metadata(
|
|
||||||
- name: ResourceAgentName, metadata: _Element
|
|
||||||
-) -> Union[ResourceAgentMetadataOcf1_0, ResourceAgentMetadataOcf1_1]:
|
|
||||||
+ name: ResourceAgentName,
|
|
||||||
+ metadata: _Element,
|
|
||||||
+) -> Tuple[
|
|
||||||
+ Union[ResourceAgentMetadataOcf1_0, ResourceAgentMetadataOcf1_1], str
|
|
||||||
+]:
|
|
||||||
"""
|
|
||||||
Parse XML metadata to a dataclass
|
|
||||||
|
|
||||||
@@ -146,11 +149,9 @@ def parse_metadata(
|
|
||||||
metadata -- metadata XML document
|
|
||||||
"""
|
|
||||||
ocf_version = _get_ocf_version(metadata)
|
|
||||||
- if ocf_version == const.OCF_1_0:
|
|
||||||
- return _parse_agent_1_0(name, metadata)
|
|
||||||
if ocf_version == const.OCF_1_1:
|
|
||||||
- return _parse_agent_1_1(name, metadata)
|
|
||||||
- raise UnsupportedOcfVersion(name.full_name, ocf_version)
|
|
||||||
+ return _parse_agent_1_1(name, metadata), ocf_version
|
|
||||||
+ return _parse_agent_1_0(name, metadata), ocf_version
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_agent_1_0(
|
|
||||||
diff --git a/pcs_test/tier0/common/reports/test_messages.py b/pcs_test/tier0/common/reports/test_messages.py
|
|
||||||
index 4a7b4945..b885a9eb 100644
|
|
||||||
--- a/pcs_test/tier0/common/reports/test_messages.py
|
|
||||||
+++ b/pcs_test/tier0/common/reports/test_messages.py
|
|
||||||
@@ -2833,22 +2833,22 @@ class AgentNameGuessFoundNone(NameBuildTest):
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
-class AgentImplementsUnsupportedOcfVersion(NameBuildTest):
|
|
||||||
+class AgentImplementsUnsupportedOcfVersionAssumedVersion(NameBuildTest):
|
|
||||||
def test_singular(self):
|
|
||||||
self.assert_message_from_report(
|
|
||||||
- "Unable to process agent 'agent-name' as it implements unsupported "
|
|
||||||
- "OCF version 'ocf-2.3', supported version is: 'v1'",
|
|
||||||
- reports.AgentImplementsUnsupportedOcfVersion(
|
|
||||||
- "agent-name", "ocf-2.3", ["v1"]
|
|
||||||
+ "Agent 'agent-name' implements unsupported OCF version 'ocf-2.3', "
|
|
||||||
+ "supported version is: 'v1'; assumed version 'v1'",
|
|
||||||
+ reports.AgentImplementsUnsupportedOcfVersionAssumedVersion(
|
|
||||||
+ "agent-name", "ocf-2.3", ["v1"], "v1"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_plural(self):
|
|
||||||
self.assert_message_from_report(
|
|
||||||
- "Unable to process agent 'agent-name' as it implements unsupported "
|
|
||||||
- "OCF version 'ocf-2.3', supported versions are: 'v1', 'v2', 'v3'",
|
|
||||||
- reports.AgentImplementsUnsupportedOcfVersion(
|
|
||||||
- "agent-name", "ocf-2.3", ["v1", "v2", "v3"]
|
|
||||||
+ "Agent 'agent-name' implements unsupported OCF version 'ocf-2.3', "
|
|
||||||
+ "supported versions are: 'v1', 'v2', 'v3'; assumed version 'v1'",
|
|
||||||
+ reports.AgentImplementsUnsupportedOcfVersionAssumedVersion(
|
|
||||||
+ "agent-name", "ocf-2.3", ["v1", "v2", "v3"], "v1"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
diff --git a/pcs_test/tier0/lib/resource_agent/test_facade.py b/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
index 654eb35e..f6a9899c 100644
|
|
||||||
--- a/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
+++ b/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
@@ -92,6 +92,14 @@ class ResourceAgentFacadeFactory(TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
+ _fixture_agent_bad_version_xml = """
|
|
||||||
+ <resource-agent name="agent">
|
|
||||||
+ <version>0.1.2</version>
|
|
||||||
+ <parameters>
|
|
||||||
+ <parameter name="agent-param"/>
|
|
||||||
+ </parameters>
|
|
||||||
+ </resource-agent>
|
|
||||||
+ """
|
|
||||||
_fixture_fenced_xml = """
|
|
||||||
<resource-agent name="pacemaker-fenced">
|
|
||||||
<parameters>
|
|
||||||
@@ -125,6 +133,45 @@ class ResourceAgentFacadeFactory(TestCase):
|
|
||||||
self.assertEqual(facade.metadata.name, name)
|
|
||||||
self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
|
|
||||||
+ def test_facade_bad_ocf_version(self):
|
|
||||||
+ name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
+ self.config.runner.pcmk.load_agent(
|
|
||||||
+ agent_name="service:daemon",
|
|
||||||
+ stdout=self._fixture_agent_bad_version_xml,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ env = self.env_assist.get_env()
|
|
||||||
+ facade = ra.ResourceAgentFacadeFactory(
|
|
||||||
+ env.cmd_runner(), env.report_processor
|
|
||||||
+ ).facade_from_parsed_name(name)
|
|
||||||
+ self.assertEqual(facade.metadata.name, name)
|
|
||||||
+ self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
+ self.env_assist.assert_reports(
|
|
||||||
+ [
|
|
||||||
+ fixture.warn(
|
|
||||||
+ reports.codes.AGENT_IMPLEMENTS_UNSUPPORTED_OCF_VERSION_ASSUMED_VERSION,
|
|
||||||
+ agent=name.full_name,
|
|
||||||
+ ocf_version="0.1.2",
|
|
||||||
+ supported_versions=sorted(ra.const.SUPPORTED_OCF_VERSIONS),
|
|
||||||
+ assumed_version=ra.const.OCF_1_0,
|
|
||||||
+ )
|
|
||||||
+ ]
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_facade_bad_ocf_version_disabled_warning(self):
|
|
||||||
+ name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
+ self.config.runner.pcmk.load_agent(
|
|
||||||
+ agent_name="service:daemon",
|
|
||||||
+ stdout=self._fixture_agent_bad_version_xml,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ env = self.env_assist.get_env()
|
|
||||||
+ facade = ra.ResourceAgentFacadeFactory(
|
|
||||||
+ env.cmd_runner(), env.report_processor
|
|
||||||
+ ).facade_from_parsed_name(name, report_warnings=False)
|
|
||||||
+ self.assertEqual(facade.metadata.name, name)
|
|
||||||
+ self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
+
|
|
||||||
def test_facade_missing_agent(self):
|
|
||||||
name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
self.config.runner.pcmk.load_agent(
|
|
||||||
diff --git a/pcs_test/tier0/lib/resource_agent/test_xml.py b/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
index c4176f32..26bbbb7d 100644
|
|
||||||
--- a/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
+++ b/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
@@ -351,6 +351,7 @@ class LoadFakeAgentMetadata(TestCase):
|
|
||||||
class ParseOcfToolsMixin:
|
|
||||||
agent_name = ra.ResourceAgentName("ocf", "pacemaker", "Dummy")
|
|
||||||
ocf_version = None
|
|
||||||
+ parsed_ocf_version = None
|
|
||||||
|
|
||||||
def parse(self, xml, agent_name=None):
|
|
||||||
agent_name = agent_name or self.agent_name
|
|
||||||
@@ -383,19 +384,17 @@ class ParseOcfToolsMixin:
|
|
||||||
version_el.text = ocf_version
|
|
||||||
return etree_to_str(dom)
|
|
||||||
|
|
||||||
-
|
|
||||||
-class ParseOcfGeneric(ParseOcfToolsMixin, TestCase):
|
|
||||||
- def test_unsupported_ocf_version(self):
|
|
||||||
- with self.assertRaises(ra.UnsupportedOcfVersion) as cm:
|
|
||||||
- self.parse(self.xml("""<resource-agent/>""", ocf_version="1.2"))
|
|
||||||
- self.assertEqual(cm.exception.agent_name, self.agent_name.full_name)
|
|
||||||
- self.assertEqual(cm.exception.ocf_version, "1.2")
|
|
||||||
+ def assert_parse_result(self, xml, metadata):
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ self.parse(xml),
|
|
||||||
+ (metadata, self.parsed_ocf_version or self.ocf_version),
|
|
||||||
+ )
|
|
||||||
|
|
||||||
|
|
||||||
class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
def test_empty_agent(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(self.xml("""<resource-agent/>""")),
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml("""<resource-agent/>"""),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
shortdesc=None,
|
|
||||||
@@ -406,16 +405,14 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<shortdesc>This is a shortdesc</shortdesc>
|
|
||||||
<longdesc>This is a longdesc</longdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -427,16 +424,14 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element_empty(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<longdesc/>
|
|
||||||
<shortdesc/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -448,15 +443,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_attribute(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent shortdesc="This is a shortdesc">
|
|
||||||
<longdesc></longdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -468,13 +461,11 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_attribute_empty(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent shortdesc=""/>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -486,15 +477,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element_and_attribute(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent shortdesc="shortdesc attribute">
|
|
||||||
<shortdesc>shortdesc element</shortdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -506,15 +495,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element_empty_and_attribute(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent shortdesc="shortdesc attribute">
|
|
||||||
<shortdesc></shortdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -526,15 +513,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element_empty_and_attribute_empty(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent shortdesc="">
|
|
||||||
<shortdesc></shortdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -546,15 +531,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_empty_list(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -581,17 +564,15 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_minimal(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter"/>
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -616,10 +597,9 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_all_settings(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter" required="1"
|
|
||||||
@@ -632,7 +612,6 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -657,10 +636,9 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_content(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="with_type">
|
|
||||||
@@ -676,7 +654,6 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -713,15 +690,13 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_actions_empty_list(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<actions/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -748,10 +723,9 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_actions_multiple(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<actions>
|
|
||||||
<action name="minimal"/>
|
|
||||||
@@ -764,7 +738,6 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
</actions>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_0(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -808,7 +781,26 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
|
|
||||||
|
|
||||||
class ParseOcf10NoVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
- pass
|
|
||||||
+ parsed_ocf_version = "1.0"
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class ParseOcf10UnsupportedVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
+ ocf_version = "0.1.2"
|
|
||||||
+
|
|
||||||
+ # These tests test that pcs raises an error if an agent doesn't conform to
|
|
||||||
+ # OCF schema. There is, however, no validation against OCF schema for
|
|
||||||
+ # agents with unsupported OCF version. That means no error message, pcs
|
|
||||||
+ # tries to process the agent and crashes. However bad that sounds, it's
|
|
||||||
+ # indended as that's how pcs behaved before OCF 1.1 was implemented.
|
|
||||||
+ # There's therefore no point in running these tests.
|
|
||||||
+
|
|
||||||
+ def test_parameters_empty_parameter(self):
|
|
||||||
+ # parameters must have at least 'name' attribute
|
|
||||||
+ pass
|
|
||||||
+
|
|
||||||
+ def test_actions_empty_action(self):
|
|
||||||
+ # actions must have at least 'name' attribute
|
|
||||||
+ pass
|
|
||||||
|
|
||||||
|
|
||||||
class ParseOcf10ExplicitVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
@@ -819,8 +811,8 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
ocf_version = "1.1"
|
|
||||||
|
|
||||||
def test_empty_agent(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(self.xml("""<resource-agent/>""")),
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml("""<resource-agent/>"""),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
shortdesc=None,
|
|
||||||
@@ -831,16 +823,14 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<shortdesc>This is a shortdesc</shortdesc>
|
|
||||||
<longdesc>This is a longdesc</longdesc>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -852,16 +842,14 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_desc_element_empty(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<longdesc/>
|
|
||||||
<shortdesc/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -873,15 +861,13 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_empty_list(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -908,17 +894,15 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_minimal(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter"/>
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -945,10 +929,9 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_deprecated_minimal(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter">
|
|
||||||
@@ -957,7 +940,6 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -984,10 +966,9 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_deprecated_replaced_with(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter">
|
|
||||||
@@ -999,7 +980,6 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -1026,10 +1006,9 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_all_settings(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="a_parameter"
|
|
||||||
@@ -1048,7 +1027,6 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -1075,10 +1053,9 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_content(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<parameters>
|
|
||||||
<parameter name="with_type">
|
|
||||||
@@ -1094,7 +1071,6 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -1135,15 +1111,13 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_actions_empty_list(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<actions/>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
@@ -1170,10 +1144,9 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_actions_multiple(self):
|
|
||||||
- self.assertEqual(
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
<resource-agent>
|
|
||||||
<actions>
|
|
||||||
<action name="minimal"/>
|
|
||||||
@@ -1186,7 +1159,6 @@ class ParseOcf11(ParseOcfToolsMixin, TestCase):
|
|
||||||
</actions>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
- )
|
|
||||||
),
|
|
||||||
ResourceAgentMetadataOcf1_1(
|
|
||||||
self.agent_name,
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
@ -1,587 +0,0 @@
|
|||||||
From 65b30a04a234449cb4aa65606d47bf1d673592a4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
|
||||||
Date: Wed, 9 Feb 2022 11:16:49 +0100
|
|
||||||
Subject: [PATCH 2/3] relax OCF 1.0 parser
|
|
||||||
|
|
||||||
---
|
|
||||||
pcs/lib/resource_agent/facade.py | 50 ++++--
|
|
||||||
pcs/lib/resource_agent/ocf_transform.py | 51 +++++-
|
|
||||||
pcs/lib/resource_agent/xml.py | 8 +-
|
|
||||||
.../tier0/lib/resource_agent/test_facade.py | 44 +++++
|
|
||||||
.../lib/resource_agent/test_ocf_transform.py | 48 +++++-
|
|
||||||
pcs_test/tier0/lib/resource_agent/test_xml.py | 155 ++++++++++--------
|
|
||||||
6 files changed, 256 insertions(+), 100 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/pcs/lib/resource_agent/facade.py b/pcs/lib/resource_agent/facade.py
|
|
||||||
index dea59a1a..8a65eb1c 100644
|
|
||||||
--- a/pcs/lib/resource_agent/facade.py
|
|
||||||
+++ b/pcs/lib/resource_agent/facade.py
|
|
||||||
@@ -2,12 +2,19 @@ from collections import defaultdict
|
|
||||||
from dataclasses import replace as dc_replace
|
|
||||||
from typing import Dict, Iterable, List, Optional, Set
|
|
||||||
|
|
||||||
+from lxml import etree
|
|
||||||
+
|
|
||||||
+from pcs import settings
|
|
||||||
from pcs.common import reports
|
|
||||||
from pcs.lib import validate
|
|
||||||
from pcs.lib.external import CommandRunner
|
|
||||||
|
|
||||||
from . import const
|
|
||||||
-from .error import ResourceAgentError, resource_agent_error_to_report_item
|
|
||||||
+from .error import (
|
|
||||||
+ ResourceAgentError,
|
|
||||||
+ resource_agent_error_to_report_item,
|
|
||||||
+ UnableToGetAgentMetadata,
|
|
||||||
+)
|
|
||||||
from .name import name_to_void_metadata
|
|
||||||
from .ocf_transform import ocf_version_to_ocf_unified
|
|
||||||
from .pcs_transform import get_additional_trace_parameters, ocf_unified_to_pcs
|
|
||||||
@@ -195,24 +202,33 @@ class ResourceAgentFacadeFactory:
|
|
||||||
|
|
||||||
name -- agent name to get a facade for
|
|
||||||
"""
|
|
||||||
- metadata, raw_ocf_version = parse_metadata(
|
|
||||||
- name,
|
|
||||||
- load_metadata(self._runner, name),
|
|
||||||
- )
|
|
||||||
- if (
|
|
||||||
- report_warnings
|
|
||||||
- and raw_ocf_version not in const.SUPPORTED_OCF_VERSIONS
|
|
||||||
- ):
|
|
||||||
- self._report_processor.report(
|
|
||||||
- reports.ReportItem.warning(
|
|
||||||
- reports.messages.AgentImplementsUnsupportedOcfVersionAssumedVersion(
|
|
||||||
- name.full_name,
|
|
||||||
- raw_ocf_version,
|
|
||||||
- sorted(const.SUPPORTED_OCF_VERSIONS),
|
|
||||||
- const.OCF_1_0,
|
|
||||||
+ dom_metadata = load_metadata(self._runner, name)
|
|
||||||
+ metadata, raw_ocf_version = parse_metadata(name, dom_metadata)
|
|
||||||
+ if report_warnings:
|
|
||||||
+ if raw_ocf_version not in const.SUPPORTED_OCF_VERSIONS:
|
|
||||||
+ self._report_processor.report(
|
|
||||||
+ reports.ReportItem.warning(
|
|
||||||
+ reports.messages.AgentImplementsUnsupportedOcfVersionAssumedVersion(
|
|
||||||
+ name.full_name,
|
|
||||||
+ raw_ocf_version,
|
|
||||||
+ sorted(const.SUPPORTED_OCF_VERSIONS),
|
|
||||||
+ const.OCF_1_0,
|
|
||||||
+ )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
- )
|
|
||||||
+ if raw_ocf_version != const.OCF_1_1:
|
|
||||||
+ try:
|
|
||||||
+ etree.RelaxNG(
|
|
||||||
+ file=settings.path.ocf_1_0_schema
|
|
||||||
+ ).assertValid(dom_metadata)
|
|
||||||
+ except etree.DocumentInvalid as e:
|
|
||||||
+ self._report_processor.report(
|
|
||||||
+ resource_agent_error_to_report_item(
|
|
||||||
+ UnableToGetAgentMetadata(name.full_name, str(e)),
|
|
||||||
+ severity=reports.ReportItemSeverity.warning(),
|
|
||||||
+ is_stonith=name.is_stonith,
|
|
||||||
+ )
|
|
||||||
+ )
|
|
||||||
return self._facade_from_metadata(ocf_version_to_ocf_unified(metadata))
|
|
||||||
|
|
||||||
def void_facade_from_parsed_name(
|
|
||||||
diff --git a/pcs/lib/resource_agent/ocf_transform.py b/pcs/lib/resource_agent/ocf_transform.py
|
|
||||||
index e841b55e..7e6a14ad 100644
|
|
||||||
--- a/pcs/lib/resource_agent/ocf_transform.py
|
|
||||||
+++ b/pcs/lib/resource_agent/ocf_transform.py
|
|
||||||
@@ -67,20 +67,42 @@ def _ocf_1_1_to_ocf_unified(
|
|
||||||
longdesc=metadata.longdesc,
|
|
||||||
parameters=_ocf_1_1_parameter_list_to_ocf_unified(metadata.parameters),
|
|
||||||
# OCF 1.1 actions are the same as in OCF 1.0
|
|
||||||
- actions=_ocf_1_0_action_list_to_ocf_unified(metadata.actions),
|
|
||||||
+ actions=_ocf_1_1_action_list_to_ocf_unified(metadata.actions),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _ocf_1_0_action_list_to_ocf_unified(
|
|
||||||
- action_list: Iterable[
|
|
||||||
- Union[ResourceAgentActionOcf1_0, ResourceAgentActionOcf1_1]
|
|
||||||
- ],
|
|
||||||
+ action_list: Iterable[ResourceAgentActionOcf1_0],
|
|
||||||
) -> List[ResourceAgentAction]:
|
|
||||||
"""
|
|
||||||
Transform OCF 1.0 actions to a universal format
|
|
||||||
|
|
||||||
action_list -- actions according OCF 1.0
|
|
||||||
"""
|
|
||||||
+ return [
|
|
||||||
+ ResourceAgentAction(
|
|
||||||
+ name=action.name,
|
|
||||||
+ timeout=action.timeout,
|
|
||||||
+ interval=action.interval,
|
|
||||||
+ role=action.role,
|
|
||||||
+ start_delay=action.start_delay,
|
|
||||||
+ depth=action.depth,
|
|
||||||
+ automatic=_bool_value_legacy(action.automatic),
|
|
||||||
+ on_target=_bool_value_legacy(action.on_target),
|
|
||||||
+ )
|
|
||||||
+ for action in action_list
|
|
||||||
+ if action.name
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def _ocf_1_1_action_list_to_ocf_unified(
|
|
||||||
+ action_list: Iterable[ResourceAgentActionOcf1_1],
|
|
||||||
+) -> List[ResourceAgentAction]:
|
|
||||||
+ """
|
|
||||||
+ Transform OCF 1.1 actions to a universal format
|
|
||||||
+
|
|
||||||
+ action_list -- actions according OCF 1.1
|
|
||||||
+ """
|
|
||||||
return [
|
|
||||||
ResourceAgentAction(
|
|
||||||
name=action.name,
|
|
||||||
@@ -111,6 +133,8 @@ def _ocf_1_0_parameter_list_to_ocf_unified(
|
|
||||||
|
|
||||||
result = []
|
|
||||||
for parameter in parameter_list:
|
|
||||||
+ if not parameter.name:
|
|
||||||
+ continue
|
|
||||||
result.append(
|
|
||||||
ResourceAgentParameter(
|
|
||||||
name=parameter.name,
|
|
||||||
@@ -119,17 +143,17 @@ def _ocf_1_0_parameter_list_to_ocf_unified(
|
|
||||||
type=parameter.type,
|
|
||||||
default=parameter.default,
|
|
||||||
enum_values=parameter.enum_values,
|
|
||||||
- required=_bool_value(parameter.required),
|
|
||||||
+ required=_bool_value_legacy(parameter.required),
|
|
||||||
advanced=False,
|
|
||||||
- deprecated=_bool_value(parameter.deprecated),
|
|
||||||
+ deprecated=_bool_value_legacy(parameter.deprecated),
|
|
||||||
deprecated_by=sorted(deprecated_by_dict[parameter.name]),
|
|
||||||
deprecated_desc=None,
|
|
||||||
unique_group=(
|
|
||||||
f"{const.DEFAULT_UNIQUE_GROUP_PREFIX}{parameter.name}"
|
|
||||||
- if _bool_value(parameter.unique)
|
|
||||||
+ if _bool_value_legacy(parameter.unique)
|
|
||||||
else None
|
|
||||||
),
|
|
||||||
- reloadable=_bool_value(parameter.unique),
|
|
||||||
+ reloadable=_bool_value_legacy(parameter.unique),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
@@ -170,3 +194,14 @@ def _bool_value(value: Optional[str]) -> bool:
|
|
||||||
value -- raw bool value
|
|
||||||
"""
|
|
||||||
return value == "1"
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def _bool_value_legacy(value: Optional[str]) -> bool:
|
|
||||||
+ """
|
|
||||||
+ Transform raw bool value from metadata to bool type in backward compatible way
|
|
||||||
+
|
|
||||||
+ value -- raw bool value
|
|
||||||
+ """
|
|
||||||
+ return (
|
|
||||||
+ False if not value else value.lower() in {"true", "on", "yes", "y", "1"}
|
|
||||||
+ )
|
|
||||||
diff --git a/pcs/lib/resource_agent/xml.py b/pcs/lib/resource_agent/xml.py
|
|
||||||
index 1ba97216..0fc70527 100644
|
|
||||||
--- a/pcs/lib/resource_agent/xml.py
|
|
||||||
+++ b/pcs/lib/resource_agent/xml.py
|
|
||||||
@@ -94,9 +94,7 @@ def _metadata_xml_to_dom(metadata: str) -> _Element:
|
|
||||||
"""
|
|
||||||
dom = xml_fromstring(metadata)
|
|
||||||
ocf_version = _get_ocf_version(dom)
|
|
||||||
- if ocf_version == const.OCF_1_0:
|
|
||||||
- etree.RelaxNG(file=settings.path.ocf_1_0_schema).assertValid(dom)
|
|
||||||
- elif ocf_version == const.OCF_1_1:
|
|
||||||
+ if ocf_version == const.OCF_1_1:
|
|
||||||
etree.RelaxNG(file=settings.path.ocf_1_1_schema).assertValid(dom)
|
|
||||||
return dom
|
|
||||||
|
|
||||||
@@ -230,7 +228,7 @@ def _parse_parameters_1_0(
|
|
||||||
)
|
|
||||||
result.append(
|
|
||||||
ResourceAgentParameterOcf1_0(
|
|
||||||
- name=str(parameter_el.attrib["name"]),
|
|
||||||
+ name=str(parameter_el.get("name", "")),
|
|
||||||
shortdesc=_get_shortdesc(parameter_el),
|
|
||||||
longdesc=_get_longdesc(parameter_el),
|
|
||||||
type=value_type,
|
|
||||||
@@ -286,7 +284,7 @@ def _parse_parameters_1_1(
|
|
||||||
def _parse_actions_1_0(element: _Element) -> List[ResourceAgentActionOcf1_0]:
|
|
||||||
return [
|
|
||||||
ResourceAgentActionOcf1_0(
|
|
||||||
- name=str(action.attrib["name"]),
|
|
||||||
+ name=str(action.get("name", "")),
|
|
||||||
timeout=action.get("timeout"),
|
|
||||||
interval=action.get("interval"),
|
|
||||||
role=action.get("role"),
|
|
||||||
diff --git a/pcs_test/tier0/lib/resource_agent/test_facade.py b/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
index f6a9899c..313dfa2b 100644
|
|
||||||
--- a/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
+++ b/pcs_test/tier0/lib/resource_agent/test_facade.py
|
|
||||||
@@ -100,6 +100,13 @@ class ResourceAgentFacadeFactory(TestCase):
|
|
||||||
</parameters>
|
|
||||||
</resource-agent>
|
|
||||||
"""
|
|
||||||
+ _fixture_agent_not_valid_xml = """
|
|
||||||
+ <resource-agent name="agent">
|
|
||||||
+ <parameters>
|
|
||||||
+ <parameter label="something wrong"/>
|
|
||||||
+ </parameters>
|
|
||||||
+ </resource-agent>
|
|
||||||
+ """
|
|
||||||
_fixture_fenced_xml = """
|
|
||||||
<resource-agent name="pacemaker-fenced">
|
|
||||||
<parameters>
|
|
||||||
@@ -172,6 +179,43 @@ class ResourceAgentFacadeFactory(TestCase):
|
|
||||||
self.assertEqual(facade.metadata.name, name)
|
|
||||||
self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
|
|
||||||
+ def test_facade_ocf_1_0_not_valid(self):
|
|
||||||
+ name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
+ self.config.runner.pcmk.load_agent(
|
|
||||||
+ agent_name="service:daemon",
|
|
||||||
+ stdout=self._fixture_agent_not_valid_xml,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ env = self.env_assist.get_env()
|
|
||||||
+ facade = ra.ResourceAgentFacadeFactory(
|
|
||||||
+ env.cmd_runner(), env.report_processor
|
|
||||||
+ ).facade_from_parsed_name(name)
|
|
||||||
+ self.assertEqual(facade.metadata.name, name)
|
|
||||||
+ self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
+ self.env_assist.assert_reports(
|
|
||||||
+ [
|
|
||||||
+ fixture.warn(
|
|
||||||
+ reports.codes.UNABLE_TO_GET_AGENT_METADATA,
|
|
||||||
+ agent=name.full_name,
|
|
||||||
+ reason="Element parameter failed to validate attributes, line 3",
|
|
||||||
+ )
|
|
||||||
+ ]
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_facade_ocf_1_0_not_valid_disabled_warning(self):
|
|
||||||
+ name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
+ self.config.runner.pcmk.load_agent(
|
|
||||||
+ agent_name="service:daemon",
|
|
||||||
+ stdout=self._fixture_agent_not_valid_xml,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ env = self.env_assist.get_env()
|
|
||||||
+ facade = ra.ResourceAgentFacadeFactory(
|
|
||||||
+ env.cmd_runner(), env.report_processor
|
|
||||||
+ ).facade_from_parsed_name(name, report_warnings=False)
|
|
||||||
+ self.assertEqual(facade.metadata.name, name)
|
|
||||||
+ self.assertTrue(facade.metadata.agent_exists)
|
|
||||||
+
|
|
||||||
def test_facade_missing_agent(self):
|
|
||||||
name = ra.ResourceAgentName("service", None, "daemon")
|
|
||||||
self.config.runner.pcmk.load_agent(
|
|
||||||
diff --git a/pcs_test/tier0/lib/resource_agent/test_ocf_transform.py b/pcs_test/tier0/lib/resource_agent/test_ocf_transform.py
|
|
||||||
index 9e41b6af..d0de86e5 100644
|
|
||||||
--- a/pcs_test/tier0/lib/resource_agent/test_ocf_transform.py
|
|
||||||
+++ b/pcs_test/tier0/lib/resource_agent/test_ocf_transform.py
|
|
||||||
@@ -66,6 +66,18 @@ class OcfVersionToOcfUnified(TestCase):
|
|
||||||
obsoletes=None,
|
|
||||||
unique=None,
|
|
||||||
),
|
|
||||||
+ ra.types.ResourceAgentParameterOcf1_0(
|
|
||||||
+ name="",
|
|
||||||
+ shortdesc="Parameters with no name are ignored",
|
|
||||||
+ longdesc=None,
|
|
||||||
+ type="string",
|
|
||||||
+ default=None,
|
|
||||||
+ enum_values=None,
|
|
||||||
+ required=None,
|
|
||||||
+ deprecated=None,
|
|
||||||
+ obsoletes=None,
|
|
||||||
+ unique=None,
|
|
||||||
+ ),
|
|
||||||
ra.types.ResourceAgentParameterOcf1_0(
|
|
||||||
name="param_2",
|
|
||||||
shortdesc="param_2 shortdesc",
|
|
||||||
@@ -109,10 +121,10 @@ class OcfVersionToOcfUnified(TestCase):
|
|
||||||
type="string",
|
|
||||||
default=None,
|
|
||||||
enum_values=None,
|
|
||||||
- required="1",
|
|
||||||
- deprecated="1",
|
|
||||||
+ required="yeS",
|
|
||||||
+ deprecated="True",
|
|
||||||
obsoletes="param_4",
|
|
||||||
- unique="1",
|
|
||||||
+ unique="on",
|
|
||||||
),
|
|
||||||
ra.types.ResourceAgentParameterOcf1_0(
|
|
||||||
name="param_6",
|
|
||||||
@@ -138,6 +150,16 @@ class OcfVersionToOcfUnified(TestCase):
|
|
||||||
automatic=None,
|
|
||||||
on_target=None,
|
|
||||||
),
|
|
||||||
+ ra.types.ResourceAgentActionOcf1_0(
|
|
||||||
+ name="",
|
|
||||||
+ timeout=None,
|
|
||||||
+ interval=None,
|
|
||||||
+ role=None,
|
|
||||||
+ start_delay=None,
|
|
||||||
+ depth=None,
|
|
||||||
+ automatic=None,
|
|
||||||
+ on_target=None,
|
|
||||||
+ ),
|
|
||||||
ra.types.ResourceAgentActionOcf1_0(
|
|
||||||
name="action_2",
|
|
||||||
timeout="12",
|
|
||||||
@@ -158,6 +180,16 @@ class OcfVersionToOcfUnified(TestCase):
|
|
||||||
automatic="1",
|
|
||||||
on_target="0",
|
|
||||||
),
|
|
||||||
+ ra.types.ResourceAgentActionOcf1_0(
|
|
||||||
+ name="action_4",
|
|
||||||
+ timeout=None,
|
|
||||||
+ interval=None,
|
|
||||||
+ role=None,
|
|
||||||
+ start_delay=None,
|
|
||||||
+ depth=None,
|
|
||||||
+ automatic="yes",
|
|
||||||
+ on_target="True",
|
|
||||||
+ ),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
metadata_out = ra.ResourceAgentMetadata(
|
|
||||||
@@ -289,6 +321,16 @@ class OcfVersionToOcfUnified(TestCase):
|
|
||||||
automatic=True,
|
|
||||||
on_target=False,
|
|
||||||
),
|
|
||||||
+ ra.ResourceAgentAction(
|
|
||||||
+ name="action_4",
|
|
||||||
+ timeout=None,
|
|
||||||
+ interval=None,
|
|
||||||
+ role=None,
|
|
||||||
+ start_delay=None,
|
|
||||||
+ depth=None,
|
|
||||||
+ automatic=True,
|
|
||||||
+ on_target=True,
|
|
||||||
+ ),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
diff --git a/pcs_test/tier0/lib/resource_agent/test_xml.py b/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
index 26bbbb7d..ea055ee2 100644
|
|
||||||
--- a/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
+++ b/pcs_test/tier0/lib/resource_agent/test_xml.py
|
|
||||||
@@ -164,8 +164,13 @@ class MetadataXmlToDom(TestCase):
|
|
||||||
ra.xml._metadata_xml_to_dom("not an xml")
|
|
||||||
|
|
||||||
def test_no_version_not_valid(self):
|
|
||||||
- with self.assertRaises(etree.DocumentInvalid):
|
|
||||||
- ra.xml._metadata_xml_to_dom("<resource-agent/>")
|
|
||||||
+ # pylint: disable=no-self-use
|
|
||||||
+ metadata = """
|
|
||||||
+ <resource-agent/>
|
|
||||||
+ """
|
|
||||||
+ assert_xml_equal(
|
|
||||||
+ metadata, etree_to_str(ra.xml._metadata_xml_to_dom(metadata))
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_no_version_valid(self):
|
|
||||||
# pylint: disable=no-self-use
|
|
||||||
@@ -178,14 +183,15 @@ class MetadataXmlToDom(TestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_ocf_1_0_not_valid(self):
|
|
||||||
- with self.assertRaises(etree.DocumentInvalid):
|
|
||||||
- ra.xml._metadata_xml_to_dom(
|
|
||||||
- """
|
|
||||||
- <resource-agent>
|
|
||||||
- <version>1.0</version>
|
|
||||||
- </resource-agent>
|
|
||||||
- """
|
|
||||||
- )
|
|
||||||
+ # pylint: disable=no-self-use
|
|
||||||
+ metadata = """
|
|
||||||
+ <resource-agent>
|
|
||||||
+ <version>1.0</version>
|
|
||||||
+ </resource-agent>
|
|
||||||
+ """
|
|
||||||
+ assert_xml_equal(
|
|
||||||
+ metadata, etree_to_str(ra.xml._metadata_xml_to_dom(metadata))
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_ocf_1_0_valid(self):
|
|
||||||
# pylint: disable=no-self-use
|
|
||||||
@@ -273,19 +279,16 @@ class LoadMetadata(TestCase):
|
|
||||||
|
|
||||||
def test_not_valid_xml(self):
|
|
||||||
agent_name = ra.ResourceAgentName("ocf", "pacemaker", "Dummy")
|
|
||||||
+ metadata = "<resource-agent/>"
|
|
||||||
self.config.runner.pcmk.load_agent(
|
|
||||||
agent_name="ocf:pacemaker:Dummy",
|
|
||||||
- stdout="<resource-agent/>",
|
|
||||||
+ stdout=metadata,
|
|
||||||
)
|
|
||||||
|
|
||||||
env = self.env_assist.get_env()
|
|
||||||
- with self.assertRaises(ra.UnableToGetAgentMetadata) as cm:
|
|
||||||
- ra.xml.load_metadata(env.cmd_runner(), agent_name)
|
|
||||||
- self.assertEqual(cm.exception.agent_name, "ocf:pacemaker:Dummy")
|
|
||||||
- self.assertTrue(
|
|
||||||
- cm.exception.message.startswith(
|
|
||||||
- "Element resource-agent failed to validate"
|
|
||||||
- )
|
|
||||||
+ assert_xml_equal(
|
|
||||||
+ metadata,
|
|
||||||
+ etree_to_str(ra.xml.load_metadata(env.cmd_runner(), agent_name)),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -335,16 +338,15 @@ class LoadFakeAgentMetadata(TestCase):
|
|
||||||
|
|
||||||
def test_not_valid_xml(self):
|
|
||||||
agent_name = ra.const.PACEMAKER_FENCED
|
|
||||||
- self.config.runner.pcmk.load_fenced_metadata(stdout="<resource-agent/>")
|
|
||||||
+ metadata = "<resource-agent/>"
|
|
||||||
+ self.config.runner.pcmk.load_fenced_metadata(stdout=metadata)
|
|
||||||
|
|
||||||
env = self.env_assist.get_env()
|
|
||||||
- with self.assertRaises(ra.UnableToGetAgentMetadata) as cm:
|
|
||||||
- ra.xml.load_fake_agent_metadata(env.cmd_runner(), agent_name)
|
|
||||||
- self.assertEqual(cm.exception.agent_name, "pacemaker-fenced")
|
|
||||||
- self.assertTrue(
|
|
||||||
- cm.exception.message.startswith(
|
|
||||||
- "Element resource-agent failed to validate"
|
|
||||||
- )
|
|
||||||
+ assert_xml_equal(
|
|
||||||
+ metadata,
|
|
||||||
+ etree_to_str(
|
|
||||||
+ ra.xml.load_fake_agent_metadata(env.cmd_runner(), agent_name)
|
|
||||||
+ ),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -549,19 +551,37 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_parameters_empty_parameter(self):
|
|
||||||
- # parameters must have at least 'name' attribute
|
|
||||||
- with self.assertRaises(ra.UnableToGetAgentMetadata):
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
- <resource-agent>
|
|
||||||
- <parameters>
|
|
||||||
- <parameter/>
|
|
||||||
- </parameters>
|
|
||||||
- </resource-agent>
|
|
||||||
- """
|
|
||||||
- )
|
|
||||||
- )
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
+ <resource-agent>
|
|
||||||
+ <parameters>
|
|
||||||
+ <parameter/>
|
|
||||||
+ </parameters>
|
|
||||||
+ </resource-agent>
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ ResourceAgentMetadataOcf1_0(
|
|
||||||
+ self.agent_name,
|
|
||||||
+ shortdesc=None,
|
|
||||||
+ longdesc=None,
|
|
||||||
+ parameters=[
|
|
||||||
+ ResourceAgentParameterOcf1_0(
|
|
||||||
+ name="",
|
|
||||||
+ shortdesc=None,
|
|
||||||
+ longdesc=None,
|
|
||||||
+ type="string",
|
|
||||||
+ default=None,
|
|
||||||
+ enum_values=None,
|
|
||||||
+ required=None,
|
|
||||||
+ deprecated=None,
|
|
||||||
+ obsoletes=None,
|
|
||||||
+ unique=None,
|
|
||||||
+ )
|
|
||||||
+ ],
|
|
||||||
+ actions=[],
|
|
||||||
+ ),
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_parameters_minimal(self):
|
|
||||||
self.assert_parse_result(
|
|
||||||
@@ -708,19 +728,35 @@ class ParseOcf10BaseMixin(ParseOcfToolsMixin):
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_actions_empty_action(self):
|
|
||||||
- # actions must have at least 'name' attribute
|
|
||||||
- with self.assertRaises(ra.UnableToGetAgentMetadata):
|
|
||||||
- self.parse(
|
|
||||||
- self.xml(
|
|
||||||
- """
|
|
||||||
- <resource-agent>
|
|
||||||
- <actions>
|
|
||||||
- <action/>
|
|
||||||
- </actions>
|
|
||||||
- </resource-agent>
|
|
||||||
- """
|
|
||||||
- )
|
|
||||||
- )
|
|
||||||
+ self.assert_parse_result(
|
|
||||||
+ self.xml(
|
|
||||||
+ """
|
|
||||||
+ <resource-agent>
|
|
||||||
+ <actions>
|
|
||||||
+ <action/>
|
|
||||||
+ </actions>
|
|
||||||
+ </resource-agent>
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ ResourceAgentMetadataOcf1_0(
|
|
||||||
+ self.agent_name,
|
|
||||||
+ shortdesc=None,
|
|
||||||
+ longdesc=None,
|
|
||||||
+ parameters=[],
|
|
||||||
+ actions=[
|
|
||||||
+ ResourceAgentActionOcf1_0(
|
|
||||||
+ name="",
|
|
||||||
+ timeout=None,
|
|
||||||
+ interval=None,
|
|
||||||
+ role=None,
|
|
||||||
+ start_delay=None,
|
|
||||||
+ depth=None,
|
|
||||||
+ automatic=None,
|
|
||||||
+ on_target=None,
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ ),
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_actions_multiple(self):
|
|
||||||
self.assert_parse_result(
|
|
||||||
@@ -787,21 +823,6 @@ class ParseOcf10NoVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
class ParseOcf10UnsupportedVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
ocf_version = "0.1.2"
|
|
||||||
|
|
||||||
- # These tests test that pcs raises an error if an agent doesn't conform to
|
|
||||||
- # OCF schema. There is, however, no validation against OCF schema for
|
|
||||||
- # agents with unsupported OCF version. That means no error message, pcs
|
|
||||||
- # tries to process the agent and crashes. However bad that sounds, it's
|
|
||||||
- # indended as that's how pcs behaved before OCF 1.1 was implemented.
|
|
||||||
- # There's therefore no point in running these tests.
|
|
||||||
-
|
|
||||||
- def test_parameters_empty_parameter(self):
|
|
||||||
- # parameters must have at least 'name' attribute
|
|
||||||
- pass
|
|
||||||
-
|
|
||||||
- def test_actions_empty_action(self):
|
|
||||||
- # actions must have at least 'name' attribute
|
|
||||||
- pass
|
|
||||||
-
|
|
||||||
|
|
||||||
class ParseOcf10ExplicitVersion(ParseOcf10BaseMixin, TestCase):
|
|
||||||
ocf_version = "1.0"
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
25
SOURCES/bz2115326-01-fix-pcs-quorum-device-remove.patch
Normal file
25
SOURCES/bz2115326-01-fix-pcs-quorum-device-remove.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From c00b5851a01361bd809a803ab88ff90d584d60e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tomas Jelinek <tojeline@redhat.com>
|
||||||
|
Date: Thu, 4 Aug 2022 15:05:41 +0200
|
||||||
|
Subject: [PATCH 1/2] fix pcs quorum device remove
|
||||||
|
|
||||||
|
---
|
||||||
|
pcsd/remote.rb | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
||||||
|
index b7bee7e6..74151190 100644
|
||||||
|
--- a/pcsd/remote.rb
|
||||||
|
+++ b/pcsd/remote.rb
|
||||||
|
@@ -2519,7 +2519,7 @@ def qdevice_net_client_destroy(param, request, auth_user)
|
||||||
|
end
|
||||||
|
stdout, stderr, retval = run_cmd(
|
||||||
|
auth_user,
|
||||||
|
- PCS, '--' 'qdevice', 'net-client', 'destroy'
|
||||||
|
+ PCS, '--', 'qdevice', 'net-client', 'destroy'
|
||||||
|
)
|
||||||
|
if retval != 0
|
||||||
|
return [400, stderr.join('')]
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From ed61fee104f6f5a16917004f12b773a49f52ca60 Mon Sep 17 00:00:00 2001
|
From 667f7bb5c6221037f40dd44bc89527e478ad7f7e Mon Sep 17 00:00:00 2001
|
||||||
From: Tomas Jelinek <tojeline@redhat.com>
|
From: Tomas Jelinek <tojeline@redhat.com>
|
||||||
Date: Wed, 10 Aug 2022 14:47:53 +0200
|
Date: Wed, 10 Aug 2022 14:47:53 +0200
|
||||||
Subject: [PATCH] fix ruby socket permissions
|
Subject: [PATCH 1/2] fix ruby socket permissions
|
||||||
|
|
||||||
---
|
---
|
||||||
pcsd/rserver.rb | 23 +++++++++++++++++++++++
|
pcsd/rserver.rb | 23 +++++++++++++++++++++++
|
||||||
@ -42,5 +42,5 @@ index c37f9df4..a54509fe 100644
|
|||||||
return [200, {}, [response.to_json.to_str]]
|
return [200, {}, [response.to_json.to_str]]
|
||||||
end
|
end
|
||||||
--
|
--
|
||||||
2.37.1
|
2.37.2
|
||||||
|
|
25
SOURCES/bz2117650-01-fix-enable-sbd-from-webui.patch
Normal file
25
SOURCES/bz2117650-01-fix-enable-sbd-from-webui.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From ef08dbdc4f1fbf86cee3842eec5de32da5468609 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ivan Devat <idevat@redhat.com>
|
||||||
|
Date: Thu, 11 Aug 2022 16:06:29 +0200
|
||||||
|
Subject: [PATCH 1/2] fix enable sbd from webui
|
||||||
|
|
||||||
|
---
|
||||||
|
pcsd/remote.rb | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
||||||
|
index 74151190..a8aff853 100644
|
||||||
|
--- a/pcsd/remote.rb
|
||||||
|
+++ b/pcsd/remote.rb
|
||||||
|
@@ -2412,7 +2412,7 @@ def remote_enable_sbd(params, request, auth_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
_, stderr, retcode = run_cmd(
|
||||||
|
- auth_user, PCS, *flags, '--' 'stonith', 'sbd', 'enable', *arg_list
|
||||||
|
+ auth_user, PCS, *flags, '--', 'stonith', 'sbd', 'enable', *arg_list
|
||||||
|
)
|
||||||
|
|
||||||
|
if retcode != 0
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From f7230b92c946add84ed6072c20a4df5d97c77de2 Mon Sep 17 00:00:00 2001
|
From 96e5fd66c022e6ac7803c391598423b8940c46c3 Mon Sep 17 00:00:00 2001
|
||||||
From: Ivan Devat <idevat@redhat.com>
|
From: Ivan Devat <idevat@redhat.com>
|
||||||
Date: Tue, 20 Nov 2018 15:03:56 +0100
|
Date: Tue, 20 Nov 2018 15:03:56 +0100
|
||||||
Subject: [PATCH 3/3] do not support cluster setup with udp(u) transport
|
Subject: [PATCH 2/2] do not support cluster setup with udp(u) transport
|
||||||
|
|
||||||
---
|
---
|
||||||
pcs/pcs.8.in | 2 ++
|
pcs/pcs.8.in | 2 ++
|
||||||
@ -10,7 +10,7 @@ Subject: [PATCH 3/3] do not support cluster setup with udp(u) transport
|
|||||||
3 files changed, 6 insertions(+)
|
3 files changed, 6 insertions(+)
|
||||||
|
|
||||||
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
|
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
|
||||||
index 05ee66db..101d66f7 100644
|
index 6a00db89..97394e96 100644
|
||||||
--- a/pcs/pcs.8.in
|
--- a/pcs/pcs.8.in
|
||||||
+++ b/pcs/pcs.8.in
|
+++ b/pcs/pcs.8.in
|
||||||
@@ -436,6 +436,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
|
@@ -436,6 +436,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
|
||||||
@ -23,10 +23,10 @@ index 05ee66db..101d66f7 100644
|
|||||||
.br
|
.br
|
||||||
Transport options are: ip_version, netmtu
|
Transport options are: ip_version, netmtu
|
||||||
diff --git a/pcs/usage.py b/pcs/usage.py
|
diff --git a/pcs/usage.py b/pcs/usage.py
|
||||||
index 78bb5ee7..b6f3dd10 100644
|
index e76bf8e5..2e721dbd 100644
|
||||||
--- a/pcs/usage.py
|
--- a/pcs/usage.py
|
||||||
+++ b/pcs/usage.py
|
+++ b/pcs/usage.py
|
||||||
@@ -890,6 +890,7 @@ Commands:
|
@@ -1002,6 +1002,7 @@ Commands:
|
||||||
hash=sha256. To disable encryption, set cipher=none and hash=none.
|
hash=sha256. To disable encryption, set cipher=none and hash=none.
|
||||||
|
|
||||||
Transports udp and udpu:
|
Transports udp and udpu:
|
||||||
@ -49,5 +49,5 @@ index 2f26e831..a7702ac4 100644
|
|||||||
#csetup-transport-options.knet .without-knet
|
#csetup-transport-options.knet .without-knet
|
||||||
{
|
{
|
||||||
--
|
--
|
||||||
2.34.1
|
2.37.2
|
||||||
|
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
From f44cdc871a39da3960bd04565b4d1d5ffa19bd23 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ivan Devat <idevat@redhat.com>
|
|
||||||
Date: Thu, 20 Jan 2022 13:32:49 +0100
|
|
||||||
Subject: [PATCH 1/2] simplify ternar expression
|
|
||||||
|
|
||||||
The motivation for this is that covscan complains about it.
|
|
||||||
---
|
|
||||||
src/app/view/share/useUrlTabs.ts | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/app/view/share/useUrlTabs.ts b/src/app/view/share/useUrlTabs.ts
|
|
||||||
index 7278dad8..a1136bf3 100644
|
|
||||||
--- a/src/app/view/share/useUrlTabs.ts
|
|
||||||
+++ b/src/app/view/share/useUrlTabs.ts
|
|
||||||
@@ -13,7 +13,7 @@ export const useUrlTabs = <TABS extends ReadonlyArray<string>>(
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentTab,
|
|
||||||
- matchedContext: tab !== null ? tab.matched : `/${defaultTab}`,
|
|
||||||
+ matchedContext: tab?.matched ?? `/${defaultTab}`,
|
|
||||||
tabList,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
Name: pcs
|
Name: pcs
|
||||||
Version: 0.10.12
|
Version: 0.10.14
|
||||||
Release: 6%{?dist}.2
|
Release: 5%{?dist}
|
||||||
# https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
|
# https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
|
||||||
# https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses
|
# https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses
|
||||||
# GPLv2: pcs
|
# GPLv2: pcs
|
||||||
@ -20,13 +20,13 @@ Summary: Pacemaker Configuration System
|
|||||||
ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
|
ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
|
||||||
|
|
||||||
%global version_or_commit %{version}
|
%global version_or_commit %{version}
|
||||||
# %%global version_or_commit %%{version}.22-9d83b
|
# %%global version_or_commit %%{version}.48-15d27
|
||||||
|
|
||||||
%global pcs_source_name %{name}-%{version_or_commit}
|
%global pcs_source_name %{name}-%{version_or_commit}
|
||||||
|
|
||||||
# ui_commit can be determined by hash, tag or branch
|
# ui_commit can be determined by hash, tag or branch
|
||||||
%global ui_commit 0.1.12
|
%global ui_commit 0.1.13
|
||||||
%global ui_modules_version 0.1.12
|
%global ui_modules_version 0.1.13
|
||||||
%global ui_src_name pcs-web-ui-%{ui_commit}
|
%global ui_src_name pcs-web-ui-%{ui_commit}
|
||||||
|
|
||||||
%global pcs_snmp_pkg_name pcs-snmp
|
%global pcs_snmp_pkg_name pcs-snmp
|
||||||
@ -36,21 +36,21 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
|
|||||||
%global dataclasses_version 0.8
|
%global dataclasses_version 0.8
|
||||||
%global dacite_version 1.6.0
|
%global dacite_version 1.6.0
|
||||||
%global dateutil_version 2.8.1
|
%global dateutil_version 2.8.1
|
||||||
%global version_rubygem_backports 3.17.2
|
%global version_rubygem_backports 3.23.0
|
||||||
%global version_rubygem_daemons 1.3.1
|
%global version_rubygem_daemons 1.4.1
|
||||||
%global version_rubygem_ethon 0.12.0
|
%global version_rubygem_ethon 0.15.0
|
||||||
%global version_rubygem_eventmachine 1.2.7
|
%global version_rubygem_eventmachine 1.2.7
|
||||||
%global version_rubygem_ffi 1.13.1
|
%global version_rubygem_ffi 1.15.5
|
||||||
%global version_rubygem_json 2.3.0
|
%global version_rubygem_json 2.6.2
|
||||||
%global version_rubygem_mustermann 1.1.1
|
%global version_rubygem_mustermann 1.1.1
|
||||||
%global version_rubygem_open4 1.3.4
|
%global version_rubygem_open4 1.3.4
|
||||||
%global version_rubygem_rack 2.2.3
|
%global version_rubygem_rack 2.2.3.1
|
||||||
%global version_rubygem_rack_protection 2.2.0
|
%global version_rubygem_rack_protection 2.2.0
|
||||||
%global version_rubygem_rack_test 1.1.0
|
%global version_rubygem_rack_test 1.1.0
|
||||||
%global version_rubygem_rexml 3.2.5
|
%global version_rubygem_rexml 3.2.5
|
||||||
%global version_rubygem_ruby2_keywords 0.0.2
|
%global version_rubygem_ruby2_keywords 0.0.5
|
||||||
%global version_rubygem_sinatra 2.2.0
|
%global version_rubygem_sinatra 2.2.0
|
||||||
%global version_rubygem_thin 1.7.2
|
%global version_rubygem_thin 1.8.1
|
||||||
%global version_rubygem_tilt 2.0.10
|
%global version_rubygem_tilt 2.0.10
|
||||||
|
|
||||||
# javascript bundled libraries for old web-ui
|
# javascript bundled libraries for old web-ui
|
||||||
@ -118,24 +118,18 @@ Source101: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_modu
|
|||||||
|
|
||||||
# pcs patches: <= 200
|
# pcs patches: <= 200
|
||||||
# Patch1: bzNUMBER-01-name.patch
|
# Patch1: bzNUMBER-01-name.patch
|
||||||
Patch1: bz2028902-01-fix-enabling-corosync-qdevice.patch
|
Patch1: bz1786964-01-code-formatting.patch
|
||||||
Patch2: bz1384485-01-fix-rsc-update-cmd-when-unable-to-get-agent-metadata.patch
|
Patch2: bz1786964-02-make-booth-ticket-mode-value-case-insensitive.patch
|
||||||
Patch3: bz2032997-01-skip-checking-of-scsi-devices-to-be-removed.patch
|
Patch3: bz1791670-01-booth-sync-check-whether-etc-booth-exists.patch
|
||||||
Patch4: bz2036633-01-Make-ocf-linbit-drbd-agent-pass-OCF-validation.patch
|
Patch4: bz2115326-01-fix-pcs-quorum-device-remove.patch
|
||||||
Patch5: bz1990784-01-Multiple-fixes-of-pcs-resource-move-autodelete-comma.patch
|
Patch5: bz2117650-01-fix-enable-sbd-from-webui.patch
|
||||||
Patch6: bz2022463-01-fix-creating-empty-cib.patch
|
Patch6: bz2116838-01-fix-ruby-socket-permissions.patch
|
||||||
Patch7: bz2047983-01-Fix-snmp-client.patch
|
|
||||||
Patch8: bz2050274-01-process-invalid-OCF-agents-the-same-way-as-before.patch
|
|
||||||
Patch9: bz2050274-02-relax-OCF-1.0-parser.patch
|
|
||||||
|
|
||||||
# Downstream patches do not come from upstream. They adapt pcs for specific
|
# Downstream patches do not come from upstream. They adapt pcs for specific
|
||||||
# RHEL needs.
|
# RHEL needs.
|
||||||
Patch101: do-not-support-cluster-setup-with-udp-u-transport.patch
|
Patch101: do-not-support-cluster-setup-with-udp-u-transport.patch
|
||||||
Patch102: bz2116837-01-fix-ruby-socket-permissions.patch
|
|
||||||
|
|
||||||
# ui patches: >200
|
# ui patches: >200
|
||||||
Patch201: simplify-ternar-expression.patch
|
|
||||||
Patch202: bz2044409-01-fix-backend-parameter-all-in-cluster-destroy.patch
|
|
||||||
|
|
||||||
# git for patches
|
# git for patches
|
||||||
BuildRequires: git-core
|
BuildRequires: git-core
|
||||||
@ -323,8 +317,6 @@ update_times_patch(){
|
|||||||
%autosetup -D -T -b 100 -a 101 -S git -n %{ui_src_name} -N
|
%autosetup -D -T -b 100 -a 101 -S git -n %{ui_src_name} -N
|
||||||
%autopatch -p1 -m 201
|
%autopatch -p1 -m 201
|
||||||
# update_times_patch %%{PATCH201}
|
# update_times_patch %%{PATCH201}
|
||||||
update_times_patch %{PATCH201}
|
|
||||||
update_times_patch %{PATCH202}
|
|
||||||
|
|
||||||
# patch pcs sources
|
# patch pcs sources
|
||||||
%autosetup -S git -n %{pcs_source_name} -N
|
%autosetup -S git -n %{pcs_source_name} -N
|
||||||
@ -336,11 +328,7 @@ update_times_patch %{PATCH3}
|
|||||||
update_times_patch %{PATCH4}
|
update_times_patch %{PATCH4}
|
||||||
update_times_patch %{PATCH5}
|
update_times_patch %{PATCH5}
|
||||||
update_times_patch %{PATCH6}
|
update_times_patch %{PATCH6}
|
||||||
update_times_patch %{PATCH7}
|
|
||||||
update_times_patch %{PATCH8}
|
|
||||||
update_times_patch %{PATCH9}
|
|
||||||
update_times_patch %{PATCH101}
|
update_times_patch %{PATCH101}
|
||||||
update_times_patch %{PATCH102}
|
|
||||||
|
|
||||||
cp -f %SOURCE1 %{pcsd_public_dir}/images
|
cp -f %SOURCE1 %{pcsd_public_dir}/images
|
||||||
|
|
||||||
@ -589,13 +577,37 @@ remove_all_tests
|
|||||||
%license pyagentx_LICENSE.txt
|
%license pyagentx_LICENSE.txt
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thu Aug 11 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.12-6.el8_6.2
|
* Mon Sep 05 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.14-5
|
||||||
- Fixed ruby socket permissions
|
- Fixed ruby socket permissions
|
||||||
- Resolves: rhbz#2116837
|
- Resolves: rhbz#2116838
|
||||||
|
|
||||||
* Mon May 16 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.12-6.el8_6.1
|
* Wed Aug 17 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.14-4
|
||||||
|
- Fixed enable sbd from webui
|
||||||
|
- Resolves: rhbz#2117650
|
||||||
|
|
||||||
|
* Mon Aug 08 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.14-3
|
||||||
|
- Fixed `pcs quorum device remove`
|
||||||
|
- Resolves: rhbz#2115326
|
||||||
|
|
||||||
|
* Thu Jul 28 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.14-2
|
||||||
|
- Fixed booth ticket mode value case insensitive
|
||||||
|
- Fixed booth sync check whether /etc/booth exists
|
||||||
|
- Resolves: rhbz#1786964 rhbz#1791670
|
||||||
|
|
||||||
|
* Fri Jun 24 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.14-1
|
||||||
|
- Rebased to latest upstream sources (see CHANGELOG.md)
|
||||||
|
- Updated bundled rubygems: rack
|
||||||
|
- Resolves: rhbz#2059500 rhbz#2096787 rhbz#2097383 rhbz#2097391 rhbz#2097392 rhbz#2097393
|
||||||
|
|
||||||
|
* Tue May 24 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.13-1
|
||||||
|
- Rebased to latest upstream sources (see CHANGELOG.md)
|
||||||
|
- Updated pcs-web-ui
|
||||||
|
- Updated bundled rubygems: backports, daemons, ethon ffi, json, ruby2_keywords, thin
|
||||||
|
- Resolves: rhbz#1730232 rhbz#1786964 rhbz#1791661 rhbz#1791670 rhbz#1874624 rhbz#1909904 rhbz#1950551 rhbz#1954099 rhbz#2019894 rhbz#2023845 rhbz#2059500 rhbz#2064805 rhbz#2068456
|
||||||
|
|
||||||
|
* Thu May 05 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.12-7
|
||||||
- Updated bundled rubygems: sinatra, rack-protection
|
- Updated bundled rubygems: sinatra, rack-protection
|
||||||
- Resolves: rhbz#2081331
|
- Resolves: rhbz#2081332
|
||||||
|
|
||||||
* Fri Feb 11 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.12-6
|
* Fri Feb 11 2022 Miroslav Lisik <mlisik@redhat.com> - 0.10.12-6
|
||||||
- Fixed processing agents not conforming to OCF schema
|
- Fixed processing agents not conforming to OCF schema
|
||||||
|
Loading…
Reference in New Issue
Block a user