From b1a44e337ada15fc607ab57225c1c92be37825e5 Mon Sep 17 00:00:00 2001 From: Kyrylo Gliebov Date: Thu, 26 Jul 2018 17:41:49 +0200 Subject: [PATCH] Add Hostname filter and column --- src/recordings.jsx | 126 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 11 deletions(-) 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 = [ (
{_("User")}
), + ref="user" className="sort-icon">
), (
{_("Start")}
), + ref="start" className="sort-icon">
), (
{_("End")}
), + ref="end" className="sort-icon">
), (
{_("Duration")}
), + ref="duration" className="sort-icon">
), ]; + if (this.props.diff_hosts === true) { + columnTitles.push((
+ {_("Hostname")}
)); + } + 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 (