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.25.3.gem
|
||||||
SOURCES/backports-3.24.1.gem
|
SOURCES/base64-0.2.0.gem
|
||||||
SOURCES/dacite-1.8.1.tar.gz
|
SOURCES/childprocess-5.1.0.gem
|
||||||
SOURCES/dataclasses-0.8.tar.gz
|
SOURCES/dacite-1.9.2.tar.gz
|
||||||
SOURCES/ethon-0.16.0.gem
|
SOURCES/ethon-0.18.0.gem
|
||||||
SOURCES/ffi-1.16.3.gem
|
SOURCES/ffi-1.17.2.gem
|
||||||
SOURCES/json-2.6.3.gem
|
SOURCES/logger-1.7.0.gem
|
||||||
SOURCES/mustermann-2.0.2.gem
|
SOURCES/mustermann-3.1.1.gem
|
||||||
SOURCES/nio4r-2.5.9.gem
|
SOURCES/nio4r-2.7.5.gem
|
||||||
SOURCES/open4-1.3.4-1.gem
|
SOURCES/pcs-0.11.12.tar.gz
|
||||||
SOURCES/pcs-0.10.18.tar.gz
|
SOURCES/pcs-web-ui-0.1.25.tar.gz
|
||||||
SOURCES/puma-6.4.0.gem
|
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/pyagentx-0.4.pcs.2.tar.gz
|
||||||
SOURCES/python-dateutil-2.8.2.tar.gz
|
SOURCES/rack-3.2.6.gem
|
||||||
SOURCES/rack-2.2.20.gem
|
SOURCES/rack-protection-4.2.1.gem
|
||||||
SOURCES/rack-protection-2.2.4.gem
|
SOURCES/rack-session-2.1.2.gem
|
||||||
SOURCES/rack-test-2.1.0.gem
|
SOURCES/rack-test-2.2.0.gem
|
||||||
SOURCES/rexml-3.4.1.gem
|
SOURCES/rackup-2.3.1.gem
|
||||||
SOURCES/ruby2_keywords-0.0.5.gem
|
SOURCES/ruby2_keywords-0.0.5.gem
|
||||||
SOURCES/sinatra-2.2.4.gem
|
SOURCES/sinatra-4.2.1.gem
|
||||||
SOURCES/tilt-2.3.0.gem
|
SOURCES/tilt-2.7.0.gem
|
||||||
SOURCES/tornado-v6.1.0.pcs.4.tar.gz
|
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
679a4ce22a33ffd4d704261a17c00cff98d9499a SOURCES/HAM-logo.png
|
41b95975c12381bcd9cbc32bd278440313fce12d SOURCES/backports-3.25.3.gem
|
||||||
0ef72a288913e220695ad62718aeb75171924028 SOURCES/backports-3.24.1.gem
|
ea3a591bdfa93655d8eec9d7bdd7fb87ecb5616a SOURCES/base64-0.2.0.gem
|
||||||
07b26abbf7ff0dcba5c7f9e814ff7eebafefb058 SOURCES/dacite-1.8.1.tar.gz
|
963b12b359251f41998eebe6f6adfec92fe6f49f SOURCES/childprocess-5.1.0.gem
|
||||||
8b7598273d2ae6dad2b88466aefac55071a41926 SOURCES/dataclasses-0.8.tar.gz
|
01690d9883c149890e04dce4db43ec305959aa39 SOURCES/dacite-1.9.2.tar.gz
|
||||||
5b56a68268708c474bef04550639ded3add5e946 SOURCES/ethon-0.16.0.gem
|
ffd8b3e5ac044a1a69791411e3e5cf4b5d4a6768 SOURCES/ethon-0.18.0.gem
|
||||||
10e4cf0e11ef4581ec4ad5fe2cdf3c78b6077d39 SOURCES/ffi-1.16.3.gem
|
01747fce469e932b701cb7a35d1ef4b3c68eb170 SOURCES/ffi-1.17.2.gem
|
||||||
6d78f730b7f3b25fb3f93684fe1364acf58bce6b SOURCES/json-2.6.3.gem
|
abfa641d98ab2e71bc8102b0aab2f466569668d2 SOURCES/logger-1.7.0.gem
|
||||||
f5f804366823c1126791dfefd98dd0539563785c SOURCES/mustermann-2.0.2.gem
|
0b23c093481361b6b7dc4c733407e28f6aba181a SOURCES/mustermann-3.1.1.gem
|
||||||
2f65d371f5f37460ad74afcedcb97d2b41a46806 SOURCES/nio4r-2.5.9.gem
|
34420ab7703c0033e18680504a9f8899322ac908 SOURCES/nio4r-2.7.5.gem
|
||||||
41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
|
4377db28b20fbf93819f3d719545d644e93b9886 SOURCES/pcs-0.11.12.tar.gz
|
||||||
b3cd873042b17021355b68f1f7aa313f0c1f3fee SOURCES/pcs-0.10.18.tar.gz
|
76c4bde0b534e8ce82ad2b2f3b155faaa09ae6fb SOURCES/pcs-web-ui-0.1.25.tar.gz
|
||||||
d6049c4555f3c9d198e6eb1d7e53ce9b68e175ff SOURCES/puma-6.4.0.gem
|
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
|
3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
|
||||||
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
|
41b3f39ab51fe8584be6f9e849152bb69b06f575 SOURCES/rack-3.2.6.gem
|
||||||
4c52ad6f798e78d4a1800257ef0d7fc5ac254712 SOURCES/rack-2.2.20.gem
|
1457dded6ffa0f564b33329861dd6b257f07498d SOURCES/rack-protection-4.2.1.gem
|
||||||
5347315a7283f0b04443e924ed4eaa17807432c8 SOURCES/rack-protection-2.2.4.gem
|
3353c03a5d41f14bfa3459436400fc363ab4fd96 SOURCES/rack-session-2.1.2.gem
|
||||||
ae09ea83748b55875edc3708fffba90db180cb8e SOURCES/rack-test-2.1.0.gem
|
922c597f0503f97dc3a058fe997590b108bc429a SOURCES/rack-test-2.2.0.gem
|
||||||
966b1564a77719483eb61068ed1dfb638e5e8eb0 SOURCES/rexml-3.4.1.gem
|
f470c1dc5a15e44a241cae4cb50d94b7b3f6b010 SOURCES/rackup-2.3.1.gem
|
||||||
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
|
d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
|
||||||
fa6a6c98f885e93f54c23dd0454cae906e82c31b SOURCES/sinatra-2.2.4.gem
|
611999f43e27779278c80acfb5825c7255497988 SOURCES/sinatra-4.2.1.gem
|
||||||
4a38a9a55887b2882182a2c5771e592efe514e5e SOURCES/tilt-2.3.0.gem
|
93253f48f74242535d1c572e88a5651f2c1565c4 SOURCES/tilt-2.7.0.gem
|
||||||
bf4020626453c8db65d1817bed7b1884ea530e92 SOURCES/tornado-v6.1.0.pcs.4.tar.gz
|
|
||||||
|
|||||||
@ -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>
|
From: Ivan Devat <idevat@redhat.com>
|
||||||
Date: Tue, 20 Nov 2018 15:03:56 +0100
|
Date: Tue, 20 Nov 2018 15:03:56 +0100
|
||||||
Subject: [PATCH 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/pcs.8.in | 2 ++
|
||||||
pcs/usage.py | 1 +
|
pcs/usage.py | 1 +
|
||||||
pcsd/public/css/style.css | 3 +++
|
2 files changed, 3 insertions(+)
|
||||||
3 files changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
|
diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
|
||||||
index d504e8b4..93202d05 100644
|
index 3b644d054..a1c573cf5 100644
|
||||||
--- a/pcs/pcs.8.in
|
--- a/pcs/pcs.8.in
|
||||||
+++ b/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:
|
Transports udp and udpu:
|
||||||
.br
|
.br
|
||||||
+WARNING: These transports are not supported in RHEL 8.
|
+WARNING: These transports are not supported in RHEL 9.
|
||||||
+.br
|
+.br
|
||||||
These transports are limited to one address per node. They do not support traffic encryption nor compression.
|
These transports are limited to one address per node. They do not support traffic encryption nor compression.
|
||||||
.br
|
.br
|
||||||
Transport options are: ip_version, netmtu
|
Transport options are: ip_version, netmtu
|
||||||
diff --git a/pcs/usage.py b/pcs/usage.py
|
diff --git a/pcs/usage.py b/pcs/usage.py
|
||||||
index f4b84202..ee10370a 100644
|
index 4bcef3d25..d6eb51750 100644
|
||||||
--- a/pcs/usage.py
|
--- a/pcs/usage.py
|
||||||
+++ b/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.
|
hash=sha256. To disable encryption, set cipher=none and hash=none.
|
||||||
|
|
||||||
Transports udp and udpu:
|
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
|
These transports are limited to one address per node. They do not
|
||||||
support traffic encryption nor compression.
|
support traffic encryption nor compression.
|
||||||
Transport options are:
|
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