feat(xo-web/about): display if XO from source is up to date (#7091)

Fixes #5934
This commit is contained in:
Mathieu 2023-10-24 15:14:01 +00:00 committed by GitHub
parent edfa729672
commit c7eb7db463
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 108 additions and 92 deletions

View File

@ -14,6 +14,7 @@
- [VM/New] Possibility to create and attach a _VTPM_ to a VM [#7066](https://github.com/vatesfr/xen-orchestra/issues/7066) [Forum#6578](https://xcp-ng.org/forum/topic/6578/xcp-ng-8-3-public-alpha/109) (PR [#7077](https://github.com/vatesfr/xen-orchestra/pull/7077))
- [Dashboard/Health] Displays number of VDIs to coalesce (PR [#7111](https://github.com/vatesfr/xen-orchestra/pull/7111))
- [Self] Show number of VMs that belong to each Resource Set (PR [#7114](https://github.com/vatesfr/xen-orchestra/pull/7114))
- [About] For source users, display if their XO is up to date [#5934](https://github.com/vatesfr/xen-orchestra/issues/5934) (PR [#7091](https://github.com/vatesfr/xen-orchestra/pull/7091))
### Bug fixes

View File

@ -3184,12 +3184,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "Xen Orchestra server"
xenOrchestraServer: 'servidor',
// Original text: "Xen Orchestra web client"
xenOrchestraWeb: 'cliente web',
// Original text: "No pro support provided!"
noProSupport: '¡Sin soporte Pro!',

View File

@ -3261,12 +3261,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "Xen Orchestra server"
xenOrchestraServer: 'Serveur Xen Orchestra',
// Original text: "Xen Orchestra web client"
xenOrchestraWeb: 'Client web Xen Orchestra',
// Original text: "No pro support provided!"
noProSupport: 'Pas de support professionel fourni !',

View File

@ -2720,12 +2720,6 @@ export default {
// Original text: 'Xen Orchestra'
xenOrchestra: undefined,
// Original text: 'server'
xenOrchestraServer: undefined,
// Original text: 'web client'
xenOrchestraWeb: undefined,
// Original text: 'No pro support provided!'
noProSupport: undefined,

View File

@ -3003,12 +3003,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'CLOUDXO',
// Original text: "Xen Orchestra server"
xenOrchestraServer: 'Cloudxo szerver',
// Original text: "Xen Orchestra web client"
xenOrchestraWeb: 'Cloudxo web kliens',
// Original text: "No pro support provided!"
noProSupport: 'Nincsen pro-szupport!',

View File

@ -4697,12 +4697,6 @@ export default {
// Original text: 'No host selected to be added'
addHostNoHostMessage: 'Nessun host selezionato da aggiungere',
// Original text: 'Xen Orchestra server'
xenOrchestraServer: 'Server Xen Orchestra',
// Original text: 'Xen Orchestra web client'
xenOrchestraWeb: 'Client web Xen Orchestra',
// Original text: 'Professional support missing!'
noProSupport: 'Manca il supporto professionale!',

View File

@ -2734,12 +2734,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "server"
xenOrchestraServer: 'serwer',
// Original text: "web client"
xenOrchestraWeb: 'web klient',
// Original text: "No pro support provided!"
noProSupport: 'No pro support provided!',

View File

@ -2729,12 +2729,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "server"
xenOrchestraServer: 'servidor',
// Original text: "web client"
xenOrchestraWeb: 'cliente web',
// Original text: "No pro support provided!"
noProSupport: 'Nenhum suporte pro fornecido!',

View File

@ -3187,12 +3187,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "Xen Orchestra server"
xenOrchestraServer: 'Сервер Xen Orchestra',
// Original text: "Xen Orchestra web client"
xenOrchestraWeb: 'WEB-клиент Xen Orchestra',
// Original text: "No pro support provided!"
noProSupport: '"PRO" поддержка не предоставляется!',

View File

@ -4011,12 +4011,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "Xen Orchestra server"
xenOrchestraServer: 'Xen Orchestra sunucusu',
// Original text: "Xen Orchestra web client"
xenOrchestraWeb: 'Xen Orchestra web istemcisi',
// Original text: "No pro support provided!"
noProSupport: 'Hiçbir profesyonel destek verilmez!',

View File

@ -2064,12 +2064,6 @@ export default {
// Original text: "Xen Orchestra"
xenOrchestra: 'Xen Orchestra',
// Original text: "server"
xenOrchestraServer: '服务器',
// Original text: "web client"
xenOrchestraWeb: 'Web客户端',
// Original text: "No pro support provided!"
noProSupport: '不提供专业支持!',

View File

@ -2106,8 +2106,7 @@ const messages = {
addHostNoHostMessage: 'No host selected to be added',
// ----- About View -----
xenOrchestraServer: 'Xen Orchestra server',
xenOrchestraWeb: 'Xen Orchestra web client',
failedToFetchLatestMasterCommit: 'Failed to fetch latest master commit',
noProSupport: 'Professional support missing!',
productionUse: 'Want to use in production?',
getSupport: 'Get pro support with the Xen Orchestra Appliance at {website}',
@ -2125,6 +2124,9 @@ const messages = {
xoAccount: 'Access your XO Account',
openTicket: 'Report a problem',
openTicketText: 'Problem? Open a ticket!',
xoUpToDate: 'Your Xen Orchestra is up to date',
xoFromSourceNotUpToDate:
'You are not up to date with master. {nBehind} commit{nBehind, plural, one {} other {s}} behind {nAhead, plural, =0 {} other {and {nAhead, number} commit{nAhead, plural, one {} other {s}} ahead}}',
// ----- Upgrade Panel -----
upgradeNeeded: 'Upgrade needed',

View File

@ -3723,3 +3723,20 @@ export const esxiListVms = (host, user, password, sslVerify) =>
_call('esxi.listVms', { host, user, password, sslVerify })
export const importVmsFromEsxi = params => _call('vm.importMultipleFromEsxi', params)
// Github API ---------------------------------------------------------------
const _callGithubApi = async (endpoint = '') => {
const url = new URL('https://api.github.com/repos/vatesfr/xen-orchestra')
url.pathname += endpoint
const resp = await fetch(url.toString())
const json = await resp.json()
if (resp.ok) {
return json
} else {
throw new Error(json.message)
}
}
export const getMasterCommit = () => _callGithubApi('/commits/master')
export const compareCommits = (base, head) => _callGithubApi(`/compare/${base}...${head}`)

View File

@ -1,17 +1,14 @@
import _ from 'intl'
import Component from 'base-component'
import Copiable from 'copiable'
import Icon from 'icon'
import Link from 'link'
import Page from '../page'
import React from 'react'
import { getUser } from 'selectors'
import { serverVersion } from 'xo'
import { compareCommits, getMasterCommit, serverVersion } from 'xo'
import { Container, Row, Col } from 'grid'
import { connectStore, getXoaPlan } from 'utils'
import pkg from '../../../package'
const COMMIT_ID = process.env.GIT_HEAD
const HEADER = (
@ -30,13 +27,51 @@ const HEADER = (
user: getUser,
}))
export default class About extends Component {
componentWillMount() {
async componentWillMount() {
serverVersion.then(serverVersion => {
this.setState({ serverVersion })
})
if (process.env.XOA_PLAN > 4 && COMMIT_ID !== '') {
try {
const commit = await getMasterCommit()
const isOnLatest = commit.sha === COMMIT_ID
const diff = {
nAhead: 0,
nBehind: 0,
}
if (!isOnLatest) {
try {
const { ahead_by, behind_by } = await compareCommits(commit.sha, COMMIT_ID)
diff.nAhead = ahead_by
diff.nBehind = behind_by
} catch (err) {
console.error(err)
diff.nBehind = 'unknown'
}
}
this.setState({
commit: {
isOnLatest,
master: commit,
diffWithMaster: diff,
fetched: true,
},
})
} catch (err) {
console.error(err)
this.setState({
commit: {
fetched: false,
},
})
}
}
}
render() {
const { user } = this.props
const { commit } = this.state
const isAdmin = user && user.permission === 'admin'
return (
@ -44,32 +79,53 @@ export default class About extends Component {
<Container className='text-xs-center'>
{isAdmin && [
process.env.XOA_PLAN > 4 && COMMIT_ID !== '' && (
<Row key='0'>
<Col>
<Icon icon='git' size={4} />
<h4>
Xen Orchestra, commit{' '}
<a href={'https://github.com/vatesfr/xen-orchestra/commit/' + COMMIT_ID}>{COMMIT_ID.slice(0, 5)}</a>
</h4>
</Col>
</Row>
<Col>
<Row key='0'>
<Col mediumSize={6}>
<Icon icon='git' size={4} />
<h4>
Xen Orchestra, commit{' '}
<a href={'https://github.com/vatesfr/xen-orchestra/commit/' + COMMIT_ID}>
{COMMIT_ID.slice(0, 5)}
</a>
</h4>
</Col>
<Col mediumSize={6} className={commit?.fetched === false ? 'text-warning' : ''}>
<Icon icon='git' size={4} />
<h4>
{commit === undefined ? (
_('statusLoading')
) : commit.fetched ? (
<span>
Master, commit <a href={commit.master.html_url}>{commit.master.sha.slice(0, 5)}</a>
</span>
) : (
_('failedToFetchLatestMasterCommit')
)}
</h4>
</Col>
</Row>
{commit?.fetched && (
<Row className={`mt-1 ${commit.isOnLatest ? '' : 'text-warning '}`}>
<h4>
{commit.isOnLatest ? (
<span>
{_('xoUpToDate')} <Icon icon='check' color='text-success' />
</span>
) : (
<span>
{_('xoFromSourceNotUpToDate', {
nBehind: commit.diffWithMaster.nBehind,
nAhead: commit.diffWithMaster.nAhead,
})}{' '}
<Icon icon='alarm' color='text-warning' />
</span>
)}
</h4>
</Row>
)}
</Col>
),
<Row key='1'>
<Col mediumSize={6}>
<Icon icon='host' size={4} />
<Copiable tagName='h4' data={`xo-server ${this.state.serverVersion}`}>
xo-server {this.state.serverVersion || 'unknown'}
</Copiable>
<p className='text-muted'>{_('xenOrchestraServer')}</p>
</Col>
<Col mediumSize={6}>
<Icon icon='vm' size={4} />
<Copiable tagName='h4' data={`xo-web ${pkg.version}`}>
xo-web {pkg.version}
</Copiable>
<p className='text-muted'>{_('xenOrchestraWeb')}</p>
</Col>
</Row>,
]}
{process.env.XOA_PLAN > 4 ? (
<div>