Compare commits
No commits in common. "c8" and "c9-beta" have entirely different histories.
40
.gitignore
vendored
40
.gitignore
vendored
@ -1,22 +1,22 @@
|
||||
SOURCES/HAM-logo.png
|
||||
SOURCES/backports-3.24.1.gem
|
||||
SOURCES/dacite-1.8.1.tar.gz
|
||||
SOURCES/dataclasses-0.8.tar.gz
|
||||
SOURCES/ethon-0.16.0.gem
|
||||
SOURCES/ffi-1.16.3.gem
|
||||
SOURCES/json-2.6.3.gem
|
||||
SOURCES/mustermann-2.0.2.gem
|
||||
SOURCES/nio4r-2.5.9.gem
|
||||
SOURCES/open4-1.3.4-1.gem
|
||||
SOURCES/pcs-0.10.18.tar.gz
|
||||
SOURCES/puma-6.4.0.gem
|
||||
SOURCES/backports-3.25.3.gem
|
||||
SOURCES/base64-0.2.0.gem
|
||||
SOURCES/childprocess-5.1.0.gem
|
||||
SOURCES/dacite-1.9.2.tar.gz
|
||||
SOURCES/ethon-0.18.0.gem
|
||||
SOURCES/ffi-1.17.2.gem
|
||||
SOURCES/logger-1.7.0.gem
|
||||
SOURCES/mustermann-3.1.1.gem
|
||||
SOURCES/nio4r-2.7.5.gem
|
||||
SOURCES/pcs-0.11.12.tar.gz
|
||||
SOURCES/pcs-web-ui-0.1.25.tar.gz
|
||||
SOURCES/pcs-web-ui-node-modules-0.1.25.tar.xz
|
||||
SOURCES/puma-8.0.1.gem
|
||||
SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||
SOURCES/python-dateutil-2.8.2.tar.gz
|
||||
SOURCES/rack-2.2.20.gem
|
||||
SOURCES/rack-protection-2.2.4.gem
|
||||
SOURCES/rack-test-2.1.0.gem
|
||||
SOURCES/rexml-3.4.1.gem
|
||||
SOURCES/rack-3.2.6.gem
|
||||
SOURCES/rack-protection-4.2.1.gem
|
||||
SOURCES/rack-session-2.1.2.gem
|
||||
SOURCES/rack-test-2.2.0.gem
|
||||
SOURCES/rackup-2.3.1.gem
|
||||
SOURCES/ruby2_keywords-0.0.5.gem
|
||||
SOURCES/sinatra-2.2.4.gem
|
||||
SOURCES/tilt-2.3.0.gem
|
||||
SOURCES/tornado-v6.1.0.pcs.4.tar.gz
|
||||
SOURCES/sinatra-4.2.1.gem
|
||||
SOURCES/tilt-2.7.0.gem
|
||||
|
||||
@ -1,22 +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
|
||||
41b95975c12381bcd9cbc32bd278440313fce12d SOURCES/backports-3.25.3.gem
|
||||
ea3a591bdfa93655d8eec9d7bdd7fb87ecb5616a SOURCES/base64-0.2.0.gem
|
||||
963b12b359251f41998eebe6f6adfec92fe6f49f SOURCES/childprocess-5.1.0.gem
|
||||
01690d9883c149890e04dce4db43ec305959aa39 SOURCES/dacite-1.9.2.tar.gz
|
||||
ffd8b3e5ac044a1a69791411e3e5cf4b5d4a6768 SOURCES/ethon-0.18.0.gem
|
||||
01747fce469e932b701cb7a35d1ef4b3c68eb170 SOURCES/ffi-1.17.2.gem
|
||||
abfa641d98ab2e71bc8102b0aab2f466569668d2 SOURCES/logger-1.7.0.gem
|
||||
0b23c093481361b6b7dc4c733407e28f6aba181a SOURCES/mustermann-3.1.1.gem
|
||||
34420ab7703c0033e18680504a9f8899322ac908 SOURCES/nio4r-2.7.5.gem
|
||||
4377db28b20fbf93819f3d719545d644e93b9886 SOURCES/pcs-0.11.12.tar.gz
|
||||
76c4bde0b534e8ce82ad2b2f3b155faaa09ae6fb SOURCES/pcs-web-ui-0.1.25.tar.gz
|
||||
384635d68c0648c3d18c53c0c7a93227167841bf SOURCES/pcs-web-ui-node-modules-0.1.25.tar.xz
|
||||
7fb9184ad87327fd94ea3c1f75158d3ca8332d4a SOURCES/puma-8.0.1.gem
|
||||
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
|
||||
4c52ad6f798e78d4a1800257ef0d7fc5ac254712 SOURCES/rack-2.2.20.gem
|
||||
5347315a7283f0b04443e924ed4eaa17807432c8 SOURCES/rack-protection-2.2.4.gem
|
||||
ae09ea83748b55875edc3708fffba90db180cb8e SOURCES/rack-test-2.1.0.gem
|
||||
966b1564a77719483eb61068ed1dfb638e5e8eb0 SOURCES/rexml-3.4.1.gem
|
||||
41b3f39ab51fe8584be6f9e849152bb69b06f575 SOURCES/rack-3.2.6.gem
|
||||
1457dded6ffa0f564b33329861dd6b257f07498d SOURCES/rack-protection-4.2.1.gem
|
||||
3353c03a5d41f14bfa3459436400fc363ab4fd96 SOURCES/rack-session-2.1.2.gem
|
||||
922c597f0503f97dc3a058fe997590b108bc429a SOURCES/rack-test-2.2.0.gem
|
||||
f470c1dc5a15e44a241cae4cb50d94b7b3f6b010 SOURCES/rackup-2.3.1.gem
|
||||
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
|
||||
fa6a6c98f885e93f54c23dd0454cae906e82c31b SOURCES/sinatra-2.2.4.gem
|
||||
4a38a9a55887b2882182a2c5771e592efe514e5e SOURCES/tilt-2.3.0.gem
|
||||
bf4020626453c8db65d1817bed7b1884ea530e92 SOURCES/tornado-v6.1.0.pcs.4.tar.gz
|
||||
611999f43e27779278c80acfb5825c7255497988 SOURCES/sinatra-4.2.1.gem
|
||||
93253f48f74242535d1c572e88a5651f2c1565c4 SOURCES/tilt-2.7.0.gem
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
From 7fc3db518798cbbd4d11028d52837d460640fb06 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michal=20Posp=C3=AD=C5=A1il?= <mpospisi@redhat.com>
|
||||
Date: Wed, 25 Mar 2026 22:01:21 +0100
|
||||
Subject: [PATCH] disable multipart requests in Tornado
|
||||
|
||||
Pcsd doesn't use multipart requests and recently, there have been
|
||||
vulnerabilities targeting both Rack and Tornado. Since we use Tornado as
|
||||
a proxy for our Ruby daemon, this also helps mitigate future Rack multipart
|
||||
vulnerabilities.
|
||||
|
||||
Multipart vulnerabilities:
|
||||
https://www.cve.org/CVERecord?id=CVE-2026-31958
|
||||
https://www.cve.org/CVERecord?id=CVE-2025-61771
|
||||
https://www.cve.org/CVERecord?id=CVE-2025-61770
|
||||
---
|
||||
pcs/daemon/run.py | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/pcs/daemon/run.py b/pcs/daemon/run.py
|
||||
index 0a6b1b211..19586b18a 100644
|
||||
--- a/pcs/daemon/run.py
|
||||
+++ b/pcs/daemon/run.py
|
||||
@@ -3,6 +3,11 @@ import signal
|
||||
import socket
|
||||
from pathlib import Path
|
||||
|
||||
+from tornado.httputil import (
|
||||
+ ParseBodyConfig,
|
||||
+ ParseMultipartConfig,
|
||||
+ set_parse_body_config,
|
||||
+)
|
||||
from tornado.ioloop import IOLoop
|
||||
from tornado.locks import Lock
|
||||
from tornado.web import Application
|
||||
@@ -71,6 +76,16 @@ def configure_app(
|
||||
reload its SSL certificates). A relevant handler should get this
|
||||
object via the method `initialize`.
|
||||
"""
|
||||
+
|
||||
+ # Disable multipart requests to enhance security due to recent CVEs
|
||||
+ # https://www.cve.org/CVERecord?id=CVE-2026-31958
|
||||
+ # https://www.cve.org/CVERecord?id=CVE-2025-61771
|
||||
+ # https://www.cve.org/CVERecord?id=CVE-2025-61770
|
||||
+ # https://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.set_parse_body_config
|
||||
+ set_parse_body_config(
|
||||
+ ParseBodyConfig(multipart=ParseMultipartConfig(enabled=False))
|
||||
+ )
|
||||
+
|
||||
routes = sinatra_remote.get_routes(
|
||||
ruby_pcsd_wrapper,
|
||||
sync_config_lock,
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
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
|
||||
|
||||
@ -0,0 +1,235 @@
|
||||
From cab85b898e69e9eb7590f10449b5c134b3b6e0ed Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Devat <idevat@redhat.com>
|
||||
Date: Wed, 3 Jun 2026 13:25:11 +0200
|
||||
Subject: [PATCH] Revert "feat: deprecate multi cluster management"
|
||||
|
||||
This reverts commit f26ee4ce4c2fc1e2ed15d0bf62e4ebeb57a72d50.
|
||||
---
|
||||
CHANGELOG.md | 5 --
|
||||
packages/app/Makefile.am | 1 -
|
||||
.../src/app/view/dashboard/DashboardApp.tsx | 36 --------------
|
||||
.../useDashboardDeprecationDismiss.ts | 21 ---------
|
||||
.../src/app/view/dataTest/json/dashboard.json | 4 --
|
||||
packages/test/Makefile.am | 1 -
|
||||
.../dashboard/deprecation-alert.test.ts | 47 -------------------
|
||||
7 files changed, 115 deletions(-)
|
||||
delete mode 100644 packages/app/src/app/view/dashboard/useDashboardDeprecationDismiss.ts
|
||||
delete mode 100644 packages/test/src/test/scenes/dashboard/deprecation-alert.test.ts
|
||||
|
||||
diff --git a/CHANGELOG.md b/CHANGELOG.md
|
||||
index bea609c9..5f66dce2 100644
|
||||
--- a/CHANGELOG.md
|
||||
+++ b/CHANGELOG.md
|
||||
@@ -6,11 +6,6 @@
|
||||
|
||||
* Support for pacemaker CIB secrets ([RHEL-7604])
|
||||
|
||||
-### Deprecated
|
||||
-
|
||||
-* Multi-cluster management is deprecated and will be removed in a future version
|
||||
- ([RHEL-148956])
|
||||
-
|
||||
### Fixed
|
||||
|
||||
* Omit empty link options in cluster setup request
|
||||
diff --git a/packages/app/Makefile.am b/packages/app/Makefile.am
|
||||
index f2919961..15b98600 100644
|
||||
--- a/packages/app/Makefile.am
|
||||
+++ b/packages/app/Makefile.am
|
||||
@@ -560,7 +560,6 @@ EXTRA_DIST = \
|
||||
src/app/view/dashboard/DashboardApp.tsx \
|
||||
src/app/view/dashboard/DashboardToolbar.tsx \
|
||||
src/app/view/dashboard/index.ts \
|
||||
- src/app/view/dashboard/useDashboardDeprecationDismiss.ts \
|
||||
src/app/view/dataTest/index.ts \
|
||||
src/app/view/dataTest/json/cluster/acl.json \
|
||||
src/app/view/dataTest/json/cluster/aclToolbar.json \
|
||||
diff --git a/packages/app/src/app/view/dashboard/DashboardApp.tsx b/packages/app/src/app/view/dashboard/DashboardApp.tsx
|
||||
index 80404724..b5d23d2a 100644
|
||||
--- a/packages/app/src/app/view/dashboard/DashboardApp.tsx
|
||||
+++ b/packages/app/src/app/view/dashboard/DashboardApp.tsx
|
||||
@@ -1,16 +1,12 @@
|
||||
import React from "react";
|
||||
import {useSelector} from "react-redux";
|
||||
import {
|
||||
- Alert,
|
||||
- AlertActionCloseButton,
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
- Button,
|
||||
PageSection,
|
||||
Stack,
|
||||
StackItem,
|
||||
} from "@patternfly/react-core";
|
||||
-import {InfoCircleIcon} from "@patternfly/react-icons";
|
||||
|
||||
import {testMarks} from "app/view/dataTest";
|
||||
import {selectors} from "app/store";
|
||||
@@ -25,7 +21,6 @@ import {
|
||||
|
||||
import {DashboardClusterList} from "./clusterList";
|
||||
import {DashboardToolbar} from "./DashboardToolbar";
|
||||
-import {useDashboardDeprecationDismiss} from "./useDashboardDeprecationDismiss";
|
||||
|
||||
const useDashboardSync = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -51,7 +46,6 @@ export const DashboardApp = () => {
|
||||
const dispatch = useDispatch();
|
||||
const importedClusterNameList = useSelector(selectors.getImportedClusterList);
|
||||
const loading = useSelector(selectors.dashboardGetLoadingStatus);
|
||||
- const {dismissed, dismiss, restore} = useDashboardDeprecationDismiss();
|
||||
|
||||
return (
|
||||
<Page>
|
||||
@@ -69,17 +63,6 @@ export const DashboardApp = () => {
|
||||
when={loading.when}
|
||||
isLoading={loading.currently}
|
||||
/>
|
||||
- {dismissed && (
|
||||
- <Button
|
||||
- variant="link"
|
||||
- icon={<InfoCircleIcon />}
|
||||
- onClick={restore}
|
||||
- {...testMarks.dashboard.deprecationAlert.showNotices
|
||||
- .mark}
|
||||
- >
|
||||
- Deprecation
|
||||
- </Button>
|
||||
- )}
|
||||
</BreadcrumbItem>
|
||||
</Breadcrumb>
|
||||
}
|
||||
@@ -90,25 +73,6 @@ export const DashboardApp = () => {
|
||||
</StackItem>
|
||||
</Stack>
|
||||
</PageSection>
|
||||
- {!dismissed && (
|
||||
- <PageSection>
|
||||
- <Alert
|
||||
- variant="info"
|
||||
- isInline
|
||||
- title="Multi-cluster management is deprecated"
|
||||
- actionClose={
|
||||
- <AlertActionCloseButton
|
||||
- {...testMarks.dashboard.deprecationAlert.close.mark}
|
||||
- onClose={dismiss}
|
||||
- />
|
||||
- }
|
||||
- {...testMarks.dashboard.deprecationAlert.mark}
|
||||
- >
|
||||
- Management of multiple clusters will be removed in a future
|
||||
- version.
|
||||
- </Alert>
|
||||
- </PageSection>
|
||||
- )}
|
||||
<PageSection {...testMarks.dashboard.mark}>
|
||||
{loading.status === "SUCCESS" && (
|
||||
<DashboardClusterList
|
||||
diff --git a/packages/app/src/app/view/dashboard/useDashboardDeprecationDismiss.ts b/packages/app/src/app/view/dashboard/useDashboardDeprecationDismiss.ts
|
||||
deleted file mode 100644
|
||||
index 88fead22..00000000
|
||||
--- a/packages/app/src/app/view/dashboard/useDashboardDeprecationDismiss.ts
|
||||
+++ /dev/null
|
||||
@@ -1,21 +0,0 @@
|
||||
-import React from "react";
|
||||
-
|
||||
-const storageKey = "deprecationMultiClusterDismissed";
|
||||
-
|
||||
-export const useDashboardDeprecationDismiss = () => {
|
||||
- const [dismissed, setDismissed] = React.useState(
|
||||
- () => localStorage.getItem(storageKey) === "true",
|
||||
- );
|
||||
-
|
||||
- const dismiss = () => {
|
||||
- localStorage.setItem(storageKey, "true");
|
||||
- setDismissed(true);
|
||||
- };
|
||||
-
|
||||
- const restore = () => {
|
||||
- localStorage.removeItem(storageKey);
|
||||
- setDismissed(false);
|
||||
- };
|
||||
-
|
||||
- return {dismissed, dismiss, restore};
|
||||
-};
|
||||
diff --git a/packages/app/src/app/view/dataTest/json/dashboard.json b/packages/app/src/app/view/dataTest/json/dashboard.json
|
||||
index 7d92a3ab..909f3fd4 100644
|
||||
--- a/packages/app/src/app/view/dataTest/json/dashboard.json
|
||||
+++ b/packages/app/src/app/view/dataTest/json/dashboard.json
|
||||
@@ -1,8 +1,4 @@
|
||||
{
|
||||
- "deprecationAlert": {
|
||||
- "close": {},
|
||||
- "showNotices": {}
|
||||
- },
|
||||
"clusterList": {
|
||||
"cluster": {
|
||||
"actions": {
|
||||
diff --git a/packages/test/Makefile.am b/packages/test/Makefile.am
|
||||
index b0cd2c38..d7c201c0 100644
|
||||
--- a/packages/test/Makefile.am
|
||||
+++ b/packages/test/Makefile.am
|
||||
@@ -43,7 +43,6 @@ EXTRA_DIST = \
|
||||
src/test/scenes/dashboard/cluster-status.test.ts \
|
||||
src/test/scenes/dashboard/cluster-stop.test.ts \
|
||||
src/test/scenes/dashboard/common.ts \
|
||||
- src/test/scenes/dashboard/deprecation-alert.test.ts \
|
||||
src/test/scenes/dashboard/import-existring-cluster.test.ts \
|
||||
src/test/scenes/dashboard/to-cluster-transition.test.ts \
|
||||
src/test/scenes/fence-devices/arguments-view.test.ts \
|
||||
diff --git a/packages/test/src/test/scenes/dashboard/deprecation-alert.test.ts b/packages/test/src/test/scenes/dashboard/deprecation-alert.test.ts
|
||||
deleted file mode 100644
|
||||
index bba245e4..00000000
|
||||
--- a/packages/test/src/test/scenes/dashboard/deprecation-alert.test.ts
|
||||
+++ /dev/null
|
||||
@@ -1,47 +0,0 @@
|
||||
-import {mock} from "test/tools";
|
||||
-
|
||||
-const {deprecationAlert} = marks.dashboard;
|
||||
-
|
||||
-describe("Deprecation alert", () => {
|
||||
- beforeEach(async () => {
|
||||
- await page.evaluate(() =>
|
||||
- localStorage.removeItem("deprecationMultiClusterDismissed"),
|
||||
- );
|
||||
- mock.shortcuts.withDashboard({clusterStatus: []});
|
||||
- });
|
||||
-
|
||||
- afterEach(mock.stop);
|
||||
-
|
||||
- it("should display deprecation alert", async () => {
|
||||
- await goToDashboard();
|
||||
- await isVisible(deprecationAlert);
|
||||
- });
|
||||
-
|
||||
- it("should hide alert after clicking close", async () => {
|
||||
- await goToDashboard();
|
||||
- await click(deprecationAlert.close);
|
||||
- await isAbsent(deprecationAlert);
|
||||
- });
|
||||
-
|
||||
- it("should show 'Show deprecation notices' after dismiss", async () => {
|
||||
- await goToDashboard();
|
||||
- await click(deprecationAlert.close);
|
||||
- await isVisible(deprecationAlert.showNotices);
|
||||
- });
|
||||
-
|
||||
- it("should restore alert when clicking 'Show deprecation notices'", async () => {
|
||||
- await goToDashboard();
|
||||
- await click(deprecationAlert.close);
|
||||
- await click(deprecationAlert.showNotices);
|
||||
- await isVisible(deprecationAlert);
|
||||
- });
|
||||
-
|
||||
- it("should stay hidden when previously dismissed", async () => {
|
||||
- await page.evaluate(() =>
|
||||
- localStorage.setItem("deprecationMultiClusterDismissed", "true"),
|
||||
- );
|
||||
- await goToDashboard();
|
||||
- await isAbsent(deprecationAlert);
|
||||
- await isVisible(deprecationAlert.showNotices);
|
||||
- });
|
||||
-});
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -0,0 +1,480 @@
|
||||
From 68354f8f91ea74ecf90333f33e7d4789ec93efa6 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Lisik <mlisik@redhat.com>
|
||||
Date: Thu, 11 Jun 2026 16:23:08 +0200
|
||||
Subject: [PATCH] fix `pcs stonith update-scsi-devices` command
|
||||
|
||||
* use new cibadmin option `--update-status` when updating scsi devices
|
||||
---
|
||||
pcs/lib/commands/stonith.py | 9 ++-
|
||||
pcs/lib/env.py | 55 +++++++++----------
|
||||
pcs/lib/pacemaker/live.py | 12 +++-
|
||||
.../test_stonith_update_scsi_devices.py | 27 +++++++++
|
||||
pcs_test/tier0/lib/test_env_cib.py | 21 +++++++
|
||||
pcs_test/tools/command_env/config_env.py | 8 ++-
|
||||
.../tools/command_env/config_runner_cib.py | 7 ++-
|
||||
.../tools/command_env/config_runner_pcmk.py | 15 +++++
|
||||
pcs_test/tools/command_env/mock_push_cib.py | 30 +++++++++-
|
||||
9 files changed, 146 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/pcs/lib/commands/stonith.py b/pcs/lib/commands/stonith.py
|
||||
index c5c1ab4b3..15a1efd52 100644
|
||||
--- a/pcs/lib/commands/stonith.py
|
||||
+++ b/pcs/lib/commands/stonith.py
|
||||
@@ -42,6 +42,7 @@ from pcs.lib.pacemaker.live import (
|
||||
fence_history_cleanup,
|
||||
fence_history_text,
|
||||
fence_history_update,
|
||||
+ is_cibadmin_update_status_supported,
|
||||
is_fence_history_supported_management,
|
||||
is_getting_resource_digest_supported,
|
||||
)
|
||||
@@ -402,7 +403,9 @@ def _update_scsi_devices_get_element_and_devices(
|
||||
cib -- cib element
|
||||
stonith_id -- id of stonith resource
|
||||
"""
|
||||
- if not is_getting_resource_digest_supported(runner):
|
||||
+ if not is_getting_resource_digest_supported(
|
||||
+ runner
|
||||
+ ) or not is_cibadmin_update_status_supported(runner):
|
||||
raise LibraryError(
|
||||
ReportItem.error(
|
||||
reports.messages.StonithRestartlessUpdateOfScsiDevicesNotSupported()
|
||||
@@ -529,7 +532,7 @@ def update_scsi_devices(
|
||||
_unfencing_scsi_devices(
|
||||
env, stonith_el, current_device_list, set_device_list, force_flags
|
||||
)
|
||||
- env.push_cib()
|
||||
+ env.push_cib(with_status=True)
|
||||
|
||||
|
||||
def update_scsi_devices_add_remove(
|
||||
@@ -583,4 +586,4 @@ def update_scsi_devices_add_remove(
|
||||
_unfencing_scsi_devices(
|
||||
env, stonith_el, current_device_list, updated_device_set, force_flags
|
||||
)
|
||||
- env.push_cib()
|
||||
+ env.push_cib(with_status=True)
|
||||
diff --git a/pcs/lib/env.py b/pcs/lib/env.py
|
||||
index d0cffc993..eea9e90bc 100644
|
||||
--- a/pcs/lib/env.py
|
||||
+++ b/pcs/lib/env.py
|
||||
@@ -1,24 +1,11 @@
|
||||
from logging import Logger
|
||||
-from typing import (
|
||||
- Any,
|
||||
- Callable,
|
||||
- Mapping,
|
||||
- Optional,
|
||||
- Union,
|
||||
- cast,
|
||||
-)
|
||||
+from typing import Any, Callable, Mapping, Optional, Union, cast
|
||||
|
||||
from lxml.etree import _Element
|
||||
|
||||
-from pcs.common import (
|
||||
- file_type_codes,
|
||||
- reports,
|
||||
-)
|
||||
+from pcs.common import file_type_codes, reports
|
||||
from pcs.common.host import PcsKnownHost
|
||||
-from pcs.common.node_communicator import (
|
||||
- Communicator,
|
||||
- NodeCommunicatorFactory,
|
||||
-)
|
||||
+from pcs.common.node_communicator import Communicator, NodeCommunicatorFactory
|
||||
from pcs.common.reports import ReportProcessor
|
||||
from pcs.common.reports.item import ReportItem
|
||||
from pcs.common.services.interfaces import ServiceManagerInterface
|
||||
@@ -31,10 +18,7 @@ from pcs.lib.communication.corosync import (
|
||||
DistributeCorosyncConf,
|
||||
ReloadCorosyncConf,
|
||||
)
|
||||
-from pcs.lib.communication.tools import (
|
||||
- run,
|
||||
- run_and_raise,
|
||||
-)
|
||||
+from pcs.lib.communication.tools import run, run_and_raise
|
||||
from pcs.lib.corosync.config_facade import ConfigFacade as CorosyncConfigFacade
|
||||
from pcs.lib.corosync.config_parser import (
|
||||
verify_section as verify_corosync_section,
|
||||
@@ -245,15 +229,21 @@ class LibraryEnvironment:
|
||||
ReportItem.error(reports.messages.WaitForIdleNotLiveCluster())
|
||||
)
|
||||
|
||||
- def push_cib(self, custom_cib=None, wait_timeout: int = -1) -> None:
|
||||
+ def push_cib(
|
||||
+ self,
|
||||
+ custom_cib: Optional[_Element] = None,
|
||||
+ wait_timeout: int = -1,
|
||||
+ with_status: bool = False,
|
||||
+ ) -> None:
|
||||
"""
|
||||
Push previously loaded instance of CIB or a custom CIB
|
||||
|
||||
- etree custom_cib -- push a custom CIB instead of a loaded instance
|
||||
+ custom_cib -- push a custom CIB instead of a loaded instance
|
||||
(allows to push an externally provided CIB and replace the one in
|
||||
the cluster completely)
|
||||
wait_timeout -- wait timeout in seconds, if less than 0 wait will be
|
||||
skipped, if 0 wait indefinitely
|
||||
+ with_status -- push also status section of a CIB
|
||||
"""
|
||||
self._ensure_wait_satisfiable(wait_timeout)
|
||||
if custom_cib is not None:
|
||||
@@ -261,10 +251,14 @@ class LibraryEnvironment:
|
||||
raise AssertionError(
|
||||
"CIB has been loaded, cannot push custom CIB"
|
||||
)
|
||||
+ if with_status:
|
||||
+ raise AssertionError(
|
||||
+ "Cannot push status section of a custom CIB"
|
||||
+ )
|
||||
return self.__push_cib_full(custom_cib, wait_timeout)
|
||||
if self.__loaded_cib_diff_source is None:
|
||||
raise AssertionError("CIB has not been loaded")
|
||||
- return self.__push_cib_diff(wait_timeout)
|
||||
+ return self.__push_cib_diff(wait_timeout, with_status)
|
||||
|
||||
def __push_cib_full(self, cib_to_push, wait_timeout: int):
|
||||
self.__do_push_cib(
|
||||
@@ -272,20 +266,23 @@ class LibraryEnvironment:
|
||||
wait_timeout,
|
||||
)
|
||||
|
||||
- def __push_cib_diff(self, wait_timeout: int):
|
||||
+ def __push_cib_diff(self, wait_timeout: int, with_status: bool = False):
|
||||
self.__do_push_cib(
|
||||
- lambda: self.__main_push_cib_diff(self.cmd_runner()), wait_timeout
|
||||
+ lambda: self.__main_push_cib_diff(self.cmd_runner(), with_status),
|
||||
+ wait_timeout,
|
||||
)
|
||||
|
||||
- def __main_push_cib_diff(self, cmd_runner):
|
||||
+ def __main_push_cib_diff(
|
||||
+ self, cmd_runner: CommandRunner, with_status: bool = False
|
||||
+ ):
|
||||
cib_diff_xml = diff_cibs_xml(
|
||||
cmd_runner,
|
||||
self.report_processor,
|
||||
- self.__loaded_cib_diff_source,
|
||||
- etree_to_str(self.__loaded_cib_to_modify),
|
||||
+ cast(str, self.__loaded_cib_diff_source),
|
||||
+ etree_to_str(cast(_Element, self.__loaded_cib_to_modify)),
|
||||
)
|
||||
if cib_diff_xml:
|
||||
- push_cib_diff_xml(cmd_runner, cib_diff_xml)
|
||||
+ push_cib_diff_xml(cmd_runner, cib_diff_xml, with_status)
|
||||
|
||||
def __do_push_cib(self, push_strategy, wait_timeout: int) -> None:
|
||||
push_strategy()
|
||||
diff --git a/pcs/lib/pacemaker/live.py b/pcs/lib/pacemaker/live.py
|
||||
index da1154f53..97cd7da59 100644
|
||||
--- a/pcs/lib/pacemaker/live.py
|
||||
+++ b/pcs/lib/pacemaker/live.py
|
||||
@@ -290,13 +290,17 @@ def replace_cib_configuration(runner: CommandRunner, tree: _Element) -> None:
|
||||
return replace_cib_configuration_xml(runner, etree_to_str(tree))
|
||||
|
||||
|
||||
-def push_cib_diff_xml(runner: CommandRunner, cib_diff_xml: str) -> None:
|
||||
+def push_cib_diff_xml(
|
||||
+ runner: CommandRunner, cib_diff_xml: str, with_status: bool = False
|
||||
+) -> None:
|
||||
cmd = [
|
||||
settings.cibadmin_exec,
|
||||
"--patch",
|
||||
"--verbose",
|
||||
"--xml-pipe",
|
||||
]
|
||||
+ if with_status:
|
||||
+ cmd.append("--update-status")
|
||||
stdout, stderr, retval = runner.run(cmd, stdin_string=cib_diff_xml)
|
||||
if retval != 0:
|
||||
raise LibraryError(
|
||||
@@ -965,6 +969,12 @@ def is_getting_resource_digest_supported(runner: CommandRunner) -> bool:
|
||||
)
|
||||
|
||||
|
||||
+def is_cibadmin_update_status_supported(runner: CommandRunner) -> bool:
|
||||
+ return _is_in_pcmk_tool_help(
|
||||
+ runner, settings.cibadmin_exec, ["--update-status"]
|
||||
+ )
|
||||
+
|
||||
+
|
||||
def get_resource_digests(
|
||||
runner: CommandRunner,
|
||||
resource_id: str,
|
||||
diff --git a/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py b/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
|
||||
index 152b51cae..3148d6815 100644
|
||||
--- a/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
|
||||
+++ b/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
|
||||
@@ -417,6 +417,7 @@ class UpdateScsiDevicesMixin:
|
||||
),
|
||||
)
|
||||
self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported()
|
||||
self.config.runner.pcmk.load_state(
|
||||
resources=fixture_crm_mon_res_running(
|
||||
self.stonith_id,
|
||||
@@ -518,6 +519,7 @@ class UpdateScsiDevicesMixin:
|
||||
lrm_monitor_ops=lrm_monitor_ops_updated,
|
||||
digests_attrs_list=digests_attrs_list_updated,
|
||||
),
|
||||
+ with_status=True,
|
||||
)
|
||||
kwargs = dict(devices_updated=devices_updated)
|
||||
if devices_add is not None:
|
||||
@@ -560,6 +562,26 @@ class UpdateScsiDevicesFailuresMixin(UpdateScsiDevicesMixin):
|
||||
expected_in_processor=False,
|
||||
)
|
||||
|
||||
+ def test_cibadmin_doesnt_support_update_status(self):
|
||||
+ self.config.runner.cib.load(
|
||||
+ resources=fixture_scsi(
|
||||
+ stonith_id=self.stonith_id, stonith_type=self.stonith_type
|
||||
+ )
|
||||
+ )
|
||||
+ self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported(
|
||||
+ is_supported=False
|
||||
+ )
|
||||
+ self.env_assist.assert_raise_library_error(
|
||||
+ self.command(),
|
||||
+ [
|
||||
+ fixture.error(
|
||||
+ reports.codes.STONITH_RESTARTLESS_UPDATE_OF_SCSI_DEVICES_NOT_SUPPORTED,
|
||||
+ )
|
||||
+ ],
|
||||
+ expected_in_processor=False,
|
||||
+ )
|
||||
+
|
||||
def test_nonexistent_id(self):
|
||||
"""
|
||||
lower level tested in
|
||||
@@ -572,6 +594,7 @@ class UpdateScsiDevicesFailuresMixin(UpdateScsiDevicesMixin):
|
||||
)
|
||||
)
|
||||
self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported()
|
||||
self.env_assist.assert_raise_library_error(self.command())
|
||||
self.env_assist.assert_reports(
|
||||
[
|
||||
@@ -597,6 +620,7 @@ class UpdateScsiDevicesFailuresMixin(UpdateScsiDevicesMixin):
|
||||
)
|
||||
)
|
||||
self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported()
|
||||
self.env_assist.assert_raise_library_error(
|
||||
self.command(devices_add=[DEV_2], devices_remove=[DEV_1])
|
||||
)
|
||||
@@ -949,6 +973,7 @@ class UpdateScsiDevicesFailuresMixin(UpdateScsiDevicesMixin):
|
||||
lrm_start_ops=DEFAULT_LRM_START_OPS_UPDATED,
|
||||
lrm_monitor_ops=DEFAULT_LRM_MONITOR_OPS_UPDATED,
|
||||
),
|
||||
+ with_status=True,
|
||||
)
|
||||
self.command(force_flags=[reports.codes.SKIP_OFFLINE_NODES])()
|
||||
self.env_assist.assert_reports(
|
||||
@@ -1240,6 +1265,7 @@ class UpdateScsiDevicesSetFailuresBaseMixin(
|
||||
)
|
||||
)
|
||||
self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported()
|
||||
self.env_assist.assert_raise_library_error(
|
||||
self.command(devices_updated=())
|
||||
)
|
||||
@@ -1271,6 +1297,7 @@ class UpdateScsiDevicesAddRemoveFailuresBaseMixin(
|
||||
)
|
||||
)
|
||||
self.config.runner.pcmk.is_resource_digests_supported()
|
||||
+ self.config.runner.pcmk.is_cibadmin_update_status_supported()
|
||||
self.env_assist.assert_raise_library_error(
|
||||
self.command(devices_add=(), devices_remove=())
|
||||
)
|
||||
diff --git a/pcs_test/tier0/lib/test_env_cib.py b/pcs_test/tier0/lib/test_env_cib.py
|
||||
index e23a55a98..8f762e809 100644
|
||||
--- a/pcs_test/tier0/lib/test_env_cib.py
|
||||
+++ b/pcs_test/tier0/lib/test_env_cib.py
|
||||
@@ -52,6 +52,11 @@ class ManageCibAssertionMixin:
|
||||
callable_obj, "CIB has been loaded, cannot push custom CIB"
|
||||
)
|
||||
|
||||
+ def assert_raises_cannot_push_status_custom(self, callable_obj):
|
||||
+ self.assert_raises_cib_error(
|
||||
+ callable_obj, "Cannot push status section of a custom CIB"
|
||||
+ )
|
||||
+
|
||||
|
||||
class IsCibLive(TestCase):
|
||||
def test_is_live_when_no_cib_data_specified(self):
|
||||
@@ -385,6 +390,16 @@ class PushLoadedCib(TestCase, ManageCibAssertionMixin):
|
||||
]
|
||||
)
|
||||
|
||||
+ def test_with_status(self):
|
||||
+ self.config_load_cib_files()
|
||||
+ self.config.runner.cib.diff(self.tmpfile_old, self.tmpfile_new)
|
||||
+ self.config.runner.cib.push_diff(with_status=True)
|
||||
+ env = self.env_assist.get_env()
|
||||
+
|
||||
+ env.get_cib()
|
||||
+ env.push_cib(with_status=True)
|
||||
+ self.env_assist.assert_reports(self.push_reports())
|
||||
+
|
||||
|
||||
class PushCustomCib(TestCase, ManageCibAssertionMixin):
|
||||
custom_cib = "<custom_cib />"
|
||||
@@ -424,6 +439,12 @@ class PushCustomCib(TestCase, ManageCibAssertionMixin):
|
||||
]
|
||||
)
|
||||
|
||||
+ def test_with_status(self):
|
||||
+ env = self.env_assist.get_env()
|
||||
+ self.assert_raises_cannot_push_status_custom(
|
||||
+ partial(env.push_cib, etree.XML(self.custom_cib), with_status=True)
|
||||
+ )
|
||||
+
|
||||
|
||||
class PushCibMockedWithWait(TestCase):
|
||||
def setUp(self):
|
||||
diff --git a/pcs_test/tools/command_env/config_env.py b/pcs_test/tools/command_env/config_env.py
|
||||
index b421c0b21..4782d62db 100644
|
||||
--- a/pcs_test/tools/command_env/config_env.py
|
||||
+++ b/pcs_test/tools/command_env/config_env.py
|
||||
@@ -89,6 +89,7 @@ class EnvConfig:
|
||||
wait=-1,
|
||||
exception=None,
|
||||
instead=None,
|
||||
+ with_status=False,
|
||||
**modifier_shortcuts,
|
||||
):
|
||||
"""
|
||||
@@ -115,7 +116,12 @@ class EnvConfig:
|
||||
)
|
||||
self.__calls.place(
|
||||
name,
|
||||
- PushCibCall(cib_xml, wait_timeout=wait, exception=exception),
|
||||
+ PushCibCall(
|
||||
+ cib_xml,
|
||||
+ wait_timeout=wait,
|
||||
+ exception=exception,
|
||||
+ with_status=with_status,
|
||||
+ ),
|
||||
instead=instead,
|
||||
)
|
||||
|
||||
diff --git a/pcs_test/tools/command_env/config_runner_cib.py b/pcs_test/tools/command_env/config_runner_cib.py
|
||||
index 16273b2b0..fabac5a28 100644
|
||||
--- a/pcs_test/tools/command_env/config_runner_cib.py
|
||||
+++ b/pcs_test/tools/command_env/config_runner_cib.py
|
||||
@@ -227,17 +227,22 @@ class CibShortcuts:
|
||||
stderr="",
|
||||
returncode=0,
|
||||
env=None,
|
||||
+ with_status=False,
|
||||
):
|
||||
"""
|
||||
Create a call for pushing a diff of CIBs
|
||||
string name -- key of the call
|
||||
string cib_diff -- the diff of CIBs
|
||||
dict env -- CommandRunner environment variables
|
||||
+ bool with_status -- if True, expect --update-status flag
|
||||
"""
|
||||
+ cmd = ["cibadmin", "--patch", "--verbose", "--xml-pipe"]
|
||||
+ if with_status:
|
||||
+ cmd.append("--update-status")
|
||||
self.__calls.place(
|
||||
name,
|
||||
RunnerCall(
|
||||
- ["cibadmin", "--patch", "--verbose", "--xml-pipe"],
|
||||
+ cmd,
|
||||
check_stdin=CheckStdinEqualXml(cib_diff),
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
diff --git a/pcs_test/tools/command_env/config_runner_pcmk.py b/pcs_test/tools/command_env/config_runner_pcmk.py
|
||||
index 778c5b67e..c944d2f7f 100644
|
||||
--- a/pcs_test/tools/command_env/config_runner_pcmk.py
|
||||
+++ b/pcs_test/tools/command_env/config_runner_pcmk.py
|
||||
@@ -885,6 +885,21 @@ class PcmkShortcuts:
|
||||
),
|
||||
)
|
||||
|
||||
+ def is_cibadmin_update_status_supported(
|
||||
+ self,
|
||||
+ name="runner.pcmk.is_cibadmin_update_status_supported",
|
||||
+ is_supported=True,
|
||||
+ ):
|
||||
+ self.__calls.place(
|
||||
+ name,
|
||||
+ RunnerCall(
|
||||
+ ["cibadmin", "--help-all"],
|
||||
+ stdout="--update-status" if is_supported else "",
|
||||
+ stderr="",
|
||||
+ returncode=0,
|
||||
+ ),
|
||||
+ )
|
||||
+
|
||||
def resource_digests(
|
||||
self,
|
||||
resource_id,
|
||||
diff --git a/pcs_test/tools/command_env/mock_push_cib.py b/pcs_test/tools/command_env/mock_push_cib.py
|
||||
index 186d14f69..67275d0e6 100644
|
||||
--- a/pcs_test/tools/command_env/mock_push_cib.py
|
||||
+++ b/pcs_test/tools/command_env/mock_push_cib.py
|
||||
@@ -8,19 +8,28 @@ class Call:
|
||||
type = CALL_TYPE_PUSH_CIB
|
||||
|
||||
def __init__(
|
||||
- self, cib_xml, custom_cib=False, wait_timeout=-1, exception=None
|
||||
+ self,
|
||||
+ cib_xml,
|
||||
+ custom_cib=False,
|
||||
+ wait_timeout=-1,
|
||||
+ exception=None,
|
||||
+ with_status=False,
|
||||
):
|
||||
self.cib_xml = cib_xml
|
||||
self.custom_cib = custom_cib
|
||||
self.wait_timeout = wait_timeout
|
||||
self.exception = exception
|
||||
+ self.with_status = with_status
|
||||
|
||||
def __repr__(self):
|
||||
- return str("<CibPush wait_timeout='{0}'>").format(self.wait_timeout)
|
||||
+ return (
|
||||
+ f"<CibPush wait_timeout='{self.wait_timeout}' "
|
||||
+ f"with_status='{self.with_status}'>"
|
||||
+ )
|
||||
|
||||
|
||||
def get_push_cib(call_queue):
|
||||
- def push_cib(lib_env, custom_cib=None, wait_timeout=-1):
|
||||
+ def push_cib(lib_env, custom_cib=None, wait_timeout=-1, with_status=False):
|
||||
i, expected_call = call_queue.take(CALL_TYPE_PUSH_CIB)
|
||||
|
||||
if custom_cib is None and expected_call.custom_cib:
|
||||
@@ -62,6 +71,21 @@ def get_push_cib(call_queue):
|
||||
expected_type=type(expected_call.wait_timeout),
|
||||
)
|
||||
)
|
||||
+ if with_status != expected_call.with_status:
|
||||
+ raise AssertionError(
|
||||
+ (
|
||||
+ "Trying to call env.push_cib (call no. {index}) with "
|
||||
+ "'with_status' == {real_value} ({real_type}) but it was "
|
||||
+ "expected 'with_status' == {expected_value} "
|
||||
+ "({expected_type})"
|
||||
+ ).format(
|
||||
+ index=i,
|
||||
+ real_value=with_status,
|
||||
+ real_type=type(with_status),
|
||||
+ expected_value=expected_call.with_status,
|
||||
+ expected_type=type(expected_call.with_status),
|
||||
+ )
|
||||
+ )
|
||||
|
||||
if expected_call.exception:
|
||||
raise expected_call.exception
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
From 0ad47ec40b7a9a2cb6bdbdf11e1e5b3c59f49b8b Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Lisik <mlisik@redhat.com>
|
||||
Date: Tue, 20 May 2025 16:34:18 +0200
|
||||
Subject: [PATCH] support for query limits in rack
|
||||
|
||||
---
|
||||
pcsd/conf/pcsd | 6 ++++++
|
||||
pcsd/pcsd.rb | 5 +++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/pcsd/conf/pcsd b/pcsd/conf/pcsd
|
||||
index 98df4744..65a9c9a9 100644
|
||||
--- a/pcsd/conf/pcsd
|
||||
+++ b/pcsd/conf/pcsd
|
||||
@@ -45,5 +45,11 @@ PCSD_SESSION_LIFETIME=3600
|
||||
# is 50 (even if set lower).
|
||||
PCSD_RESTART_AFTER_REQUESTS=200
|
||||
|
||||
+# These environment variables set the maximum query string bytesize and the
|
||||
+# maximum number of query parameters that pcsd will attempt to parse.
|
||||
+# See CVE-2025-46727 for details.
|
||||
+#RACK_QUERY_PARSER_BYTESIZE_LIMIT=4194304
|
||||
+#RACK_QUERY_PARSER_PARAMS_LIMIT=4096
|
||||
+
|
||||
# Do not change
|
||||
RACK_ENV=production
|
||||
diff --git a/pcsd/pcsd.rb b/pcsd/pcsd.rb
|
||||
index 11698f54..a2634e4e 100644
|
||||
--- a/pcsd/pcsd.rb
|
||||
+++ b/pcsd/pcsd.rb
|
||||
@@ -90,6 +90,11 @@ configure do
|
||||
CAPABILITIES_PCSD = capabilities_pcsd.freeze
|
||||
end
|
||||
|
||||
+error Rack::QueryParser::QueryLimitError do
|
||||
+ $logger.warn(env['sinatra.error'].message)
|
||||
+ return 400, env['sinatra.error'].message
|
||||
+end
|
||||
+
|
||||
def run_cfgsync
|
||||
node_connected = true
|
||||
if Cfgsync::ConfigSyncControl.sync_thread_allowed?()
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,53 +1,38 @@
|
||||
From 854efcf148c82e5a5e4f0afd71cc3333ea4a8ce4 Mon Sep 17 00:00:00 2001
|
||||
From 20140bbe7ac508ae38dea9ff5dd6fa92ec84b8bf 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
|
||||
Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL9
|
||||
|
||||
---
|
||||
pcs/pcs.8.in | 2 ++
|
||||
pcs/usage.py | 1 +
|
||||
pcsd/public/css/style.css | 3 +++
|
||||
3 files changed, 6 insertions(+)
|
||||
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 d504e8b4..93202d05 100644
|
||||
index 3b644d054..a1c573cf5 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
|
||||
@@ -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 8.
|
||||
+WARNING: These transports are not supported in RHEL 9.
|
||||
+.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
|
||||
index 4bcef3d25..d6eb51750 100644
|
||||
--- a/pcs/usage.py
|
||||
+++ b/pcs/usage.py
|
||||
@@ -1038,6 +1038,7 @@ Commands:
|
||||
@@ -1502,6 +1502,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.
|
||||
+ WARNING: These transports are not supported in RHEL 9.
|
||||
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
|
||||
2.54.0
|
||||
|
||||
|
||||
1055
SPECS/pcs.spec
1055
SPECS/pcs.spec
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user