Skip to content

Commit

Permalink
sosreport: Port to fsinfo
Browse files Browse the repository at this point in the history
`fswatch1` is being deprecated. This also gets rid of the ugly
`find | xargs stat` shellery, as fsinfo gets us the modification time.

fsinfo also gives us an initial 'change' event, so we don't need the "initial"
and "on change" handler duplication.
  • Loading branch information
martinpitt authored and jelly committed Nov 6, 2024
1 parent 620fdb7 commit 581c509
Showing 1 changed file with 36 additions and 41 deletions.
77 changes: 36 additions & 41 deletions pkg/sosreport/sosreport.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ import { ListingTable } from "cockpit-components-table.jsx";
import { basename as path_basename } from "cockpit-path";

import cockpit from "cockpit";
import { superuser } from "superuser";
import { useObject, useEvent } from "hooks";
import { superuser } from "superuser";
import * as python from "python";
import { FsInfoClient } from "cockpit/fsinfo";

import { SuperuserButton } from "../shell/superuser.jsx";

Expand Down Expand Up @@ -74,10 +75,9 @@ function sosLister() {
self.dispatchEvent("changed");
}

function parse_report_name(path) {
const basename = path_basename(path);
function parse_report_name(name, date) {
const archive_rx = /^(secured-)?sosreport-(.*)\.tar\.[^.]+(\.gpg)?$/;
const m = basename.match(archive_rx);
const m = name.match(archive_rx);
if (m) {
let name = m[2];
let obfuscated = false;
Expand All @@ -87,61 +87,56 @@ function sosLister() {
}

return {
name,
encrypted: !!m[1],
obfuscated,
name
date,
};
}
}

function update_reports(report_dir) {
cockpit.script(`find ${report_dir} -maxdepth 1 -name '*sosreport-*.tar.*' -print0 | ` +
'xargs -0 -r stat --printf="%n\\r%W\\n"',
{ superuser: "require", err: "message" })
.then(output => {
const reports = { };
const lines = output.split("\n");
for (const line of lines) {
const [path, date] = line.split("\r");
const report = parse_report_name(path);
if (report) {
report.date = Number(date);
reports[path] = report;
}
}
self.reports = reports;
self.ready = true;
emit_changed();
})
.catch(err => {
self.problem = err.problem || err.message;
self.ready = true;
emit_changed();
});
}

let watch = null;
let fsinfo = null;

async function restart() {
if (superuser.allowed === null)
return;

if (watch)
watch.close("cancelled");
if (fsinfo)
fsinfo.close();
self.ready = false;
self.problem = null;
watch = null;

const report_dir = (await python.spawn(get_report_dir_py)).trim();

watch = cockpit.channel({ payload: "fswatch1", path: report_dir, superuser: "require" });
watch.addEventListener("message", (event, payload) => {
const msg = JSON.parse(payload);
if (msg.event != "present" && parse_report_name(msg.path))
update_reports(report_dir);
fsinfo = new FsInfoClient(report_dir, ["entries", "mtime", "type"], { superuser: "require" });
fsinfo.on("change", state => {
if (state.loading)
return;
if (state.error) { // Should Not Happen™, realistic errors come through close event
console.warn("Failed to watch for sosreports:", state.error);
self.problem = state.error.message ?? state.error.problem;
emit_changed();
return;
}
const entries = state.info?.entries;
const reports = { };
for (const name in entries) {
if (entries[name].type == "reg") {
const report = parse_report_name(name, entries[name].mtime);
if (report)
reports[report_dir + '/' + name] = report;
}
}
self.reports = reports;
self.ready = true;
emit_changed();
});

update_reports(report_dir);
fsinfo.on("close", ex => {
self.problem = ex.problem;
self.ready = true;
emit_changed();
});
}

restart();
Expand Down

0 comments on commit 581c509

Please sign in to comment.