From bba794e49c4455520a8340c179e82c30b232c952 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 11 Mar 2025 07:57:13 +0000 Subject: [PATCH] import CS pcs-0.11.9-2.el9 --- .gitignore | 22 +- .pcs.metadata | 22 +- ...lones-by-agent-name-in-resource-tree.patch | 82 +++++ ...9055-fix-restarting-bundle-instances.patch | 154 ++++++++++ ...ix-deletion-of-misconfigured-bundles.patch | 280 ++++++++++++++++++ SPECS/pcs.spec | 211 ++++++++----- 6 files changed, 677 insertions(+), 94 deletions(-) create mode 100644 SOURCES/RHEL-78653-fix-filter-clones-by-agent-name-in-resource-tree.patch create mode 100644 SOURCES/RHEL-79055-fix-restarting-bundle-instances.patch create mode 100644 SOURCES/RHEL-79160-fix-deletion-of-misconfigured-bundles.patch diff --git a/.gitignore b/.gitignore index 28f63d7..3c71f98 100644 --- a/.gitignore +++ b/.gitignore @@ -3,21 +3,19 @@ SOURCES/base64-0.2.0.gem SOURCES/childprocess-5.0.0.gem SOURCES/dacite-1.8.1.tar.gz SOURCES/ethon-0.16.0.gem -SOURCES/ffi-1.16.3.gem -SOURCES/mustermann-3.0.0.gem -SOURCES/nio4r-2.7.3.gem -SOURCES/pcs-0.11.8.tar.gz -SOURCES/pcs-web-ui-0.1.20.tar.gz -SOURCES/pcs-web-ui-node-modules-0.1.20.tar.xz -SOURCES/puma-6.4.2.gem +SOURCES/ffi-1.17.0.gem +SOURCES/mustermann-3.0.3.gem +SOURCES/nio4r-2.7.4.gem +SOURCES/pcs-0.11.9.tar.gz +SOURCES/pcs-web-ui-0.1.22.tar.gz +SOURCES/pcs-web-ui-node-modules-0.1.22.tar.xz +SOURCES/puma-6.4.3.gem SOURCES/pyagentx-0.4.pcs.2.tar.gz -SOURCES/rack-3.0.11.gem +SOURCES/rack-3.1.10.gem SOURCES/rack-protection-4.0.0.gem SOURCES/rack-session-2.0.0.gem SOURCES/rack-test-2.1.0.gem -SOURCES/rackup-2.1.0.gem +SOURCES/rackup-2.2.1.gem SOURCES/ruby2_keywords-0.0.5.gem SOURCES/sinatra-4.0.0.gem -SOURCES/tilt-2.3.0.gem -SOURCES/tornado-6.4.0.tar.gz -SOURCES/webrick-1.8.1.gem +SOURCES/tilt-2.4.0.gem diff --git a/.pcs.metadata b/.pcs.metadata index 6994015..46318eb 100644 --- a/.pcs.metadata +++ b/.pcs.metadata @@ -3,21 +3,19 @@ ea3a591bdfa93655d8eec9d7bdd7fb87ecb5616a SOURCES/base64-0.2.0.gem 8f910640f84d085707138aa70d6eedb7df10ca73 SOURCES/childprocess-5.0.0.gem 07b26abbf7ff0dcba5c7f9e814ff7eebafefb058 SOURCES/dacite-1.8.1.tar.gz 5b56a68268708c474bef04550639ded3add5e946 SOURCES/ethon-0.16.0.gem -10e4cf0e11ef4581ec4ad5fe2cdf3c78b6077d39 SOURCES/ffi-1.16.3.gem -e892678aaf02ccb27f3a6cd58482cda00aea6ce8 SOURCES/mustermann-3.0.0.gem -632c455f6e27a5f568e9d24761b8a4246cfcc603 SOURCES/nio4r-2.7.3.gem -ee97cec01761e5b727a265eb551d784dfdc6f548 SOURCES/pcs-0.11.8.tar.gz -c75288254b282cb8aed7307fd18dbdd8dda9252d SOURCES/pcs-web-ui-0.1.20.tar.gz -1dbe81ac08cfe60da25cc8650292cdc7c33cdb89 SOURCES/pcs-web-ui-node-modules-0.1.20.tar.xz -623cb3ebec75de449cad3c9f50d5d370edf9e2f9 SOURCES/puma-6.4.2.gem +8edfdd7cc314b5dc84851ea05b6fceedadf386a1 SOURCES/ffi-1.17.0.gem +249a573022dde130372f0ebbeaf2430f36c2b664 SOURCES/mustermann-3.0.3.gem +34b5b1cb50f18d6ec6c5d5cbcb823e7f81f54290 SOURCES/nio4r-2.7.4.gem +9cee532ac692420c0dbb09e22efaeb2f8ec1d4ed SOURCES/pcs-0.11.9.tar.gz +b19baebde3b478071597b5579a36d5a6e9064790 SOURCES/pcs-web-ui-0.1.22.tar.gz +29c9677893485e6ad75862092fc9eedd6f0ad9e9 SOURCES/pcs-web-ui-node-modules-0.1.22.tar.xz +f72357acbdcfd68b4b41a999ed47926c0e54ea5e SOURCES/puma-6.4.3.gem 3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz -a156440aaee17f60b83f2f681ec60fce2329a480 SOURCES/rack-3.0.11.gem +0d5ab43a8cbab21249803ff49a7caae4e271131c SOURCES/rack-3.1.10.gem f91158b296882aa5b3798ff6c24f01cdf233ef48 SOURCES/rack-protection-4.0.0.gem 9e7935696af0b64cc5f5ce2dfeabdb7e0d3a84f0 SOURCES/rack-session-2.0.0.gem ae09ea83748b55875edc3708fffba90db180cb8e SOURCES/rack-test-2.1.0.gem -657a2dc63695e1bf9eb5feae4d9d65a7c6b900ad SOURCES/rackup-2.1.0.gem +efa414fe946ccc1f70e64337d206e98807baa717 SOURCES/rackup-2.2.1.gem d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem 28c671c6d061475ed2bfd3e6a4a17970a0a12d8a SOURCES/sinatra-4.0.0.gem -4a38a9a55887b2882182a2c5771e592efe514e5e SOURCES/tilt-2.3.0.gem -ee95560139af1bb8d0d49d4acf0518deb04877d2 SOURCES/tornado-6.4.0.tar.gz -0696afa9cc0b56f541aacb7483aecdb385a5bd37 SOURCES/webrick-1.8.1.gem +ad6225a8c3b4b66f88ae878d76ef6dec1d0c2f9e SOURCES/tilt-2.4.0.gem diff --git a/SOURCES/RHEL-78653-fix-filter-clones-by-agent-name-in-resource-tree.patch b/SOURCES/RHEL-78653-fix-filter-clones-by-agent-name-in-resource-tree.patch new file mode 100644 index 0000000..2ddaf01 --- /dev/null +++ b/SOURCES/RHEL-78653-fix-filter-clones-by-agent-name-in-resource-tree.patch @@ -0,0 +1,82 @@ +From e949ae0e2fc350ed1e74ce48b50ac812efd92f30 Mon Sep 17 00:00:00 2001 +From: Ivan Devat +Date: Mon, 20 Jan 2025 12:13:25 +0100 +Subject: [PATCH] fix: filter clones by agent name in resource tree + +--- + .../src/app/view/cluster/resources/tree/filter.ts | 13 +++++++------ + .../test/src/test/scenes/resources/tree.test.ts | 14 +++++++++++--- + 2 files changed, 18 insertions(+), 9 deletions(-) + +diff --git a/packages/app/src/app/view/cluster/resources/tree/filter.ts b/packages/app/src/app/view/cluster/resources/tree/filter.ts +index 118e6cc2..b047a094 100644 +--- a/packages/app/src/app/view/cluster/resources/tree/filter.ts ++++ b/packages/app/src/app/view/cluster/resources/tree/filter.ts +@@ -1,4 +1,4 @@ +-import {Resource} from "app/view/cluster/types"; ++import type {FenceDevice, Resource} from "app/view/cluster/types"; + + type Group = Extract; + type Clone = Extract; +@@ -14,13 +14,14 @@ const createResourceFilter = (filter: string) => { + const match = (searchable: string) => + searchable.toLowerCase().includes(filter.toLowerCase()); + ++ const matchPrimitive = (primitive: Primitive | FenceDevice) => ++ match(primitive.id) || match(primitive.agentName); ++ + const filterPrimitive = (primitive: Primitive) => +- match(primitive.id) || match(primitive.agentName) ? primitive : null; ++ matchPrimitive(primitive) ? primitive : null; + + const filterGroup = (group: Group): Group | null => { +- const primitives = group.resources.filter( +- primitive => match(primitive.id) || match(primitive.agentName), +- ); ++ const primitives = group.resources.filter(matchPrimitive); + return match(group.id) || primitives.length > 0 + ? {...group, resources: primitives} + : null; +@@ -34,7 +35,7 @@ const createResourceFilter = (filter: string) => { + : null; + } + +- if (match(clone.member.id)) { ++ if (matchPrimitive(clone.member)) { + return clone; + } + +diff --git a/packages/test/src/test/scenes/resources/tree.test.ts b/packages/test/src/test/scenes/resources/tree.test.ts +index f9b118f8..19190955 100644 +--- a/packages/test/src/test/scenes/resources/tree.test.ts ++++ b/packages/test/src/test/scenes/resources/tree.test.ts +@@ -19,7 +19,15 @@ const resourceList = [ + "Clone1", + cs.group("Group2", [cs.primitive("ResourceD"), cs.primitive("ResourceE")]), + ), +- cs.clone("Clone2", cs.primitive("ResourceF")), ++ cs.clone( ++ "Clone2", ++ cs.primitive("ResourceF", { ++ agentname: "ocf:heartbeat:apache", ++ provider: "heartbeat", ++ class: "ocf", ++ type: "apache", ++ }), ++ ), + ]; + + const primitiveItem = (id: string) => +@@ -129,7 +137,7 @@ describe("Resource tree filter", () => { + await isAbsent(groupItem("Group2")); + await isAbsent(primitiveItem("ResourceD")); + await isAbsent(primitiveItem("ResourceE")); +- await isAbsent(cloneItem("Clone2")); +- await isAbsent(primitiveItem("ResourceF")); ++ await isVisible(cloneItem("Clone2")); ++ await isVisible(primitiveItem("ResourceF")); + }); + }); +-- +2.48.1 + diff --git a/SOURCES/RHEL-79055-fix-restarting-bundle-instances.patch b/SOURCES/RHEL-79055-fix-restarting-bundle-instances.patch new file mode 100644 index 0000000..604324f --- /dev/null +++ b/SOURCES/RHEL-79055-fix-restarting-bundle-instances.patch @@ -0,0 +1,154 @@ +From 618dbcf1f7be271f63f399befdde93ced6448a52 Mon Sep 17 00:00:00 2001 +From: Tomas Jelinek +Date: Wed, 12 Feb 2025 14:00:26 +0100 +Subject: [PATCH 1/2] fix restarting bundle instances + +* fixes a regression introduced in ccffba735128ea4be62aa33e7319114d8b26a8b0 +--- + pcs/lib/commands/resource.py | 85 ++++++++++--------- + .../lib/commands/resource/test_restart.py | 16 +--- + 2 files changed, 46 insertions(+), 55 deletions(-) + +diff --git a/pcs/lib/commands/resource.py b/pcs/lib/commands/resource.py +index 719f8acd3..945e40759 100644 +--- a/pcs/lib/commands/resource.py ++++ b/pcs/lib/commands/resource.py +@@ -2566,56 +2566,59 @@ def restart( + timeout -- abort if the command doesn't finish in this time (integer + unit) + """ + cib = env.get_cib() ++ ++ # To be able to restart bundle instances, which are not to be found in CIB, ++ # do not fail if specified ID is not found in CIB. Pacemaker provides ++ # reasonable messages when the ID to be restarted is not a resource or ++ # doesn't exist. We only search for the resource in order to provide hints ++ # when the user attempts to restart bundle's or clone's inner resources. ++ resource_found = False + try: + resource_el = get_element_by_id(cib, resource_id) +- except ElementNotFound as e: +- env.report_processor.report( +- ReportItem.error( +- reports.messages.IdNotFound( +- resource_id, expected_types=["resource"] +- ) +- ) +- ) +- raise LibraryError() from e +- if not resource.common.is_resource(resource_el): +- env.report_processor.report( +- ReportItem.error( +- reports.messages.IdBelongsToUnexpectedType( +- resource_id, +- expected_types=["resource"], +- current_type=resource_el.tag, ++ resource_found = True ++ except ElementNotFound: ++ pass ++ ++ if resource_found: ++ if not resource.common.is_resource(resource_el): ++ env.report_processor.report( ++ ReportItem.error( ++ reports.messages.IdBelongsToUnexpectedType( ++ resource_id, ++ expected_types=["resource"], ++ current_type=resource_el.tag, ++ ) + ) + ) +- ) +- raise LibraryError() ++ raise LibraryError() + +- parent_resource_el = resource.clone.get_parent_any_clone(resource_el) +- if parent_resource_el is None: +- parent_resource_el = resource.bundle.get_parent_bundle(resource_el) +- if parent_resource_el is not None: +- env.report_processor.report( +- reports.ReportItem.warning( +- reports.messages.ResourceRestartUsingParentRersource( +- str(resource_el.attrib["id"]), +- str(parent_resource_el.attrib["id"]), ++ parent_resource_el = resource.clone.get_parent_any_clone(resource_el) ++ if parent_resource_el is None: ++ parent_resource_el = resource.bundle.get_parent_bundle(resource_el) ++ if parent_resource_el is not None: ++ env.report_processor.report( ++ reports.ReportItem.warning( ++ reports.messages.ResourceRestartUsingParentRersource( ++ str(resource_el.attrib["id"]), ++ str(parent_resource_el.attrib["id"]), ++ ) + ) + ) +- ) +- resource_el = parent_resource_el ++ resource_el = parent_resource_el + +- if node and not ( +- resource.clone.is_any_clone(resource_el) +- or resource.bundle.is_bundle(resource_el) +- ): +- env.report_processor.report( +- reports.ReportItem.error( +- reports.messages.ResourceRestartNodeIsForMultiinstanceOnly( +- str(resource_el.attrib["id"]), +- resource_el.tag, +- node, ++ if node and not ( ++ resource.clone.is_any_clone(resource_el) ++ or resource.bundle.is_bundle(resource_el) ++ ): ++ env.report_processor.report( ++ reports.ReportItem.error( ++ reports.messages.ResourceRestartNodeIsForMultiinstanceOnly( ++ str(resource_el.attrib["id"]), ++ resource_el.tag, ++ node, ++ ) + ) + ) +- ) + + if timeout is not None: + env.report_processor.report_list( +@@ -2627,7 +2630,7 @@ def restart( + + resource_restart( + env.cmd_runner(), +- str(resource_el.attrib["id"]), ++ str(resource_el.attrib["id"]) if resource_found else resource_id, + node=node, + timeout=timeout, + ) +diff --git a/pcs_test/tier0/lib/commands/resource/test_restart.py b/pcs_test/tier0/lib/commands/resource/test_restart.py +index 9d61f5704..af5004b43 100644 +--- a/pcs_test/tier0/lib/commands/resource/test_restart.py ++++ b/pcs_test/tier0/lib/commands/resource/test_restart.py +@@ -104,20 +104,8 @@ class ResourceRestart(TestCase): + ) + + def test_resource_not_found(self): +- self.env_assist.assert_raise_library_error( +- lambda: resource.restart(self.env_assist.get_env(), "RX") +- ) +- self.env_assist.assert_reports( +- [ +- fixture.error( +- reports.codes.ID_NOT_FOUND, +- id="RX", +- expected_types=["resource"], +- context_type="", +- context_id="", +- ) +- ] +- ) ++ self.config.runner.pcmk.resource_restart("RX") ++ resource.restart(self.env_assist.get_env(), "RX") + + def test_not_a_resource(self): + self.env_assist.assert_raise_library_error( +-- +2.48.1 + diff --git a/SOURCES/RHEL-79160-fix-deletion-of-misconfigured-bundles.patch b/SOURCES/RHEL-79160-fix-deletion-of-misconfigured-bundles.patch new file mode 100644 index 0000000..8f0fd69 --- /dev/null +++ b/SOURCES/RHEL-79160-fix-deletion-of-misconfigured-bundles.patch @@ -0,0 +1,280 @@ +From 196be7e21aeb9e1a656e94136f7f15139c56b6e1 Mon Sep 17 00:00:00 2001 +From: Peter Romancik +Date: Thu, 13 Feb 2025 11:03:20 +0100 +Subject: [PATCH 2/2] fix deletion of misconfigured bundles + +--- + pcs/common/reports/codes.py | 3 + + pcs/common/reports/messages.py | 30 +++++++++ + pcs/lib/cib/remove_elements.py | 59 +++++++++++------ + .../tier0/common/reports/test_messages.py | 23 +++++++ + pcs_test/tier0/lib/commands/test_cib.py | 66 +++++++++++++++++++ + 5 files changed, 162 insertions(+), 19 deletions(-) + +diff --git a/pcs/common/reports/codes.py b/pcs/common/reports/codes.py +index 3f0e669b5..bcee00cd7 100644 +--- a/pcs/common/reports/codes.py ++++ b/pcs/common/reports/codes.py +@@ -176,6 +176,9 @@ CLUSTER_UUID_ALREADY_SET = M("CLUSTER_UUID_ALREADY_SET") + CLUSTER_WILL_BE_DESTROYED = M("CLUSTER_WILL_BE_DESTROYED") + COMMAND_INVALID_PAYLOAD = M("COMMAND_INVALID_PAYLOAD") + COMMAND_UNKNOWN = M("COMMAND_UNKNOWN") ++CONFIGURED_RESOURCE_MISSING_IN_STATUS = M( ++ "CONFIGURED_RESOURCE_MISSING_IN_STATUS" ++) + LIVE_ENVIRONMENT_NOT_CONSISTENT = M("LIVE_ENVIRONMENT_NOT_CONSISTENT") + LIVE_ENVIRONMENT_REQUIRED = M("LIVE_ENVIRONMENT_REQUIRED") + LIVE_ENVIRONMENT_REQUIRED_FOR_LOCAL_NODE = M( +diff --git a/pcs/common/reports/messages.py b/pcs/common/reports/messages.py +index 0809c91d1..bfa4e9750 100644 +--- a/pcs/common/reports/messages.py ++++ b/pcs/common/reports/messages.py +@@ -31,6 +31,7 @@ from pcs.common.resource_agent.dto import ( + ResourceAgentNameDto, + get_resource_agent_full_name, + ) ++from pcs.common.resource_status import ResourceState + from pcs.common.str_tools import ( + format_list, + format_list_custom_last_separator, +@@ -6442,6 +6443,35 @@ class CannotStopResourcesBeforeDeleting(ReportItemMessage): + ) + + ++@dataclass(frozen=True) ++class ConfiguredResourceMissingInStatus(ReportItemMessage): ++ """ ++ Cannot check status of resource, because the resource is missing in cluster ++ status despite being configured in CIB. This happens for misconfigured ++ resources, e.g. bundle with primitive resource inside and no IP address ++ for the bundle specified. ++ ++ resource_id -- id of the resource ++ checked_state -- expected state of the resource ++ """ ++ ++ resource_id: str ++ checked_state: Optional[ResourceState] = None ++ _code = codes.CONFIGURED_RESOURCE_MISSING_IN_STATUS ++ ++ @property ++ def message(self) -> str: ++ return ( ++ "Cannot check if the resource '{resource_id}' is in expected " ++ "state{state}, since the resource is missing in cluster status" ++ ).format( ++ resource_id=self.resource_id, ++ state=format_optional( ++ self.checked_state and self.checked_state.name.lower(), " ({})" ++ ), ++ ) ++ ++ + @dataclass(frozen=True) + class ResourceBanPcmkError(ReportItemMessage): + """ +diff --git a/pcs/lib/cib/remove_elements.py b/pcs/lib/cib/remove_elements.py +index 093218dac..04fbe5bf2 100644 +--- a/pcs/lib/cib/remove_elements.py ++++ b/pcs/lib/cib/remove_elements.py +@@ -259,17 +259,27 @@ def warn_resource_unmanaged( + report_list.extend(parser.get_warnings()) + + status = ResourcesStatusFacade.from_resources_status_dto(status_dto) +- report_list.extend( +- reports.ReportItem.warning( +- reports.messages.ResourceIsUnmanaged(resource_id) +- ) +- for resource_id in resource_ids +- if status.is_state( +- resource_id, +- None, +- ResourceState.UNMANAGED, +- ) +- ) ++ for r_id in resource_ids: ++ if not status.exists(r_id, None): ++ # Pacemaker does not put misconfigured resources into cluster ++ # status and we are unable to check state of such resources. ++ # This happens for e.g. undle with primitive resource inside and ++ # no IP address for the bundle specified. We expect the resource ++ # to be stopped since it is misconfigured. Stopping it again ++ # even when it is unmanaged should not break anything. ++ report_list.append( ++ reports.ReportItem.debug( ++ reports.messages.ConfiguredResourceMissingInStatus( ++ r_id, ResourceState.UNMANAGED ++ ) ++ ) ++ ) ++ elif status.is_state(r_id, None, ResourceState.UNMANAGED): ++ report_list.append( ++ reports.ReportItem.warning( ++ reports.messages.ResourceIsUnmanaged(r_id) ++ ) ++ ) + except NotImplementedError: + # TODO remove when issue with bundles in status is fixed + report_list.extend( +@@ -318,20 +328,31 @@ def ensure_resources_stopped( + report_list.extend(parser.get_warnings()) + + status = ResourcesStatusFacade.from_resources_status_dto(status_dto) +- not_stopped_ids = [ +- resource_id +- for resource_id in resource_ids +- if not status.is_state( +- resource_id, ++ for r_id in resource_ids: ++ if not status.exists(r_id, None): ++ # Pacemaker does not put misconfigured resources into cluster ++ # status and we are unable to check state of such resources. ++ # This happens for e.g. undle with primitive resource inside and ++ # no IP address for the bundle specified. We expect the resource ++ # to be stopped since it is misconfigured. ++ report_list.append( ++ reports.ReportItem.debug( ++ reports.messages.ConfiguredResourceMissingInStatus( ++ r_id, ResourceState.STOPPED ++ ) ++ ) ++ ) ++ elif not status.is_state( ++ r_id, + None, + ResourceState.STOPPED, + instances_quantifier=( + MoreChildrenQuantifierType.ALL +- if status.can_have_multiple_instances(resource_id) ++ if status.can_have_multiple_instances(r_id) + else None + ), +- ) +- ] ++ ): ++ not_stopped_ids.append(r_id) + except NotImplementedError: + # TODO remove when issue with bundles in status is fixed + not_stopped_ids = [ +diff --git a/pcs_test/tier0/common/reports/test_messages.py b/pcs_test/tier0/common/reports/test_messages.py +index e9f47786d..305644449 100644 +--- a/pcs_test/tier0/common/reports/test_messages.py ++++ b/pcs_test/tier0/common/reports/test_messages.py +@@ -11,6 +11,7 @@ from pcs.common.file import RawFileError + from pcs.common.reports import const + from pcs.common.reports import messages as reports + from pcs.common.resource_agent.dto import ResourceAgentNameDto ++from pcs.common.resource_status import ResourceState + from pcs.common.types import CibRuleExpressionType + + # pylint: disable=too-many-lines +@@ -6075,3 +6076,25 @@ class GuestNodeRemovalIncomplete(NameBuildTest): + ), + reports.GuestNodeRemovalIncomplete("guest-node"), + ) ++ ++ ++class ConfiguredResourceMissingInStatus(NameBuildTest): ++ def test_only_resource_id(self): ++ self.assert_message_from_report( ++ ( ++ "Cannot check if the resource 'id' is in expected state, " ++ "since the resource is missing in cluster status" ++ ), ++ reports.ConfiguredResourceMissingInStatus("id"), ++ ) ++ ++ def test_with_expected_state(self): ++ self.assert_message_from_report( ++ ( ++ "Cannot check if the resource 'id' is in expected state " ++ "(stopped), since the resource is missing in cluster status" ++ ), ++ reports.ConfiguredResourceMissingInStatus( ++ "id", ResourceState.STOPPED ++ ), ++ ) +diff --git a/pcs_test/tier0/lib/commands/test_cib.py b/pcs_test/tier0/lib/commands/test_cib.py +index 7c72fd047..a6d68ae36 100644 +--- a/pcs_test/tier0/lib/commands/test_cib.py ++++ b/pcs_test/tier0/lib/commands/test_cib.py +@@ -5,6 +5,7 @@ from unittest import ( + ) + + from pcs.common import reports ++from pcs.common.resource_status import ResourceState + from pcs.lib.commands import cib as lib + + from pcs_test.tools import fixture +@@ -991,3 +992,68 @@ class RemoveElementsStopResources(TestCase, StopResourcesWaitMixin): + ), + ] + ) ++ ++ def test_skip_state_check_on_missing_from_status(self): ++ self.config.runner.cib.load( ++ resources=""" ++ ++ ++ ++ ++ ++ ++ """ ++ ) ++ self.fixture_stop_resources_wait_calls( ++ self.config.calls.get("runner.cib.load").stdout, ++ initial_state_modifiers={"resources": ""}, ++ after_disable_cib_modifiers={ ++ "resources": """ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ """ ++ }, ++ after_disable_state_modifiers={"resources": ""}, ++ ) ++ self.fixture_push_cib_after_stopping( ++ resources=""" ++ ++ ++ ++ ++ ++ """ ++ ) ++ lib.remove_elements(self.env_assist.get_env(), ["apa"]) ++ self.env_assist.assert_reports( ++ [ ++ fixture.info( ++ reports.codes.STOPPING_RESOURCES_BEFORE_DELETING, ++ resource_id_list=["apa"], ++ ), ++ fixture.debug( ++ reports.codes.CONFIGURED_RESOURCE_MISSING_IN_STATUS, ++ resource_id="apa", ++ checked_state=ResourceState.UNMANAGED, ++ ), ++ fixture.info(reports.codes.WAIT_FOR_IDLE_STARTED, timeout=0), ++ fixture.debug( ++ reports.codes.CONFIGURED_RESOURCE_MISSING_IN_STATUS, ++ resource_id="apa", ++ checked_state=ResourceState.STOPPED, ++ ), ++ fixture.info( ++ reports.codes.CIB_REMOVE_REFERENCES, ++ id_tag_map={"apa": "primitive", "test-bundle": "bundle"}, ++ removing_references_from={"apa": {"test-bundle"}}, ++ ), ++ ] ++ ) +-- +2.48.1 + diff --git a/SPECS/pcs.spec b/SPECS/pcs.spec index 776d8c1..9d5daa1 100644 --- a/SPECS/pcs.spec +++ b/SPECS/pcs.spec @@ -1,55 +1,66 @@ Name: pcs -Version: 0.11.8 -Release: 1%{?dist} +Version: 0.11.9 +Release: 2%{?dist} # https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/ # https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses # GPL-2.0-only: pcs -# Apache-2.0: tornado # MIT: backports, childprocess, dacite, ethon, mustermann, rack, # rack-protection, rack-session, rack-test, rackup, sinatra, tilt # MIT and (BSD-2-Clause or GPL-2.0-or-later): nio4r -# BSD-2-Clause or Ruby: base64, ruby2_keywords, webrick +# BSD-2-Clause or Ruby: base64, ruby2_keywords # BSD-3-Clause: puma # BSD-3-Clause and MIT: ffi -License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later) +License: GPL-2.0-only AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later) URL: https://github.com/ClusterLabs/pcs Group: System Environment/Base Summary: Pacemaker/Corosync Configuration System #building only for architectures with pacemaker and corosync available ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 -# When specifying a commit, use its long hash -%global version_or_commit %{version} -# %%global version_or_commit be17a9beeb9a55e0c10a34cce5672ebe793bf650 +# To build an official pcs release, comment out branch_or_commit +# Use long commit hash or branch name to build an unreleased version +# %%global branch_or_commit 73c3ba7aec1e2abf2ef7c3d0ffddeeef7c7516d0 +%if 0%{?branch_or_commit:1} + %global version_or_commit %{branch_or_commit} +%else + %global version_or_commit %{version} +%endif %global pcs_source_name %{name}-%{version_or_commit} -# ui_commit can be determined by hash, tag or branch -%global ui_commit 0.1.20 -%global ui_modules_version 0.1.20 -%global ui_src_name pcs-web-ui-%{ui_commit} +# To build an official pcs-web-ui release, comment out ui_branch_or_commit +# Last tagged version, also used as fallback version for untagged tarballs +%global ui_version 0.1.22 +# Use long commit hash or branch name to build an unreleased version +# %%global ui_branch_or_commit 34372d1268f065ed186546f55216aaa2d7e76b54 +%if 0%{?ui_branch_or_commit:1} + %global ui_version_or_commit %{ui_branch_or_commit} +%else + %global ui_version_or_commit %{ui_version} +%endif +%global ui_src_name pcs-web-ui-%{ui_version_or_commit} + +%global ui_modules_version 0.1.22 %global pcs_snmp_pkg_name pcs-snmp %global pyagentx_version 0.4.pcs.2 -%global tornado_version 6.4.0 %global dacite_version 1.8.1 %global version_rubygem_backports 3.25.0 %global version_rubygem_base64 0.2.0 %global version_rubygem_childprocess 5.0.0 %global version_rubygem_ethon 0.16.0 -%global version_rubygem_ffi 1.16.3 -%global version_rubygem_mustermann 3.0.0 -%global version_rubygem_nio4r 2.7.3 -%global version_rubygem_puma 6.4.2 -%global version_rubygem_rack 3.0.11 +%global version_rubygem_ffi 1.17.0 +%global version_rubygem_mustermann 3.0.3 +%global version_rubygem_nio4r 2.7.4 +%global version_rubygem_puma 6.4.3 +%global version_rubygem_rack 3.1.10 %global version_rubygem_rack_protection 4.0.0 %global version_rubygem_rack_session 2.0.0 %global version_rubygem_rack_test 2.1.0 -%global version_rubygem_rackup 2.1.0 +%global version_rubygem_rackup 2.2.1 %global version_rubygem_ruby2_keywords 0.0.5 %global version_rubygem_sinatra 4.0.0 -%global version_rubygem_tilt 2.3.0 -%global version_rubygem_webrick 1.8.1 +%global version_rubygem_tilt 2.4.0 %global required_pacemaker_version 2.1.0 @@ -58,14 +69,6 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 %global rubygem_bundle_dir pcsd/vendor/bundle %global rubygem_cache_dir %{rubygem_bundle_dir}/cache -# mangling shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test from /usr/bin/env ruby to #!/usr/bin/ruby -#*** ERROR: ./usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/test.ru has shebang which doesn't start with '/' (../../bin/rackup) -#mangling shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/rackup_stub.rb from /usr/bin/env ruby to #!/usr/bin/ruby -#*** WARNING: ./usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/sample_rackup.ru is executable but has empty or no shebang, removing executable bit -#*** WARNING: ./usr/lib/pcsd/vendor/bundle/ruby/gems/rack-2.0.5/test/cgi/lighttpd.conf is executable but has empty or no shebang, removing executable bit -#*** ERROR: ambiguous python shebang in /usr/lib/pcsd/vendor/bundle/ruby/gems/ffi-1.9.25/ext/ffi_c/libffi/generate-darwin-source-and-headers.py: #!/usr/bin/env python. Change it to python3 (or python2) explicitly. -%undefine __brp_mangle_shebangs - # https://fedoraproject.org/wiki/Changes/Avoid_usr_bin_python_in_RPM_Build#Python_bytecompilation # Enforce python3 because bytecompilation of tornado produced warnings: # DEPRECATION WARNING: python2 invoked with /usr/bin/python. @@ -82,7 +85,6 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64 Source0: %{url}/archive/%{?v_prefix}%{version_or_commit}/%{pcs_source_name}.tar.gz Source41: https://github.com/ondrejmular/pyagentx/archive/v%{pyagentx_version}/pyagentx-%{pyagentx_version}.tar.gz -Source42: https://github.com/tornadoweb/tornado/archive/v%{tornado_version}/tornado-%{tornado_version}.tar.gz Source44: https://github.com/konradhalas/dacite/archive/v%{dacite_version}/dacite-%{dacite_version}.tar.gz Source81: https://rubygems.org/downloads/backports-%{version_rubygem_backports}.gem @@ -101,22 +103,27 @@ Source93: https://rubygems.org/downloads/ruby2_keywords-%{version_rubygem_ruby2_ Source94: https://rubygems.org/downloads/base64-%{version_rubygem_base64}.gem Source95: https://rubygems.org/downloads/rack-session-%{version_rubygem_rack_session}.gem Source96: https://rubygems.org/downloads/rackup-%{version_rubygem_rackup}.gem -Source97: https://rubygems.org/downloads/webrick-%{version_rubygem_webrick}.gem -Source100: https://github.com/ClusterLabs/pcs-web-ui/archive/%{ui_commit}/%{ui_src_name}.tar.gz -Source101: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_commit}/pcs-web-ui-node-modules-%{ui_modules_version}.tar.xz +Source100: https://github.com/ClusterLabs/pcs-web-ui/archive/%{ui_version_or_commit}/%{ui_src_name}.tar.gz +Source101: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_version_or_commit}/pcs-web-ui-node-modules-%{ui_modules_version}.tar.xz # pcs patches: <= 200 -# Patch0: bzNUMBER-01-name.patch -Patch0: do-not-support-cluster-setup-with-udp-u-transport.patch +# Patch1: bzNUMBER-01-name.patch +Patch1: do-not-support-cluster-setup-with-udp-u-transport.patch +Patch2: RHEL-79055-fix-restarting-bundle-instances.patch +Patch3: RHEL-79160-fix-deletion-of-misconfigured-bundles.patch # ui patches: >200 # Patch201: bzNUMBER-01-name.patch +Patch201: RHEL-78653-fix-filter-clones-by-agent-name-in-resource-tree.patch + # git for patches BuildRequires: git-core # printf from coreutils is used in makefile, head is used in spec BuildRequires: coreutils +# find is used in Makefile and also somewhere else +BuildRequires: findutils # python for pcs BuildRequires: python3 >= 3.9 BuildRequires: python3-cryptography @@ -132,6 +139,7 @@ BuildRequires: python3-lxml BuildRequires: python3-wheel # for bundled python dateutil BuildRequires: python3-setuptools_scm +BuildRequires: python3-tornado # gcc for compiling custom rubygems BuildRequires: gcc BuildRequires: gcc-c++ @@ -158,7 +166,6 @@ BuildRequires: redhat-logos BuildRequires: npm # cluster stack packages for pkg-config BuildRequires: booth -BuildRequires: corosync-qdevice-devel BuildRequires: corosynclib-devel >= 3.0 BuildRequires: fence-agents-common BuildRequires: pacemaker-libs-devel >= %{required_pacemaker_version} @@ -168,6 +175,8 @@ BuildRequires: sbd BuildRequires: nss-tools # for generating MiniDebugInfo with find-debuginfo BuildRequires: debugedit +# pcs now provides a pc file +BuildRequires: pkgconfig # python and libraries for pcs, setuptools for pcs entrypoint Requires: python3 >= 3.9 @@ -177,7 +186,7 @@ Requires: python3-lxml Requires: python3-setuptools Requires: python3-pycurl Requires: python3-pyparsing -Requires: python3-cryptography +Requires: python3-tornado # ruby and gems for pcsd Requires: ruby >= 2.5 Requires: rubygems @@ -206,7 +215,6 @@ Requires: logrotate # for working with qdevice certificates (certutil) Requires: nss-tools -Provides: bundled(tornado) = %{tornado_version} Provides: bundled(dacite) = %{dacite_version} Provides: bundled(backports) = %{version_rubygem_backports} Provides: bundled(base64) = %{version_rubygem_base64} @@ -224,7 +232,6 @@ Provides: bundled(rackup) = %{version_rubygem_rackup} Provides: bundled(ruby2_keywords) = %{version_rubygem_ruby2_keywords} Provides: bundled(sinatra) = %{version_rubygem_sinatra} Provides: bundled(tilt) = %{version_rubygem_tilt} -Provides: bundled(webrick) = %{version_rubygem_webrick} %description pcs is a corosync and pacemaker configuration tool. It permits users to @@ -296,15 +303,29 @@ update_times_patch(){ # * http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html # * https://rpm-software-management.github.io/rpm/manual/autosetup.html # patch web-ui sources -%autosetup -D -T -b 100 -a 101 -S git -n %{ui_src_name} -N +# -n — Set Name of Build Directory +# -T — Do Not Perform Default Archive Unpacking +# -b — Unpack The nth Sources Before Changing Directory +# -a — Unpack The nth Sources After Changing Directory +# -N — disables automatic patch application, use autopatch to apply patches +# +# 1. unpack sources (-b 0) +# 2. then cd into sources tree (the setup macro itself) +# 3. then unpack node_modules into sources tree (-a 1). +%autosetup -T -b 100 -a 101 -N -n %{ui_src_name} %autopatch -p1 -m 201 + + # update_times_patch %%{PATCH201} +update_times_patch %{PATCH201} # patch pcs sources %autosetup -S git -n %{pcs_source_name} -N %autopatch -p1 -M 200 -# update_times_patch %%{PATCH0} -update_times_patch %{PATCH0} +# update_times_patch %%{PATCH1} +update_times_patch %{PATCH1} +update_times_patch %{PATCH2} +update_times_patch %{PATCH3} # generate .tarball-version if building from an untagged commit, not a released version # autogen uses git-version-gen which uses .tarball-version for generating version number @@ -312,6 +333,11 @@ update_times_patch %{PATCH0} echo "%version+$(echo "%{version_or_commit}" | head -c 8)" > %{_builddir}/%{pcs_source_name}/.tarball-version %endif + +%if "x%{?ui_branch_or_commit}" != "x" + echo "%{ui_version}+$(echo "%{ui_branch_or_commit}" | head -c 8)" > %{_builddir}/%{ui_src_name}/.tarball-version +%endif + # prepare dirs/files necessary for building all bundles # ----------------------------------------------------- # 1) rubygems sources @@ -333,18 +359,17 @@ cp -f %SOURCE93 %{rubygem_cache_dir} cp -f %SOURCE94 %{rubygem_cache_dir} cp -f %SOURCE95 %{rubygem_cache_dir} cp -f %SOURCE96 %{rubygem_cache_dir} -cp -f %SOURCE97 %{rubygem_cache_dir} # 2) prepare python bundles mkdir -p %{pcs_bundled_dir}/src cp -f %SOURCE41 rpm/ -cp -f %SOURCE42 rpm/ cp -f %SOURCE44 rpm/ %build %define debug_package %{nil} +# We left off by setting up pcs, so we are in its directory now ./autogen.sh %{configure} --enable-local-build --enable-use-local-cache-only \ --enable-individual-bundling --with-pcsd-default-cipherlist='PROFILE=SYSTEM' \ @@ -352,25 +377,34 @@ cp -f %SOURCE44 rpm/ PYTHON=%{__python3} ruby_CFLAGS="%{optflags}" ruby_LIBS="%{build_ldflags}" make all -# build pcs-web-ui -BUILD_USE_CURRENT_NODE_MODULES=true make -C %{_builddir}/%{ui_src_name} build +# Web UI build +# Switch to web ui folder first +cd ../%{ui_src_name} +./autogen.sh +%{configure} \ + --disable-cockpit \ + --with-pcsd-webui-dir="%{_libdir}/%{pcsd_public_dir}/ui" +make all %install -rm -rf $RPM_BUILD_ROOT +rm -rf %{buildroot} pwd +# Install cockpit pcs-web-ui +cd ../%{ui_src_name} +%make_install + +# symlink favicon into pcsd directories +mkdir -p %{buildroot}%{_libdir}/%{pcsd_public_dir}/ui/static/media +ln -fs /etc/favicon.png %{buildroot}%{_libdir}/%{pcsd_public_dir}/ui/static/media/favicon.png + +# Install pcs +cd ../%{pcs_source_name} %make_install # RHEL-7716 - fix rubygem permissions - remove write access for owner's group # and other users -chmod --recursive g-w,o-w ${RPM_BUILD_ROOT}%{_libdir}/%{rubygem_bundle_dir} - -# install pcs-web-ui -cp -r %{_builddir}/%{ui_src_name}/build ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui - -# symlink favicon into pcsd directories -mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media -ln -fs /etc/favicon.png ${RPM_BUILD_ROOT}%{_libdir}/%{pcsd_public_dir}/ui/static/media/favicon.png +chmod --recursive g-w,o-w %{buildroot}%{_libdir}/%{rubygem_bundle_dir} # prepare license files mv %{rubygem_bundle_dir}/gems/backports-%{version_rubygem_backports}/LICENSE.txt backports_LICENSE.txt @@ -392,15 +426,11 @@ mv %{rubygem_bundle_dir}/gems/rackup-%{version_rubygem_rackup}/license.md rackup mv %{rubygem_bundle_dir}/gems/ruby2_keywords-%{version_rubygem_ruby2_keywords}/LICENSE ruby2_keywords_LICENSE mv %{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/LICENSE sinatra_LICENSE mv %{rubygem_bundle_dir}/gems/tilt-%{version_rubygem_tilt}/COPYING tilt_COPYING -mv %{rubygem_bundle_dir}/gems/webrick-%{version_rubygem_webrick}/LICENSE.txt webrick_LICENSE.txt cp %{pcs_bundled_dir}/src/pyagentx-*/LICENSE.txt pyagentx_LICENSE.txt cp %{pcs_bundled_dir}/src/pyagentx-*/CONTRIBUTORS.txt pyagentx_CONTRIBUTORS.txt cp %{pcs_bundled_dir}/src/pyagentx-*/README.md pyagentx_README.md -cp %{pcs_bundled_dir}/src/tornado-*/LICENSE tornado_LICENSE -cp %{pcs_bundled_dir}/src/tornado-*/README.rst tornado_README.rst - cp %{pcs_bundled_dir}/src/dacite-*/LICENSE dacite_LICENSE cp %{pcs_bundled_dir}/src/dacite-*/README.md dacite_README.md @@ -412,14 +442,28 @@ cp %{pcs_bundled_dir}/src/dacite-*/README.md dacite_README.md find-debuginfo -j2 -m -i -S debugsourcefiles.list # find-debuginfo generated some files into /usr/lib/debug and # /usr/src/debug/ that we don't want in the package -rm -rf $RPM_BUILD_ROOT%{_libdir}/debug -rm -rf $RPM_BUILD_ROOT/usr/lib/debug -rm -rf $RPM_BUILD_ROOT%{_prefix}/src/debug +rm -rf %{buildroot}%{_libdir}/debug +rm -rf %{buildroot}/usr/lib/debug +rm -rf %{buildroot}%{_prefix}/src/debug # We can remove files required for gem compilation -rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/ext -rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/nio4r-%{version_rubygem_nio4r}/ext -rm -rf $RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/ext +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/ext +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/nio4r-%{version_rubygem_nio4r}/ext +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/ext + +# Sinatra contains example applications which are unnecessary (discovered by brp_mangle_shebangs) +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/examples +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/examples + +# Puma contains an unnecessary rc init script (discovered by brp_mangle_shebangs) +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/docs/jungle/rc.d +rm -rf %{buildroot}%{_libdir}/%{rubygem_bundle_dir}/gems/puma-%{version_rubygem_puma}/docs/jungle/rc.d + +# Remove unused rubygem executables with wrong shebangs (discovered by brp_mangle_shebangs) +rm -fv %{buildroot}/%{_libdir}/pcsd/vendor/bundle/gems/puma-*/bin/puma +rm -fv %{buildroot}/%{_libdir}/pcsd/vendor/bundle/gems/puma-*/bin/pumactl +rm -fv %{buildroot}/%{_libdir}/pcsd/vendor/bundle/gems/rackup-*/bin/rackup +rm -fv %{buildroot}/%{_libdir}/pcsd/vendor/bundle/gems/tilt-*/bin/tilt %check # In the building environment LC_CTYPE is set to C which causes tests to fail @@ -447,8 +491,8 @@ run_all_tests(){ test_result_python=$? #run pcsd tests and remove them - GEM_HOME=$RPM_BUILD_ROOT%{_libdir}/%{rubygem_bundle_dir} ruby \ - -I$RPM_BUILD_ROOT%{_libdir}/pcsd \ + GEM_HOME=%{buildroot}%{_libdir}/%{rubygem_bundle_dir} ruby \ + -I%{buildroot}%{_libdir}/pcsd \ -Ipcsd/test \ pcsd/test/test_all_suite.rb test_result_ruby=$? @@ -493,9 +537,7 @@ run_all_tests %files %doc CHANGELOG.md %doc README.md -%doc tornado_README.rst %doc dacite_README.md -%license tornado_LICENSE %license dacite_LICENSE %license COPYING # rubygem licenses @@ -518,12 +560,12 @@ run_all_tests %license ruby2_keywords_LICENSE %license sinatra_LICENSE %license tilt_COPYING -%license webrick_LICENSE.txt %{python3_sitelib}/* %{_sbindir}/pcs %{_sbindir}/pcsd %{_libdir}/pcs/* %{_libdir}/pcsd/* +%{_libdir}/pkgconfig/pcs.pc %{_unitdir}/pcsd.service %{_unitdir}/pcsd-ruby.service %{_datadir}/bash-completion/completions/pcs @@ -559,6 +601,35 @@ run_all_tests %license pyagentx_LICENSE.txt %changelog +* Fri Feb 14 2025 Michal Pospisil - 0.11.9-2 +- Fixed restarting bundles + Resolves: RHEL-79055 +- Fixed deletion of misconfigured bundles + Resolves: RHEL-79160 +- Fixed filtering of resource clones in web console + Resolves: RHEL-78653 +- Updated bundled rubygem rack + Resolves: RHEL-79500 + +* Mon Jan 13 2025 Michal Pospisil - 0.11.9-1 +- Rebased pcs to the latest sources (see CHANGELOG.md) + Resolves: RHEL-44420 +- Updated pcs-web-ui to 0.1.22 + +* Mon Dec 16 2024 Michal Pospisil - 0.11.8-2 +- Rebased pcs to the latest sources (see CHANGELOG.md) + Resolves: RHEL-46303, RHEL-69040 +- Rebased pcs-web-ui to the latest sources + Resolves: RHEL-69272, RHEL-69278, RHEL-69279, RHEL-69280, RHEL-69281, RHEL-69282 + +* Tue Nov 19 2024 Michal Pospisil - 0.11.8-2 +- Rebased to the latest sources (see CHANGELOG.md) + Resolves: RHEL-16232, RHEL-46284, RHEL-46286, RHEL-46293, RHEL-55441, RHEL-61738, RHEL-61901 +- Updated pcs-web-ui to 0.1.21 +- Updated bundled rubygems: ffi, mustermann, puma, rack, rackup, tilt +- Removed bundled rubygem webrick +- New runtime dependency python3-tornado which has been bundled in previous versions + * Tue Jul 9 2024 Michal Pospisil - 0.11.8-1 - Updated pcs-web-ui to 0.1.20 - Rebased to the latest sources (see CHANGELOG.md)