Compare commits

..

No commits in common. "c10s" and "c8" have entirely different histories.
c10s ... c8

18 changed files with 1383 additions and 2072 deletions

View File

@ -1 +0,0 @@
1

76
.gitignore vendored
View File

@ -1,54 +1,22 @@
/backports-3.24.1.gem SOURCES/HAM-logo.png
/childprocess-4.1.0.gem SOURCES/backports-3.24.1.gem
/dacite-1.8.1.tar.gz SOURCES/dacite-1.8.1.tar.gz
/ethon-0.16.0.gem SOURCES/dataclasses-0.8.tar.gz
/ffi-1.16.3.gem SOURCES/ethon-0.16.0.gem
/mustermann-3.0.0.gem SOURCES/ffi-1.16.3.gem
/nio4r-2.5.9.gem SOURCES/json-2.6.3.gem
/pcs-0.11.7.tar.gz SOURCES/mustermann-2.0.2.gem
/pcs-web-ui-0.1.18.tar.gz SOURCES/nio4r-2.5.9.gem
/pcs-web-ui-node-modules-0.1.18.tar.xz SOURCES/open4-1.3.4-1.gem
/puma-6.4.0.gem SOURCES/pcs-0.10.18.tar.gz
/pyagentx-0.4.pcs.2.tar.gz SOURCES/puma-6.4.0.gem
/pycurl-7.45.3.tar.gz SOURCES/pyagentx-0.4.pcs.2.tar.gz
/rack-2.2.8.1.gem SOURCES/python-dateutil-2.8.2.tar.gz
/rack-protection-3.1.0.gem SOURCES/rack-2.2.8.1.gem
/rack-test-2.1.0.gem SOURCES/rack-protection-2.2.4.gem
/ruby2_keywords-0.0.5.gem SOURCES/rack-test-2.1.0.gem
/sinatra-3.1.0.gem SOURCES/rexml-3.3.6.gem
/tilt-2.3.0.gem SOURCES/ruby2_keywords-0.0.5.gem
/tornado-6.3.3.tar.gz SOURCES/sinatra-2.2.4.gem
/backports-3.25.0.gem SOURCES/tilt-2.3.0.gem
/base64-0.2.0.gem SOURCES/tornado-6.1.0.tar.gz
/childprocess-5.0.0.gem
/nio4r-2.7.3.gem
/puma-6.4.2.gem
/rack-3.0.11.gem
/rack-protection-4.0.0.gem
/rack-session-2.0.0.gem
/rackup-2.1.0.gem
/sinatra-4.0.0.gem
/webrick-1.8.1.gem
/tornado-6.4.0.tar.gz
/pcs-web-ui-0.1.19.tar.gz
/pcs-web-ui-node-modules-0.1.19.tar.xz
/pcs-5b7d498915e0cc876b29fe9ebd709c061ac754db.tar.gz
/pcs-0.12.0a1.tar.gz
/pcs-web-ui-0.1.20.tar.gz
/pcs-web-ui-node-modules-0.1.20.tar.xz
/ffi-1.17.0.gem
/mustermann-3.0.3.gem
/nio4r-2.7.4.gem
/puma-6.4.3.gem
/rack-3.1.8.gem
/rackup-2.2.1.gem
/tilt-2.4.0.gem
/pcs-0.12.0b1.tar.gz
/pcs-web-ui-0.1.21.tar.gz
/pcs-web-ui-node-modules-0.1.21.tar.xz
/pcs-1353dfbb3af82d77f4de17a3fa4cbde185bb2b2d.tar.gz
/pcs-web-ui-34372d1268f065ed186546f55216aaa2d7e76b54.tar.gz
/pcs-web-ui-0.1.22.tar.gz
/pcs-web-ui-node-modules-0.1.22.tar.xz
/pcs-0.12.0.tar.gz
/rack-3.1.10.gem

22
.pcs.metadata Normal file
View File

