Compare commits

...

14 Commits

Author SHA1 Message Date
Florent Beauchamp
91f79be44a show debug once per cleanVm 2022-05-12 15:35:11 +02:00
Florent Beauchamp
7d094f6706 fix: remove debug of vhd children 2022-05-12 15:31:46 +02:00
Florent Beauchamp
b34c43db81 fix scope 2022-05-12 15:28:56 +02:00
Florent Beauchamp
42dce7d10c feat: add more debug in getUsedChildChainOrDelete and don't delete vhd 2022-05-12 15:04:15 +02:00
Julien Fontanet
c92b371d9e feat(xo-server): 5.93.1 2022-05-12 11:50:48 +02:00
Julien Fontanet
35e6bb30db feat(@xen-orchestra/proxy): 0.22.1 2022-05-12 11:49:32 +02:00
Julien Fontanet
1aaa123f47 feat(@xen-orchestra/mixins): 0.4.0 2022-05-12 11:47:59 +02:00
Julien Fontanet
a8c507a1df feat(@xen-orchestra/backups): 0.23.0 2022-05-12 11:43:41 +02:00
Julien Fontanet
581e3c358f feat(@xen-orchestra/xapi): 1.0.0 2022-05-12 11:41:09 +02:00
Julien Fontanet
e4f1b8f2e0 fix(xo-server/installPatches): fix pool wide detection (#6231)
Introduced by 3f1c41a4f

Fixes zammad#6819 zammad#6781 zammad#6827

In #6186 the behavior was changed to always pass hosts, which broke the pool wide detection.
2022-05-12 10:56:18 +02:00
Julien Fontanet
29e8a7fd7e docs(xo-server/REST API): Set-Cookie is not implemented 2022-05-10 15:31:40 +02:00
Julien Fontanet
4af289c492 feat(docs/architecture): update xo-cli usage 2022-05-10 11:38:19 +02:00
Julien Fontanet
cd95793054 chore(mixins): convert to ESM 2022-05-09 14:46:25 +02:00
Julien Fontanet
ab71578cf2 chore(xapi): major version
When using major version zero, every increase of the minor version number is breaking.

Which means that each new version of `xapi` required also a new release of `@xen-orchestra/backups`, using a true major version will fix that.
2022-05-09 10:00:36 +02:00
19 changed files with 136 additions and 60 deletions

View File

@@ -7,7 +7,7 @@
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"dependencies": {
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.22.0",
"@xen-orchestra/backups": "^0.23.0",
"@xen-orchestra/fs": "^1.0.1",
"filenamify": "^4.1.0",
"getopts": "^2.2.5",

View File

@@ -5,7 +5,7 @@ const sum = require('lodash/sum')
const { asyncMap } = require('@xen-orchestra/async-map')
const { Constants, mergeVhd, openVhd, VhdAbstract, VhdFile } = require('vhd-lib')
const { isVhdAlias, resolveVhdAlias } = require('vhd-lib/aliases')
const { dirname, resolve } = require('path')
const { dirname, resolve, basename } = require('path')
const { DISK_TYPES } = Constants
const { isMetadataFile, isVhdFile, isXvaFile, isXvaSumFile } = require('./_backupType.js')
const { limitConcurrency } = require('limit-concurrency-decorator')
@@ -90,7 +90,7 @@ async function mergeVhdChain(chain, { handler, onLog, remove, merge }) {
asyncMap(children.slice(0, -1), child => {
onLog(`the VHD ${child} is unused`)
if (remove) {
onLog(`deleting unused VHD ${child}`)
onLog(`mergeVhdChain: deleting unused VHD ${child}`)
return VhdAbstract.unlink(handler, child)
}
}),
@@ -383,7 +383,7 @@ exports.cleanVm = async function cleanVm(
const vhdChainsToMerge = { __proto__: null }
const toCheck = new Set(unusedVhds)
let shouldDelete = false
const getUsedChildChainOrDelete = vhd => {
if (vhd in vhdChainsToMerge) {
const chain = vhdChainsToMerge[vhd]
@@ -409,8 +409,12 @@ exports.cleanVm = async function cleanVm(
onLog(`the VHD ${vhd} is unused`)
if (remove) {
onLog(`deleting unused VHD ${vhd}`)
unusedVhdsDeletion.push(VhdAbstract.unlink(handler, vhd))
onLog(`getUsedChildChainOrDelete: deleting unused VHD`, {
vhd,
})
// temporarly disabled
shouldDelete = true
// unusedVhdsDeletion.push(VhdAbstract.unlink(handler, vhd))
}
}
@@ -418,6 +422,57 @@ exports.cleanVm = async function cleanVm(
vhdChainsToMerge[vhd] = getUsedChildChainOrDelete(vhd)
})
{
// eslint-disable-next-line no-console
const debug = console.debug
if (shouldDelete) {
const chains = { __proto__: null }
const queue = new Set(vhds)
function addChildren(parent, chain) {
queue.delete(parent)
const child = vhdChildren[parent]
if (child !== undefined) {
const childChain = chains[child]
if (childChain !== undefined) {
// if a chain already exists, use it
delete chains[child]
chain.push(...childChain)
} else {
chain.push(child)
addChildren(child, chain)
}
}
}
for (const vhd of queue) {
const chain = []
addChildren(vhd, chain)
chains[vhd] = chain
}
const entries = Object.entries(chains)
debug(`${vhds.size} VHDs (${unusedVhds.size} unused) found among ${entries.length} chains [`)
const decorateVhd = vhd => {
const shortPath = basename(vhd)
return unusedVhds.has(vhd) ? `${shortPath} [unused]` : shortPath
}
for (let i = 0, n = entries.length; i < n; ++i) {
debug(`in ${dirname(entries[i][0])}`)
debug(' [')
const [parent, children] = entries[i]
debug(' ' + decorateVhd(parent))
for (const child of children) {
debug(' ' + decorateVhd(child))
}
debug(' ]')
}
debug(']')
}
}
// merge interrupted VHDs
for (const parent of interruptedVhds.keys()) {
vhdChainsToMerge[parent] = [vhdChildren[parent], parent]

View File

@@ -8,7 +8,7 @@
"type": "git",
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"version": "0.22.0",
"version": "0.23.0",
"engines": {
"node": ">=14.6"
},
@@ -45,7 +45,7 @@
"tmp": "^0.2.1"
},
"peerDependencies": {
"@xen-orchestra/xapi": "^0.11.0"
"@xen-orchestra/xapi": "^1.0.0"
},
"license": "AGPL-3.0-or-later",
"author": {

View File

@@ -1,15 +1,13 @@
'use strict'
const get = require('lodash/get')
const identity = require('lodash/identity')
const isEqual = require('lodash/isEqual')
const { createLogger } = require('@xen-orchestra/log')
const { parseDuration } = require('@vates/parse-duration')
const { watch } = require('app-conf')
import get from 'lodash/get.js'
import identity from 'lodash/identity.js'
import isEqual from 'lodash/isEqual.js'
import { createLogger } from '@xen-orchestra/log'
import { parseDuration } from '@vates/parse-duration'
import { watch } from 'app-conf'
const { warn } = createLogger('xo:mixins:config')
module.exports = class Config {
export default class Config {
constructor(app, { appDir, appName, config }) {
this._config = config
const watchers = (this._watchers = new Set())

View File

@@ -1,9 +1,7 @@
'use strict'
const assert = require('assert')
const emitAsync = require('@xen-orchestra/emit-async')
const EventEmitter = require('events')
const { createLogger } = require('@xen-orchestra/log')
import assert from 'assert'
import emitAsync from '@xen-orchestra/emit-async'
import EventEmitter from 'events'
import { createLogger } from '@xen-orchestra/log'
const { debug, warn } = createLogger('xo:mixins:hooks')
@@ -19,7 +17,7 @@ const runHook = async (emitter, hook) => {
debug(`${hook} finished`)
}
module.exports = class Hooks extends EventEmitter {
export default class Hooks extends EventEmitter {
// Run *clean* async listeners.
//
// They normalize existing data, clear invalid entries, etc.

View File

@@ -1,15 +1,15 @@
'use strict'
import { createLogger } from '@xen-orchestra/log'
import { EventListenersManager } from '@vates/event-listeners-manager'
import { pipeline } from 'stream'
import { ServerResponse, request } from 'http'
import assert from 'assert'
import fromCallback from 'promise-toolbox/fromCallback'
import fromEvent from 'promise-toolbox/fromEvent'
import net from 'net'
const { debug, warn } = require('@xen-orchestra/log').createLogger('xo:mixins:HttpProxy')
const { EventListenersManager } = require('@vates/event-listeners-manager')
const { pipeline } = require('stream')
const { ServerResponse, request } = require('http')
const assert = require('assert')
const fromCallback = require('promise-toolbox/fromCallback')
const fromEvent = require('promise-toolbox/fromEvent')
const net = require('net')
import { parseBasicAuth } from './_parseBasicAuth.mjs'
const { parseBasicAuth } = require('./_parseBasicAuth.js')
const { debug, warn } = createLogger('xo:mixins:HttpProxy')
const IGNORED_HEADERS = new Set([
// https://datatracker.ietf.org/doc/html/rfc2616#section-13.5.1
@@ -26,7 +26,7 @@ const IGNORED_HEADERS = new Set([
'host',
])
module.exports = class HttpProxy {
export default class HttpProxy {
#app
constructor(app, { httpServer }) {

View File

@@ -1,8 +1,6 @@
'use strict'
const RE = /^\s*basic\s+(.+?)\s*$/i
exports.parseBasicAuth = function parseBasicAuth(header) {
export function parseBasicAuth(header) {
if (header === undefined) {
return
}

View File

@@ -14,7 +14,7 @@
"url": "https://vates.fr"
},
"license": "AGPL-3.0-or-later",
"version": "0.3.1",
"version": "0.4.0",
"engines": {
"node": ">=12"
},

View File

@@ -1,6 +1,6 @@
import Config from '@xen-orchestra/mixins/Config.js'
import Hooks from '@xen-orchestra/mixins/Hooks.js'
import HttpProxy from '@xen-orchestra/mixins/HttpProxy.js'
import Config from '@xen-orchestra/mixins/Config.mjs'
import Hooks from '@xen-orchestra/mixins/Hooks.mjs'
import HttpProxy from '@xen-orchestra/mixins/HttpProxy.mjs'
import mixin from '@xen-orchestra/mixin'
import { createDebounceResource } from '@vates/disposable/debounceResource.js'

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@xen-orchestra/proxy",
"version": "0.22.0",
"version": "0.22.1",
"license": "AGPL-3.0-or-later",
"description": "XO Proxy used to remotely execute backup jobs",
"keywords": [
@@ -32,13 +32,13 @@
"@vates/decorate-with": "^2.0.0",
"@vates/disposable": "^0.1.1",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.22.0",
"@xen-orchestra/backups": "^0.23.0",
"@xen-orchestra/fs": "^1.0.1",
"@xen-orchestra/log": "^0.3.0",
"@xen-orchestra/mixin": "^0.1.0",
"@xen-orchestra/mixins": "^0.3.1",
"@xen-orchestra/mixins": "^0.4.0",
"@xen-orchestra/self-signed": "^0.1.0",
"@xen-orchestra/xapi": "^0.11.0",
"@xen-orchestra/xapi": "^1.0.0",
"ajv": "^8.0.3",
"app-conf": "^2.1.0",
"async-iterator-to-stream": "^1.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@xen-orchestra/xapi",
"version": "0.11.0",
"version": "1.0.0",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/xapi",
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"repository": {

View File

@@ -1,5 +1,19 @@
# ChangeLog
## **next**
### Bug fixes
- [Pool/Patches] Fix failure to install patches on Citrix Hypervisor (PR [#6231](https://github.com/vatesfr/xen-orchestra/pull/6231))
### Released packages
- @xen-orchestra/xapi 1.0.0
- @xen-orchestra/backups 0.23.0
- @xen-orchestra/mixins 0.4.0
- @xen-orchestra/proxy 0.22.1
- xo-server 5.93.1
## 5.70.1 (2022-05-04)
### Enhancement

View File

@@ -33,5 +33,4 @@
<!--packages-start-->
<!--packages-end-->

View File

@@ -138,9 +138,22 @@ This CLI is mainly used as a debug tool, there's no 100% guarantee on its stabil
> xo-cli --help
Usage:
xo-cli --register <XO-Server URL> <username> [<password>]
xo-cli --register [--allowUnauthorized] [--expiresIn duration] <XO-Server URL> <username> [<password>]
Registers the XO instance to use.
--allowUnauthorized, --au
Accept invalid certificate (e.g. self-signed).
--expiresIn duration
Can be used to change the validity duration of the
authorization token (default: one month).
xo-cli --createToken <params>…
Create an authentication token for XO API.
<params>…
Accept the same parameters as --register, see its usage.
xo-cli --unregister
Remove stored credentials.
@@ -160,7 +173,6 @@ Usage:
xo-cli <command> [<name>=<value>]...
Executes a command on the current XO instance.
```
#### Register your XO instance

View File

@@ -22,7 +22,7 @@ Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
The server will respond to an invalid token with a `401 Unauthorized` status.
The server can request that the client updates its token with a `Set-Cookie` header:
**[Not implemented at this time]** The server can request that the client updates its token with a `Set-Cookie` header:
```http
HTTP/1.1 200 OK

View File

@@ -20,7 +20,7 @@ Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
The server will respond to an invalid token with a `401 Unauthorized` status.
The server can request that the client updates its token with a `Set-Cookie` header:
**[Not implemented at this time]** The server can request that the client updates its token with a `Set-Cookie` header:
```http
HTTP/1.1 200 OK

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "xo-server",
"version": "5.93.0",
"version": "5.93.1",
"license": "AGPL-3.0-or-later",
"description": "Server part of Xen-Orchestra",
"keywords": [
@@ -39,17 +39,17 @@
"@vates/predicates": "^1.0.0",
"@vates/read-chunk": "^0.1.2",
"@xen-orchestra/async-map": "^0.1.2",
"@xen-orchestra/backups": "^0.22.0",
"@xen-orchestra/backups": "^0.23.0",
"@xen-orchestra/cron": "^1.0.6",
"@xen-orchestra/defined": "^0.0.1",
"@xen-orchestra/emit-async": "^0.1.0",
"@xen-orchestra/fs": "^1.0.1",
"@xen-orchestra/log": "^0.3.0",
"@xen-orchestra/mixin": "^0.1.0",
"@xen-orchestra/mixins": "^0.3.1",
"@xen-orchestra/mixins": "^0.4.0",
"@xen-orchestra/self-signed": "^0.1.0",
"@xen-orchestra/template": "^0.1.0",
"@xen-orchestra/xapi": "^0.11.0",
"@xen-orchestra/xapi": "^1.0.0",
"ajv": "^8.0.3",
"app-conf": "^2.1.0",
"async-iterator-to-stream": "^1.0.1",

View File

@@ -116,6 +116,7 @@ listMissingPatches.resolve = {
// -------------------------------------------------------------------
export async function installPatches({ pool, patches, hosts }) {
const opts = { patches }
let xapi
if (pool !== undefined) {
pool = this.getXapiObject(pool, 'pool')
@@ -123,6 +124,7 @@ export async function installPatches({ pool, patches, hosts }) {
hosts = Object.values(xapi.objects.indexes.type.host)
} else {
hosts = hosts.map(_ => this.getXapiObject(_))
opts.hosts = hosts
xapi = hosts[0].$xapi
pool = xapi.pool
}
@@ -136,7 +138,7 @@ export async function installPatches({ pool, patches, hosts }) {
})
}
await xapi.installPatches({ hosts, patches })
await xapi.installPatches(opts)
const masterRef = pool.master
if (moveFirst(hosts, _ => _.$ref === masterRef)) {

View File

@@ -1,7 +1,7 @@
import Config from '@xen-orchestra/mixins/Config.js'
import Config from '@xen-orchestra/mixins/Config.mjs'
import forEach from 'lodash/forEach.js'
import Hooks from '@xen-orchestra/mixins/Hooks.js'
import HttpProxy from '@xen-orchestra/mixins/HttpProxy.js'
import Hooks from '@xen-orchestra/mixins/Hooks.mjs'
import HttpProxy from '@xen-orchestra/mixins/HttpProxy.mjs'
import includes from 'lodash/includes.js'
import isEmpty from 'lodash/isEmpty.js'
import iteratee from 'lodash/iteratee.js'