diff --git a/pkg/kdump/kdump-view.jsx b/pkg/kdump/kdump-view.jsx index fede357a842d..7412610c1c7f 100644 --- a/pkg/kdump/kdump-view.jsx +++ b/pkg/kdump/kdump-view.jsx @@ -34,12 +34,14 @@ import { DescriptionList, DescriptionListDescription, DescriptionListGroup, Desc import { Modal } from "@patternfly/react-core/dist/esm/components/Modal/index.js"; import { Spinner } from "@patternfly/react-core/dist/esm/components/Spinner/index.js"; import { Switch } from "@patternfly/react-core/dist/esm/components/Switch/index.js"; +import { Text, TextContent, TextVariants } from "@patternfly/react-core/dist/esm/components/Text/index.js"; import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js"; import { Title } from "@patternfly/react-core/dist/esm/components/Title/index.js"; import { Tooltip, TooltipPosition } from "@patternfly/react-core/dist/esm/components/Tooltip/index.js"; import { OutlinedQuestionCircleIcon } from "@patternfly/react-icons"; import { useDialogs, DialogsContext } from "dialogs.jsx"; +import { fmt_to_fragments } from 'utils.jsx'; import { show_modal_dialog } from "cockpit-components-dialog.jsx"; import { FormHelper } from "cockpit-components-form-helper"; import { ModalError } from 'cockpit-components-inline-notification.jsx'; @@ -263,12 +265,39 @@ export class KdumpPage extends React.Component { } handleTestSettingsClick() { + // if we have multiple targets defined, the config is invalid + const target = this.props.kdumpStatus.target; + let verifyMessage; + if (!target.multipleTargets) { + let path = target.path || "/var/crash"; + if (target.type === "local") { + verifyMessage = fmt_to_fragments( + ' ' + _("Results of the crash will be stored in $0 as $1, if kdump is properly configured."), + {path}, + vmcore); + } else if (target.type === "ssh" || target.type == "nfs") { + path = (target.type == "nfs" && path[0] !== '/') ? '/' + path : path; + verifyMessage = fmt_to_fragments( + ' ' + _("Results of the crash will be copied through $0 to $1 as $2, if kdump is properly configured."), + {target.type === "ssh" ? "SSH" : "NFS"}, + {`${target.server}:${target.type === "ssh" ? target.export + path : path}`}, + vmcore); + } + } + // open a dialog to confirm crashing the kernel to test the settings - then do it const dialogProps = { title: _("Test kdump settings"), - body: ( - {_("Test kdump settings by crashing the kernel. This may take a while and the system might not automatically reboot. Do not purposefully crash the system while any important task is running.")} - ) + body: ( + + {_("Test kdump settings by crashing the kernel. This may take a while and the system might not automatically reboot. Do not purposefully crash the system while any important task is running.")} + + {verifyMessage && + {verifyMessage} + } + ), + showClose: true, + titleIconVariant: "warning", }; // also test modifying properties in subsequent render calls const footerProps = { diff --git a/pkg/kdump/kdump.scss b/pkg/kdump/kdump.scss index f775a808269e..5e6e2b02d77a 100644 --- a/pkg/kdump/kdump.scss +++ b/pkg/kdump/kdump.scss @@ -19,6 +19,9 @@ @use "page"; +@import "global-variables"; +@import "@patternfly/patternfly/utilities/Text/text.scss"; + #kdump-settings-location { inline-size: 100%; } diff --git a/test/verify/check-kdump b/test/verify/check-kdump index 8a146633b526..62f6ac806f8a 100755 --- a/test/verify/check-kdump +++ b/test/verify/check-kdump @@ -32,20 +32,24 @@ class KdumpHelpers(testlib.MachineCase): self.browser.switch_to_top() self.browser.relogin("/kdump") - def crashKernel(self): + def crashKernel(self, message, cancel=False): b = self.browser b.click(f"button{self.default_btn_class}") - # we should get a warning dialog, confirm - b.click(f"button{self.danger_btn_class}") - # wait until we've actually triggered a crash - b.wait_visible(".apply.pf-m-in-progress") + self.browser.wait_in_text(".pf-v5-c-modal-box__body", message) + if cancel: + b.click(".pf-v5-c-modal-box button:contains('Cancel')") + else: + # we should get a warning dialog, confirm + b.click(f"button{self.danger_btn_class}") + # wait until we've actually triggered a crash + b.wait_visible(".apply.pf-m-in-progress") - # wait for disconnect and then try connecting again - b.switch_to_top() - with b.wait_timeout(60): - b.wait_in_text("div.curtains-ct h1", "Disconnected") - self.machine.disconnect() - self.machine.wait_boot(timeout_sec=300) + # wait for disconnect and then try connecting again + b.switch_to_top() + with b.wait_timeout(60): + b.wait_in_text("div.curtains-ct h1", "Disconnected") + self.machine.disconnect() + self.machine.wait_boot(timeout_sec=300) @testlib.skipOstree("kexec-tools not installed") @@ -141,6 +145,7 @@ class TestKdump(KdumpHelpers): b.set_input_text(pathInput, "/var/crash") b.click(f"#kdump-settings-dialog button{self.primary_btn_class}") b.wait_not_present(pathInput) + self.crashKernel("copied through SSH to root@localhost:/var/crash as vmcore", cancel=True) # we should have the amount of memory reserved that we indicated b.wait_in_text("#app", "256 MiB") @@ -174,7 +179,7 @@ class TestKdump(KdumpHelpers): assertActive(active=True) # crash the kernel and make sure it wrote a report into the right directory - self.crashKernel() + self.crashKernel("stored in /var/crash2 as vmcore") m.execute(f"until test -e {customPath}/127.0.0.1*/vmcore; do sleep 1; done", timeout=180) self.assertIn("Kdump compressed dump", m.execute(f"file {customPath}/127.0.0.1*/vmcore")) @@ -425,7 +430,7 @@ class TestKdumpNFS(KdumpHelpers): self.assertIn("\nnfs 10.111.113.2:/srv/kdump\n", conf) self.assertNotIn("\npath", conf) - self.crashKernel() + self.crashKernel("copied through NFS at 10.111.113.2:/srv/kdump/var/crash") # dump is done during boot, so should exist now self.assertIn("Kdump compressed dump", @@ -454,7 +459,7 @@ class TestKdumpNFS(KdumpHelpers): b.wait_visible(".pf-v5-c-switch__input:checked") - self.crashKernel() + self.crashKernel("copied through NFS at 10.111.113.2:/srv/kdump/dumps") self.assertIn("Kdump compressed dump", self.machines["nfs"].execute("file /srv/kdump/dumps/10.111.113.1*/vmcore"))