@ -0,0 +1,22 @@
679a4ce22a33ffd4d704261a17c00cff98d9499a SOURCES/HAM-logo.png
0ef72a288913e220695ad62718aeb75171924028 SOURCES/backports-3.24.1.gem
07b26abbf7ff0dcba5c7f9e814ff7eebafefb058 SOURCES/dacite-1.8.1.tar.gz
8b7598273d2ae6dad2b88466aefac55071a41926 SOURCES/dataclasses-0.8.tar.gz
5b56a68268708c474bef04550639ded3add5e946 SOURCES/ethon-0.16.0.gem
10e4cf0e11ef4581ec4ad5fe2cdf3c78b6077d39 SOURCES/ffi-1.16.3.gem
6d78f730b7f3b25fb3f93684fe1364acf58bce6b SOURCES/json-2.6.3.gem
f5f804366823c1126791dfefd98dd0539563785c SOURCES/mustermann-2.0.2.gem
2f65d371f5f37460ad74afcedcb97d2b41a46806 SOURCES/nio4r-2.5.9.gem
41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
b3cd873042b17021355b68f1f7aa313f0c1f3fee SOURCES/pcs-0.10.18.tar.gz
d6049c4555f3c9d198e6eb1d7e53ce9b68e175ff SOURCES/puma-6.4.0.gem
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
fcdee79d1b0bb7e3666bad96321fc124bc8215e9 SOURCES/rack-2.2.8.1.gem
5347315a7283f0b04443e924ed4eaa17807432c8 SOURCES/rack-protection-2.2.4.gem
ae09ea83748b55875edc3708fffba90db180cb8e SOURCES/rack-test-2.1.0.gem
89f8446e89976f3677767d426a4edc6ccba574be SOURCES/rexml-3.3.6.gem
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
fa6a6c98f885e93f54c23dd0454cae906e82c31b SOURCES/sinatra-2.2.4.gem
4a38a9a55887b2882182a2c5771e592efe514e5e SOURCES/tilt-2.3.0.gem
c23c617c7a0205e465bebad5b8cdf289ae8402a2 SOURCES/tornado-6.1.0.tar.gz

View File

@ -1,82 +0,0 @@
From e949ae0e2fc350ed1e74ce48b50ac812efd92f30 Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
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<Resource, {itemType: "group"}>;
type Clone = Extract<Resource, {itemType: "clone"}>;
@@ -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

View File

