From 7109a2d114cc25b712eec7c8e9831ce559931677071519540479610e7000b12f Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 08:59:38 +0000 Subject: [PATCH 1/7] Accepting request 1001225 from home:jtomasiak:branches:systemsmanagement:cockpit - Update kdump-suse.patch to match upstream. - Add kdump-close.patch required by patches below. - Add kdump-refactor.patch and kdump-suse.patch to support SUSE kdump config management in cockpit. OBS-URL: https://build.opensuse.org/request/show/1001225 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=105 --- cockpit.changes | 12 + cockpit.spec | 6 + kdump-close.patch | 23 ++ kdump-refactor.patch | 712 +++++++++++++++++++++++++++++++++++++++++++ kdump-suse.patch | 491 +++++++++++++++++++++++++++++ 5 files changed, 1244 insertions(+) create mode 100644 kdump-close.patch create mode 100644 kdump-refactor.patch create mode 100644 kdump-suse.patch diff --git a/cockpit.changes b/cockpit.changes index 8e5cc5f..d0987a0 100644 --- a/cockpit.changes +++ b/cockpit.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Mon Sep 5 08:09:56 UTC 2022 - Jacek Tomasiak + +- Update kdump-suse.patch to match upstream. + +------------------------------------------------------------------- +Wed Aug 24 12:25:42 UTC 2022 - Jacek Tomasiak + +- Add kdump-close.patch required by patches below. +- Add kdump-refactor.patch and kdump-suse.patch to support SUSE + kdump config management in cockpit. + ------------------------------------------------------------------- Wed Aug 24 07:37:46 UTC 2022 - Adam Majer diff --git a/cockpit.spec b/cockpit.spec index 0755d40..dae613e 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -64,6 +64,9 @@ Patch2: hide-docs.patch 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 @@ -185,6 +188,9 @@ Requires: subscription-manager-cockpit %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 %if 0%{?sle_version} %patch100 -p1 diff --git a/kdump-close.patch b/kdump-close.patch new file mode 100644 index 0000000..ee0a8c5 --- /dev/null +++ b/kdump-close.patch @@ -0,0 +1,23 @@ +From 9be51b563c98744053e4a7412e5030fa2ab3e061 Mon Sep 17 00:00:00 2001 +From: Marius Vollmer +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; + } + } diff --git a/kdump-refactor.patch b/kdump-refactor.patch new file mode 100644 index 0000000..72e4093 --- /dev/null +++ b/kdump-refactor.patch @@ -0,0 +1,712 @@ +From b61b273451987a283825a585a4f40901be12b11c Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Tue, 12 Jul 2022 01:38:04 +0200 +Subject: [PATCH 1/4] kdump: Refactor config handling + +Config handling was modified to decouple UI from config file format. +All of the platform-specific code was moved to config-client.js and +"abstract" settings model was added as an interface. +In addition, NFS UI page was modified to not require NFS mounts in +specific format but as separate "server" and "export" fields. +--- + pkg/kdump/config-client.js | 186 +++++++++++++++++++++++++++++++++++-- + pkg/kdump/kdump-client.js | 87 ++++------------- + pkg/kdump/kdump-view.jsx | 125 ++++++++----------------- + 3 files changed, 237 insertions(+), 161 deletions(-) + +diff --git a/pkg/kdump/config-client.js b/pkg/kdump/config-client.js +index 39913bb6c86..d292bd9bebd 100644 +--- a/pkg/kdump/config-client.js ++++ b/pkg/kdump/config-client.js +@@ -19,6 +19,12 @@ + + import cockpit from 'cockpit'; + ++const deprecatedKeys = ["net", "options", "link_delay", "disk_timeout", "debug_mem_level", "blacklist"]; ++const knownKeys = [ ++ "raw", "nfs", "ssh", "sshkey", "path", "core_collector", "kdump_post", "kdump_pre", "extra_bins", "extra_modules", ++ "default", "force_rebuild", "override_resettable", "dracut_args", "fence_kdump_args", "fence_kdump_nodes" ++]; ++ + /* Parse an ini-style config file + * and monitor it for changes + */ +@@ -82,7 +88,12 @@ export class ConfigFile { + // parse the config file + this._lines = rawContent.split(/\r?\n/); + +- this.settings = { }; ++ // this is the format expected by the UI ++ this.settings = { ++ _internal: {}, ++ targets: {}, ++ compression: { enabled: false, allowed: false, }, ++ }; + this._lines.forEach((line, index) => { + const trimmed = line.trim(); + // if the line is empty or only a comment, skip +@@ -103,7 +114,7 @@ export class ConfigFile { + comment = value.substring(commentIndex).trim(); + value = value.substring(0, commentIndex).trim(); + } +- this.settings[key] = { ++ this.settings._internal[key] = { + index: index, + value: value, + origLine: line, +@@ -113,21 +124,182 @@ export class ConfigFile { + + // make sure we copy the original keys so we overwrite the correct lines when saving + this._originalSettings = { }; +- Object.keys(this.settings).forEach((key) => { +- this._originalSettings[key] = { ...this.settings[key] }; ++ 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() { ++ // "path" applies to all targets ++ const path = this.settings._internal.path || { value: "" }; ++ ++ Object.keys(this.settings._internal).forEach((key) => { ++ if (key === "nfs") { ++ // split nfs line into server and export parts ++ const parts = this.settings._internal.nfs.value.match(/^([^[][^:]+|\[[^\]]+\]):(.*)$/); ++ if (!parts) ++ return; ++ this.settings.targets.nfs = { ++ type: key, ++ path: path.value, ++ server: parts[1], ++ export: parts[2], ++ }; ++ } else if (key === "ssh") { ++ this.settings.targets.ssh = { ++ type: key, ++ path: path.value, ++ server: this.settings._internal.ssh.value, ++ }; ++ if ("sshkey" in this.settings._internal) ++ this.settings.targets.ssh.sshkey = this.settings._internal.sshkey.value; ++ } else if (key === "raw") { ++ this.settings.targets.raw = { ++ type: key, ++ partition: this.settings._internal.raw.value ++ }; ++ } else { ++ // probably local, but we might also have a mount ++ // check against known keys, the ones left over may be a mount target ++ // if the key is empty or known, we don't care about it here ++ if (!key || key in knownKeys || key in deprecatedKeys) ++ return; ++ // if we have a UUID, LABEL or /dev in the value, we can be pretty sure it's a mount option ++ const value = JSON.stringify(this.settings._internal[key]).toLowerCase(); ++ if (value.indexOf("uuid") > -1 || value.indexOf("label") > -1 || value.indexOf("/dev") > -1) { ++ this.settings.targets.mount = { ++ type: "mount", ++ path: path.value, ++ fsType: key, ++ partition: this.settings._internal[key].value, ++ }; ++ } else { ++ // TODO: check for know filesystem types here ++ } ++ } ++ }); ++ ++ // default to local if no target configured ++ if (Object.keys(this.settings.targets).length === 0) ++ this.settings.targets.local = { type: "local", path: path.value }; ++ ++ // only allow compression if there is no core collector set or it's set to makedumpfile ++ this.settings.compression.allowed = ( ++ !("core_collector" in this.settings._internal) || ++ (this.settings._internal.core_collector.value.trim().indexOf("makedumpfile") === 0) ++ ); ++ // compression is enabled if we have a core_collector command with the "-c" parameter ++ this.settings.compression.enabled = ( ++ ("core_collector" in this.settings._internal) && ++ this.settings._internal.core_collector.value && ++ (this.settings._internal.core_collector.value.split(" ").indexOf("-c") != -1) ++ ); ++ } ++ ++ /* update single _internal setting to given value ++ * make sure setting exists if value is not empty ++ */ ++ _updateSetting(settings, key, value) { ++ if (key in settings._internal) { ++ if (value) ++ settings._internal[key].value = value; ++ else ++ delete settings._internal[key]; ++ } 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]; ++ this._updateSetting(settings, "path", target.path); ++ ++ // wipe old target settings ++ for (const key in this.settings.targets) { ++ const oldTarget = this.settings.targets[key]; ++ if (oldTarget.type == "mount") { ++ delete settings._internal[oldTarget.fsType]; ++ } else { ++ delete settings._internal[key]; ++ } ++ } ++ ++ if (target.type === "nfs") { ++ this._updateSetting(settings, "nfs", [target.server, target.export].join(":")); ++ } else if (target.type === "ssh") { ++ this._updateSetting(settings, "ssh", target.server); ++ if ("sshkey" in target) ++ this._updateSetting(settings, "sshkey", target.sshkey); ++ } else if (target.type === "raw") { ++ this._updateSetting(settings, "raw", target.partition); ++ } else if (target.type === "mount") { ++ this._updateSetting(settings, target.fsType, target.partition); ++ } ++ ++ /* ssh target needs a flattened vmcore for transport */ ++ if ("core_collector" in settings._internal && ++ settings._internal.core_collector.value.includes("makedumpfile")) { ++ if (target.type === "ssh" && !settings._internal.core_collector.value.includes("-F")) ++ settings._internal.core_collector.value += " -F"; ++ else if (settings._internal.core_collector.value.includes("-F")) ++ settings._internal.core_collector.value = ++ settings._internal.core_collector.value ++ .split(" ") ++ .filter(e => e != "-F") ++ .join(" "); ++ } ++ } ++ // compression ++ if (this.settings.compression.enabled != settings.compression.enabled) { ++ if (settings.compression.enabled) { ++ // enable compression ++ if ("core_collector" in settings._internal) ++ settings._internal.core_collector.value = settings._internal.core_collector.value + " -c"; ++ else ++ settings._internal.core_collector = { value: "makedumpfile -c" }; ++ } else { ++ // disable compression ++ if ("core_collector" in this.settings._internal) { ++ // just remove all "-c" parameters ++ settings._internal.core_collector.value = ++ settings._internal.core_collector.value ++ .split(" ") ++ .filter((e) => { return (e != "-c") }) ++ .join(" "); ++ } else { ++ // if we don't have anything on this in the original settings, ++ // we can get rid of the entry altogether ++ delete settings._internal.core_collector; ++ } ++ } ++ } ++ return settings; ++ } ++ + /* generate the config file from raw text and settings + */ + _generateConfig(settings) { ++ settings = this._persistSettings(settings); ++ + const lines = this._lines.slice(0); + const linesToDelete = []; + // first find the settings lines that have been disabled/deleted + Object.keys(this._originalSettings).forEach((key) => { +- if (!(key in settings) || !(key in settings && settings[key].value)) { ++ if (!(key in settings._internal) || !(key in settings._internal && settings._internal[key].value)) { + const origEntry = this._originalSettings[key]; + // if the line had a comment, keep it, otherwise delete + if (origEntry.comment !== undefined) +@@ -138,8 +310,8 @@ export class ConfigFile { + }); + + // we take the lines from our last read operation and modify them with the new settings +- Object.keys(settings).forEach((key) => { +- const entry = settings[key]; ++ Object.keys(settings._internal).forEach((key) => { ++ const entry = settings._internal[key]; + let line = key + " " + entry.value; + if (entry.comment) + line = line + " " + entry.comment; +diff --git a/pkg/kdump/kdump-client.js b/pkg/kdump/kdump-client.js +index a161fc25214..d001ebb0b5a 100644 +--- a/pkg/kdump/kdump-client.js ++++ b/pkg/kdump/kdump-client.js +@@ -25,12 +25,6 @@ import crashKernelScript from 'raw-loader!./crashkernel.sh'; + import testWritableScript from 'raw-loader!./testwritable.sh'; + const _ = cockpit.gettext; + +-const deprecatedKeys = ["net", "options", "link_delay", "disk_timeout", "debug_mem_level", "blacklist"]; +-const knownKeys = [ +- "raw", "nfs", "ssh", "sshkey", "path", "core_collector", "kdump_post", "kdump_pre", "extra_bins", "extra_modules", +- "default", "force_rebuild", "override_resettable", "dracut_args", "fence_kdump_args", "fence_kdump_nodes" +-]; +- + /* initializes the kdump status + * emits "kdumpStatusChanged" when the status changes, along with a status object: + * { +@@ -40,7 +34,7 @@ const knownKeys = [ + * config: settings from kdump.conf + * target: dump target info, content depends on dump type + * always contains the keys: +- * target value in ["local", "nfs", "ssh", "raw", "mount", "unknown"] ++ * type value in ["local", "nfs", "ssh", "raw", "mount", "unknown"] + * multipleTargets true if the config file has more than one target defined, false otherwise + * } + * +@@ -106,19 +100,24 @@ export class KdumpClient { + path = "/var/crash"; + + return new Promise((resolve, reject) => { +- if (target.target === "local") { ++ if (target.type === "local") { + // local path, try to see if we can write + cockpit.script(testWritableScript, [path], { superuser: "try" }) + .then(resolve) + .catch(() => reject(cockpit.format(_("Directory $0 isn't writable or doesn't exist."), path))); + return; +- } else if (target.target === "nfs") { +- if (!target.nfs.value.match("\\S+:/.+")) +- reject(_("nfs dump target isn't formatted as server:path")); +- } else if (target.target === "ssh") { +- if (!target.ssh.value.trim()) ++ } else if (target.type === "nfs") { ++ if (!target.server || !target.server.trim()) ++ reject(_("nfs server is empty")); ++ // IPv6 must be enclosed in square brackets ++ if (target.server.trim().match(/^\[.*[^\]]$/)) ++ reject(_("nfs server is not valid IPv6")); ++ if (!target.export || !target.export.trim()) ++ reject(_("nfs export is empty")); ++ } else if (target.type === "ssh") { ++ if (!target.server || !target.server.trim()) + reject(_("ssh server is empty")); +- if (target.sshkey && !target.sshkey.value.match("/.+")) ++ if (target.sshkey && !target.sshkey.match("/.+")) + reject(_("ssh key isn't a path")); + } + +@@ -149,67 +148,17 @@ export class KdumpClient { + } + + targetFromSettings(settings) { +- // since local target is the default and can be used even without "path", we need to +- // check for the presence of all known targets +- // we have the additional difficulty that partitions don't have a good config key, since their +- // lines begin with the fs_type + const target = { +- target: "unknown", ++ type: "unknown", + multipleTargets: false, + }; + +- if (!settings) ++ if (!settings || Object.keys(settings.targets).length === 0) + return target; + +- if ("nfs" in settings) { +- if (target.target != "unknown") +- target.multipleTargets = true; +- target.target = "nfs"; +- target.nfs = settings.nfs; +- if ("path" in settings) +- target.path = settings.path; +- } else if ("ssh" in settings) { +- if (target.target != "unknown") +- target.multipleTargets = true; +- target.target = "ssh"; +- target.ssh = settings.ssh; +- target.sshkey = settings.sshkey; +- } else if ("raw" in settings) { +- if (target.target != "unknown") +- target.multipleTargets = true; +- target.target = "raw"; +- target.raw = settings.raw; +- } else { +- // probably local, but we might also have a mount +- // check all keys against known keys, the ones left over may be a mount target +- Object.keys(settings).forEach((key) => { +- // if the key is empty or known, we don't care about it here +- if (!key || key in knownKeys || key in deprecatedKeys) +- return; +- // if we have a UUID, LABEL or /dev in the value, we can be pretty sure it's a mount option +- const value = JSON.stringify(settings[key]).toLowerCase(); +- if (value.indexOf("uuid") > -1 || value.indexOf("label") > -1 || value.indexOf("/dev") > -1) { +- if (target.target != "unknown") +- target.multipleTargets = true; +- target.target = "mount"; +- target.fsType = key; +- target.partition = settings[key].value; +- } else { +- // TODO: check for know filesystem types here +- } +- }); +- } +- +- // if no target matches, then we use the local filesystem +- if (target.target == "unknown") +- target.target = "local"; +- +- // "path" applies to all targets +- // default to "/var/crash for " +- if ("path" in settings) +- target.path = settings.path.value; +- else if (["local", "ssh", "nfs", "mount"].indexOf(target.target) !== -1) +- target.path = "/var/crash"; ++ // copy first target ++ cockpit.extend(target, Object.values(settings.targets)[0]); ++ target.multipleTargets = Object.keys(settings.targets).length > 1; + return target; + } + } +diff --git a/pkg/kdump/kdump-view.jsx b/pkg/kdump/kdump-view.jsx +index 718d8c43bc9..956811d7826 100644 +--- a/pkg/kdump/kdump-view.jsx ++++ b/pkg/kdump/kdump-view.jsx +@@ -57,7 +57,7 @@ class KdumpTargetBody extends React.Component { + constructor(props) { + super(props); + this.state = { +- storeDest: this.props.initialTarget.target, // dialog mode, depends on location ++ storeDest: this.props.initialTarget.type, // dialog mode, depends on location + }; + this.changeLocation = this.changeLocation.bind(this); + } +@@ -71,15 +71,10 @@ class KdumpTargetBody extends React.Component { + + render() { + let detailRows; +- // only allow compression if there is no core collector set or it's set to makedumpfile +- const compressionPossible = ( +- !this.props.settings || +- !("core_collector" in this.props.settings) || +- (this.props.settings.core_collector.value.trim().indexOf("makedumpfile") === 0) +- ); ++ const compressionPossible = !this.props.settings || this.props.settings.compression.allowed; + let directory = ""; +- if (this.props.settings && "path" in this.props.settings) +- directory = this.props.settings.path.value; ++ if (this.props.settings && "path" in this.props.settings.targets[this.state.storeDest]) ++ directory = this.props.settings.targets[this.state.storeDest].path; + + if (this.state.storeDest == "local") { + detailRows = ( +@@ -91,15 +86,22 @@ class KdumpTargetBody extends React.Component { + + ); + } else if (this.state.storeDest == "nfs") { +- let nfs = ""; +- if (this.props.settings && "nfs" in this.props.settings) +- nfs = this.props.settings.nfs.value; ++ let nfs = {}; ++ if (this.props.settings && "nfs" in this.props.settings.targets) ++ nfs = this.props.settings.targets.nfs; ++ const server = nfs.server || ""; ++ const exportpath = nfs.export || ""; + detailRows = ( + <> +- +- this.props.onChange("nfs", value)} /> ++ ++ this.props.onChange("server", value)} /> ++ ++ ++ this.props.onChange("export", value)} /> + + + + ); + } else if (this.state.storeDest == "ssh") { +- let ssh = ""; +- if (this.props.settings && "ssh" in this.props.settings) +- ssh = this.props.settings.ssh.value; +- let sshkey = ""; +- if (this.props.settings && "sshkey" in this.props.settings) +- sshkey = this.props.settings.sshkey.value; ++ let ssh = {}; ++ if (this.props.settings && "ssh" in this.props.settings.targets) ++ ssh = this.props.settings.targets.ssh; ++ const server = ssh.server || ""; ++ const sshkey = ssh.sshkey || ""; + detailRows = ( + <> + + this.props.onChange("ssh", value)} /> ++ placeholder="user@server.com" value={server} ++ onChange={value => this.props.onChange("server", value)} /> + + + +@@ -201,78 +202,32 @@ export class KdumpPage extends React.Component { + } + + compressionStatus(settings) { +- // compression is enabled if we have a core_collector command with the "-c" parameter +- return ( +- settings && +- ("core_collector" in settings) && +- settings.core_collector.value && +- (settings.core_collector.value.split(" ").indexOf("-c") != -1) +- ); ++ return settings && settings.compression.enabled; + } + + changeSetting(key, value) { + let settings = this.state.dialogSettings; + +- // a few special cases, otherwise write to config directly ++ // a few special cases, otherwise write to config target directly + if (key == "compression") { +- if (value) { +- // enable compression +- if ("core_collector" in settings) +- settings.core_collector.value = settings.core_collector.value + " -c"; +- else +- settings.core_collector = { value: "makedumpfile -c" }; +- } else { +- // disable compression +- if ("core_collector" in this.props.kdumpStatus.config) { +- // just remove all "-c" parameters +- settings.core_collector.value = +- settings.core_collector.value +- .split(" ") +- .filter((e) => { return (e != "-c") }) +- .join(" "); +- } else { +- // if we don't have anything on this in the original settings, +- // we can get rid of the entry altogether +- delete settings.core_collector; +- } +- } ++ settings.compression.enabled = value; + } else if (key === "target") { + /* target changed, restore settings and wipe all settings associated + * with a target so no conflicting settings remain */ + settings = {}; ++ // TODO: do we need a deep copy here? + Object.keys(this.props.kdumpStatus.config).forEach((key) => { + settings[key] = { ...this.props.kdumpStatus.config[key] }; + }); +- Object.keys(this.props.kdumpStatus.target).forEach((key) => { +- if (settings[key]) +- delete settings[key]; +- }); +- if (value === "ssh") +- settings.ssh = { value: "" }; +- else if (value === "nfs") +- settings.nfs = { value: "" }; +- +- if ("core_collector" in settings && +- settings.core_collector.value.includes("makedumpfile")) { +- /* ssh target needs a flattened vmcore for transport */ +- if (value === "ssh" && !settings.core_collector.value.includes("-F")) +- settings.core_collector.value += " -F"; +- else if (settings.core_collector.value.includes("-F")) +- settings.core_collector.value = +- settings.core_collector.value +- .split(" ") +- .filter(e => e != "-F") +- .join(" "); +- } ++ settings.targets = {}; ++ settings.targets[value] = { type: value }; + } else if (key !== undefined) { ++ const type = Object.keys(settings.targets)[0]; + if (!value) { +- if (settings[key]) +- delete settings[key]; ++ if (settings.targets[type][key]) ++ delete settings.targets[type][key]; + } else { +- if (key in settings) +- settings[key].value = value; +- else +- settings[key] = { value: value }; ++ settings.targets[type][key] = value; + } + } + this.setState({ dialogSettings: settings }); +@@ -391,21 +346,21 @@ export class KdumpPage extends React.Component { + if (target.multipleTargets) { + kdumpLocation = _("invalid: multiple targets defined"); + } else { +- if (target.target == "local") { ++ if (target.type == "local") { + if (target.path) + kdumpLocation = cockpit.format(_("locally in $0"), target.path); + else + kdumpLocation = cockpit.format(_("locally in $0"), "/var/crash"); + targetCanChange = true; +- } else if (target.target == "ssh") { ++ } else if (target.type == "ssh") { + kdumpLocation = _("Remote over SSH"); + targetCanChange = true; +- } else if (target.target == "nfs") { ++ } else if (target.type == "nfs") { + kdumpLocation = _("Remote over NFS"); + targetCanChange = true; +- } else if (target.target == "raw") { ++ } else if (target.type == "raw") { + kdumpLocation = _("Raw to a device"); +- } else if (target.target == "mount") { ++ } else if (target.type == "mount") { + /* mount targets outside of nfs are too complex for the + * current target dialog */ + kdumpLocation = _("On a mounted device"); + +From 2d045f916a9cff40e38411f8c07487d0b0f65b48 Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Tue, 12 Jul 2022 12:03:28 +0200 +Subject: [PATCH 2/4] kdump: Update config-client test + +--- + pkg/kdump/test-config-client.js | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/pkg/kdump/test-config-client.js b/pkg/kdump/test-config-client.js +index 61b10a57cb4..6eb84592d26 100644 +--- a/pkg/kdump/test-config-client.js ++++ b/pkg/kdump/test-config-client.js +@@ -49,10 +49,10 @@ QUnit.test("config_update", function (assert) { + const dataWasChanged = new Promise(resolve => { this.dataWasChangedResolve = resolve }); + let config; + const configChanged = (event, settings) => { +- assert.equal(settings.foo.value, "moo", "value changed correctly"); +- assert.equal("key" in settings, false, "setting with comment deleted correctly"); +- assert.equal("will" in settings, false, "setting without comment deleted correctly"); +- assert.equal(settings.hooray.value, "value", "value added correctly"); ++ assert.equal(settings._internal.foo.value, "moo", "value changed correctly"); ++ assert.equal("key" in settings._internal, false, "setting with comment deleted correctly"); ++ assert.equal("will" in settings._internal, false, "setting without comment deleted correctly"); ++ assert.equal(settings._internal.hooray.value, "value", "value added correctly"); + assert.equal(config._rawContent, changedConfig, "raw text for changed config is correct"); + this.dataWasChangedResolve(); + }; +@@ -65,10 +65,10 @@ QUnit.test("config_update", function (assert) { + assert.equal(configFile.path, filename, "file has correct path"); + config = new kdump.ConfigFile(filename); + config.wait().then(() => { +- config.settings.foo.value = "moo"; +- delete config.settings.key; +- delete config.settings.will; +- config.settings.hooray = { value: "value" }; ++ config.settings._internal.foo.value = "moo"; ++ delete config.settings._internal.key; ++ delete config.settings._internal.will; ++ config.settings._internal.hooray = { value: "value" }; + config.addEventListener('kdumpConfigChanged', configChanged); + config.write(config.settings) + .then(() => dataWasChanged.then(done)); + +From f94cf930e138681feeda272edef8172a5504cfb9 Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Tue, 12 Jul 2022 12:21:59 +0200 +Subject: [PATCH 3/4] kdump: Update kdump tests + +--- + test/verify/check-kdump | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/test/verify/check-kdump b/test/verify/check-kdump +index 5ef7108062c..107c6730dfa 100755 +--- a/test/verify/check-kdump ++++ b/test/verify/check-kdump +@@ -109,15 +109,15 @@ class TestKdump(KdumpHelpers): + b.click("#kdump-change-target") + b.wait_visible("#kdump-settings-dialog") + b.set_val("#kdump-settings-location", "nfs") +- mountInput = "#kdump-settings-nfs-mount" +- b.set_input_text(mountInput, ":/var/crash") ++ serverInput = "#kdump-settings-nfs-server" ++ b.set_input_text(serverInput, "") + b.click(f"#kdump-settings-dialog button{self.primary_btn_class}") +- b.wait_in_text("#kdump-settings-dialog h4.pf-c-alert__title", "Unable to save settings: nfs dump target isn't formatted as server:path") ++ b.wait_in_text("#kdump-settings-dialog h4.pf-c-alert__title", "Unable to save settings: nfs server is empty") + # no further details/journal + self.assertFalse(b.is_present("#kdump-settings-dialog .pf-c-code-block__code")) +- b.set_input_text(mountInput, "localhost:") ++ b.set_input_text(serverInput, "localhost") + b.click(f"#kdump-settings-dialog button{self.primary_btn_class}") +- b.wait_in_text("#kdump-settings-dialog h4.pf-c-alert__title", "Unable to save settings: nfs dump target isn't formatted as server:path") ++ b.wait_in_text("#kdump-settings-dialog h4.pf-c-alert__title", "Unable to save settings: nfs export is empty") + b.click("#kdump-settings-dialog button.cancel") + b.wait_not_present("#kdump-settings-dialog") + +@@ -207,7 +207,8 @@ class TestKdump(KdumpHelpers): + 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-mount", "someserver:/srv") ++ 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") + conf = m.execute("cat /etc/kdump.conf") +@@ -277,7 +278,8 @@ class TestKdumpNFS(KdumpHelpers): + 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-mount", "10.111.113.2:/srv/kdump") ++ b.set_input_text("#kdump-settings-nfs-server", "10.111.113.2") ++ b.set_input_text("#kdump-settings-nfs-export", "/srv/kdump") + b.click(f"#kdump-settings-dialog button{self.primary_btn_class}") + # rebuilding initrd might take a while on busy CI machines + with b.wait_timeout(300): + +From 7a0d578063a1f4e25697eb13a9331f37d277857d Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Tue, 19 Jul 2022 15:58:03 +0200 +Subject: [PATCH 4/4] kdump: Fix ssh settings wiping + +Leftover sshkey setting confused kdump on Fedora-35. +--- + pkg/kdump/config-client.js | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/pkg/kdump/config-client.js b/pkg/kdump/config-client.js +index d292bd9bebd..9b95b9a0c65 100644 +--- a/pkg/kdump/config-client.js ++++ b/pkg/kdump/config-client.js +@@ -233,6 +233,9 @@ export class ConfigFile { + const oldTarget = this.settings.targets[key]; + if (oldTarget.type == "mount") { + delete settings._internal[oldTarget.fsType]; ++ } else if (oldTarget.type == "ssh") { ++ delete settings._internal.ssh; ++ delete settings._internal.sshkey; + } else { + delete settings._internal[key]; + } diff --git a/kdump-suse.patch b/kdump-suse.patch new file mode 100644 index 0000000..74efe23 --- /dev/null +++ b/kdump-suse.patch @@ -0,0 +1,491 @@ +From d95850239f81a65c90743f20a0bc0450cb61823a Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +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 . ++ */ ++ ++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 + ? +- : { kdumpLocation }; ++ : { kdumpLocation }; + 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") From ec90edb7236e2170515ef6735fbabd6d9800234927d7ef7c97bee1c77133804d Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 09:02:52 +0000 Subject: [PATCH 2/7] Accepting request 1003260 from home:ancorgs:branches:systemsmanagement:cockpit OBS ate my description OBS-URL: https://build.opensuse.org/request/show/1003260 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=106 --- cockpit.spec | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cockpit.spec b/cockpit.spec index dae613e..bb8eb90 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -703,14 +703,16 @@ Dummy package from building optional packages only; never install or publish me. Summary: Cockpit user interface for storage, using udisks Requires: cockpit-shell >= 266 Requires: udisks2 >= 2.9 +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} -%if 0%{?suse_version} -Requires: python3-dbus-python -%else Requires: python3-dbus %endif BuildArch: noarch From 37d2d8ad7074a5ea8cb839b03ea21609a33bb4347b84bfaa27ceca65941100cc Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 09:46:39 +0000 Subject: [PATCH 3/7] - Fix cockpit-storage dependencies OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=107 --- cockpit.changes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cockpit.changes b/cockpit.changes index d0987a0..ae7dcf5 100644 --- a/cockpit.changes +++ b/cockpit.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Sep 13 09:46:17 UTC 2022 - Adam Majer + +- Fix cockpit-storage dependencies + ------------------------------------------------------------------- Mon Sep 5 08:09:56 UTC 2022 - Jacek Tomasiak From 3d55c61c7d59363517a1b0e46a7864a6752a7487186f6f60e6553199677cf6e1 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 16:16:08 +0000 Subject: [PATCH 4/7] - Merge SUSE branding into cockpit package OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=108 --- _service | 17 +++++++++++++++++ _servicedata | 4 +++- cockpit-suse-theme-fe08b35.obscpio | 3 +++ cockpit-suse-theme.obsinfo | 4 ++++ cockpit.changes | 1 + cockpit.spec | 10 +++++++++- 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 cockpit-suse-theme-fe08b35.obscpio create mode 100644 cockpit-suse-theme.obsinfo diff --git a/_service b/_service index f804a83..81f03c0 100644 --- a/_service +++ b/_service @@ -1,4 +1,19 @@ + + https://github.com/dgdavid/cockpit-suse-theme.git + %h + git + main + + + cockpit-suse-theme.obsinfo + + + cockpit-suse-theme + cockpit-suse-these.tar + + + @PARENT_TAG@ http://github.com/cockpit-project/cockpit.git @@ -17,4 +32,6 @@ cockpit + + diff --git a/_servicedata b/_servicedata index 5065ec3..4a037d0 100644 --- a/_servicedata +++ b/_servicedata @@ -1,4 +1,6 @@ http://github.com/cockpit-project/cockpit.git - 046b3d4b381cd60f9d44756fc51f15ed7e17d0b5 \ No newline at end of file + 046b3d4b381cd60f9d44756fc51f15ed7e17d0b5 + https://github.com/dgdavid/cockpit-suse-theme.git + fe08b35e64ad45f4b56cd636fdfec8fb18d69ab7 \ No newline at end of file diff --git a/cockpit-suse-theme-fe08b35.obscpio b/cockpit-suse-theme-fe08b35.obscpio new file mode 100644 index 0000000..075cce0 --- /dev/null +++ b/cockpit-suse-theme-fe08b35.obscpio @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc2c191f02147e115fd4bc3bd804b3625c68be495fd789ff5a10236e3796b10f +size 1276428 diff --git a/cockpit-suse-theme.obsinfo b/cockpit-suse-theme.obsinfo new file mode 100644 index 0000000..39714c9 --- /dev/null +++ b/cockpit-suse-theme.obsinfo @@ -0,0 +1,4 @@ +name: cockpit-suse-theme +version: fe08b35 +mtime: 1655379139 +commit: fe08b35e64ad45f4b56cd636fdfec8fb18d69ab7 diff --git a/cockpit.changes b/cockpit.changes index ae7dcf5..4a76e4e 100644 --- a/cockpit.changes +++ b/cockpit.changes @@ -2,6 +2,7 @@ Tue Sep 13 09:46:17 UTC 2022 - Adam Majer - Fix cockpit-storage dependencies +- Merge SUSE branding into cockpit package ------------------------------------------------------------------- Mon Sep 5 08:09:56 UTC 2022 - Jacek Tomasiak diff --git a/cockpit.spec b/cockpit.spec index bb8eb90..87cf8ca 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -55,6 +55,7 @@ Release: 0 Source0: cockpit-%{version}.tar Source1: cockpit.pam Source2: cockpit-rpmlintrc +Source3: cockpit-suse-theme-fe08b35.tar Source99: README.packaging Source98: package-lock.json Source97: node_modules.spec.inc @@ -182,7 +183,7 @@ Requires: subscription-manager-cockpit %endif %prep -%setup -q -n cockpit-%{version} +%setup -q -n cockpit-%{version} -a 3 %patch1 -p1 %patch2 -p1 %patch3 -p1 @@ -236,6 +237,13 @@ install -p -m 644 tools/cockpit.pam $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/cockpit 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 From 5530f36c2eb7943d36f41bd13a0814809f499b91655c23f116129251690fb15a Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 16:18:37 +0000 Subject: [PATCH 5/7] don't delete SUSE branding OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=109 --- cockpit.spec | 337 +++++++++++++++++++++++++-------------------------- 1 file changed, 163 insertions(+), 174 deletions(-) diff --git a/cockpit.spec b/cockpit.spec index 87cf8ca..810f281 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -1,32 +1,22 @@ # +# spec file for package cockpit +# +# Copyright (c) 2022 SUSE LLC # Copyright (C) 2014-2020 Red Hat, Inc. # -# 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 . +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # -# -# This file is maintained at the following location: -# https://github.com/cockpit-project/cockpit/blob/main/tools/cockpit.spec -# -# If you are editing this file in another location, changes will likely -# be clobbered the next time an automated release is done. -# -# Check first cockpit-devel@lists.fedorahosted.org -# -# earliest base that the subpackages work on; the instances of this get computed/updated -# by tools/gen-spec-dependencies during "make dist", but keep a hardcoded fallback %define required_base 122 # we generally want CentOS packages to be like RHEL; special cases need to check %{centos} explicitly @@ -101,85 +91,86 @@ Patch101: hide-pcp.patch %endif %endif -BuildRequires: gcc -BuildRequires: pkgconfig(gio-unix-2.0) -BuildRequires: pkgconfig(json-glib-1.0) -BuildRequires: pkgconfig(polkit-agent-1) >= 0.105 -BuildRequires: pam-devel +BuildRequires: gcc +BuildRequires: pam-devel +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(polkit-agent-1) >= 0.105 -BuildRequires: autoconf automake -BuildRequires: make -BuildRequires: /usr/bin/python3 +BuildRequires: /usr/bin/python3 +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: make %if 0%{?rhel} && 0%{?rhel} <= 8 # RHEL 8's gettext does not yet have metainfo.its -BuildRequires: gettext >= 0.19.7 -BuildRequires: libappstream-glib-devel +BuildRequires: gettext >= 0.19.7 +BuildRequires: libappstream-glib-devel %else -BuildRequires: gettext >= 0.21 +BuildRequires: gettext >= 0.21 %endif %if 0%{?build_basic} -BuildRequires: libssh-devel >= 0.8.5 +BuildRequires: libssh-devel >= 0.8.5 %endif -BuildRequires: openssl-devel -BuildRequires: gnutls-devel >= 3.4.3 -BuildRequires: zlib-devel -BuildRequires: pkgconfig(krb5) >= 1.11 -BuildRequires: libxslt-devel -BuildRequires: glib-networking -BuildRequires: sed +BuildRequires: glib-networking +BuildRequires: gnutls-devel >= 3.4.3 +BuildRequires: libxslt-devel +BuildRequires: openssl-devel +BuildRequires: sed +BuildRequires: zlib-devel +BuildRequires: pkgconfig(krb5) >= 1.11 -BuildRequires: glib2-devel >= 2.50.0 +BuildRequires: glib2-devel >= 2.50.0 # this is for runtimedir in the tls proxy ace21c8879 -BuildRequires: pkgconfig(libsystemd) >= 235 +BuildRequires: pkgconfig(libsystemd) >= 235 %if 0%{?suse_version} -BuildRequires: distribution-release -BuildRequires: libpcp-devel -BuildRequires: pcp-devel -BuildRequires: libpcp3 -BuildRequires: libpcp_import1 -BuildRequires: openssh -BuildRequires: distribution-logos -BuildRequires: wallpaper-branding +BuildRequires: distribution-logos +BuildRequires: distribution-release +BuildRequires: libpcp-devel +BuildRequires: libpcp3 +BuildRequires: libpcp_import1 +BuildRequires: openssh +BuildRequires: pcp-devel +BuildRequires: wallpaper-branding # needed for /var/lib/pcp directory ownership -BuildRequires: pcp +BuildRequires: pcp %else -BuildRequires: pcp-libs-devel -BuildRequires: openssh-clients -BuildRequires: docbook-style-xsl +BuildRequires: docbook-style-xsl +BuildRequires: openssh-clients +BuildRequires: pcp-libs-devel %endif -BuildRequires: krb5-server -BuildRequires: gdb +BuildRequires: gdb +BuildRequires: krb5-server # For documentation -BuildRequires: xmlto +BuildRequires: xmlto BuildRequires: selinux-policy BuildRequires: selinux-policy-%{selinuxtype} BuildRequires: selinux-policy-devel # for rebuilding nodejs bits -BuildRequires: npm -BuildRequires: sassc -BuildRequires: local-npm-registry +BuildRequires: npm +BuildRequires: local-npm-registry +BuildRequires: sassc # This is the "cockpit" metapackage. It should only # Require, Suggest or Recommend other cockpit-xxx subpackages -Requires: cockpit-bridge -Requires: cockpit-ws -Requires: cockpit-system +Requires: cockpit-bridge +Requires: cockpit-system +Requires: cockpit-ws # Optional components -Recommends: (cockpit-storaged if udisks2) -Recommends: (cockpit-packagekit if dnf) -Suggests: cockpit-pcp +Recommends: (cockpit-storaged if udisks2) +Recommends: (cockpit-packagekit if dnf) +Suggests: cockpit-pcp %if 0%{?rhel} == 0 -Recommends: (cockpit-networkmanager if NetworkManager) -Suggests: cockpit-selinux +Recommends: (cockpit-networkmanager if NetworkManager) +Suggests: cockpit-selinux %endif %if 0%{?rhel} && 0%{?centos} == 0 -Requires: subscription-manager-cockpit +Requires: subscription-manager-cockpit %endif %prep @@ -357,7 +348,7 @@ rm %{buildroot}/%{_prefix}/share/metainfo/org.cockpit-project.cockpit-selinux.me # 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 @@ -407,20 +398,19 @@ troubleshooting, interactive command-line sessions, and more. %{_datadir}/pixmaps/cockpit.png %doc %{_mandir}/man1/cockpit.1.gz - %package bridge -Summary: Cockpit bridge server-side component -Requires: glib-networking -Provides: cockpit-ssh = %{version}-%{release} +Summary: Cockpit bridge server-side component +Requires: glib-networking +Provides: cockpit-ssh = %{version}-%{release} # PR #10430 dropped workaround for ws' inability to understand x-host-key challenge -Conflicts: cockpit-ws < 181.x +Conflicts: cockpit-ws < 181.x # 233 dropped jquery.js, pages started to bundle it (commit 049e8b8dce) -Conflicts: cockpit-dashboard < 233 -Conflicts: cockpit-networkmanager < 233 -Conflicts: cockpit-storaged < 233 -Conflicts: cockpit-system < 233 -Conflicts: cockpit-tests < 233 -Conflicts: cockpit-docker < 233 +Conflicts: cockpit-dashboard < 233 +Conflicts: cockpit-docker < 233 +Conflicts: cockpit-networkmanager < 233 +Conflicts: cockpit-storaged < 233 +Conflicts: cockpit-system < 233 +Conflicts: cockpit-tests < 233 %description bridge The Cockpit bridge component installed server side and runs commands on the @@ -432,8 +422,8 @@ system on behalf of the web based user interface. %{_libexecdir}/cockpit-askpass %package doc -Summary: Cockpit deployment and developer guide -BuildArch: noarch +Summary: Cockpit deployment and developer guide +BuildArch: noarch %description doc The Cockpit Deployment and Developer Guide shows sysadmins how to @@ -447,40 +437,40 @@ embed or extend Cockpit. %{_docdir}/cockpit %package system -Summary: Cockpit admin interface package for configuring and troubleshooting a system -BuildArch: noarch -Requires: cockpit-bridge >= %{version}-%{release} +Summary: Cockpit admin interface package for configuring and troubleshooting a system +BuildArch: noarch +Requires: cockpit-bridge >= %{version}-%{release} %if !0%{?suse_version} -Requires: shadow-utils +Requires: shadow-utils %endif -Requires: grep +Requires: grep %if !0%{?sle_version} -Requires: /usr/bin/pwscore +Requires: /usr/bin/pwscore %endif -Requires: /usr/bin/date -Provides: cockpit-shell = %{version}-%{release} -Provides: cockpit-systemd = %{version}-%{release} -Provides: cockpit-tuned = %{version}-%{release} -Provides: cockpit-users = %{version}-%{release} -Obsoletes: cockpit-dashboard < %{version}-%{release} +Requires: /usr/bin/date +Provides: cockpit-shell = %{version}-%{release} +Provides: cockpit-systemd = %{version}-%{release} +Provides: cockpit-tuned = %{version}-%{release} +Provides: cockpit-users = %{version}-%{release} +Obsoletes: cockpit-dashboard < %{version}-%{release} %if 0%{?rhel} -Requires: NetworkManager >= 1.6 -Requires: kexec-tools -Requires: sos -Requires: sudo -Recommends: PackageKit -Recommends: setroubleshoot-server >= 3.3.3 -Suggests: NetworkManager-team -Provides: cockpit-kdump = %{version}-%{release} -Provides: cockpit-networkmanager = %{version}-%{release} -Provides: cockpit-selinux = %{version}-%{release} -Provides: cockpit-sosreport = %{version}-%{release} +Requires: NetworkManager >= 1.6 +Requires: kexec-tools +Requires: sos +Requires: sudo +Recommends: PackageKit +Recommends: setroubleshoot-server >= 3.3.3 +Suggests: NetworkManager-team +Provides: cockpit-kdump = %{version}-%{release} +Provides: cockpit-networkmanager = %{version}-%{release} +Provides: cockpit-selinux = %{version}-%{release} +Provides: cockpit-sosreport = %{version}-%{release} %endif %if 0%{?fedora} -Recommends: (reportd if abrt) +Recommends: (reportd if abrt) %endif # NPM modules which are also available as packages -Provides: bundled(xstatic-patternfly-common) = 3.59.5 +Provides: bundled(xstatic-patternfly-common) = 3.59.5 %description system This package contains the Cockpit shell and system configuration interfaces. @@ -489,23 +479,23 @@ This package contains the Cockpit shell and system configuration interfaces. %dir %{_datadir}/cockpit/shell/images %package ws -Summary: Cockpit Web Service -Requires: glib-networking -Requires: openssl -Requires: glib2 >= 2.50.0 -Requires: (selinux-policy >= %{_selinux_policy_version} if selinux-policy-%{selinuxtype}) +Summary: Cockpit Web Service +Requires: glib-networking +Requires: glib2 >= 2.50.0 +Requires: openssl +Requires: (selinux-policy >= %{_selinux_policy_version} if selinux-policy-%{selinuxtype}) Requires(post): (policycoreutils if selinux-policy-%{selinuxtype}) -Conflicts: firewalld < 0.6.0-1 -Recommends: sscg >= 2.3 -Recommends: system-logos -Suggests: sssd-dbus +Conflicts: firewalld < 0.6.0-1 +Recommends: sscg >= 2.3 +Recommends: system-logos +Suggests: sssd-dbus %if 0%{?suse_version} -Requires(pre): permissions -Requires: distribution-logos -Requires: wallpaper-branding +Requires(pre): permissions +Requires: distribution-logos +Requires: wallpaper-branding %endif # for cockpit-desktop -Suggests: python3 +Suggests: python3 # prevent hard python3 dependency for cockpit-desktop, it falls back to other browsers %global __requires_exclude_from ^%{_libexecdir}/cockpit-client$ @@ -628,11 +618,11 @@ fi %if 0%{?rhel} == 0 %package kdump -Summary: Cockpit user interface for kernel crash dumping -Requires: cockpit-bridge >= 130 -Requires: cockpit-shell >= 130 -Requires: kexec-tools -BuildArch: noarch +Summary: Cockpit user interface for kernel crash dumping +Requires: cockpit-bridge >= 130 +Requires: cockpit-shell >= 130 +Requires: kexec-tools +BuildArch: noarch %description kdump The Cockpit component for configuring kernel crash dumping. @@ -642,11 +632,11 @@ The Cockpit component for configuring kernel crash dumping. %if !0%{?suse_version} %package sosreport -Summary: Cockpit user interface for diagnostic reports -Requires: cockpit-bridge >= 122 -Requires: cockpit-shell >= 122 -Requires: sos -BuildArch: noarch +Summary: Cockpit user interface for diagnostic reports +Requires: cockpit-bridge >= 122 +Requires: cockpit-shell >= 122 +Requires: sos +BuildArch: noarch %description sosreport The Cockpit component for creating diagnostic reports with the @@ -658,14 +648,14 @@ sosreport tool. %endif %package networkmanager -Summary: Cockpit user interface for networking, using NetworkManager -Requires: cockpit-bridge >= 186 -Requires: cockpit-shell >= 186 -Requires: NetworkManager >= 1.6 -Conflicts: cockpit-wicked +Summary: Cockpit user interface for networking, using NetworkManager +Requires: NetworkManager >= 1.6 +Requires: cockpit-bridge >= 186 +Requires: cockpit-shell >= 186 +Conflicts: cockpit-wicked # Optional components -Recommends: NetworkManager-team -BuildArch: noarch +Recommends: NetworkManager-team +BuildArch: noarch %description networkmanager The Cockpit component for managing networking. This package uses NetworkManager. @@ -677,11 +667,11 @@ The Cockpit component for managing networking. This package uses NetworkManager %if 0%{?rhel} == 0 && !0%{?suse_version} %package selinux -Summary: Cockpit SELinux package -Requires: cockpit-bridge >= 122 -Requires: cockpit-shell >= 122 -Requires: setroubleshoot-server >= 3.3.3 -BuildArch: noarch +Summary: Cockpit SELinux package +Requires: cockpit-bridge >= 122 +Requires: cockpit-shell >= 122 +Requires: setroubleshoot-server >= 3.3.3 +BuildArch: noarch %description selinux This package contains the Cockpit user interface integration with the @@ -708,22 +698,22 @@ Dummy package from building optional packages only; never install or publish me. %if 0%{?build_optional} %package -n cockpit-storaged -Summary: Cockpit user interface for storage, using udisks -Requires: cockpit-shell >= 266 -Requires: udisks2 >= 2.9 -Requires: %{__python3} +Summary: Cockpit user interface for storage, using udisks +Requires: %{__python3} +Requires: cockpit-shell >= 266 +Requires: udisks2 >= 2.9 %if 0%{?suse_version} -Requires: libudisks2-0_lvm2 >= 2.9 -Recommends: multipath-tools -Requires: python3-dbus-python +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 +Recommends: clevis-luks +Recommends: device-mapper-multipath +Recommends: udisks2-iscsi >= 2.9 +Recommends: udisks2-lvm2 >= 2.9 +Requires: python3-dbus %endif -BuildArch: noarch +BuildArch: noarch %description -n cockpit-storaged The Cockpit component for managing storage. This package uses udisks. @@ -733,11 +723,11 @@ The Cockpit component for managing storage. This package uses udisks. %{_datadir}/metainfo/org.cockpit-project.cockpit-storaged.metainfo.xml %package -n cockpit-tests -Summary: Tests for Cockpit -Requires: cockpit-bridge >= 138 -Requires: cockpit-system >= 138 -Requires: openssh-clients -Provides: cockpit-test-assets = %{version}-%{release} +Summary: Tests for Cockpit +Requires: cockpit-bridge >= 138 +Requires: cockpit-system >= 138 +Requires: openssh-clients +Provides: cockpit-test-assets = %{version}-%{release} %description -n cockpit-tests This package contains tests and files used while testing Cockpit. @@ -747,7 +737,7 @@ These files are not required for running Cockpit. %{_prefix}/%{__lib}/cockpit-test-assets %package devel -Summary: Development files for for Cockpit +Summary: Development files for for Cockpit %description devel This package contains files used to develop cockpit modules @@ -756,9 +746,9 @@ This package contains files used to develop cockpit modules %{_datadir}/cockpit/devel %package -n cockpit-pcp -Summary: Cockpit PCP integration -Requires: cockpit-bridge >= 238.1.1 -Requires: pcp +Summary: Cockpit PCP integration +Requires: cockpit-bridge >= 238.1.1 +Requires: pcp %description -n cockpit-pcp Cockpit support for reading PCP metrics and loading PCP archives. @@ -771,13 +761,13 @@ Cockpit support for reading PCP metrics and loading PCP archives. systemctl reload-or-try-restart pmlogger %package -n cockpit-packagekit -Summary: Cockpit user interface for packages -BuildArch: noarch -Requires: cockpit-bridge >= 186 -Requires: PackageKit -Recommends: python3-tracer +Summary: Cockpit user interface for packages +BuildArch: noarch +Requires: PackageKit +Requires: cockpit-bridge >= 186 +Recommends: python3-tracer # HACK: https://bugzilla.redhat.com/show_bug.cgi?id=1800468 -Requires: polkit +Requires: polkit %description -n cockpit-packagekit The Cockpit components for installing OS updates and Cockpit add-ons, @@ -788,5 +778,4 @@ via PackageKit. #/ build optional extension packages %endif -# The changelog is automatically generated and merged %changelog From a1e535cb0e470a3c0cbf786308310d423df78145684e37049287b3e099f98d4a Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Tue, 13 Sep 2022 16:20:22 +0000 Subject: [PATCH 6/7] OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=110 --- cockpit.spec | 335 ++++++++++++++++++++++++++------------------------- 1 file changed, 173 insertions(+), 162 deletions(-) diff --git a/cockpit.spec b/cockpit.spec index 810f281..c6360ea 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -1,22 +1,32 @@ # -# spec file for package cockpit -# -# Copyright (c) 2022 SUSE LLC # Copyright (C) 2014-2020 Red Hat, Inc. # -# All modifications and additions to the file contributed by third parties -# remain the property of their copyright owners, unless otherwise agreed -# upon. The license for this file, and modifications and additions to the -# file, is the same license as for the pristine package itself (unless the -# license for the pristine package is not an Open Source License, in which -# case the license is the MIT License). An "Open Source License" is a -# license that conforms to the Open Source Definition (Version 1.9) -# published by the Open Source Initiative. - -# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# 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 . # +# +# This file is maintained at the following location: +# https://github.com/cockpit-project/cockpit/blob/main/tools/cockpit.spec +# +# If you are editing this file in another location, changes will likely +# be clobbered the next time an automated release is done. +# +# Check first cockpit-devel@lists.fedorahosted.org +# +# earliest base that the subpackages work on; the instances of this get computed/updated +# by tools/gen-spec-dependencies during "make dist", but keep a hardcoded fallback %define required_base 122 # we generally want CentOS packages to be like RHEL; special cases need to check %{centos} explicitly @@ -91,86 +101,85 @@ Patch101: hide-pcp.patch %endif %endif -BuildRequires: gcc -BuildRequires: pam-devel -BuildRequires: pkgconfig(gio-unix-2.0) -BuildRequires: pkgconfig(json-glib-1.0) -BuildRequires: pkgconfig(polkit-agent-1) >= 0.105 +BuildRequires: gcc +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(polkit-agent-1) >= 0.105 +BuildRequires: pam-devel -BuildRequires: /usr/bin/python3 -BuildRequires: autoconf -BuildRequires: automake -BuildRequires: make +BuildRequires: autoconf automake +BuildRequires: make +BuildRequires: /usr/bin/python3 %if 0%{?rhel} && 0%{?rhel} <= 8 # RHEL 8's gettext does not yet have metainfo.its -BuildRequires: gettext >= 0.19.7 -BuildRequires: libappstream-glib-devel +BuildRequires: gettext >= 0.19.7 +BuildRequires: libappstream-glib-devel %else -BuildRequires: gettext >= 0.21 +BuildRequires: gettext >= 0.21 %endif %if 0%{?build_basic} -BuildRequires: libssh-devel >= 0.8.5 +BuildRequires: libssh-devel >= 0.8.5 %endif -BuildRequires: glib-networking -BuildRequires: gnutls-devel >= 3.4.3 -BuildRequires: libxslt-devel -BuildRequires: openssl-devel -BuildRequires: sed -BuildRequires: zlib-devel -BuildRequires: pkgconfig(krb5) >= 1.11 +BuildRequires: openssl-devel +BuildRequires: gnutls-devel >= 3.4.3 +BuildRequires: zlib-devel +BuildRequires: pkgconfig(krb5) >= 1.11 +BuildRequires: libxslt-devel +BuildRequires: glib-networking +BuildRequires: sed -BuildRequires: glib2-devel >= 2.50.0 +BuildRequires: glib2-devel >= 2.50.0 # this is for runtimedir in the tls proxy ace21c8879 -BuildRequires: pkgconfig(libsystemd) >= 235 +BuildRequires: pkgconfig(libsystemd) >= 235 %if 0%{?suse_version} -BuildRequires: distribution-logos -BuildRequires: distribution-release -BuildRequires: libpcp-devel -BuildRequires: libpcp3 -BuildRequires: libpcp_import1 -BuildRequires: openssh -BuildRequires: pcp-devel -BuildRequires: wallpaper-branding +BuildRequires: distribution-release +BuildRequires: libpcp-devel +BuildRequires: pcp-devel +BuildRequires: libpcp3 +BuildRequires: libpcp_import1 +BuildRequires: openssh +BuildRequires: distribution-logos +BuildRequires: wallpaper-branding # needed for /var/lib/pcp directory ownership -BuildRequires: pcp +BuildRequires: pcp %else -BuildRequires: docbook-style-xsl -BuildRequires: openssh-clients -BuildRequires: pcp-libs-devel +BuildRequires: pcp-libs-devel +BuildRequires: openssh-clients +BuildRequires: docbook-style-xsl %endif -BuildRequires: gdb -BuildRequires: krb5-server +BuildRequires: krb5-server +BuildRequires: gdb # For documentation -BuildRequires: xmlto +BuildRequires: xmlto BuildRequires: selinux-policy BuildRequires: selinux-policy-%{selinuxtype} BuildRequires: selinux-policy-devel # for rebuilding nodejs bits -BuildRequires: npm -BuildRequires: local-npm-registry -BuildRequires: sassc +BuildRequires: npm +BuildRequires: sassc +BuildRequires: local-npm-registry # This is the "cockpit" metapackage. It should only # Require, Suggest or Recommend other cockpit-xxx subpackages -Requires: cockpit-bridge -Requires: cockpit-system -Requires: cockpit-ws +Requires: cockpit-bridge +Requires: cockpit-ws +Requires: cockpit-system # Optional components -Recommends: (cockpit-storaged if udisks2) -Recommends: (cockpit-packagekit if dnf) -Suggests: cockpit-pcp +Recommends: (cockpit-storaged if udisks2) +Recommends: (cockpit-packagekit if dnf) +Suggests: cockpit-pcp %if 0%{?rhel} == 0 -Recommends: (cockpit-networkmanager if NetworkManager) -Suggests: cockpit-selinux +Recommends: (cockpit-networkmanager if NetworkManager) +Suggests: cockpit-selinux %endif %if 0%{?rhel} && 0%{?centos} == 0 -Requires: subscription-manager-cockpit +Requires: subscription-manager-cockpit %endif %prep @@ -398,19 +407,20 @@ troubleshooting, interactive command-line sessions, and more. %{_datadir}/pixmaps/cockpit.png %doc %{_mandir}/man1/cockpit.1.gz + %package bridge -Summary: Cockpit bridge server-side component -Requires: glib-networking -Provides: cockpit-ssh = %{version}-%{release} +Summary: Cockpit bridge server-side component +Requires: glib-networking +Provides: cockpit-ssh = %{version}-%{release} # PR #10430 dropped workaround for ws' inability to understand x-host-key challenge -Conflicts: cockpit-ws < 181.x +Conflicts: cockpit-ws < 181.x # 233 dropped jquery.js, pages started to bundle it (commit 049e8b8dce) -Conflicts: cockpit-dashboard < 233 -Conflicts: cockpit-docker < 233 -Conflicts: cockpit-networkmanager < 233 -Conflicts: cockpit-storaged < 233 -Conflicts: cockpit-system < 233 -Conflicts: cockpit-tests < 233 +Conflicts: cockpit-dashboard < 233 +Conflicts: cockpit-networkmanager < 233 +Conflicts: cockpit-storaged < 233 +Conflicts: cockpit-system < 233 +Conflicts: cockpit-tests < 233 +Conflicts: cockpit-docker < 233 %description bridge The Cockpit bridge component installed server side and runs commands on the @@ -422,8 +432,8 @@ system on behalf of the web based user interface. %{_libexecdir}/cockpit-askpass %package doc -Summary: Cockpit deployment and developer guide -BuildArch: noarch +Summary: Cockpit deployment and developer guide +BuildArch: noarch %description doc The Cockpit Deployment and Developer Guide shows sysadmins how to @@ -437,40 +447,40 @@ embed or extend Cockpit. %{_docdir}/cockpit %package system -Summary: Cockpit admin interface package for configuring and troubleshooting a system -BuildArch: noarch -Requires: cockpit-bridge >= %{version}-%{release} +Summary: Cockpit admin interface package for configuring and troubleshooting a system +BuildArch: noarch +Requires: cockpit-bridge >= %{version}-%{release} %if !0%{?suse_version} -Requires: shadow-utils +Requires: shadow-utils %endif -Requires: grep +Requires: grep %if !0%{?sle_version} -Requires: /usr/bin/pwscore +Requires: /usr/bin/pwscore %endif -Requires: /usr/bin/date -Provides: cockpit-shell = %{version}-%{release} -Provides: cockpit-systemd = %{version}-%{release} -Provides: cockpit-tuned = %{version}-%{release} -Provides: cockpit-users = %{version}-%{release} -Obsoletes: cockpit-dashboard < %{version}-%{release} +Requires: /usr/bin/date +Provides: cockpit-shell = %{version}-%{release} +Provides: cockpit-systemd = %{version}-%{release} +Provides: cockpit-tuned = %{version}-%{release} +Provides: cockpit-users = %{version}-%{release} +Obsoletes: cockpit-dashboard < %{version}-%{release} %if 0%{?rhel} -Requires: NetworkManager >= 1.6 -Requires: kexec-tools -Requires: sos -Requires: sudo -Recommends: PackageKit -Recommends: setroubleshoot-server >= 3.3.3 -Suggests: NetworkManager-team -Provides: cockpit-kdump = %{version}-%{release} -Provides: cockpit-networkmanager = %{version}-%{release} -Provides: cockpit-selinux = %{version}-%{release} -Provides: cockpit-sosreport = %{version}-%{release} +Requires: NetworkManager >= 1.6 +Requires: kexec-tools +Requires: sos +Requires: sudo +Recommends: PackageKit +Recommends: setroubleshoot-server >= 3.3.3 +Suggests: NetworkManager-team +Provides: cockpit-kdump = %{version}-%{release} +Provides: cockpit-networkmanager = %{version}-%{release} +Provides: cockpit-selinux = %{version}-%{release} +Provides: cockpit-sosreport = %{version}-%{release} %endif %if 0%{?fedora} -Recommends: (reportd if abrt) +Recommends: (reportd if abrt) %endif # NPM modules which are also available as packages -Provides: bundled(xstatic-patternfly-common) = 3.59.5 +Provides: bundled(xstatic-patternfly-common) = 3.59.5 %description system This package contains the Cockpit shell and system configuration interfaces. @@ -479,23 +489,23 @@ This package contains the Cockpit shell and system configuration interfaces. %dir %{_datadir}/cockpit/shell/images %package ws -Summary: Cockpit Web Service -Requires: glib-networking -Requires: glib2 >= 2.50.0 -Requires: openssl -Requires: (selinux-policy >= %{_selinux_policy_version} if selinux-policy-%{selinuxtype}) +Summary: Cockpit Web Service +Requires: glib-networking +Requires: openssl +Requires: glib2 >= 2.50.0 +Requires: (selinux-policy >= %{_selinux_policy_version} if selinux-policy-%{selinuxtype}) Requires(post): (policycoreutils if selinux-policy-%{selinuxtype}) -Conflicts: firewalld < 0.6.0-1 -Recommends: sscg >= 2.3 -Recommends: system-logos -Suggests: sssd-dbus +Conflicts: firewalld < 0.6.0-1 +Recommends: sscg >= 2.3 +Recommends: system-logos +Suggests: sssd-dbus %if 0%{?suse_version} -Requires(pre): permissions -Requires: distribution-logos -Requires: wallpaper-branding +Requires(pre): permissions +Requires: distribution-logos +Requires: wallpaper-branding %endif # for cockpit-desktop -Suggests: python3 +Suggests: python3 # prevent hard python3 dependency for cockpit-desktop, it falls back to other browsers %global __requires_exclude_from ^%{_libexecdir}/cockpit-client$ @@ -618,11 +628,11 @@ fi %if 0%{?rhel} == 0 %package kdump -Summary: Cockpit user interface for kernel crash dumping -Requires: cockpit-bridge >= 130 -Requires: cockpit-shell >= 130 -Requires: kexec-tools -BuildArch: noarch +Summary: Cockpit user interface for kernel crash dumping +Requires: cockpit-bridge >= 130 +Requires: cockpit-shell >= 130 +Requires: kexec-tools +BuildArch: noarch %description kdump The Cockpit component for configuring kernel crash dumping. @@ -632,11 +642,11 @@ The Cockpit component for configuring kernel crash dumping. %if !0%{?suse_version} %package sosreport -Summary: Cockpit user interface for diagnostic reports -Requires: cockpit-bridge >= 122 -Requires: cockpit-shell >= 122 -Requires: sos -BuildArch: noarch +Summary: Cockpit user interface for diagnostic reports +Requires: cockpit-bridge >= 122 +Requires: cockpit-shell >= 122 +Requires: sos +BuildArch: noarch %description sosreport The Cockpit component for creating diagnostic reports with the @@ -648,14 +658,14 @@ sosreport tool. %endif %package networkmanager -Summary: Cockpit user interface for networking, using NetworkManager -Requires: NetworkManager >= 1.6 -Requires: cockpit-bridge >= 186 -Requires: cockpit-shell >= 186 -Conflicts: cockpit-wicked +Summary: Cockpit user interface for networking, using NetworkManager +Requires: cockpit-bridge >= 186 +Requires: cockpit-shell >= 186 +Requires: NetworkManager >= 1.6 +Conflicts: cockpit-wicked # Optional components -Recommends: NetworkManager-team -BuildArch: noarch +Recommends: NetworkManager-team +BuildArch: noarch %description networkmanager The Cockpit component for managing networking. This package uses NetworkManager. @@ -667,11 +677,11 @@ The Cockpit component for managing networking. This package uses NetworkManager %if 0%{?rhel} == 0 && !0%{?suse_version} %package selinux -Summary: Cockpit SELinux package -Requires: cockpit-bridge >= 122 -Requires: cockpit-shell >= 122 -Requires: setroubleshoot-server >= 3.3.3 -BuildArch: noarch +Summary: Cockpit SELinux package +Requires: cockpit-bridge >= 122 +Requires: cockpit-shell >= 122 +Requires: setroubleshoot-server >= 3.3.3 +BuildArch: noarch %description selinux This package contains the Cockpit user interface integration with the @@ -698,22 +708,22 @@ Dummy package from building optional packages only; never install or publish me. %if 0%{?build_optional} %package -n cockpit-storaged -Summary: Cockpit user interface for storage, using udisks -Requires: %{__python3} -Requires: cockpit-shell >= 266 -Requires: udisks2 >= 2.9 +Summary: Cockpit user interface for storage, using udisks +Requires: cockpit-shell >= 266 +Requires: udisks2 >= 2.9 +Requires: %{__python3} %if 0%{?suse_version} -Requires: libudisks2-0_lvm2 >= 2.9 -Recommends: multipath-tools -Requires: python3-dbus-python +Requires: libudisks2-0_lvm2 >= 2.9 +Recommends: multipath-tools +Requires: python3-dbus-python %else -Recommends: clevis-luks -Recommends: device-mapper-multipath -Recommends: udisks2-iscsi >= 2.9 -Recommends: udisks2-lvm2 >= 2.9 -Requires: python3-dbus +Recommends: udisks2-lvm2 >= 2.9 +Recommends: udisks2-iscsi >= 2.9 +Recommends: device-mapper-multipath +Recommends: clevis-luks +Requires: python3-dbus %endif -BuildArch: noarch +BuildArch: noarch %description -n cockpit-storaged The Cockpit component for managing storage. This package uses udisks. @@ -723,11 +733,11 @@ The Cockpit component for managing storage. This package uses udisks. %{_datadir}/metainfo/org.cockpit-project.cockpit-storaged.metainfo.xml %package -n cockpit-tests -Summary: Tests for Cockpit -Requires: cockpit-bridge >= 138 -Requires: cockpit-system >= 138 -Requires: openssh-clients -Provides: cockpit-test-assets = %{version}-%{release} +Summary: Tests for Cockpit +Requires: cockpit-bridge >= 138 +Requires: cockpit-system >= 138 +Requires: openssh-clients +Provides: cockpit-test-assets = %{version}-%{release} %description -n cockpit-tests This package contains tests and files used while testing Cockpit. @@ -737,7 +747,7 @@ These files are not required for running Cockpit. %{_prefix}/%{__lib}/cockpit-test-assets %package devel -Summary: Development files for for Cockpit +Summary: Development files for for Cockpit %description devel This package contains files used to develop cockpit modules @@ -746,9 +756,9 @@ This package contains files used to develop cockpit modules %{_datadir}/cockpit/devel %package -n cockpit-pcp -Summary: Cockpit PCP integration -Requires: cockpit-bridge >= 238.1.1 -Requires: pcp +Summary: Cockpit PCP integration +Requires: cockpit-bridge >= 238.1.1 +Requires: pcp %description -n cockpit-pcp Cockpit support for reading PCP metrics and loading PCP archives. @@ -761,13 +771,13 @@ Cockpit support for reading PCP metrics and loading PCP archives. systemctl reload-or-try-restart pmlogger %package -n cockpit-packagekit -Summary: Cockpit user interface for packages -BuildArch: noarch -Requires: PackageKit -Requires: cockpit-bridge >= 186 -Recommends: python3-tracer +Summary: Cockpit user interface for packages +BuildArch: noarch +Requires: cockpit-bridge >= 186 +Requires: PackageKit +Recommends: python3-tracer # HACK: https://bugzilla.redhat.com/show_bug.cgi?id=1800468 -Requires: polkit +Requires: polkit %description -n cockpit-packagekit The Cockpit components for installing OS updates and Cockpit add-ons, @@ -778,4 +788,5 @@ via PackageKit. #/ build optional extension packages %endif +# The changelog is automatically generated and merged %changelog From 2613237f81a296e9ffaadefe024106980d4df7874766b2774f8abae5988e1352 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Wed, 14 Sep 2022 12:13:34 +0000 Subject: [PATCH 7/7] Don't use set_version service for cockpit-suse-theme Should be manually updated, as needed. OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:cockpit/cockpit?expand=0&rev=111 --- _service | 7 +------ cockpit-suse-theme-fe08b35.obscpio | 3 --- cockpit-suse-theme.obscpio | 3 +++ cockpit-suse-theme.obsinfo | 2 +- cockpit.spec | 4 ++-- 5 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 cockpit-suse-theme-fe08b35.obscpio create mode 100644 cockpit-suse-theme.obscpio diff --git a/_service b/_service index 81f03c0..0adac21 100644 --- a/_service +++ b/_service @@ -1,18 +1,13 @@ https://github.com/dgdavid/cockpit-suse-theme.git - %h + git main cockpit-suse-theme.obsinfo - - cockpit-suse-theme - cockpit-suse-these.tar - - @PARENT_TAG@ diff --git a/cockpit-suse-theme-fe08b35.obscpio b/cockpit-suse-theme-fe08b35.obscpio deleted file mode 100644 index 075cce0..0000000 --- a/cockpit-suse-theme-fe08b35.obscpio +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dc2c191f02147e115fd4bc3bd804b3625c68be495fd789ff5a10236e3796b10f -size 1276428 diff --git a/cockpit-suse-theme.obscpio b/cockpit-suse-theme.obscpio new file mode 100644 index 0000000..757fc1d --- /dev/null +++ b/cockpit-suse-theme.obscpio @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c608d92eb3a695dd3148d2e01bf676429189755267826a061f44c7f2843877b4 +size 1275916 diff --git a/cockpit-suse-theme.obsinfo b/cockpit-suse-theme.obsinfo index 39714c9..1a37f47 100644 --- a/cockpit-suse-theme.obsinfo +++ b/cockpit-suse-theme.obsinfo @@ -1,4 +1,4 @@ name: cockpit-suse-theme -version: fe08b35 +version: mtime: 1655379139 commit: fe08b35e64ad45f4b56cd636fdfec8fb18d69ab7 diff --git a/cockpit.spec b/cockpit.spec index c6360ea..4ecc28d 100644 --- a/cockpit.spec +++ b/cockpit.spec @@ -55,7 +55,7 @@ Release: 0 Source0: cockpit-%{version}.tar Source1: cockpit.pam Source2: cockpit-rpmlintrc -Source3: cockpit-suse-theme-fe08b35.tar +Source3: cockpit-suse-theme.tar Source99: README.packaging Source98: package-lock.json Source97: node_modules.spec.inc @@ -238,7 +238,7 @@ 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-* +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