Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(xo-web/backup): show if NBD is used in the backup logs #6685

Merged
merged 4 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions @xen-orchestra/backups/writers/DeltaBackupWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,9 @@ class DeltaBackupWriter extends MixinBackupWriter(AbstractDeltaWriter) {
$defer(() => nbdClient.disconnect())

info('NBD client ready', { vdi: id, path })
Task.info('NBD used')
} catch (error) {
Task.warning('NBD configured but unusable', { error })
nbdClient = undefined
warn('error connecting to NBD server', { error, vdi: id, path })
}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”

- [VM/Advanced] Warning message when enabling Windows update tools [#6627](https://github.com/vatesfr/xen-orchestra/issues/6627) (PR [#6681](https://github.com/vatesfr/xen-orchestra/issues/6681))
- [Backup] Show if NBD is used in the backup logs (PR [#6685](https://github.com/vatesfr/xen-orchestra/issues/6685))

### Bug fixes

Expand All @@ -32,6 +33,7 @@

<!--packages-start-->

- @xen-orchestra/backups minor
- xo-cli minor
- xo-web minor

Expand Down
28 changes: 16 additions & 12 deletions packages/xo-web/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ $brand-danger: #990822;
$brand-warning: #eca649;
$brand-info: #044b7f;

@import "../../../node_modules/bootstrap/scss/bootstrap";
@import '../../../node_modules/bootstrap/scss/bootstrap';

// imported from https://github.com/twbs/bootstrap/blob/d64466a2488bbaac9a1005db3a199a8bc6846e3e/scss/_variables.scss#L420
.text-monospace {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
}

// -------------------------------------------------------------------

$fa-font-path: ".";
$fa-font-path: '.';

@import "../../../node_modules/font-awesome/scss/font-awesome";
@import '../../../node_modules/font-awesome/scss/font-awesome';

// Replace Bootstrap's glyphicons by Font Awesome.
.glyphicon {
Expand All @@ -31,14 +31,14 @@ $fa-font-path: ".";

// -------------------------------------------------------------------

@import "../../../node_modules/font-mfizz/dist/font-mfizz";
@import '../../../node_modules/font-mfizz/dist/font-mfizz';

// -------------------------------------------------------------------

@import "./chartist";
@import "./meter";
@import "./icons";
@import "./usage";
@import './chartist';
@import './meter';
@import './icons';
@import './usage';

// ROOT STYLES =================================================================

Expand Down Expand Up @@ -114,7 +114,9 @@ $select-input-height: 40px; // Bootstrap input height
@extend .text-info;
}

.xo-status-unknown, .xo-status-paused, .xo-status-disabled {
.xo-status-unknown,
.xo-status-paused,
.xo-status-disabled {
@extend .text-muted;
}

Expand Down Expand Up @@ -151,7 +153,8 @@ $select-input-height: 40px; // Bootstrap input height

// MENU STYLE ==================================================================

.xo-menu, .xo-sub-menu {
.xo-menu,
.xo-sub-menu {
background: $side-menu-bg;
color: $side-menu-color;
}
Expand Down Expand Up @@ -183,7 +186,7 @@ $select-input-height: 40px; // Bootstrap input height
opacity: 0;
position: absolute;
top: 0;
transition: opacity .3s;
transition: opacity 0.3s;
visibility: hidden;
width: max-content;
z-index: 1000;
Expand Down Expand Up @@ -265,6 +268,7 @@ $select-input-height: 40px; // Bootstrap input height
}
}

.task-info,
.task-warning {
padding: 2px 10px;
margin: 10px 0;
Expand Down
60 changes: 59 additions & 1 deletion packages/xo-web/src/xo-app/logs/backup-ng/log-alert-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { FormattedDate } from 'react-intl'
import { injectState, provideState } from 'reaclette'
import { runBackupNgJob, subscribeBackupNgLogs } from 'xo'
import { Vm, Sr, Remote, Pool } from 'render-xo-item'
import BaseComponent from 'base-component'

const hasTaskFailed = ({ status }) => status !== 'success' && status !== 'pending'

Expand Down Expand Up @@ -160,6 +161,53 @@ TaskWarnings.propTypes = {
warnings: PropTypes.arrayOf(PropTypes.shape(TaskWarning.propTypes)),
}

class TaskInfo extends BaseComponent {
constructor(props) {
super(props)
this.state = {
expanded: false,
}
}
render() {
const className = `text-info ${this.props.data ? 'message-expandable' : ''}`
return (
<div>
<span className={className} onClick={this.toggleState('expanded')}>
<Icon icon='info' /> {this.props.message}
</span>
{this.state.expanded && this.props.data && (
<ul className='task-info'>
{Object.keys(this.props.data).map(key => (
<li key={key}>
<strong>{key}</strong>
<span>{JSON.stringify(this.props.data[key])}</span>
</li>
))}
</ul>
)}
</div>
)
}
}

TaskInfo.propTypes = {
message: PropTypes.string.isRequired,
data: PropTypes.object,
}

const TaskInfos = ({ infos }) =>
infos !== undefined ? (
<div>
{infos.map(({ message, data }, key) => (
<TaskInfo message={message} data={data} key={key} />
))}
</div>
) : null

TaskInfos.propTypes = {
infos: PropTypes.arrayOf(PropTypes.shape(TaskInfo.propTypes)),
}

const VmTask = ({ children, className, restartVmJob, task }) => (
<li className={className}>
<Vm id={task.data.id} link newTab /> <TaskStateInfos status={task.status} />{' '}
Expand All @@ -184,6 +232,7 @@ const VmTask = ({ children, className, restartVmJob, task }) => (
</ButtonGroup>
)}
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand Down Expand Up @@ -211,6 +260,7 @@ const PoolTask = ({ children, className, task }) => (
<li className={className}>
<Pool id={task.data.id} link newTab /> <TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand All @@ -223,6 +273,7 @@ const XoTask = ({ children, className, task }) => (
<li className={className}>
<Icon icon='menu-xoa' /> XO <TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand All @@ -235,6 +286,7 @@ const SnapshotTask = ({ className, task }) => (
<li className={className}>
<Icon icon='task' /> {_('snapshotVmLabel')} <TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
<TaskStart task={task} />
<TaskEnd task={task} />
<TaskError task={task} />
Expand All @@ -246,6 +298,7 @@ const CleanVmTask = ({ children, className, task }) =>
<li className={className}>
<Icon icon='clean-vm' /> {_('cleanVm')} <TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand All @@ -256,6 +309,7 @@ const HealthCheckTask = ({ children, className, task }) => (
<li className={className}>
<Icon icon='health' /> {task.message} <TaskStateInfos status={task.status} />{' '}
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand Down Expand Up @@ -287,6 +341,7 @@ const SrTask = ({ children, className, task }) => (
<li className={className}>
<Sr id={task.data.id} link newTab /> <TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
{children}
<TaskStart task={task} />
<TaskEnd task={task} />
Expand Down Expand Up @@ -315,6 +370,7 @@ const TransferMergeTask = ({ className, task }) => {
{task.message}
<TaskStateInfos status={task.status} />
<TaskWarnings warnings={task.warnings} />
<TaskInfos infos={task.infos} />
<TaskStart task={task} />
<TaskEnd task={task} />
<TaskDuration task={task} />
Expand Down Expand Up @@ -525,10 +581,11 @@ export default decorate([
}),
injectState,
({ state, effects }) => {
const { scheduleId, warnings, tasks = [] } = state.log
const { scheduleId, warnings, infos, tasks = [] } = state.log
return tasks.length === 0 ? (
<div>
<TaskWarnings warnings={warnings} />
<TaskInfos infos={infos} />
<TaskError task={state.log} />
</div>
) : (
Expand All @@ -550,6 +607,7 @@ export default decorate([
valueKey='value'
/>
<TaskWarnings warnings={warnings} />
<TaskInfos infos={infos} />
<br />
<ul className='list-group'>
{map(state.displayedTasks, taskLog => {
Expand Down