@ -1,169 +0,0 @@
From df6e16235702f3d5f2bb8eb24e633a75c27e1e70 Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Wed, 12 Feb 2025 14:00:26 +0100
Subject: [PATCH 1/2] fix restarting bundle instances
* fixes a regression introduced in 557ea61b7cfb7948fb2f60916dda84651c4ef4f8
---
pcs/lib/commands/resource.py | 98 ++++++++++---------
.../lib/commands/resource/test_restart.py | 16 +--
2 files changed, 54 insertions(+), 60 deletions(-)
diff --git a/pcs/lib/commands/resource.py b/pcs/lib/commands/resource.py
index db9be21fe..10a43e1cc 100644
--- a/pcs/lib/commands/resource.py
+++ b/pcs/lib/commands/resource.py
@@ -2665,63 +2665,69 @@ 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"]
+ 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() 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,
+ raise LibraryError()
+
+ if resource.stonith.is_stonith(resource_el):
+ env.report_processor.report(
+ reports.ReportItem.error(
+ reports.messages.CommandArgumentTypeMismatch(
+ "stonith resource"
+ )
)
)
- )
- raise LibraryError()
- if resource.stonith.is_stonith(resource_el):
- env.report_processor.report(
- reports.ReportItem.error(
- reports.messages.CommandArgumentTypeMismatch("stonith resource")
- )
- )
- 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(
@@ -2733,7 +2739,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 d3c8fae92..7c072dc5f 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

View File

@ -1,280 +0,0 @@
From ae5fbbefab98618c644befe80c8791d513bdd711 Mon Sep 17 00:00:00 2001
From: Peter Romancik <promanci@redhat.com>
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 cde8365f6..0da1aa08b 100644
--- a/pcs/common/reports/codes.py
+++ b/pcs/common/reports/codes.py
@@ -182,6 +182,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 b8e151ef4..23bebd1f5 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,
@@ -6430,6 +6431,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 d9596a679..d601f85c1 100644
--- a/pcs/lib/cib/remove_elements.py
+++ b/pcs/lib/cib/remove_elements.py
@@ -251,17 +251,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(
@@ -310,20 +320,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 f2e2fb70c..b4eff2a20 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
@@ -6101,3 +6102,25 @@ class CannotStopResourcesBeforeDeleting(NameBuildTest):
["resourceId1", "resourceId2"]
),
)
+
+
+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 603447689..78bdaa85a 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
@@ -949,3 +950,68 @@ class RemoveElementsStopResources(TestCase, StopResourcesWaitMixin):
),
]
)
+
+ def test_skip_state_check_on_missing_from_status(self):
+ self.config.runner.cib.load(
+ resources="""
+ <resources>
+ <bundle id="test-bundle">
+ <podman image="localhost/pcmktest:test"/>
+ <primitive id="apa" class="ocf" type="apache" provider="heartbeat"/>
+ </bundle>
+ </resources>
+ """
+ )
+ self.fixture_stop_resources_wait_calls(
+ self.config.calls.get("runner.cib.load").stdout,
+ initial_state_modifiers={"resources": "<resources/>"},
+ after_disable_cib_modifiers={
+ "resources": """
+ <resources>
+ <bundle id="test-bundle">
+ <podman image="localhost/pcmktest:test"/>
+ <primitive id="apa" class="ocf" type="apache" provider="heartbeat">
+ <meta_attributes id="apa-meta_attributes">
+ <nvpair id="apa-meta_attributes-target-role" name="target-role" value="Stopped"/>
+ </meta_attributes>
+ </primitive>
+ </bundle>
+ </resources>
+ """
+ },
+ after_disable_state_modifiers={"resources": "<resources/>"},
+ )
+ self.fixture_push_cib_after_stopping(
+ resources="""
+ <resources>
+ <bundle id="test-bundle">
+ <podman image="localhost/pcmktest:test"/>
+ </bundle>
+ </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

View File

@ -0,0 +1,55 @@
From 957856a556f5ed92129ce602538c3df3aebce7a3 Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 5 Dec 2023 15:18:35 +0100
Subject: [PATCH 2/2] disable alternative webui routes
This commit is intended to be downstream only.
The new web ui was part of rhel8 as a technical preview. But new web ui
is now the main in rhel9 and there is no need to keep it in rhel8.
To prevent unnecessary maintenance burden it is disabled now.
No handler code is removed, just routing disabled.
---
pcs/daemon/run.py | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/pcs/daemon/run.py b/pcs/daemon/run.py
index 7fdeda2a..0a6b1b21 100644
--- a/pcs/daemon/run.py
+++ b/pcs/daemon/run.py
@@ -81,16 +81,22 @@ def configure_app(
routes.extend(
# old web ui by default
[(r"/", RedirectHandler, dict(url="/manage"))]
- + [(r"/ui", RedirectHandler, dict(url="/ui/"))]
- + ui.get_routes(
- url_prefix="/ui/",
- app_dir=os.path.join(public_dir, "ui"),
- fallback_page_path=os.path.join(
- public_dir,
- "ui_instructions.html",
- ),
- session_storage=session_storage,
- )
+ # The following disabled routes was for the new web ui. The new
+ # web ui was here as a technical preview. But new web ui is now
+ # the main in rhel9 and there is no need to keep it in rhel8.
+ # To prevent unnecessary maintenance burden it is disabled now.
+ # No handler code is removed, just routing disabled.
+ #
+ # + [(r"/ui", RedirectHandler, dict(url="/ui/"))]
+ # + ui.get_routes(
+ # url_prefix="/ui/",
+ # app_dir=os.path.join(public_dir, "ui"),
+ # fallback_page_path=os.path.join(
+ # public_dir,
+ # "ui_instructions.html",
+ # ),
+ # session_storage=session_storage,
+ # )
+ sinatra_ui.get_routes(
session_storage, ruby_pcsd_wrapper, public_dir
)
--
2.43.0

View File

@ -0,0 +1,52 @@
From 6142961fe0e39bdbba0d70f792fc27fb2bc096ba Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Thu, 7 Mar 2024 16:51:13 +0100
Subject: [PATCH] stop sending http headers to ruby part of pcsd
---
pcs/daemon/ruby_pcsd.py | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/pcs/daemon/ruby_pcsd.py b/pcs/daemon/ruby_pcsd.py
index 4b3b0ea1..e07e17cc 100644
--- a/pcs/daemon/ruby_pcsd.py
+++ b/pcs/daemon/ruby_pcsd.py
@@ -87,13 +87,34 @@ class RubyDaemonRequest(
http_request: HTTPServerRequest = None,
payload=None,
):
- headers = http_request.headers if http_request else HTTPHeaders()
+ # Headers from request are not propagated to ruby part. Ruby part doesn't
+ # work with standard headers in any special way. So, we send only path,
+ # method, query, body and special headers for communication between
+ # python part and ruby part. Tornado then adds necessary default
+ # headers. The motivation here is to prevent processing potentially
+ # maliciously crafted headers by rack.
+ headers = HTTPHeaders()
headers.add("X-Pcsd-Type", request_type)
if payload:
headers.add(
"X-Pcsd-Payload",
b64encode(json.dumps(payload).encode()).decode(),
)
+ if http_request:
+ for key, val in http_request.headers.get_all():
+ # From webui, POST request can come with either
+ # application/x-www-form-urlencoded or application/json content
+ # type. When we remove original HTTP headers, content type is
+ # added by tornado. But in the case of original application/json,
+ # tornado puts application/x-www-form-urlencoded there. To fix
+ # this let's keep the original header here in this case.
+ #
+ # The token, CIB_user and CIB_user_groups are transferred by the
+ # "Cookie" header and these information are evaluated in ruby.
+ if (
+ key.lower() == "content-type" and val == "application/json"
+ ) or key.lower() == "cookie":
+ headers.add(key, val)
return super(RubyDaemonRequest, cls).__new__(
cls,
request_type,
--
2.47.0

View File

@ -0,0 +1,53 @@
From 854efcf148c82e5a5e4f0afd71cc3333ea4a8ce4 Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 20 Nov 2018 15:03:56 +0100
Subject: [PATCH 1/2] do not support cluster setup with udp(u) transport
---
pcs/pcs.8.in | 2 ++
pcs/usage.py | 1 +
pcsd/public/css/style.css | 3 +++
3 files changed, 6 insertions(+)
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
index d504e8b4..93202d05 100644
--- a/pcs/pcs.8.in
+++ b/pcs/pcs.8.in
@@ -438,6 +438,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
Transports udp and udpu:
.br
+WARNING: These transports are not supported in RHEL 8.
+.br
These transports are limited to one address per node. They do not support traffic encryption nor compression.
.br
Transport options are: ip_version, netmtu
diff --git a/pcs/usage.py b/pcs/usage.py
index f4b84202..ee10370a 100644
--- a/pcs/usage.py
+++ b/pcs/usage.py
@@ -1038,6 +1038,7 @@ Commands:
hash=sha256. To disable encryption, set cipher=none and hash=none.
Transports udp and udpu:
+ WARNING: These transports are not supported in RHEL 8.
These transports are limited to one address per node. They do not
support traffic encryption nor compression.
Transport options are:
diff --git a/pcsd/public/css/style.css b/pcsd/public/css/style.css
index 2f26e831..a7702ac4 100644
--- a/pcsd/public/css/style.css
+++ b/pcsd/public/css/style.css
@@ -949,6 +949,9 @@ table.args-table td.reg {
width: 6ch;
text-align: right;
}
+#csetup-transport .transport-types {
+ display: none;
+}
#csetup-transport-options.udp .knet-only,
#csetup-transport-options.knet .without-knet
{
--
2.43.0

1179
SPECS/pcs.spec Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
From 7bfa2ad4f4f5f59fd501b0cec23cdc489f90a09e Mon Sep 17 00:00:00 2001
From: Michal Pospisil <mpospisi@redhat.com>
Date: Thu, 23 May 2024 17:22:12 +0200
Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL10
---
pcs/pcs.8.in | 2 ++
pcs/usage.py | 1 +
2 files changed, 3 insertions(+)
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
index 0bc1a4e5..4dea3582 100644
--- a/pcs/pcs.8.in
+++ b/pcs/pcs.8.in
@@ -479,6 +479,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
Transports udp and udpu:
.br
+WARNING: These transports are not supported in RHEL 10.
+.br
These transports are limited to one address per node. They do not support traffic encryption nor compression.
.br
Transport options are: ip_version, netmtu
diff --git a/pcs/usage.py b/pcs/usage.py
index 26204c59..31eba549 100644
--- a/pcs/usage.py
+++ b/pcs/usage.py
@@ -1496,6 +1496,7 @@ Commands:
hash=sha256. To disable encryption, set cipher=none and hash=none.
Transports udp and udpu:
+ WARNING: These transports are not supported in RHEL 10.
These transports are limited to one address per node. They do not
support traffic encryption nor compression.
Transport options are:
--
2.45.1

View File

@ -1,49 +0,0 @@
summary: PCS gating test plan
description: Runs upstream tier0, tier1 and smoke tests
discover:
how: shell
dist-git-source: true
tests:
# Workaround until tmt supports patching sources
- name: Patch sources and run autotools
test: ./prepare-env.sh
duration: 30m
- name: Tier 0 tests
test: ./builddir/pcs-*/pcs_test/suite --tier0 -v --vanilla --installed
duration: 10m
- name: Tier 1 tests
test: ./builddir/pcs-*/pcs_test/suite --tier1 -v --vanilla --installed
duration: 2h
- name: Smoke tests
test: |
systemctl start pcsd
./builddir/pcs-*/pcs_test/smoke.sh
duration: 10m
prepare:
- name: Install packages
how: install
package:
- autoconf
- automake
- make
- diffstat
- rpm-build
- ruby-devel
- git-core
- booth-site
- fence-agents-apc
- fence-agents-ipmilan
- fence-agents-scsi
- fence-virt
- openssl
- pcs
- pcs-snmp
- python3-pip
- python3-setuptools_scm
- python3-wheel
- rubygem-json
- rubygem-test-unit
- wget
execute:
how: tmt

View File

@ -1,7 +0,0 @@
# recipients: idevat,mlisik,mpospisi,omular,tojeline
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

1197
pcs.spec

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
set -eo xtrace
# Rpmbuild expects patches in the _sourcedir
find *.patch &> /dev/null && mv *.patch $TMT_SOURCE_DIR
mkdir builddir
rpmbuild -bp pcs.spec --nodeps --define "_sourcedir $TMT_SOURCE_DIR" \
--define "_builddir $(pwd)/builddir"
# Remove *SPECPARTS folders generated by rpmbuild
rm -rfv builddir/*SPECPARTS
# Remove pcs-web-ui in builddir for "cd pcs-*" to have exactly one match
rm -rf builddir/pcs-web-ui-*
cd builddir/pcs-*
# Run autotools, use bundled dependencies from the system
export PYTHONPATH=/usr/lib64/pcs/pcs_bundled/packages/
export GEM_HOME=/usr/lib64/pcsd/vendor/bundle/
./autogen.sh
./configure
# Remove pcs sources to make sure tests are not using any of those files
rm -rf pcs

View File

@ -1,8 +0,0 @@
xml:
# exclude ruby templates from checks
exclude_path: .*\.erb$
shellsyntax:
# exclude ruby templates from checks
ignore:
- /usr/lib*/pcsd/vendor/bundle/gems/thin*/lib/thin/controllers/*.erb

View File

@ -1,148 +0,0 @@
From 264b69c1eedae035bbb1bcf345403978ebe5a222 Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 5 Nov 2024 16:35:02 +0100
Subject: [PATCH] show info page instead of webui
---
pcs/Makefile.am | 1 +
pcs/daemon/app/webui_info_handler.py | 31 ++++++++++++++++++++++++++++
pcs/daemon/run.py | 4 +++-
pcs_test/smoke.sh.in | 4 ++--
pcsd/public/ui_instructions.html | 26 ++++++++++-------------
5 files changed, 48 insertions(+), 18 deletions(-)
create mode 100644 pcs/daemon/app/webui_info_handler.py
diff --git a/pcs/Makefile.am b/pcs/Makefile.am
index 7a734dc1..45d5801f 100644
--- a/pcs/Makefile.am
+++ b/pcs/Makefile.am
@@ -206,6 +206,7 @@ EXTRA_DIST = \
daemon/app/webui/core.py \
daemon/app/webui/session.py \
daemon/app/webui/sinatra_ui.py \
+ daemon/app/webui_info_handler.py \
daemon/async_tasks/__init__.py \
daemon/async_tasks/scheduler.py \
daemon/async_tasks/task.py \
diff --git a/pcs/daemon/app/webui_info_handler.py b/pcs/daemon/app/webui_info_handler.py
new file mode 100644
index 00000000..3ab8275b
--- /dev/null
+++ b/pcs/daemon/app/webui_info_handler.py
@@ -0,0 +1,31 @@
+from pcs.daemon.app.common import (
+ BaseHandler,
+ RoutesType,
+)
+
+
+class _WebuiInfoHandler(BaseHandler):
+ __path = None
+
+ def initialize(self, path):
+ self.__path = path
+
+ def get(self):
+ self.set_status(404)
+ self.render(self.__path)
+
+
+def get_routes(path: str) -> RoutesType:
+ return [
+ # The following two rules can be compressed into one: r"/(ui/?)?".
+ # However, the content of the parentheses used here should be captured
+ # and passed in to the handlers get method as an argument.
+ # Unfortunately, it seems that tornado version 6.4.1 don't pass this
+ # argument (unlike version 6.3.3). Maybe it's a bug (it needs further
+ # inspection). These rules are a safe way to avoid surprises.
+ # Moreover, the captured parameter is irrelevant to the functionality
+ # of the handler.
+ (r"/", _WebuiInfoHandler, dict(path=path)),
+ (r"/ui/?", _WebuiInfoHandler, dict(path=path)),
+ (r"/ui/.*", _WebuiInfoHandler, dict(path=path)),
+ ]
diff --git a/pcs/daemon/run.py b/pcs/daemon/run.py
index e0090fc1..e80eecfe 100644
--- a/pcs/daemon/run.py
+++ b/pcs/daemon/run.py
@@ -35,6 +35,7 @@ from pcs.daemon.app import capabilities as capabilities_app
from pcs.daemon.app import (
sinatra_remote,
sinatra_ui,
+ webui_info_handler,
)
try:
@@ -142,7 +143,8 @@ def configure_app(
# Even with disabled (standalone) webui the following routes must be
# provided because they can be used via unix socket from cockpit.
routes.extend(
- sinatra_ui.get_routes(auth_provider, ruby_pcsd_wrapper)
+ webui_info_handler.get_routes(webui_fallback)
+ + sinatra_ui.get_routes(auth_provider, ruby_pcsd_wrapper)
)
return Application(
diff --git a/pcs_test/smoke.sh.in b/pcs_test/smoke.sh.in
index fdfe8be2..a9bb8344 100755
--- a/pcs_test/smoke.sh.in
+++ b/pcs_test/smoke.sh.in
@@ -71,10 +71,10 @@ if [ "$webui_http_code_response" = "200" ]; then
curl --insecure --cookie ${cookie_file} --header "X-Requested-With: XMLHttpRequest" --data "hidden[hidden_input]=&config[stonith-enabled]=false" https://localhost:2224/managec/${cluster_name}/update_cluster_settings > "${output_file}"
cat "${output_file}"; echo ""
[ "$(cat ${output_file})" = "Update Successful" ]
-elif [ "$webui_http_code_response" = "401" ]; then
+elif [ "$webui_http_code_response" = "404" ]; then
curl --insecure https://localhost:2224/ui/ > "${output_file}"
cat "${output_file}"; echo ""
- [ "$(cat "${output_file}")" = '{"notauthorized":"true"}' ]
+ grep "HA cluster management has been moved" "${output_file}"
else
echo "Unexpected response from https://localhost:2224/ui/ - http code: '${webui_http_code_response}'"
exit 1
diff --git a/pcsd/public/ui_instructions.html b/pcsd/public/ui_instructions.html
index a120ed3d..ac0117c8 100644
--- a/pcsd/public/ui_instructions.html
+++ b/pcsd/public/ui_instructions.html
@@ -1,27 +1,23 @@
<!DOCTYPE html>
<html>
<head>
- <title>Pcs WebUI instructions</title>
+ <title>HA cluster management has been moved</title>
<meta charset="utf-8" />
</head>
<body>
- <h1>Pcs WebUI instructions</h1>
+ <h1>HA cluster management has been moved</h1>
<p>
- WebUI is not a part of pcs repository but it has its own
- <a href="https://github.com/ClusterLabs/pcs-web-ui">repository</a>.
+ Since RHEL 10, pcsd web UI is no longer available. Management of high
+ availability clusters has been<br>moved to an add-on for the RHEL web
+ console. The HA Cluster Management add-on can be installed<br>from within
+ the RHEL web console or by installing the <code>cockpit-ha-cluster</code>
+ RPM package.
</p>
<p>
- You can clone <a href="https://github.com/ClusterLabs/pcs-web-ui">WebUI repository</a>
- and build the web application into pcs by:
- </p>
- <pre><code>
- $ npm install
- $ npm run build
- $ mv ./build [/path/to/]pcs/pcsd/public/ui
- </code></pre>
- <p>
- For more details, see instructions in
- <a href="https://github.com/ClusterLabs/pcs-web-ui/blob/main/README.md">README.md</a>.
+ To learn more, please visit:
+ <a href="https://access.redhat.com/solutions/7099451">
+ https://access.redhat.com/solutions/7099451
+ </a>
</p>
</body>
</html>
--
2.47.1

21
sources
View File

@ -1,21 +0,0 @@
SHA512 (dacite-1.8.1.tar.gz) = 4b40c0bdcf5490bcc77de9e7f04b7267642bcfd41e4168607a5457f38abe3ad4b3041d8a23cb43af76de14eabee45f900ad5ddf7af8f70a2be4850bccc2d3af1
SHA512 (ethon-0.16.0.gem) = 3b31affcee0d5a5be05b5497d4a8d13515f8393f54579a3a9c8de49f78d3f065bb92659434b023f0a8bf8e0cccfbc94b617695b93c4d3f744cccd1eff2e68905
SHA512 (pyagentx-0.4.pcs.2.tar.gz) = d4194fec9a3e5fefe3793d49b7fec1feafef294c7e613a06046c2993daeefc5cb39d7c5b2b402ff83e49b2d976953f862264288c758c0be09d997b5323cc558a
SHA512 (pycurl-7.45.3.tar.gz) = 12a55070602a1fd22b160ad582a4001bdd28531d2b2ccd365ff0136bc13dd23af80b19488bdbbc60a902a3a362b64383b9ae6acce6ed328c74dcffc8a6a3f4ad
SHA512 (rack-test-2.1.0.gem) = e349ce61c3d787e0a772980db697e92212d4d9592ce33f55516d1f85fba55cbe666496c76392679b057786d6dab603d74b83e7bb773ab54940343e36dbf05d6f
SHA512 (backports-3.25.0.gem) = 47a2ffb83030cb317e85a4f72a1c4a76a90324b8928ac73e1aa3404a22136661e9ce718bfdd937fbe07b9e05a338fcbd717bb505fb1dd91cfee570bbff9e3f72
SHA512 (base64-0.2.0.gem) = ee5cdc30e73e625c15cb674cdd16a839ad44ffb0a27d1363f94491b48d95da37a2976c34f6f616b722a35750a067eb2245c4746d7d36f8e9a9ecee68ff5540fb
SHA512 (childprocess-5.0.0.gem) = 9ec340c86f4fd978b7a9925bcf90811ff3443f014469e4ff121e2c4758a4068823029ab413d1a57eb9de4a864435505b1edfa60a611709f2a5f99aaf08da422d
SHA512 (rack-protection-4.0.0.gem) = 5eb33e4829e5e0d320a14d169fd007111641e388f2b6e5f8de98d45dfd1e6705cdb4e1ce29524ebb6fb5afe14079b8e5370c9c389cb2befca4ca508da73165b3
SHA512 (rack-session-2.0.0.gem) = 827cd1acf20eb814adda7663f61755febd2e6acec6ee085dbc393b614a621f845dffa8f759e434055dbf029be370afeb921c8759c9e9e1fee17119830d9b2899
SHA512 (sinatra-4.0.0.gem) = 1eb8c6e8966461d3fa463b5c87e8bc3cd58243fc997a104671e252b866bb653dfc16d7b9f677e016ae91cb30998d72f8778eb2b2254ce27cf304944a6bfa8c05
SHA512 (ffi-1.17.0.gem) = 5cdaf19eaa499127607de7389f69b4927c7bd8a154a53071c53906050bc712b67c1fbc7b4b37fcf9a82fa6c79d705796032cd7ab61755646cfed0c2d279940a1
SHA512 (mustermann-3.0.3.gem) = d205985a5da83d83248899642ed359056b0cdb511e77d51309319c2f8d8b6c84040e9e1d3a56b7f83a0b26aed4b344f4df371b310e419c20170f0a486e89ba6f
SHA512 (nio4r-2.7.4.gem) = 6c8280484066ffc39e98b99dfaf5a69fe2a28cafb380924f448673fda8b69b5d97f8b75b8345b91d92f6186f0664e09bec8e1c7c19c070219b030f554824d2ac
SHA512 (puma-6.4.3.gem) = e8baf137c5164f11b8563561405fc4218210707bfb15d0f21118d4be0fd0d071050c46357337a9c6fdda7ce230f3ae09ebfe9976f0a7a0243824bda7871d7a18
SHA512 (rackup-2.2.1.gem) = e63c4dee6f1a677d507df0ae7bcebec88673e7a0a8d6621997949045db60801907038a148a0608f6e62864cb2ac056fca382f3438dc227b0fa7a3be52d56ea66
SHA512 (tilt-2.4.0.gem) = 8cf5036017f501da8843340a9c574ee647074782dcb27ee0aa906fb96ad1e66b90dfb80159aa4c5e7605490058c5ae478bd0fe09f17ae50a2697327d02c814cc
SHA512 (pcs-web-ui-0.1.22.tar.gz) = cb97ffba625326ab3857b9c22b4400907177a5ea88769ae611cc9315758c1ceca7e16a1b92d43fc594911fcde6003d3beadb388c6bdd5c1bcc67d699c49c9b2c
SHA512 (pcs-web-ui-node-modules-0.1.22.tar.xz) = b1db7d8c04e942baf8a99f115cbda31a84f562c7deeee5f1371e5ddf5fb5e73ce084ede1f0da7083b2d0114228f58006599f1b9a29dd3a5202b3119e41f74d69
SHA512 (pcs-0.12.0.tar.gz) = f9b93bd39ce18898aa3bab7d4da86535e7351b75f15a0bc333598e2dae03ebf0f0f0638b1b441533af7f32909902353c3cf3ed5a219d0ce3b67a3a0e2c63b194
SHA512 (rack-3.1.10.gem) = 2da18867543b7c536e152cbb48a1680473b9b53c405f71c51c3263ae7d40435dfcc66b99caee0e14d901affa36bfcedb6fa5defe9ecbd2ce82687f71f8d2ef43