diff --git a/src/recordings.jsx b/src/recordings.jsx
index 43f88ec..3153ee4 100644
--- a/src/recordings.jsx
+++ b/src/recordings.jsx
@@ -223,6 +223,26 @@
}
}
+ let HostnamePicker = class extends React.Component {
+ constructor(props) {
+ super(props);
+ this.handleHostnameChange = this.handleHostnameChange.bind(this);
+ }
+
+ handleHostnameChange(e) {
+ this.props.onHostnameChange(e.target.value);
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+ }
+
/*
* A component representing a single recording view.
* Properties:
@@ -233,6 +253,9 @@
constructor(props) {
super(props);
this.goBackToList = this.goBackToList.bind(this);
+ this.getHostname = this.getHostname.bind(this);
+ this.Hostname = this.Hostname.bind(this);
+ this.hostname = null;
}
goBackToList() {
@@ -243,6 +266,35 @@
}
}
+ getHostname() {
+ cockpit.spawn(["hostname"], { err: "ignore" })
+ .done(function(output) {
+ this.hostname = $.trim(output);
+ })
+ .fail(function(ex) {
+ console.log(ex);
+ });
+ }
+
+ Hostname(props) {
+ let style = {
+ display: "none"
+ };
+ if (this.hostname != null && this.hostname != props.hostname) {
+ style = {};
+ }
+ return (
+
+ | {_("Hostname")} |
+ {props.hostname} |
+
+ );
+ }
+
+ componentWillMount() {
+ this.getHostname();
+ }
+
render() {
let r = this.props.recording;
if (r == null) {
@@ -275,6 +327,7 @@
{_("ID")} |
{r.id} |
+
| {_("Boot ID")} |
{r.boot_id} |
@@ -328,6 +381,8 @@
this.handleColumnClick = this.handleColumnClick.bind(this);
this.getSortedList = this.getSortedList.bind(this);
this.drawSortDir = this.drawSortDir.bind(this);
+ this.getColumnTitles = this.getColumnTitles.bind(this);
+ this.getColumns = this.getColumns.bind(this);
this.state = {
sorting_field: "start",
sorting_asc: true,
@@ -383,26 +438,43 @@
this.drawSortDir();
}
- render() {
+ getColumnTitles() {
let columnTitles = [
(),
+ ref="user" className="sort-icon">),
(),
+ ref="start" className="sort-icon">),
(),
+ ref="end" className="sort-icon">),
(),
+ ref="duration" className="sort-icon">),
];
+ if (this.props.diff_hosts === true) {
+ columnTitles.push(());
+ }
+ return columnTitles;
+ }
+
+ getColumns(r) {
+ let columns = [r.user,
+ formatDateTime(r.start),
+ formatDateTime(r.end),
+ formatDuration(r.end - r.start)]
+ if (this.props.diff_hosts === true) {
+ columns.push(r.hostname);
+ }
+ return columns;
+ }
+
+ render() {
+ let columnTitles = this.getColumnTitles();
let list = this.getSortedList();
let rows = [];
for (let i = 0; i < list.length; i++) {
let r = list[i];
- let columns = [r.user,
- formatDateTime(r.start),
- formatDateTime(r.end),
- formatDuration(r.end - r.start)];
+ let columns = this.getColumns(r);
rows.push(
+
+
+ |
+
+
+ |
|
@@ -468,6 +547,7 @@
this.handleDateSinceChange = this.handleDateSinceChange.bind(this);
this.handleDateUntilChange = this.handleDateUntilChange.bind(this);
this.handleUsernameChange = this.handleUsernameChange.bind(this);
+ this.handleHostnameChange = this.handleHostnameChange.bind(this);
/* Journalctl instance */
this.journalctl = null;
/* Recording ID journalctl instance is invoked with */
@@ -487,7 +567,9 @@
dateUntilLastValid: null,
/* value to filter recordings by username */
username: cockpit.location.options.username || null,
+ hostname: cockpit.location.options.hostname || null,
error_tlog_uid: false,
+ diff_hosts: false,
}
}
@@ -508,6 +590,7 @@
dateSince: cockpit.location.options.dateSince || null,
dateUntil: cockpit.location.options.dateUntil || null,
username: cockpit.location.options.username || null,
+ hostname: cockpit.location.options.hostname || null,
});
}
@@ -518,6 +601,13 @@
let recordingList = this.state.recordingList.slice();
let i;
let j;
+ let hostname;
+
+ if (entryList[0]) {
+ if (entryList[0]["_HOSTNAME"]) {
+ hostname = entryList[0]["_HOSTNAME"];
+ }
+ }
for (i = 0; i < entryList.length; i++) {
let e = entryList[i];
@@ -536,6 +626,10 @@
/* If no recording found */
if (r === undefined) {
/* Create new recording */
+ if (hostname != e["_HOSTNAME"]) {
+ this.setState({diff_hosts: true});
+ }
+
r = {id: id,
matchList: ["_UID=" + this.uid,
"TLOG_REC=" + id],
@@ -593,6 +687,10 @@
if (this.state.username) {
matches.push("TLOG_USER=" + this.state.username);
}
+ if (this.state.hostname && this.state.hostname != null &&
+ this.state.hostname != "") {
+ matches.push("_HOSTNAME=" + this.state.hostname);
+ }
let options = {follow: true, count: "all"};
@@ -664,6 +762,10 @@
cockpit.location.go([], $.extend(cockpit.location.options, { username: username }));
}
+ handleHostnameChange(hostname) {
+ cockpit.location.go([], $.extend(cockpit.location.options, { hostname: hostname }));
+ }
+
componentDidMount() {
let proc = cockpit.spawn(["getent", "passwd", "tlog"]);
@@ -713,7 +815,8 @@
}
if (this.state.dateSinceLastValid != prevState.dateSinceLastValid ||
this.state.dateUntilLastValid != prevState.dateUntilLastValid ||
- this.state.username != prevState.username
+ this.state.username != prevState.username ||
+ this.state.hostname != prevState.hostname
) {
this.clearRecordings();
this.journalctlRestart();
@@ -734,7 +837,8 @@
onDateSinceChange={this.handleDateSinceChange} dateSince={this.state.dateSince}
onDateUntilChange={this.handleDateUntilChange} dateUntil={this.state.dateUntil}
onUsernameChange={this.handleUsernameChange} username={this.state.username}
- list={this.state.recordingList} />
+ onHostnameChange={this.handleHostnameChange} hostname={this.state.hostname}
+ list={this.state.recordingList} diff_hosts={this.state.diff_hosts} />
);
} else {
return (