Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package cockpit for openSUSE:Factory checked 
in at 2022-09-16 13:32:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cockpit (Old)
 and      /work/SRC/openSUSE:Factory/.cockpit.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cockpit"

Fri Sep 16 13:32:05 2022 rev:24 rq:1003842 version:271

Changes:
--------
--- /work/SRC/openSUSE:Factory/cockpit/cockpit.changes  2022-08-26 
09:07:57.505364170 +0200
+++ /work/SRC/openSUSE:Factory/.cockpit.new.2083/cockpit.changes        
2022-09-16 13:32:28.573294955 +0200
@@ -1,0 +2,18 @@
+Tue Sep 13 09:46:17 UTC 2022 - Adam Majer <[email protected]>
+
+- Fix cockpit-storage dependencies
+- Merge SUSE branding into cockpit package
+
+-------------------------------------------------------------------
+Mon Sep  5 08:09:56 UTC 2022 - Jacek Tomasiak <[email protected]>
+
+- Update kdump-suse.patch to match upstream.
+
+-------------------------------------------------------------------
+Wed Aug 24 12:25:42 UTC 2022 - Jacek Tomasiak <[email protected]>
+
+- Add kdump-close.patch required by patches below.
+- Add kdump-refactor.patch and kdump-suse.patch to support SUSE
+  kdump config management in cockpit.
+
+-------------------------------------------------------------------

New:
----
  cockpit-suse-theme.obscpio
  cockpit-suse-theme.obsinfo
  kdump-close.patch
  kdump-refactor.patch
  kdump-suse.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cockpit.spec ++++++
--- /var/tmp/diff_new_pack.cEsjmH/_old  2022-09-16 13:32:30.321300602 +0200
+++ /var/tmp/diff_new_pack.cEsjmH/_new  2022-09-16 13:32:30.345300680 +0200
@@ -55,6 +55,7 @@
 Source0:        cockpit-%{version}.tar
 Source1:        cockpit.pam
 Source2:        cockpit-rpmlintrc
+Source3:        cockpit-suse-theme.tar
 Source99:       README.packaging
 Source98:       package-lock.json
 Source97:       node_modules.spec.inc
@@ -64,6 +65,9 @@
 Patch3:         suse-microos-branding.patch
 Patch4:         css-overrides.patch
 Patch5:         storage-btrfs.patch
+Patch6:         kdump-close.patch
+Patch7:         kdump-refactor.patch
+Patch8:         kdump-suse.patch
 # SLE Micro specific patches
 Patch100:       remove-pwscore.patch
 Patch101:       hide-pcp.patch
@@ -179,12 +183,15 @@
 %endif
 
 %prep
-%setup -q -n cockpit-%{version}
+%setup -q -n cockpit-%{version} -a 3
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
 %patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
 
 %if 0%{?sle_version}
 %patch100 -p1
