Compare commits
14 Commits
feat_s3_ad
...
fix_invest
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91f79be44a | ||
|
|
7d094f6706 | ||
|
|
b34c43db81 | ||
|
|
42dce7d10c | ||
|
|
c92b371d9e | ||
|
|
35e6bb30db | ||
|
|
1aaa123f47 | ||
|
|
a8c507a1df | ||
|
|
581e3c358f | ||
|
|
e4f1b8f2e0 | ||
|
|
29e8a7fd7e | ||
|
|
4af289c492 | ||
|
|
cd95793054 | ||
|
|
ab71578cf2 |
@@ -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",
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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())
|
||||
@@ -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.
|
||||
@@ -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 }) {
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": {
|
||||
|
||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -33,5 +33,4 @@
|
||||
|
||||
<!--packages-start-->
|
||||
|
||||
|
||||
<!--packages-end-->
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user