Skip to content

Commit

Permalink
Merge branch 'master' into alarms
Browse files Browse the repository at this point in the history
  • Loading branch information
P4l0m4 committed Jul 26, 2024
2 parents 7abdf65 + 333012b commit 8c6913e
Show file tree
Hide file tree
Showing 123 changed files with 1,701 additions and 516 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module.exports = {
'n/no-missing-import': 'off', // using 'import' plugin instead, to support TS aliases
'no-redeclare': 'off', // automatically checked by the TypeScript compiler
'no-dupe-class-members': 'off', // automatically checked by the TypeScript compiler
'no-undef': 'off', // automatically checked by the TypeScript compiler
'@typescript-eslint/no-explicit-any': 'off',
'vue/multi-word-component-names': 'off',
// Vue 3 - Strongly Recommended
Expand Down
3 changes: 0 additions & 3 deletions @vates/nbd-client/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export default class NbdClient {
#exportSize

#waitBeforeReconnect
#readAhead
#readBlockRetries
#reconnectRetry
#connectTimeout
Expand All @@ -55,7 +54,6 @@ export default class NbdClient {
connectTimeout = 6e4,
messageTimeout = 6e4,
waitBeforeReconnect = 1e3,
readAhead = 10,
readBlockRetries = 5,
reconnectRetry = 5,
} = {}
Expand All @@ -65,7 +63,6 @@ export default class NbdClient {
this.#exportName = exportname
this.#serverCert = cert
this.#waitBeforeReconnect = waitBeforeReconnect
this.#readAhead = readAhead
this.#readBlockRetries = readBlockRetries
this.#reconnectRetry = reconnectRetry
this.#connectTimeout = connectTimeout
Expand Down
57 changes: 44 additions & 13 deletions @vates/nbd-client/multi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,75 @@ import { createLogger } from '@xen-orchestra/log'
const { warn } = createLogger('vates:nbd-client:multi')
export default class MultiNbdClient {
#clients = []
#nbdConcurrency
#options
#readAhead
#settings

get exportSize() {
return this.#clients[0].exportSize
}

constructor(settings, { nbdConcurrency = 8, readAhead = 16, ...options } = {}) {
this.#readAhead = readAhead
this.#options = options
this.#nbdConcurrency = nbdConcurrency
if (!Array.isArray(settings)) {
settings = [settings]
}
for (let i = 0; i < nbdConcurrency; i++) {
this.#clients.push(
new NbdClient(settings[i % settings.length], { ...options, readAhead: Math.ceil(readAhead / nbdConcurrency) })
)
}
this.#settings = settings
}

/**
*
* open nbdConcurrency connections to NBD servers
* it must obtain at least one connection to succeed
* it tries to spread connections on multiple host
*/
async connect() {
const connectedClients = []
for (const clientId in this.#clients) {
const client = this.#clients[clientId]
const candidates = [...this.#settings]

const promises = []
const baseOptions = this.#options
const _connect = async () => {
if (candidates.length === 0) {
return
}
// a little bit of randomization to spread the load
const nbdInfo = candidates[Math.floor(Math.random() * candidates.length)]
const client = new NbdClient(nbdInfo, {
...baseOptions,
readAhead: Math.ceil(this.#readAhead / this.#nbdConcurrency),
})
try {
await client.connect()
connectedClients.push(client)
this.#clients.push(client)
} catch (err) {
client.disconnect().catch(() => {})
// do not hammer unreachable hosts, once failed, remove from the list
const candidateIndex = candidates.findIndex(({ address }) => address === nbdInfo.address)
if (candidateIndex >= 0) {
// this candidate may have already been deleted by another parallel promise
candidates.splice(candidateIndex, 1)
}

warn(`can't connect to one nbd client`, { err })
// retry with another candidate (if available)
return _connect()
}
}
if (connectedClients.length === 0) {
for (let i = 0; i < this.#nbdConcurrency; i++) {
promises.push(_connect())
}
await Promise.all(promises)

if (this.#clients.length === 0) {
throw new Error(`Fail to connect to any Nbd client`)
}
if (connectedClients.length < this.#clients.length) {
if (this.#clients.length < this.#nbdConcurrency) {
warn(
`incomplete connection by multi Nbd, only ${connectedClients.length} over ${this.#clients.length} expected clients`
`incomplete connection by multi Nbd, only ${this.#clients.length} over ${this.#nbdConcurrency} expected clients`
)
this.#clients = connectedClients
}
}

Expand Down
4 changes: 2 additions & 2 deletions @vates/nbd-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"url": "https://vates.fr"
},
"license": "ISC",
"version": "3.0.2",
"version": "3.1.0",
"engines": {
"node": ">=14.0"
},
Expand All @@ -24,7 +24,7 @@
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/log": "^0.6.0",
"promise-toolbox": "^0.21.0",
"xen-api": "^4.0.0"
"xen-api": "^4.2.0"
},
"devDependencies": {
"tap": "^18.7.0",
Expand Down
44 changes: 32 additions & 12 deletions @vates/nbd-client/tests/nbdclient.integ.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,14 @@ async function killNbdKit() {
)
}

test('it works with unsecured network', async tap => {
test('it works secured network', async tap => {
const path = await createTempFile(FILE_SIZE)

let nbdServer = await spawnNbdKit(path)
const client = new MultiNbdClient(
{
address: '127.0.0.1',
exportname: 'MY_SECRET_EXPORT',
cert: `-----BEGIN CERTIFICATE-----
const connectionSettings = {
address: '127.0.0.1',
exportname: 'MY_SECRET_EXPORT',
cert: `-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUeHpQ0IeD6BmP2zgsv3LV3J4BI/EwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzA1MTcxMzU1MzBaFw0yNDA1
Expand All @@ -108,12 +107,18 @@ CYu1Xn/FVPx1HoRgWc7E8wFhDcA/P3SJtfIQWHB9FzSaBflKGR4t8WCE2eE8+cTB
57ABhfYpMlZ4aHjuN1bL
-----END CERTIFICATE-----
`,
},
{
nbdConcurrency: 1,
readAhead: 2,
}
)
}
const invalid = {
address: '500.500.500.500',
port: 0,
exportname: 'nop',
}
// it should work even with some broken servers
const nbdInfos = [connectionSettings, connectionSettings, invalid]
const client = new MultiNbdClient(nbdInfos, {
nbdConcurrency: 4,
readAhead: 2,
})

await client.connect()
tap.equal(client.exportSize, BigInt(FILE_SIZE))
Expand Down Expand Up @@ -156,3 +161,18 @@ CYu1Xn/FVPx1HoRgWc7E8wFhDcA/P3SJtfIQWHB9FzSaBflKGR4t8WCE2eE8+cTB
nbdServer.kill()
await fs.unlink(path)
})

test('fails if server does not answer', async () => {
const client = new MultiNbdClient(
{
address: '500.500.500.500',
port: 0,
exportname: 'nop',
},
{
nbdConcurrency: 1,
readAhead: 2,
}
)
await assert.rejects(client.connect())
})
2 changes: 1 addition & 1 deletion @xen-orchestra/backups-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"dependencies": {
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.52.1",
"@xen-orchestra/backups": "^0.52.2",
"@xen-orchestra/fs": "^4.1.7",
"filenamify": "^6.0.0",
"getopts": "^2.2.5",
Expand Down
9 changes: 6 additions & 3 deletions @xen-orchestra/backups/_runners/_vmRunners/_AbstractXapi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
}
})
})
}

async _removeSnapshotData() {
// now that we use CBT, we can destroy the data of the snapshot used for this backup
// going back to a previous version of XO not supporting CBT will create a full backup
// this will only do something after snapshot and transfer
Expand All @@ -280,12 +282,12 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {
this._settings.cbtDestroySnapshotData
) {
Task.info('will delete snapshot data')
const vdiRefs = await this._xapi.VM_getDisks(this._exportedVm?.$ref)
await xapi.call('VM.destroy', this._exportedVm.$ref)
const vdiRefs = await this._xapi.VM_getDisks(this._exportedVm.$ref)
await this._xapi.call('VM.destroy', this._exportedVm.$ref)
for (const vdiRef of vdiRefs) {
try {
// data_destroy will fail with a VDI_NO_CBT_METADATA error if CBT is not enabled on this VDI
await xapi.call('VDI.data_destroy', vdiRef)
await this._xapi.call('VDI.data_destroy', vdiRef)
Task.info(`Snapshot data has been deleted`, { vdiRef })
} catch (error) {
Task.warning(`Couldn't deleted snapshot data`, { error, vdiRef })
Expand Down Expand Up @@ -373,6 +375,7 @@ export const AbstractXapi = class AbstractXapiVmBackupRunner extends Abstract {

await this._fetchJobSnapshots()
await this._removeUnusedSnapshots()
await this._removeSnapshotData()
}
await this._healthCheck()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export class IncrementalRemoteWriter extends MixinRemoteWriter(AbstractIncrement
if (isDifferencing) {
assert.notStrictEqual(
parentVdiPaths,
undefined,
'checkbasevdi must be called before updateUuidAndChain for incremental backups'
)
const parentPath = parentVdiPaths[dirname(path)]
Expand Down
8 changes: 4 additions & 4 deletions @xen-orchestra/backups/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"type": "git",
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"version": "0.52.1",
"version": "0.52.2",
"engines": {
"node": ">=14.18"
},
Expand All @@ -25,7 +25,7 @@
"@vates/decorate-with": "^2.1.0",
"@vates/disposable": "^0.1.5",
"@vates/fuse-vhd": "^2.1.1",
"@vates/nbd-client": "^3.0.2",
"@vates/nbd-client": "^3.1.0",
"@vates/parse-duration": "^0.1.1",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/fs": "^4.1.7",
Expand All @@ -47,7 +47,7 @@
"tar": "^6.1.15",
"uuid": "^9.0.0",
"vhd-lib": "^4.11.0",
"xen-api": "^4.0.0",
"xen-api": "^4.2.0",
"yazl": "^2.5.1"
},
"devDependencies": {
Expand All @@ -58,7 +58,7 @@
"tmp": "^0.2.1"
},
"peerDependencies": {
"@xen-orchestra/xapi": "^7.1.1"
"@xen-orchestra/xapi": "^7.2.1"
},
"license": "AGPL-3.0-or-later",
"author": {
Expand Down
2 changes: 1 addition & 1 deletion @xen-orchestra/cr-seed-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"preferGlobal": true,
"dependencies": {
"golike-defer": "^0.5.1",
"xen-api": "^4.0.0"
"xen-api": "^4.2.0"
},
"scripts": {
"postversion": "npm publish"
Expand Down
2 changes: 1 addition & 1 deletion @xen-orchestra/immutable-backups/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"dependencies": {
"@vates/async-each": "^1.0.0",
"@xen-orchestra/backups": "^0.52.1",
"@xen-orchestra/backups": "^0.52.2",
"@xen-orchestra/log": "^0.6.0",
"app-conf": "^3.0.0",
"chokidar": "^3.5.3",
Expand Down
1 change: 1 addition & 0 deletions @xen-orchestra/lite/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- [Pool/Dashboard] Add missing translations for hosts and VMs statuses (PR [#7744](https://github.com/vatesfr/xen-orchestra/pull/7744))
- [i18n] Add Persian translation (based on the contribution made by [@Jokar-xen](https://github.com/Jokar-xen)) (PR [#7775](https://github.com/vatesfr/xen-orchestra/pull/7775))
- [Access XOA] Support `xo-server`'s' setting `http.publicUrl` to redirect to a custom URL when "Access XOA" button is clicked in XO Lite [Forum#9392](https://xcp-ng.org/forum/topic/9392) (PR [#7849](https://github.com/vatesfr/xen-orchestra/pull/7849))

## **0.2.3** (2024-05-31)

Expand Down
6 changes: 3 additions & 3 deletions @xen-orchestra/lite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@xen-orchestra/lite",
"version": "0.2.4",
"version": "0.2.5",
"type": "module",
"scripts": {
"dev": "GIT_HEAD=$(git rev-parse HEAD) vite",
Expand Down Expand Up @@ -31,7 +31,7 @@
"@vueuse/core": "^10.7.1",
"@vueuse/math": "^10.7.1",
"@vueuse/shared": "^10.7.1",
"@xen-orchestra/web-core": "^0.0.3",
"@xen-orchestra/web-core": "^0.0.4",
"complex-matcher": "^0.7.1",
"d3-time-format": "^4.1.0",
"decorator-synchronized": "^0.6.0",
Expand Down Expand Up @@ -59,7 +59,7 @@
"vue": "^3.4.13",
"vue-echarts": "^6.6.8",
"vue-i18n": "^9.9.0",
"vue-router": "^4.2.5",
"vue-router": "^4.4.0",
"vue-tsc": "^1.8.27",
"zx": "^7.2.3"
},
Expand Down
10 changes: 8 additions & 2 deletions @xen-orchestra/lite/src/components/XoaButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ interface InterfaceInfo {
interface ClientInfo {
lastConnected: number
networkInterfaces: Record<string, InterfaceInfo[]>
networkInterfaces?: Record<string, InterfaceInfo[]>
publicUrl?: string
}
const xoasInfo = computed(() => {
Expand Down Expand Up @@ -60,7 +61,12 @@ const xoaAddress = computed(() => {
return
}
const { networkInterfaces } = xoaInfo.value
const { networkInterfaces, publicUrl } = xoaInfo.value
if (publicUrl !== undefined) {
return publicUrl
}
if (networkInterfaces === undefined || Object.keys(networkInterfaces).length === 0) {
return
}
Expand Down
10 changes: 2 additions & 8 deletions @xen-orchestra/lite/src/components/infra/InfraItemLabel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
class="infra-item-label"
v-bind="$attrs"
>
<a v-tooltip="{ selector: '.text' }" :href class="link" @click="navigate">
<a v-tooltip="{ selector: '.text-ellipsis' }" :href class="link" @click="navigate">
<UiIcon :icon class="icon" />
<div class="text typo h6-medium">
<div class="text-ellipsis typo h6-medium">
<slot />
</div>
</a>
Expand Down Expand Up @@ -77,12 +77,6 @@ defineProps<{
font-size: 2rem;
}
.text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.actions {
display: flex;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion @xen-orchestra/lite/src/components/infra/InfraVmItem.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<TreeItem v-if="vm !== undefined" ref="rootElement" class="infra-vm-item">
<TreeItem v-if="vm !== undefined" ref="rootElement" expanded class="infra-vm-item">
<TreeItemLabel v-if="isVisible" :route="{ name: 'vm.console', params: { uuid: vm.uuid } }" no-indent>
{{ vm.name_label || '(VM)' }}
<template #icon>
Expand Down
Loading

0 comments on commit 8c6913e

Please sign in to comment.