@@ -230,6 +237,13 @@
 rm -f %{buildroot}/%{_libdir}/cockpit/*.so
 install -D -p -m 644 AUTHORS COPYING README.md %{buildroot}%{_docdir}/cockpit/
 
+mkdir -p %{buildroot}%{_datadir}/cockpit/branding/suse
+pushd cockpit-suse-theme
+cp src/css-overrides.css %{buildroot}%{_datadir}/cockpit/branding/suse
+cp src/fonts.css %{buildroot}%{_datadir}/cockpit/branding/suse
+cp -a src/fonts %{buildroot}%{_datadir}/cockpit/branding/suse
+popd
+
 # only ship deprecated PatternFly API for stable releases
 %if 0%{?rhel} == 8
     if [ -f %{buildroot}/%{_datadir}/cockpit/base1/cockpit.css.gz ]; then
@@ -343,7 +357,7 @@
 # remove brandings with stale symlinks. Means they don't match
 # the distro.
 pushd %{buildroot}/%{_datadir}/cockpit/branding
-ls --hide={default,kubernetes,opensuse,registry,sle-micro} | xargs rm -rv
+ls --hide={default,kubernetes,opensuse,registry,sle-micro,suse} | xargs rm -rv
 popd
 # need this in SUSE as post build checks dislike stale symlinks
 install -m 644 -D /dev/null %{buildroot}/run/cockpit/motd
@@ -697,14 +711,16 @@
 Summary: Cockpit user interface for storage, using udisks
 Requires: cockpit-shell >= 266
 Requires: udisks2 >= 2.9
-Recommends: udisks2-lvm2 >= 2.9
-Recommends: udisks2-iscsi >= 2.9
-Recommends: device-mapper-multipath
-Recommends: clevis-luks
 Requires: %{__python3}
 %if 0%{?suse_version}
+Requires: libudisks2-0_lvm2 >= 2.9
+Recommends: multipath-tools
 Requires: python3-dbus-python
 %else
+Recommends: udisks2-lvm2 >= 2.9
+Recommends: udisks2-iscsi >= 2.9
+Recommends: device-mapper-multipath
+Recommends: clevis-luks
 Requires: python3-dbus
 %endif
 BuildArch: noarch

++++++ _service ++++++
--- /var/tmp/diff_new_pack.cEsjmH/_old  2022-09-16 13:32:30.413300900 +0200
+++ /var/tmp/diff_new_pack.cEsjmH/_new  2022-09-16 13:32:30.417300912 +0200
@@ -1,5 +1,15 @@
 <services>
   <service name="obs_scm" mode="manual">
+    <param name="url">https://github.com/dgdavid/cockpit-suse-theme.git</param>
+    <param name="versionformat"></param>
+    <param name="scm">git</param>
+    <param name="revision">main</param>
+  </service>
+  <service mode="buildtime" name="tar">
+    <param name="obsinfo">cockpit-suse-theme.obsinfo</param>
+  </service>
+
+  <service name="obs_scm" mode="manual">
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="url">http://github.com/cockpit-project/cockpit.git</param>
     <param name="scm">git</param>
@@ -17,5 +27,7 @@
   <service mode="buildtime" name="set_version">
     <param name="basename">cockpit</param>
   </service>
+
+
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.cEsjmH/_old  2022-09-16 13:32:30.437300977 +0200
+++ /var/tmp/diff_new_pack.cEsjmH/_new  2022-09-16 13:32:30.441300990 +0200
@@ -1,6 +1,8 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">http://github.com/cockpit-project/cockpit.git</param>
-              <param 
name="changesrevision">046b3d4b381cd60f9d44756fc51f15ed7e17d0b5</param></service></servicedata>
+              <param 
name="changesrevision">046b3d4b381cd60f9d44756fc51f15ed7e17d0b5</param></service><service
 name="tar_scm">
+                <param 
name="url">https://github.com/dgdavid/cockpit-suse-theme.git</param>
+              <param 
name="changesrevision">fe08b35e64ad45f4b56cd636fdfec8fb18d69ab7</param></service></servicedata>
 (No newline at EOF)
 

++++++ cockpit-suse-theme.obsinfo ++++++
name: cockpit-suse-theme
version: 
mtime: 1655379139
commit: fe08b35e64ad45f4b56cd636fdfec8fb18d69ab7

++++++ kdump-close.patch ++++++
>From 9be51b563c98744053e4a7412e5030fa2ab3e061 Mon Sep 17 00:00:00 2001
From: Marius Vollmer <[email protected]>
Date: Mon, 8 Aug 2022 14:50:51 +0300
Subject: [PATCH] kdump: Use close with cockpit.file, not remove

There is no remove, and the intention is to close the watch channel.
---
 pkg/kdump/config-client.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/kdump/config-client.js b/pkg/kdump/config-client.js
index 9b95b9a0c65..c58cb85fd99 100644
--- a/pkg/kdump/config-client.js
+++ b/pkg/kdump/config-client.js
@@ -47,7 +47,7 @@ export class ConfigFile {
 
     close() {
         if (this._fileHandle) {
-            this._fileHandle.remove();
+            this._fileHandle.close();
             this._fileHandle = undefined;
         }
     }

++++++ kdump-refactor.patch ++++++
++++ 713 lines (skipped)

++++++ kdump-suse.patch ++++++
>From d95850239f81a65c90743f20a0bc0450cb61823a Mon Sep 17 00:00:00 2001
From: Jacek Tomasiak <[email protected]>
Date: Fri, 2 Sep 2022 16:51:02 +0200
Subject: [PATCH] kdump: Add SUSE kdump config support

If parsing /etc/kdump.conf doesn't return usable settings, try
/etc/sysconfig/kdump which is used by SUSE distributions as the main
kdump config.

The file is in dotenv format and currently only KDUMP_SAVEDIR,
KDUMP_DUMPFORMAT and KDUMP_SSH_IDENTITY entries
are used by Cockpit.

SUSE supports additional dump target types (ftp, sftp, cifs) but doesn't
support others (raw, mount). The target dialog currently supports the
common types (nfs, ssh, local).
---
 pkg/kdump/config-client-suse.js | 265 ++++++++++++++++++++++++++++++++
 pkg/kdump/kdump-client.js       |  14 ++
 pkg/kdump/kdump-view.jsx        |   8 +-
 test/verify/check-kdump         | 127 +++++++++++++++
 4 files changed, 413 insertions(+), 1 deletion(-)
 create mode 100644 pkg/kdump/config-client-suse.js

diff --git a/pkg/kdump/config-client-suse.js b/pkg/kdump/config-client-suse.js
new file mode 100644
index 00000000000..074d9e406ca
--- /dev/null
+++ b/pkg/kdump/config-client-suse.js
@@ -0,0 +1,265 @@
+/*
+ * This file is part of Cockpit.
+ *
+ * Copyright (C) 2022 SUSE LLC
+ *
+ * Cockpit is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * Cockpit is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { ConfigFile } from './config-client.js';
+
+/* Parse an dotenv-style config file
+ * and monitor it for changes
+ */
+export class ConfigFileSUSE extends ConfigFile {
+    /* parse lines of the config file
+     * if a line has a valid key=value format, use the key in _internal 
structure
+     * and also store original line, line index, value and optional line 
suffix / comment
+     * if value was quoted it will be stripped of quotes in `value` and 
`quoted` flag will
+     * be used when writing the file to keep original formatting
+     * e.g. for line 'someKey="foo" # comment'
+     * outputObject._internal["someKey"] = {
+     *      index: 0,
+     *      value: "foo",
+     *      quoted: true,
+     *      origLine: 'someKey="foo" # comment',
+     *      suffix: "# comment"
+     * }
+     * skipNotify: Don't notify about changes, e.g.to avoid multiple updates 
when writing a file
+     */
+    _parseText(rawContent, skipNotify = false) {
+        this._dataAvailableResolve();
+
+        // clear settings if file is empty/missing
+        if (!rawContent) {
+            this._originalSettings = null;
+            this.settings = null;
+            if (!skipNotify)
+                this.dispatchEvent("kdumpConfigChanged", this.settings);
+            return;
+        }
+
+        // if nothing changed, don't bother parsing the content
+        if (rawContent == this._rawContent)
+            return;
+
+        this._rawContent = rawContent;
+
+        // this is the format expected by the UI
+        this.settings = {
+            _internal: {},
+            targets: {},
+            compression: { enabled: false, allowed: true },
+        };
+
+        this._lines = rawContent.split(/\r?\n/);
+        this._lines.forEach((line, index) => {
+            const trimmed = line.trim();
+            // if the line is empty or only a comment, skip
+            if (trimmed.indexOf("#") === 0 || trimmed.length === 0)
+                return;
+
+            // parse KEY=value or KEY="value" line
+            let parts = trimmed.match(/^([A-Z_]+)\s*=\s*(.*)$/);
+            if (parts === null) {
+                console.warn("Malformed kdump config line:", trimmed, "in", 
this.filename);
+                return;
+            }
+            const key = parts[1];
+            let value = parts[2];
+
+            // value might be quoted
+            let quoted = false;
+            if (value.startsWith('"')) {
+                quoted = true;
+                parts = value.match(/^"([^"]*)"\s*(.*)$/);
+                // malformed line, no ending quote?
+                if (parts === null) {
+                    console.warn("Incorrectly quoted value in kdump config 
line:", line, "in", this.filename);
+                    return;
+                }
+            } else {
+                // not quoted should be simple value but grab everything and 
quote on write
+                parts = value.match(/^([^#]+?)\s*(#.*)?$/);
+                if (parts === null)
+                    parts = ["", ""];
+            }
+            value = parts[1];
+            const suffix = (parts[2] || "").trim();
+
+            this.settings._internal[key] = {
+                index: index,
+                value: value,
+                origLine: line,
+                quoted: quoted,
+                suffix: suffix
+            };
+        });
+
+        // make sure we copy the original keys so we overwrite the correct 
lines when saving
+        this._originalSettings = { };
+        Object.keys(this.settings._internal).forEach((key) => {
+            this._originalSettings[key] = { ...this.settings._internal[key] };
+        });
+
+        this._extractSettings();
+
+        if (!skipNotify)
+            this.dispatchEvent("kdumpConfigChanged", this.settings);
+    }
+
+    /* extract settings managed by cockpit from _internal into platform 
independent model
+     */
+    _extractSettings() {
+        // generate target(s) from KDUMP_SAVEDIR
+        if ("KDUMP_SAVEDIR" in this.settings._internal && 
this.settings._internal.KDUMP_SAVEDIR.value) {
+            let savedir = this.settings._internal.KDUMP_SAVEDIR.value;
+            // handle legacy "file" without prefix
+            if (savedir.startsWith("/"))
+                savedir = "file://" + savedir;
+            // server includes "username:password@" and can be empty for 
file://
+            const parts = savedir.match(/^(.*):\/\/([^/]*)(\/.*)$/);
+            // malformed KDUMP_SAVEDIR
+            if (parts === null) {
+                console.warn("Malformed KDUMP_SAVEDIR entry:", savedir, "in", 
this.filename);
+                return;
+            }
+            const [, scheme, server, path] = parts;
+            if (scheme === "file") {
+                this.settings.targets.local = {
+                    type: "local",
+                    path: path,
+                };
+            } else if (scheme === "nfs") {
+                this.settings.targets.nfs = {
+                    type: scheme,
+                    // on read full path is used as export
+                    export: path,
+                    server: server,
+                };
+            } else {
+                this.settings.targets[scheme] = {
+                    type: scheme,
+                    path: path,
+                    server: server,
+                };
+                // sshkey is used by ssh and sftp/scp
+                if ("KDUMP_SSH_IDENTITY" in this.settings._internal) {
+                    this.settings.targets[scheme].sshkey =
+                        this.settings._internal.KDUMP_SSH_IDENTITY.value;
+                }
+            }
+        }
+
+        // default to local if no target configured
+        if (Object.keys(this.settings.targets).length === 0)
+            this.settings.targets.local = { type: "local" };
+
+        this.settings.compression.enabled = (
+            !("KDUMP_DUMPFORMAT" in this.settings._internal) ||
+            // TODO: what about other compression formats (lzo, snappy)?
+            this.settings._internal.KDUMP_DUMPFORMAT.value === "compressed"
+        );
+    }
+
+    /* update single _internal setting to given value
+     * make sure setting exists if value is not empty
+     * don't delete existing settings
+     */
+    _updateSetting(settings, key, value) {
+        if (key in settings._internal) {
+            settings._internal[key].value = value;
+        } else {
+            if (value)
+                settings._internal[key] = { value: value };
+        }
+    }
+
+    /* transform settings from model back to _internal format
+     * this.settings = current state from file
+     * settings = in-memory state from UI
+     */
+    _persistSettings(settings) {
+        // target
+        if (Object.keys(settings.targets).length > 0) {
+            const target = Object.values(settings.targets)[0];
+
+            if ("sshkey" in target)
+                this._updateSetting(settings, "KDUMP_SSH_IDENTITY", 
target.sshkey);
+
+            let savedir;
+            // default for empty path (except nfs, see below)
+            let path = target.path || "/var/crash";
+            if (path && !path.startsWith("/"))
+                path = "/" + path;
+            if (target.type === "local") {
+                savedir = "file://" + path;
+            } else if (target.type === "nfs") {
+                // override empty path default as nfs path is merged into 
export on read
+                if (!target.path)
+                    path = "";
+                let exprt = target.export;
+                if (!exprt.startsWith("/"))
+                    exprt = "/" + exprt;
+                savedir = "nfs://" + target.server + exprt + path;
+            } else {
+                savedir = target.type + "://" + target.server + path;
+            }
+            this._updateSetting(settings, "KDUMP_SAVEDIR", savedir);
+        }
+        // compression
+        if (this.settings.compression.enabled != settings.compression.enabled) 
{
+            if (settings.compression.enabled) {
+                this._updateSetting(settings, "KDUMP_DUMPFORMAT", 
"compressed");
+            } else {
+                this._updateSetting(settings, "KDUMP_DUMPFORMAT", "ELF");
+            }
+        }
+        return settings;
+    }
+
+    /* generate the config file from raw text and settings
+     */
+    _generateConfig(settings) {
+        settings = this._persistSettings(settings);
+
+        const lines = this._lines.slice(0);
+
+        // we take the lines from our last read operation and modify them with 
the new settings
+        Object.keys(settings._internal).forEach((key) => {
+            const entry = settings._internal[key];
+
+            let value = entry.value !== undefined ? entry.value : "";
+            // quote what was quoted before + empty values + multi-word values
+            if (entry.quoted || value === "" || value.includes(" "))
+                value = '"' + value + '"';
+            let line = key + "=" + value;
+            if (entry.suffix)
+                line = line + " " + entry.suffix;
+            // this might be a new entry
+            if (!(key in this._originalSettings)) {
+                lines.push(line);
+                return;
+            }
+            // otherwise edit the old line
+            const origEntry = this._originalSettings[key];
+            lines[origEntry.index] = line;
+        });
+
+        // make sure file ends with a newline
+        if (lines[lines.length - 1] !== "")
+            lines.push("");
+        return lines.join("\n");
+    }
+}
diff --git a/pkg/kdump/kdump-client.js b/pkg/kdump/kdump-client.js
index d001ebb0b5a..7af24dc1bcb 100644
--- a/pkg/kdump/kdump-client.js
+++ b/pkg/kdump/kdump-client.js
@@ -20,6 +20,7 @@
 import cockpit from 'cockpit';
 import { proxy as serviceProxy } from 'service';
 import { ConfigFile } from './config-client.js';
+import { ConfigFileSUSE } from './config-client-suse.js';
 
 import crashKernelScript from 'raw-loader!./crashkernel.sh';
 import testWritableScript from 'raw-loader!./testwritable.sh';
@@ -61,6 +62,19 @@ export class KdumpClient {
 
         // watch the config file
         this.configClient = new ConfigFile("/etc/kdump.conf", true);
+        this._watchConfigChanges();
+
+        this.configClient.wait().then(() => {
+            // if no configuration found, try SUSE version
+            if (this.configClient.settings === null) {
+                this.configClient.close();
+                this.configClient = new ConfigFileSUSE("/etc/sysconfig/kdump", 
true);
+                this._watchConfigChanges();
+            }
+        });
+    }
+
+    _watchConfigChanges() {
         // catch config changes
         this.configClient.addEventListener('kdumpConfigChanged', () => {
             this.state.config = this.configClient.settings;
diff --git a/pkg/kdump/kdump-view.jsx b/pkg/kdump/kdump-view.jsx
index 956811d7826..3de3761706b 100644
--- a/pkg/kdump/kdump-view.jsx
+++ b/pkg/kdump/kdump-view.jsx
@@ -364,6 +364,12 @@ export class KdumpPage extends React.Component {
                     /* mount targets outside of nfs are too complex for the
                      * current target dialog */
                     kdumpLocation = _("On a mounted device");
+                } else if (target.type == "ftp") {
+                    kdumpLocation = _("Remote over FTP");
+                } else if (target.type == "sftp") {
+                    kdumpLocation = _("Remote over SFTP");
+                } else if (target.type == "cifs") {
+                    kdumpLocation = _("Remote over CIFS/SMB");
                 } else {
                     kdumpLocation = _("No configuration found");
                 }
@@ -372,7 +378,7 @@ export class KdumpPage extends React.Component {
         // this.storeLocation(this.props.kdumpStatus.config);
         const settingsLink = targetCanChange
             ? <Button variant="link" isInline id="kdump-change-target" 
onClick={this.handleSettingsClick}>{ kdumpLocation }</Button>
-            : <span>{ kdumpLocation }</span>;
+            : <span id="kdump-target-info">{ kdumpLocation }</span>;
         let reservedMemory;
         if (this.props.reservedMemory === undefined) {
             // still waiting for result
diff --git a/test/verify/check-kdump b/test/verify/check-kdump
index 03d9a199970..855636eb0da 100755
--- a/test/verify/check-kdump
+++ b/test/verify/check-kdump
@@ -248,6 +248,133 @@ class TestKdump(KdumpHelpers):
         conf = m.execute("cat /etc/kdump.conf")
         self.assertIn(current + " -c", conf)
 
+    @nondestructive
+    def testConfigurationSUSE(self):
+        b = self.browser
+        m = self.machine
+
+        testConfig = [
+            "# some comment",
+            "KDUMP_DUMPFORMAT=compressed # suffix",
+            "KDUMP_SSH_IDENTITY=\"\"",
+            "skip this line",
+            "BAD_QUOTES=unquoted value # suffix",
+            "BAD_SPACES = 42 # comment",
+            "MORE_BAD_SPACES = 4 2 # long comment",
+            "KDUMP_SAVEDIR=ssh//missing/colon",
+        ]
+
+        # clean default config to trigger SUSE config mode
+        self.write_file("/etc/kdump.conf", "")
+        # write initial SUSE config (append to keep original contents as well)
+        self.write_file("/etc/sysconfig/kdump", "\n".join(testConfig), 
append=True)
+
+        m.execute("systemctl disable --now kdump")
+
+        self.login_and_go("/kdump")
+        b.wait_visible("#app")
+
+        # Check malformed lines
+        b.wait_text("#kdump-target-info", "No configuration found")
+        b.wait(lambda: "warning: Malformed kdump config line: skip this line 
in /etc/sysconfig/kdump" in list(self.browser.get_js_log()))
+        b.wait(lambda: "warning: Malformed KDUMP_SAVEDIR entry: 
ssh//missing/colon in /etc/sysconfig/kdump" in list(self.browser.get_js_log()))
+
+        # Remove malformed KDUMP_SAVEDIR to check default if nothing specified
+        m.execute("sed -i '/KDUMP_SAVEDIR=.*/d' /etc/sysconfig/kdump")
+        b.wait_text("#kdump-change-target", "locally in /var/crash")
+
+        # Check fixing of (some) malformed lines and local target without 
file://
+        m.execute("echo KDUMP_SAVEDIR=/tmp >> /etc/sysconfig/kdump")
+        b.wait_text("#kdump-change-target", "locally in /tmp")
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_SAVEDIR=file:///tmp', conf)
+        self.assertIn('BAD_QUOTES="unquoted value" # suffix', conf)
+        self.assertIn('BAD_SPACES=42 # comment', conf)
+        self.assertIn('MORE_BAD_SPACES="4 2" # long comment', conf)
+
+        # Check remote ssh location
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_val("#kdump-settings-location", "ssh")
+        b.set_input_text("#kdump-settings-ssh-server", "admin@localhost")
+        b.set_input_text("#kdump-settings-ssh-key", "/home/admin/.ssh/id_rsa")
+        b.set_input_text("#kdump-settings-ssh-directory", "/var/tmp/crash")
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        b.wait_text("#kdump-change-target", "Remote over SSH")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_SAVEDIR=ssh://admin@localhost/var/tmp/crash', 
conf)
+        self.assertIn('KDUMP_SSH_IDENTITY="/home/admin/.ssh/id_rsa"', conf)
+
+        # Check remote NFS location
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_val("#kdump-settings-location", "nfs")
+        b.set_input_text("#kdump-settings-nfs-server", "someserver")
+        b.set_input_text("#kdump-settings-nfs-export", "/srv")
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        b.wait_text("#kdump-change-target", "Remote over NFS")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_SAVEDIR=nfs://someserver/srv', conf)
+        self.assertNotIn("ssh://", conf)
+
+        # NFS with custom path
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_input_text("#kdump-settings-nfs-directory", "dumps")
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        b.wait_text("#kdump-change-target", "Remote over NFS")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_SAVEDIR=nfs://someserver/srv/dumps', conf)
+
+        # Check local location
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_val("#kdump-settings-location", "local")
+        b.set_input_text("#kdump-settings-local-directory", "/var/tmp")
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        b.wait_text("#kdump-change-target", "locally in /var/tmp")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_SAVEDIR=file:///var/tmp', conf)
+        self.assertNotIn("nfs://", conf)
+
+        # Check compression
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_DUMPFORMAT=compressed', conf)
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_checked("#kdump-settings-compression", False)
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_DUMPFORMAT=ELF', conf)
+        b.click("#kdump-change-target")
+        b.wait_visible("#kdump-settings-dialog")
+        b.set_checked("#kdump-settings-compression", True)
+        b.click("button:contains('Save')")
+        b.wait_not_present("#kdump-settings-dialog")
+        conf = m.execute("cat /etc/sysconfig/kdump")
+        self.assertIn('KDUMP_DUMPFORMAT=compressed', conf)
+
+        # Check remote FTP location (no config dialog)
+        m.execute("sed -i 
's/KDUMP_SAVEDIR=.*/KDUMP_SAVEDIR=ftp:\\/\\/user@ftpserver\\/dumps1/g' 
/etc/sysconfig/kdump")
+        b.wait_text("#kdump-target-info", "Remote over FTP")
+
+        # Check remote SFTP location (no config dialog)
+        m.execute("sed -i 
's/KDUMP_SAVEDIR=.*/KDUMP_SAVEDIR=sftp:\\/\\/sftpserver\\/dumps2/g' 
/etc/sysconfig/kdump")
+        b.wait_text("#kdump-target-info", "Remote over SFTP")
+
+        # Check remote CIFS location (no config dialog)
+        m.execute("sed -i 
's/KDUMP_SAVEDIR=.*/KDUMP_SAVEDIR=cifs:\\/\\/user:pass@smbserver\\/dumps3/g' 
/etc/sysconfig/kdump")
+        b.wait_text("#kdump-target-info", "Remote over CIFS/SMB")
+
 
 @skipImage("kexec-tools not installed", "fedora-coreos", "debian-stable",
            "debian-testing", "ubuntu-2204", "ubuntu-stable", "arch")

Reply via email to