Compare commits
374 Commits
ldap-origi
...
fix-home-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03cda4d190 | ||
|
|
d7fe1afc08 | ||
|
|
ae9aeaf5fd | ||
|
|
ec9476216f | ||
|
|
619f2ef119 | ||
|
|
52020abde8 | ||
|
|
1bd504d67e | ||
|
|
edc4414de4 | ||
|
|
c1d588264c | ||
|
|
94b84b75ad | ||
|
|
b72a4c5aa9 | ||
|
|
857a9f3efc | ||
|
|
ce53128657 | ||
|
|
d9211053ce | ||
|
|
e8316178a0 | ||
|
|
bf763d2cf4 | ||
|
|
eba5b34982 | ||
|
|
afb8b3dd6b | ||
|
|
c5fa94894b | ||
|
|
4137758caa | ||
|
|
3578d16e9e | ||
|
|
3ef263a5cc | ||
|
|
510460c966 | ||
|
|
f74ecc53ae | ||
|
|
c4121073ad | ||
|
|
9ded2641a7 | ||
|
|
295ca68d02 | ||
|
|
27f53f262b | ||
|
|
3fc16cb414 | ||
|
|
90db25d732 | ||
|
|
bbb359470e | ||
|
|
319652c7c7 | ||
|
|
c9c271fee8 | ||
|
|
ca0755e92b | ||
|
|
acd38597f6 | ||
|
|
f4a5a80f3c | ||
|
|
c45d00fee8 | ||
|
|
ffae59fa1c | ||
|
|
b697178f68 | ||
|
|
83ade5eecb | ||
|
|
6973b92c4a | ||
|
|
6261f8a778 | ||
|
|
6048493ac6 | ||
|
|
1cbd715235 | ||
|
|
703fcbccd6 | ||
|
|
2f9cbec07e | ||
|
|
9f0b22d3e9 | ||
|
|
ab5907c09c | ||
|
|
fae0b168f6 | ||
|
|
f18e98a63e | ||
|
|
3524886d5d | ||
|
|
fb44eea06c | ||
|
|
3ea4c757e6 | ||
|
|
cfb8d79049 | ||
|
|
1ea86da7af | ||
|
|
e289f2dba2 | ||
|
|
7f64cd1801 | ||
|
|
d4526e1ed2 | ||
|
|
34f42216c8 | ||
|
|
a26a24a8ad | ||
|
|
4530fd4164 | ||
|
|
9156b8f48c | ||
|
|
6212109fc1 | ||
|
|
c22a080e23 | ||
|
|
834a7109f9 | ||
|
|
7cbf32202d | ||
|
|
d0b9380dca | ||
|
|
13fd9be566 | ||
|
|
53a9aa6ad2 | ||
|
|
c2ce4aca1b | ||
|
|
567f6d7cc0 | ||
|
|
489c0b27f9 | ||
|
|
343f988584 | ||
|
|
7f676c56c8 | ||
|
|
3c0ca7026f | ||
|
|
2ceba11aa7 | ||
|
|
6db5e0b27c | ||
|
|
dfecb801db | ||
|
|
c10bfe3db2 | ||
|
|
20fb2c99bc | ||
|
|
b4a0b5c58b | ||
|
|
faa46c2a21 | ||
|
|
9691199ae8 | ||
|
|
f736381933 | ||
|
|
f44e5b3b7a | ||
|
|
6e24bf5f8c | ||
|
|
8fb43e31c5 | ||
|
|
0860c80e51 | ||
|
|
66fc25756f | ||
|
|
f008e240cd | ||
|
|
8d7e95d6e9 | ||
|
|
3e3ce543a8 | ||
|
|
6c447a82f1 | ||
|
|
64a0918ff1 | ||
|
|
9274223701 | ||
|
|
1368c18844 | ||
|
|
67a60a7557 | ||
|
|
3d5fd47748 | ||
|
|
b9a18807ae | ||
|
|
088c0b6321 | ||
|
|
ecee11a24c | ||
|
|
ec8df7ce57 | ||
|
|
4159fd2ffb | ||
|
|
1a1d21bbb3 | ||
|
|
be1045fed9 | ||
|
|
e43773c712 | ||
|
|
30d69dadbb | ||
|
|
b138438036 | ||
|
|
d649211330 | ||
|
|
6cf211a9ad | ||
|
|
3388e5e8a4 | ||
|
|
5d497a1908 | ||
|
|
c820646fb6 | ||
|
|
5870f6f734 | ||
|
|
6732150121 | ||
|
|
1dead8b080 | ||
|
|
d547aa8ebd | ||
|
|
1da889e420 | ||
|
|
5d0a308d1d | ||
|
|
f9886d52da | ||
|
|
4f8e48b7d4 | ||
|
|
258e07c2ca | ||
|
|
cc32c50665 | ||
|
|
ec1d91f73e | ||
|
|
eb2f429964 | ||
|
|
1ad067309d | ||
|
|
48ce7df43a | ||
|
|
6555e2c440 | ||
|
|
a05191e112 | ||
|
|
b8eeee1d5d | ||
|
|
4aa87f3fa5 | ||
|
|
40c37d923b | ||
|
|
5a5837b8ed | ||
|
|
1e0b521070 | ||
|
|
35ed58cc5e | ||
|
|
c4a1579197 | ||
|
|
e471706422 | ||
|
|
d78b7350b5 | ||
|
|
47b29d5a49 | ||
|
|
e5946a51d1 | ||
|
|
a88798cc22 | ||
|
|
6fbd32523a | ||
|
|
94b1cc2bdd | ||
|
|
0ed5c8f0ae | ||
|
|
5f883f552b | ||
|
|
9db99ab4a5 | ||
|
|
287214c2b2 | ||
|
|
317a020841 | ||
|
|
b50e3aec5f | ||
|
|
21a9e0e2a7 | ||
|
|
7775df8ef1 | ||
|
|
53f9b5d131 | ||
|
|
bf4d4a4742 | ||
|
|
0dbbe7104d | ||
|
|
561ef00680 | ||
|
|
85428fa72e | ||
|
|
29d0593b86 | ||
|
|
ac524dd799 | ||
|
|
aba8b764b6 | ||
|
|
a9050e0f41 | ||
|
|
15ef84e238 | ||
|
|
09096fef5b | ||
|
|
19b08e1019 | ||
|
|
06d67642dd | ||
|
|
ceb6c450c0 | ||
|
|
a745e42cf5 | ||
|
|
462d6a4450 | ||
|
|
a2e39c5e2e | ||
|
|
ec899be3b5 | ||
|
|
c79ebfdd0a | ||
|
|
cd95e6c552 | ||
|
|
f676145302 | ||
|
|
0847267069 | ||
|
|
6fe1da1587 | ||
|
|
7ab555d869 | ||
|
|
4a35e9e60d | ||
|
|
5e8dfdfd9b | ||
|
|
278a1b8ab3 | ||
|
|
6cb03dded1 | ||
|
|
4752ec1b67 | ||
|
|
e641371544 | ||
|
|
8d9a7e9af1 | ||
|
|
2b8e9bf887 | ||
|
|
a16c55c679 | ||
|
|
9a72c40149 | ||
|
|
8424fc4c19 | ||
|
|
9f29a047a7 | ||
|
|
af4904ce8d | ||
|
|
6f2a323063 | ||
|
|
1da8ecfaac | ||
|
|
1ba386bbd2 | ||
|
|
d00d791cda | ||
|
|
51aabd7b21 | ||
|
|
7840c3bdc8 | ||
|
|
07d13002b0 | ||
|
|
23abe2ba06 | ||
|
|
4d73821d21 | ||
|
|
f2687cf807 | ||
|
|
8abce0d4cf | ||
|
|
62ad3848c4 | ||
|
|
521e9969f1 | ||
|
|
5ee1ceced3 | ||
|
|
efffbafa42 | ||
|
|
899cec8814 | ||
|
|
55beb993e5 | ||
|
|
fba46a1e00 | ||
|
|
68c4d6f295 | ||
|
|
2ad07c018e | ||
|
|
c2418559f1 | ||
|
|
de0277eb3b | ||
|
|
b58802b495 | ||
|
|
898e20e8b2 | ||
|
|
75bf10d83d | ||
|
|
e8e58cc4a2 | ||
|
|
342d02c8a8 | ||
|
|
ae885eaddc | ||
|
|
b75bb4ed9f | ||
|
|
a171863591 | ||
|
|
bcc2286018 | ||
|
|
beb8b9723f | ||
|
|
ab3129b9c3 | ||
|
|
c061505bf8 | ||
|
|
171bbedcde | ||
|
|
ae655727c0 | ||
|
|
288b3783c3 | ||
|
|
320612c826 | ||
|
|
9b0a293d2b | ||
|
|
d5b6f27e97 | ||
|
|
cf8bd759e3 | ||
|
|
c2142c5cd9 | ||
|
|
eeef536803 | ||
|
|
ec51cf7606 | ||
|
|
ec83b76e46 | ||
|
|
6bc73f8f43 | ||
|
|
65127e04aa | ||
|
|
2726045fb0 | ||
|
|
d4046c3295 | ||
|
|
97d4f5583c | ||
|
|
96dc36cd16 | ||
|
|
ab2344ebfc | ||
|
|
4dd7d86ea8 | ||
|
|
6adfa618a3 | ||
|
|
855e896a5a | ||
|
|
2bacb0f073 | ||
|
|
399131a5a9 | ||
|
|
4c77be9e83 | ||
|
|
8ed5463f19 | ||
|
|
63739df903 | ||
|
|
3d72232bb9 | ||
|
|
d5ff811de7 | ||
|
|
f74f47965c | ||
|
|
79adb7225e | ||
|
|
11e79914ef | ||
|
|
9b34fc369b | ||
|
|
ae812806a1 | ||
|
|
956c7728bf | ||
|
|
6d5a5a46e4 | ||
|
|
b244126d60 | ||
|
|
2a7f8c5229 | ||
|
|
59fddf7c59 | ||
|
|
d21fd2a1ed | ||
|
|
6828a5d9a0 | ||
|
|
32960332b9 | ||
|
|
9ba77c9498 | ||
|
|
65f9a9dcc1 | ||
|
|
13315eec42 | ||
|
|
e43ccd155b | ||
|
|
e92960a413 | ||
|
|
e82eec0cd6 | ||
|
|
23b687c528 | ||
|
|
5044a814a1 | ||
|
|
3250b95f5e | ||
|
|
2a0934ec28 | ||
|
|
f1752abc5d | ||
|
|
e931ec74dd | ||
|
|
528d823c55 | ||
|
|
6475b58541 | ||
|
|
59e8b26015 | ||
|
|
0894c21296 | ||
|
|
4223bdd4ad | ||
|
|
c55ed42b2b | ||
|
|
7abc833ebe | ||
|
|
6abe399e36 | ||
|
|
555b1a16da | ||
|
|
52b956e677 | ||
|
|
0296cbe9e9 | ||
|
|
8315d7790a | ||
|
|
dd60d289ff | ||
|
|
8c61fd0bf7 | ||
|
|
814e08edd4 | ||
|
|
44956dff85 | ||
|
|
18685d061a | ||
|
|
692d5be166 | ||
|
|
60bdaef716 | ||
|
|
cb51f44a45 | ||
|
|
88f43a8124 | ||
|
|
7de7cdba60 | ||
|
|
ba140c60e3 | ||
|
|
95a5c7a001 | ||
|
|
b399da72d8 | ||
|
|
f9a10d8932 | ||
|
|
549ce6fbf9 | ||
|
|
e63d27a035 | ||
|
|
ab3621fe3c | ||
|
|
8b99f2ecbc | ||
|
|
433b309907 | ||
|
|
ac40cec138 | ||
|
|
93702ece48 | ||
|
|
1678474830 | ||
|
|
4260099c23 | ||
|
|
6139cb50bc | ||
|
|
49e334d726 | ||
|
|
6beded153b | ||
|
|
750308a16a | ||
|
|
57fa00b765 | ||
|
|
b57d4fdbec | ||
|
|
93aca81265 | ||
|
|
5c704e142e | ||
|
|
1a4a77066e | ||
|
|
a690b9d825 | ||
|
|
b70969fd03 | ||
|
|
daf5fff83f | ||
|
|
aef1f9b857 | ||
|
|
c1c8ea7df0 | ||
|
|
b75034b40c | ||
|
|
cb41a79b36 | ||
|
|
cedc20ce6a | ||
|
|
43bc1e9116 | ||
|
|
6fa1379c1e | ||
|
|
cb16438b1c | ||
|
|
e6c8d6cc7d | ||
|
|
f0e87e71ab | ||
|
|
cdd28b8e31 | ||
|
|
9bff564ace | ||
|
|
62c616c6af | ||
|
|
8a35f5d6ca | ||
|
|
e1b051324d | ||
|
|
a947c3152a | ||
|
|
cca43040d3 | ||
|
|
9b42657ca7 | ||
|
|
bb19c55c3a | ||
|
|
1ec6611410 | ||
|
|
218bd0ffc1 | ||
|
|
d649a22b80 | ||
|
|
0bffbbfe65 | ||
|
|
04a562372b | ||
|
|
11b08ce53a | ||
|
|
70f8f9679d | ||
|
|
4773f9ebf6 | ||
|
|
c1b6d1706a | ||
|
|
9f94b8f915 | ||
|
|
3abd97d0fb | ||
|
|
416a0687ee | ||
|
|
7056e20075 | ||
|
|
de4b158a44 | ||
|
|
c7f4648d5a | ||
|
|
a456be9d76 | ||
|
|
3befaac114 | ||
|
|
11616ee03b | ||
|
|
2a59feddb6 | ||
|
|
e2fa0aface | ||
|
|
6d4d954713 | ||
|
|
a4592ca425 | ||
|
|
700eae4cc6 | ||
|
|
2c9fe6f37d | ||
|
|
558ede11cf | ||
|
|
4c0a68ab0b | ||
|
|
d6b4931001 | ||
|
|
79ef01cb25 | ||
|
|
ea8735f390 | ||
|
|
7b70855e94 | ||
|
|
65f818b631 | ||
|
|
0a0baeaeab | ||
|
|
e011ed1f64 |
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
arrowParens: 'avoid',
|
||||
jsxSingleQuote: true,
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: 'es5',
|
||||
}
|
||||
|
||||
45
@vates/decorate-with/README.md
Normal file
45
@vates/decorate-with/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @vates/decorate-with
|
||||
|
||||
[](https://npmjs.org/package/@vates/decorate-with)  [](https://bundlephobia.com/result?p=@vates/decorate-with) [](https://npmjs.org/package/@vates/decorate-with)
|
||||
|
||||
> Creates a decorator from a function wrapper
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@vates/decorate-with):
|
||||
|
||||
```
|
||||
> npm install --save @vates/decorate-with
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
For instance, allows using Lodash's functions as decorators:
|
||||
|
||||
```js
|
||||
import { decorateWith } from '@vates/decorate-with'
|
||||
|
||||
class Foo {
|
||||
@decorateWith(lodash.debounce, 150)
|
||||
bar() {
|
||||
// body
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
12
@vates/decorate-with/USAGE.md
Normal file
12
@vates/decorate-with/USAGE.md
Normal file
@@ -0,0 +1,12 @@
|
||||
For instance, allows using Lodash's functions as decorators:
|
||||
|
||||
```js
|
||||
import { decorateWith } from '@vates/decorate-with'
|
||||
|
||||
class Foo {
|
||||
@decorateWith(lodash.debounce, 150)
|
||||
bar() {
|
||||
// body
|
||||
}
|
||||
}
|
||||
```
|
||||
4
@vates/decorate-with/index.js
Normal file
4
@vates/decorate-with/index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
exports.decorateWith = (fn, ...args) => (target, name, descriptor) => ({
|
||||
...descriptor,
|
||||
value: fn(descriptor.value, ...args),
|
||||
})
|
||||
30
@vates/decorate-with/package.json
Normal file
30
@vates/decorate-with/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@vates/decorate-with",
|
||||
"description": "Creates a decorator from a function wrapper",
|
||||
"keywords": [
|
||||
"apply",
|
||||
"decorator",
|
||||
"factory",
|
||||
"wrapper"
|
||||
],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@vates/decorate-with",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@vates/decorate-with",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"license": "ISC",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
}
|
||||
}
|
||||
47
@vates/parse-duration/README.md
Normal file
47
@vates/parse-duration/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @vates/parse-duration
|
||||
|
||||
[](https://npmjs.org/package/@vates/parse-duration)  [](https://bundlephobia.com/result?p=@vates/parse-duration) [](https://npmjs.org/package/@vates/parse-duration)
|
||||
|
||||
> Small wrapper around ms to parse a duration
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@vates/parse-duration):
|
||||
|
||||
```
|
||||
> npm install --save @vates/parse-duration
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`ms` without magic: always parse a duration and throws if invalid.
|
||||
|
||||
```js
|
||||
import { parseDuration } from '@vates/parse-duration'
|
||||
|
||||
parseDuration('2 days')
|
||||
// 172800000
|
||||
|
||||
parseDuration(172800000)
|
||||
// 172800000
|
||||
|
||||
parseDuration(undefined)
|
||||
// throws TypeError('not a valid duration: undefined')
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
14
@vates/parse-duration/USAGE.md
Normal file
14
@vates/parse-duration/USAGE.md
Normal file
@@ -0,0 +1,14 @@
|
||||
`ms` without magic: always parse a duration and throws if invalid.
|
||||
|
||||
```js
|
||||
import { parseDuration } from '@vates/parse-duration'
|
||||
|
||||
parseDuration('2 days')
|
||||
// 172800000
|
||||
|
||||
parseDuration(172800000)
|
||||
// 172800000
|
||||
|
||||
parseDuration(undefined)
|
||||
// throws TypeError('not a valid duration: undefined')
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
import ms from 'ms'
|
||||
const ms = require('ms')
|
||||
|
||||
export default value => {
|
||||
exports.parseDuration = value => {
|
||||
if (typeof value === 'number') {
|
||||
return value
|
||||
}
|
||||
32
@vates/parse-duration/package.json
Normal file
32
@vates/parse-duration/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@vates/parse-duration",
|
||||
"description": "Small wrapper around ms to parse a duration",
|
||||
"keywords": [
|
||||
"duration",
|
||||
"ms",
|
||||
"parse"
|
||||
],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@vates/parse-duration",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@vates/parse-duration",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"version": "0.1.0",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": "^2.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
}
|
||||
}
|
||||
46
@vates/read-chunk/README.md
Normal file
46
@vates/read-chunk/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @vates/read-chunk
|
||||
|
||||
[](https://npmjs.org/package/@vates/read-chunk)  [](https://bundlephobia.com/result?p=@vates/read-chunk) [](https://npmjs.org/package/@vates/read-chunk)
|
||||
|
||||
> Read a chunk of a Node stream
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@vates/read-chunk):
|
||||
|
||||
```
|
||||
> npm install --save @vates/read-chunk
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
- returns the next available chunk of data
|
||||
- like `stream.read()`, a number of bytes can be specified
|
||||
- returns `null` if the stream has ended
|
||||
|
||||
```js
|
||||
import { readChunk } from '@vates/read-chunk'
|
||||
;(async () => {
|
||||
let chunk
|
||||
while ((chunk = await readChunk(stream, 1024)) !== null) {
|
||||
// do something with chunk
|
||||
}
|
||||
})()
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
13
@vates/read-chunk/USAGE.md
Normal file
13
@vates/read-chunk/USAGE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
- returns the next available chunk of data
|
||||
- like `stream.read()`, a number of bytes can be specified
|
||||
- returns `null` if the stream has ended
|
||||
|
||||
```js
|
||||
import { readChunk } from '@vates/read-chunk'
|
||||
;(async () => {
|
||||
let chunk
|
||||
while ((chunk = await readChunk(stream, 1024)) !== null) {
|
||||
// do something with chunk
|
||||
}
|
||||
})()
|
||||
```
|
||||
27
@vates/read-chunk/index.js
Normal file
27
@vates/read-chunk/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
exports.readChunk = (stream, size) =>
|
||||
new Promise((resolve, reject) => {
|
||||
function onEnd() {
|
||||
resolve(null)
|
||||
removeListeners()
|
||||
}
|
||||
function onError(error) {
|
||||
reject(error)
|
||||
removeListeners()
|
||||
}
|
||||
function onReadable() {
|
||||
const data = stream.read(size)
|
||||
if (data !== null) {
|
||||
resolve(data)
|
||||
removeListeners()
|
||||
}
|
||||
}
|
||||
function removeListeners() {
|
||||
stream.removeListener('end', onEnd)
|
||||
stream.removeListener('error', onError)
|
||||
stream.removeListener('readable', onReadable)
|
||||
}
|
||||
stream.on('end', onEnd)
|
||||
stream.on('error', onError)
|
||||
stream.on('readable', onReadable)
|
||||
onReadable()
|
||||
})
|
||||
33
@vates/read-chunk/package.json
Normal file
33
@vates/read-chunk/package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@vates/read-chunk",
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@vates/read-chunk",
|
||||
"description": "Read a chunk of a Node stream",
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"async",
|
||||
"chunk",
|
||||
"data",
|
||||
"node",
|
||||
"promise",
|
||||
"read",
|
||||
"stream"
|
||||
],
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@vates/read-chunk",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
# @xen-orchestra/async-map [](https://travis-ci.org/vatesfr/xen-orchestra)
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
> ${pkg.description}
|
||||
# @xen-orchestra/async-map
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/async-map)  [](https://bundlephobia.com/result?p=@xen-orchestra/async-map) [](https://npmjs.org/package/@xen-orchestra/async-map)
|
||||
|
||||
> Similar to Promise.all + lodash.map but wait for all promises to be settled
|
||||
|
||||
## Install
|
||||
|
||||
@@ -12,25 +16,10 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/async
|
||||
|
||||
## Usage
|
||||
|
||||
**TODO**
|
||||
```js
|
||||
import asyncMap from '@xen-orchestra/async-map'
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
const array = await asyncMap(collection, iteratee)
|
||||
```
|
||||
|
||||
## Contributions
|
||||
@@ -46,4 +35,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
5
@xen-orchestra/async-map/USAGE.md
Normal file
5
@xen-orchestra/async-map/USAGE.md
Normal file
@@ -0,0 +1,5 @@
|
||||
```js
|
||||
import asyncMap from '@xen-orchestra/async-map'
|
||||
|
||||
const array = await asyncMap(collection, iteratee)
|
||||
```
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/async-map",
|
||||
"version": "0.0.0",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"description": "Similar to Promise.all + lodash.map but wait for all promises to be settled",
|
||||
"keywords": [],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/async-map",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
@@ -12,8 +13,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@isonoe.net"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -36,7 +37,7 @@
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
3
@xen-orchestra/audit-core/.babelrc.js
Normal file
3
@xen-orchestra/audit-core/.babelrc.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = require('../../@xen-orchestra/babel-config')(
|
||||
require('./package.json')
|
||||
)
|
||||
24
@xen-orchestra/audit-core/.npmignore
Normal file
24
@xen-orchestra/audit-core/.npmignore
Normal file
@@ -0,0 +1,24 @@
|
||||
/benchmark/
|
||||
/benchmarks/
|
||||
*.bench.js
|
||||
*.bench.js.map
|
||||
|
||||
/examples/
|
||||
example.js
|
||||
example.js.map
|
||||
*.example.js
|
||||
*.example.js.map
|
||||
|
||||
/fixture/
|
||||
/fixtures/
|
||||
*.fixture.js
|
||||
*.fixture.js.map
|
||||
*.fixtures.js
|
||||
*.fixtures.js.map
|
||||
|
||||
/test/
|
||||
/tests/
|
||||
*.spec.js
|
||||
*.spec.js.map
|
||||
|
||||
__snapshots__/
|
||||
28
@xen-orchestra/audit-core/README.md
Normal file
28
@xen-orchestra/audit-core/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/audit-core
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/audit-core)  [](https://bundlephobia.com/result?p=@xen-orchestra/audit-core) [](https://npmjs.org/package/@xen-orchestra/audit-core)
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/audit-core):
|
||||
|
||||
```
|
||||
> npm install --save @xen-orchestra/audit-core
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/audit-core/USAGE.md
Normal file
0
@xen-orchestra/audit-core/USAGE.md
Normal file
44
@xen-orchestra/audit-core/package.json
Normal file
44
@xen-orchestra/audit-core/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@xen-orchestra/audit-core",
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/audit-core",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@xen-orchestra/audit-core",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"main": "dist/",
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
|
||||
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
|
||||
"postversion": "npm publish --access public",
|
||||
"prebuild": "rimraf dist/",
|
||||
"predev": "yarn run prebuild",
|
||||
"prepublishOnly": "yarn run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.7.4",
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/plugin-proposal-decorators": "^7.8.0",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.0",
|
||||
"@babel/preset-env": "^7.7.4",
|
||||
"cross": "^1.0.0",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.4",
|
||||
"golike-defer": "^0.4.1",
|
||||
"lodash": "^4.17.15",
|
||||
"object-hash": "^2.0.1"
|
||||
},
|
||||
"private": false,
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
142
@xen-orchestra/audit-core/src/index.js
Normal file
142
@xen-orchestra/audit-core/src/index.js
Normal file
@@ -0,0 +1,142 @@
|
||||
// see https://github.com/babel/babel/issues/8450
|
||||
import 'core-js/features/symbol/async-iterator'
|
||||
|
||||
import assert from 'assert'
|
||||
import defer from 'golike-defer'
|
||||
import hash from 'object-hash'
|
||||
|
||||
export class Storage {
|
||||
constructor() {
|
||||
this._lock = Promise.resolve()
|
||||
}
|
||||
|
||||
async acquireLock() {
|
||||
const lock = this._lock
|
||||
let releaseLock
|
||||
this._lock = new Promise(resolve => {
|
||||
releaseLock = resolve
|
||||
})
|
||||
await lock
|
||||
return releaseLock
|
||||
}
|
||||
}
|
||||
|
||||
// Format: $<algorithm>$<salt>$<encrypted>
|
||||
//
|
||||
// http://man7.org/linux/man-pages/man3/crypt.3.html#NOTES
|
||||
const ID_TO_ALGORITHM = {
|
||||
'5': 'sha256',
|
||||
}
|
||||
|
||||
export class AlteredRecordError extends Error {
|
||||
constructor(id, nValid, record) {
|
||||
super('altered record')
|
||||
|
||||
this.id = id
|
||||
this.nValid = nValid
|
||||
this.record = record
|
||||
}
|
||||
}
|
||||
|
||||
export class MissingRecordError extends Error {
|
||||
constructor(id, nValid) {
|
||||
super('missing record')
|
||||
|
||||
this.id = id
|
||||
this.nValid = nValid
|
||||
}
|
||||
}
|
||||
|
||||
export const NULL_ID = 'nullId'
|
||||
|
||||
const HASH_ALGORITHM_ID = '5'
|
||||
const createHash = (data, algorithmId = HASH_ALGORITHM_ID) =>
|
||||
`$${algorithmId}$$${hash(data, {
|
||||
algorithm: ID_TO_ALGORITHM[algorithmId],
|
||||
excludeKeys: key => key === 'id',
|
||||
})}`
|
||||
|
||||
export class AuditCore {
|
||||
constructor(storage) {
|
||||
assert.notStrictEqual(storage, undefined)
|
||||
this._storage = storage
|
||||
}
|
||||
|
||||
@defer
|
||||
async add($defer, subject, event, data) {
|
||||
const time = Date.now()
|
||||
const storage = this._storage
|
||||
$defer(await storage.acquireLock())
|
||||
|
||||
// delete "undefined" properties and normalize data with JSON.stringify
|
||||
const record = JSON.parse(
|
||||
JSON.stringify({
|
||||
data,
|
||||
event,
|
||||
previousId: (await storage.getLastId()) ?? NULL_ID,
|
||||
subject,
|
||||
time,
|
||||
})
|
||||
)
|
||||
record.id = createHash(record)
|
||||
await storage.put(record)
|
||||
await storage.setLastId(record.id)
|
||||
return record
|
||||
}
|
||||
|
||||
async checkIntegrity(oldest, newest) {
|
||||
const storage = this._storage
|
||||
|
||||
// handle separated chains case
|
||||
if (newest !== (await storage.getLastId())) {
|
||||
let isNewestAccessible = false
|
||||
for await (const { id } of this.getFrom()) {
|
||||
if (id === newest) {
|
||||
isNewestAccessible = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isNewestAccessible) {
|
||||
throw new MissingRecordError(newest, 0)
|
||||
}
|
||||
}
|
||||
|
||||
let nValid = 0
|
||||
while (newest !== oldest) {
|
||||
const record = await storage.get(newest)
|
||||
if (record === undefined) {
|
||||
throw new MissingRecordError(newest, nValid)
|
||||
}
|
||||
if (
|
||||
newest !== createHash(record, newest.slice(1, newest.indexOf('$', 1)))
|
||||
) {
|
||||
throw new AlteredRecordError(newest, nValid, record)
|
||||
}
|
||||
newest = record.previousId
|
||||
nValid++
|
||||
}
|
||||
return nValid
|
||||
}
|
||||
|
||||
async *getFrom(newest) {
|
||||
const storage = this._storage
|
||||
|
||||
let id = newest ?? (await storage.getLastId())
|
||||
if (id === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
let record
|
||||
while ((record = await storage.get(id)) !== undefined) {
|
||||
yield record
|
||||
id = record.previousId
|
||||
}
|
||||
}
|
||||
|
||||
async deleteFrom(newest) {
|
||||
assert.notStrictEqual(newest, undefined)
|
||||
for await (const { id } of this.getFrom(newest)) {
|
||||
await this._storage.del(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
126
@xen-orchestra/audit-core/src/index.spec.js
Normal file
126
@xen-orchestra/audit-core/src/index.spec.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/* eslint-env jest */
|
||||
|
||||
import {
|
||||
AlteredRecordError,
|
||||
AuditCore,
|
||||
MissingRecordError,
|
||||
NULL_ID,
|
||||
Storage,
|
||||
} from '.'
|
||||
|
||||
const asyncIteratorToArray = async asyncIterator => {
|
||||
const array = []
|
||||
for await (const entry of asyncIterator) {
|
||||
array.push(entry)
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
class DB extends Storage {
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
this._db = new Map()
|
||||
this._lastId = undefined
|
||||
}
|
||||
|
||||
async put(record) {
|
||||
this._db.set(record.id, record)
|
||||
}
|
||||
|
||||
async setLastId(id) {
|
||||
this._lastId = id
|
||||
}
|
||||
|
||||
async getLastId() {
|
||||
return this._lastId
|
||||
}
|
||||
|
||||
async del(id) {
|
||||
this._db.delete(id)
|
||||
}
|
||||
|
||||
async get(id) {
|
||||
return this._db.get(id)
|
||||
}
|
||||
|
||||
_clear() {
|
||||
return this._db.clear()
|
||||
}
|
||||
}
|
||||
|
||||
const DATA = [
|
||||
[
|
||||
{
|
||||
name: 'subject0',
|
||||
},
|
||||
'event0',
|
||||
{},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'subject1',
|
||||
},
|
||||
'event1',
|
||||
{},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'subject2',
|
||||
},
|
||||
'event2',
|
||||
{},
|
||||
],
|
||||
]
|
||||
|
||||
const db = new DB()
|
||||
const auditCore = new AuditCore(db)
|
||||
const storeAuditRecords = async () => {
|
||||
await Promise.all(DATA.map(data => auditCore.add(...data)))
|
||||
const records = await asyncIteratorToArray(auditCore.getFrom())
|
||||
expect(records.length).toBe(DATA.length)
|
||||
return records
|
||||
}
|
||||
|
||||
describe('auditCore', () => {
|
||||
afterEach(() => db._clear())
|
||||
|
||||
it('detects that a record is missing', async () => {
|
||||
const [newestRecord, deletedRecord] = await storeAuditRecords()
|
||||
|
||||
const nValidRecords = await auditCore.checkIntegrity(
|
||||
NULL_ID,
|
||||
newestRecord.id
|
||||
)
|
||||
expect(nValidRecords).toBe(DATA.length)
|
||||
|
||||
await db.del(deletedRecord.id)
|
||||
await expect(
|
||||
auditCore.checkIntegrity(NULL_ID, newestRecord.id)
|
||||
).rejects.toEqual(new MissingRecordError(deletedRecord.id, 1))
|
||||
})
|
||||
|
||||
it('detects that a record has been altered', async () => {
|
||||
const [newestRecord, alteredRecord] = await storeAuditRecords()
|
||||
|
||||
alteredRecord.event = ''
|
||||
await db.put(alteredRecord)
|
||||
|
||||
await expect(
|
||||
auditCore.checkIntegrity(NULL_ID, newestRecord.id)
|
||||
).rejects.toEqual(
|
||||
new AlteredRecordError(alteredRecord.id, 1, alteredRecord)
|
||||
)
|
||||
})
|
||||
|
||||
it('confirms interval integrity after deletion of records outside of the interval', async () => {
|
||||
const [thirdRecord, secondRecord, firstRecord] = await storeAuditRecords()
|
||||
|
||||
await auditCore.deleteFrom(secondRecord.id)
|
||||
|
||||
expect(await db.get(firstRecord.id)).toBe(undefined)
|
||||
expect(await db.get(secondRecord.id)).toBe(undefined)
|
||||
|
||||
await auditCore.checkIntegrity(secondRecord.id, thirdRecord.id)
|
||||
})
|
||||
})
|
||||
25
@xen-orchestra/audit-core/src/specification.ts
Normal file
25
@xen-orchestra/audit-core/src/specification.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
class Storage {
|
||||
acquire: () => Promise<() => undefined>
|
||||
del: (id: string) => Promise<void>
|
||||
get: (id: string) => Promise<Record | void>
|
||||
getLastId: () => Promise<string | void>
|
||||
put: (record: Record) => Promise<void>
|
||||
setLastId: (id: string) => Promise<void>
|
||||
}
|
||||
|
||||
interface Record {
|
||||
data: object
|
||||
event: string
|
||||
id: string
|
||||
previousId: string
|
||||
subject: object
|
||||
time: number
|
||||
}
|
||||
|
||||
export class AuditCore {
|
||||
constructor(storage: Storage) {}
|
||||
public add(subject: any, event: string, data: any): Promise<Record> {}
|
||||
public checkIntegrity(oldest: string, newest: string): Promise<number> {}
|
||||
public getFrom(newest?: string): AsyncIterator {}
|
||||
public deleteFrom(newest: string): Promise<void> {}
|
||||
}
|
||||
18
@xen-orchestra/babel-config/README.md
Normal file
18
@xen-orchestra/babel-config/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/babel-config
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/babel-config/USAGE.md
Normal file
0
@xen-orchestra/babel-config/USAGE.md
Normal file
@@ -32,7 +32,6 @@ const configs = {
|
||||
}
|
||||
return { browsers: pkg.browserslist, node }
|
||||
})(),
|
||||
useBuiltIns: '@babel/polyfill' in (pkg.dependencies || {}) && 'usage',
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -52,7 +51,7 @@ const pluginsOrder = [
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
]
|
||||
|
||||
module.exports = function(pkg, plugins, presets) {
|
||||
module.exports = function (pkg, plugins, presets) {
|
||||
plugins === undefined && (plugins = {})
|
||||
presets === undefined && (presets = {})
|
||||
|
||||
|
||||
@@ -11,5 +11,10 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
|
||||
28
@xen-orchestra/backups-cli/README.md
Normal file
28
@xen-orchestra/backups-cli/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/backups-cli
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/backups-cli)  [](https://bundlephobia.com/result?p=@xen-orchestra/backups-cli) [](https://npmjs.org/package/@xen-orchestra/backups-cli)
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/backups-cli):
|
||||
|
||||
```
|
||||
> npm install --global @xen-orchestra/backups-cli
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/backups-cli/USAGE.md
Normal file
0
@xen-orchestra/backups-cli/USAGE.md
Normal file
@@ -3,7 +3,7 @@ const getopts = require('getopts')
|
||||
const { version } = require('./package.json')
|
||||
|
||||
module.exports = commands =>
|
||||
async function(args, prefix) {
|
||||
async function (args, prefix) {
|
||||
const opts = getopts(args, {
|
||||
alias: {
|
||||
help: 'h',
|
||||
|
||||
@@ -34,14 +34,15 @@ fs.readdir2 = path =>
|
||||
return entries
|
||||
},
|
||||
error => {
|
||||
if (
|
||||
error != null &&
|
||||
(error.code === 'ENOENT' || error.code === 'ENOTDIR')
|
||||
) {
|
||||
const { code } = error
|
||||
if (code === 'ENOENT') {
|
||||
// do nothing
|
||||
} else if (code === 'ENOTDIR') {
|
||||
console.warn('WARN: readdir(%s)', path, error)
|
||||
return []
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
throw error
|
||||
return []
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ const pipe = require('promise-toolbox/pipe')
|
||||
const { default: Vhd } = require('vhd-lib')
|
||||
const { dirname, resolve } = require('path')
|
||||
const { DISK_TYPE_DIFFERENCING } = require('vhd-lib/dist/_constants')
|
||||
const { isValidXva } = require('@xen-orchestra/backups/isValidXva')
|
||||
|
||||
const asyncMap = require('../_asyncMap')
|
||||
const fs = require('../_fs')
|
||||
@@ -21,70 +22,6 @@ const handler = require('@xen-orchestra/fs').getHandler({ url: 'file://' })
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const isGzipFile = async fd => {
|
||||
// https://tools.ietf.org/html/rfc1952.html#page-5
|
||||
const magicNumber = Buffer.allocUnsafe(2)
|
||||
assert.strictEqual(
|
||||
await fs.read(fd, magicNumber, 0, magicNumber.length, 0),
|
||||
magicNumber.length
|
||||
)
|
||||
return magicNumber[0] === 31 && magicNumber[1] === 139
|
||||
}
|
||||
|
||||
// TODO: better check?
|
||||
//
|
||||
// our heuristic is not good enough, there has been some false positives
|
||||
// (detected as invalid by us but valid by `tar` and imported with success),
|
||||
// either THOUGH THEY MAY HAVE BEEN COMPRESSED FILES:
|
||||
// - these files were normal but the check is incorrect
|
||||
// - these files were invalid but without data loss
|
||||
// - these files were invalid but with silent data loss
|
||||
//
|
||||
// maybe reading the end of the file looking for a file named
|
||||
// /^Ref:\d+/\d+\.checksum$/ and then validating the tar structure from it
|
||||
//
|
||||
// https://github.com/npm/node-tar/issues/234#issuecomment-538190295
|
||||
const isValidTar = async (size, fd) => {
|
||||
if (size <= 1024 || size % 512 !== 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const buf = Buffer.allocUnsafe(1024)
|
||||
assert.strictEqual(
|
||||
await fs.read(fd, buf, 0, buf.length, size - buf.length),
|
||||
buf.length
|
||||
)
|
||||
return buf.every(_ => _ === 0)
|
||||
}
|
||||
|
||||
// TODO: find an heuristic for compressed files
|
||||
const isValidXva = async path => {
|
||||
try {
|
||||
const fd = await fs.open(path, 'r')
|
||||
try {
|
||||
const { size } = await fs.fstat(fd)
|
||||
if (size < 20) {
|
||||
// neither a valid gzip not tar
|
||||
return false
|
||||
}
|
||||
|
||||
return (await isGzipFile(fd))
|
||||
? true // gzip files cannot be validated at this time
|
||||
: await isValidTar(size, fd)
|
||||
} finally {
|
||||
fs.close(fd).catch(noop)
|
||||
}
|
||||
} catch (error) {
|
||||
// never throw, log and report as valid to avoid side effects
|
||||
console.error('isValidXva', path, error)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const noop = Function.prototype
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// chain is an array of VHDs from child to parent
|
||||
//
|
||||
// the whole chain will be merged into parent, parent will be renamed to child
|
||||
@@ -215,11 +152,12 @@ async function handleVm(vmDir) {
|
||||
await Promise.all(deletions)
|
||||
}
|
||||
|
||||
const [jsons, xvas] = await fs
|
||||
const [jsons, xvas, xvaSums] = await fs
|
||||
.readdir2(vmDir)
|
||||
.then(entries => [
|
||||
entries.filter(_ => _.endsWith('.json')),
|
||||
new Set(entries.filter(_ => _.endsWith('.xva'))),
|
||||
entries.filter(_ => _.endsWith('.xva.cheksum')),
|
||||
])
|
||||
|
||||
await asyncMap(xvas, async path => {
|
||||
@@ -337,6 +275,15 @@ async function handleVm(vmDir) {
|
||||
console.warn('')
|
||||
return force && handler.unlink(path)
|
||||
}),
|
||||
asyncMap(xvaSums, path => {
|
||||
// no need to handle checksums for XVAs deleted by the script, they will be handled by `unlink()`
|
||||
if (!xvas.has(path.slice(0, -'.checksum'.length))) {
|
||||
console.warn('Unused XVA checksum', path)
|
||||
force && console.warn(' deleting…')
|
||||
console.warn('')
|
||||
return force && handler.unlink(path)
|
||||
}
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
{
|
||||
"private": false,
|
||||
"bin": {
|
||||
"xo-backups": "index.js"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"dependencies": {
|
||||
"@xen-orchestra/fs": "^0.10.2",
|
||||
"@xen-orchestra/backups": "^0.1.1",
|
||||
"@xen-orchestra/fs": "^0.10.4",
|
||||
"filenamify": "^4.1.0",
|
||||
"getopts": "^2.2.5",
|
||||
"lodash": "^4.17.15",
|
||||
@@ -15,6 +18,10 @@
|
||||
"engines": {
|
||||
"node": ">=7.10.1"
|
||||
},
|
||||
"files": [
|
||||
"commands",
|
||||
"*.js"
|
||||
],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/backups-cli",
|
||||
"name": "@xen-orchestra/backups-cli",
|
||||
"repository": {
|
||||
@@ -25,5 +32,10 @@
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
},
|
||||
"version": "0.0.0"
|
||||
"version": "0.0.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
|
||||
28
@xen-orchestra/backups/README.md
Normal file
28
@xen-orchestra/backups/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/backups
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/backups)  [](https://bundlephobia.com/result?p=@xen-orchestra/backups) [](https://npmjs.org/package/@xen-orchestra/backups)
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/backups):
|
||||
|
||||
```
|
||||
> npm install --save @xen-orchestra/backups
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/backups/USAGE.md
Normal file
0
@xen-orchestra/backups/USAGE.md
Normal file
30
@xen-orchestra/backups/extractIdsFromSimplePattern.js
Normal file
30
@xen-orchestra/backups/extractIdsFromSimplePattern.js
Normal file
@@ -0,0 +1,30 @@
|
||||
function extractIdsFromSimplePattern(pattern) {
|
||||
if (pattern === undefined) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (pattern !== null && typeof pattern === 'object') {
|
||||
let keys = Object.keys(pattern)
|
||||
|
||||
if (keys.length === 1 && keys[0] === 'id') {
|
||||
pattern = pattern.id
|
||||
if (typeof pattern === 'string') {
|
||||
return [pattern]
|
||||
}
|
||||
if (pattern !== null && typeof pattern === 'object') {
|
||||
keys = Object.keys(pattern)
|
||||
if (
|
||||
keys.length === 1 &&
|
||||
keys[0] === '__or' &&
|
||||
Array.isArray((pattern = pattern.__or)) &&
|
||||
pattern.every(_ => typeof _ === 'string')
|
||||
) {
|
||||
return pattern
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('invalid pattern')
|
||||
}
|
||||
exports.extractIdsFromSimplePattern = extractIdsFromSimplePattern
|
||||
6
@xen-orchestra/backups/filenameDate.js
Normal file
6
@xen-orchestra/backups/filenameDate.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const { utcFormat, utcParse } = require('d3-time-format')
|
||||
|
||||
// Format a date in ISO 8601 in a safe way to be used in filenames
|
||||
// (even on Windows).
|
||||
exports.formatFilenameDate = utcFormat('%Y%m%dT%H%M%SZ')
|
||||
exports.parseFilenameDate = utcParse('%Y%m%dT%H%M%SZ')
|
||||
7
@xen-orchestra/backups/getOldEntries.js
Normal file
7
@xen-orchestra/backups/getOldEntries.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// returns all entries but the last retention-th
|
||||
exports.getOldEntries = (retention, entries) =>
|
||||
entries === undefined
|
||||
? []
|
||||
: retention > 0
|
||||
? entries.slice(0, -retention)
|
||||
: entries
|
||||
65
@xen-orchestra/backups/isValidXva.js
Normal file
65
@xen-orchestra/backups/isValidXva.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const assert = require('assert')
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const isGzipFile = async fd => {
|
||||
// https://tools.ietf.org/html/rfc1952.html#page-5
|
||||
const magicNumber = Buffer.allocUnsafe(2)
|
||||
assert.strictEqual(
|
||||
(await fs.read(fd, magicNumber, 0, magicNumber.length, 0)).bytesRead,
|
||||
magicNumber.length
|
||||
)
|
||||
return magicNumber[0] === 31 && magicNumber[1] === 139
|
||||
}
|
||||
|
||||
// TODO: better check?
|
||||
//
|
||||
// our heuristic is not good enough, there has been some false positives
|
||||
// (detected as invalid by us but valid by `tar` and imported with success),
|
||||
// either THOUGH THEY MAY HAVE BEEN COMPRESSED FILES:
|
||||
// - these files were normal but the check is incorrect
|
||||
// - these files were invalid but without data loss
|
||||
// - these files were invalid but with silent data loss
|
||||
//
|
||||
// maybe reading the end of the file looking for a file named
|
||||
// /^Ref:\d+/\d+\.checksum$/ and then validating the tar structure from it
|
||||
//
|
||||
// https://github.com/npm/node-tar/issues/234#issuecomment-538190295
|
||||
const isValidTar = async (size, fd) => {
|
||||
if (size <= 1024 || size % 512 !== 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const buf = Buffer.allocUnsafe(1024)
|
||||
assert.strictEqual(
|
||||
(await fs.read(fd, buf, 0, buf.length, size - buf.length)).bytesRead,
|
||||
buf.length
|
||||
)
|
||||
return buf.every(_ => _ === 0)
|
||||
}
|
||||
|
||||
// TODO: find an heuristic for compressed files
|
||||
const isValidXva = async path => {
|
||||
try {
|
||||
const fd = await fs.open(path, 'r')
|
||||
try {
|
||||
const { size } = await fs.fstat(fd)
|
||||
if (size < 20) {
|
||||
// neither a valid gzip not tar
|
||||
return false
|
||||
}
|
||||
|
||||
return (await isGzipFile(fd))
|
||||
? true // gzip files cannot be validated at this time
|
||||
: await isValidTar(size, fd)
|
||||
} finally {
|
||||
fs.close(fd).catch(noop)
|
||||
}
|
||||
} catch (error) {
|
||||
// never throw, log and report as valid to avoid side effects
|
||||
console.error('isValidXva', path, error)
|
||||
return true
|
||||
}
|
||||
}
|
||||
exports.isValidXva = isValidXva
|
||||
|
||||
const noop = Function.prototype
|
||||
27
@xen-orchestra/backups/package.json
Normal file
27
@xen-orchestra/backups/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/backups",
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/backups",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@xen-orchestra/backups",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-time-format": "^2.2.3",
|
||||
"fs-extra": "^9.0.0"
|
||||
},
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
11
@xen-orchestra/backups/watchStreamSize.js
Normal file
11
@xen-orchestra/backups/watchStreamSize.js
Normal file
@@ -0,0 +1,11 @@
|
||||
exports.watchStreamSize = stream => {
|
||||
const container = { size: 0 }
|
||||
const isPaused = stream.isPaused()
|
||||
stream.on('data', data => {
|
||||
container.size += data.length
|
||||
})
|
||||
if (isPaused) {
|
||||
stream.pause()
|
||||
}
|
||||
return container
|
||||
}
|
||||
28
@xen-orchestra/cr-seed-cli/README.md
Normal file
28
@xen-orchestra/cr-seed-cli/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/cr-seed-cli
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/cr-seed-cli)  [](https://bundlephobia.com/result?p=@xen-orchestra/cr-seed-cli) [](https://npmjs.org/package/@xen-orchestra/cr-seed-cli)
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/cr-seed-cli):
|
||||
|
||||
```
|
||||
> npm install --global @xen-orchestra/cr-seed-cli
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/cr-seed-cli/USAGE.md
Normal file
0
@xen-orchestra/cr-seed-cli/USAGE.md
Normal file
@@ -5,7 +5,7 @@ const { NULL_REF, Xapi } = require('xen-api')
|
||||
|
||||
const pkg = require('./package.json')
|
||||
|
||||
Xapi.prototype.getVmDisks = async function(vm) {
|
||||
Xapi.prototype.getVmDisks = async function (vm) {
|
||||
const disks = { __proto__: null }
|
||||
await Promise.all([
|
||||
...vm.VBDs.map(async vbdRef => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/cr-seed-cli",
|
||||
"version": "0.2.0",
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/cr-seed-cli",
|
||||
@@ -14,11 +15,17 @@
|
||||
"bin": {
|
||||
"xo-cr-seed": "./index.js"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"golike-defer": "^0.4.1",
|
||||
"xen-api": "^0.27.3"
|
||||
"xen-api": "^0.28.5"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish"
|
||||
},
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# @xen-orchestra/cron [](https://travis-ci.org/vatesfr/xen-orchestra)
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/cron
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/cron)  [](https://bundlephobia.com/result?p=@xen-orchestra/cron) [](https://npmjs.org/package/@xen-orchestra/cron)
|
||||
|
||||
> Focused, well maintained, cron parser/scheduler
|
||||
|
||||
@@ -10,6 +14,8 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/cron)
|
||||
> npm install --save @xen-orchestra/cron
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Pattern syntax
|
||||
|
||||
```
|
||||
@@ -109,25 +115,6 @@ job.start()
|
||||
job.stop()
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -141,4 +128,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
98
@xen-orchestra/cron/USAGE.md
Normal file
98
@xen-orchestra/cron/USAGE.md
Normal file
@@ -0,0 +1,98 @@
|
||||
### Pattern syntax
|
||||
|
||||
```
|
||||
<minute> <hour> <day of month> <month> <day of week>
|
||||
```
|
||||
|
||||
Each entry can be:
|
||||
|
||||
- a single value
|
||||
- a range (`0-23` or `*/2`)
|
||||
- a list of values/ranges (`1,8-12`)
|
||||
|
||||
A wildcard (`*`) can be used as a shortcut for the whole range
|
||||
(`first-last`).
|
||||
|
||||
Step values can be used in conjunctions with ranges. For instance,
|
||||
`1-7/2` is the same as `1,3,5,7`.
|
||||
|
||||
| Field | Allowed values |
|
||||
| ---------------- | ------------------------------------------------------------------ |
|
||||
| minute | 0-59 |
|
||||
| hour | 0-23 |
|
||||
| day of the month | 1-31 or 3-letter names (`jan`, `feb`, …) |
|
||||
| month | 0-11 |
|
||||
| day of week | 0-7 (0 and 7 both mean Sunday) or 3-letter names (`mon`, `tue`, …) |
|
||||
|
||||
> Note: the month range is 0-11 to be compatible with
|
||||
> [cron](https://github.com/kelektiv/node-cron), it does not appear to
|
||||
> be very standard though.
|
||||
|
||||
### API
|
||||
|
||||
`createSchedule(pattern: string, zone: string = 'utc'): Schedule`
|
||||
|
||||
> Create a new schedule.
|
||||
|
||||
- `pattern`: the pattern to use, see [the syntax](#pattern-syntax)
|
||||
- `zone`: the timezone to use, use `'local'` for the local timezone
|
||||
|
||||
```js
|
||||
import { createSchedule } from '@xen-orchestra/cron'
|
||||
|
||||
const schedule = createSchedule('0 0 * * sun', 'America/New_York')
|
||||
```
|
||||
|
||||
`Schedule#createJob(fn: Function): Job`
|
||||
|
||||
> Create a new job from this schedule.
|
||||
|
||||
- `fn`: function to execute, if it returns a promise, it will be
|
||||
awaited before scheduling the next run.
|
||||
|
||||
```js
|
||||
const job = schedule.createJob(() => {
|
||||
console.log(new Date())
|
||||
})
|
||||
```
|
||||
|
||||
`Schedule#next(n: number): Array<Date>`
|
||||
|
||||
> Returns the next dates matching this schedule.
|
||||
|
||||
- `n`: number of dates to return
|
||||
|
||||
```js
|
||||
schedule.next(2)
|
||||
// [ 2018-02-11T05:00:00.000Z, 2018-02-18T05:00:00.000Z ]
|
||||
```
|
||||
|
||||
`Schedule#startJob(fn: Function): () => void`
|
||||
|
||||
> Start a new job from this schedule and return a function to stop it.
|
||||
|
||||
- `fn`: function to execute, if it returns a promise, it will be
|
||||
awaited before scheduling the next run.
|
||||
|
||||
```js
|
||||
const stopJob = schedule.startJob(() => {
|
||||
console.log(new Date())
|
||||
})
|
||||
stopJob()
|
||||
```
|
||||
|
||||
`Job#start(): void`
|
||||
|
||||
> Start this job.
|
||||
|
||||
```js
|
||||
job.start()
|
||||
```
|
||||
|
||||
`Job#stop(): void`
|
||||
|
||||
> Stop this job.
|
||||
|
||||
```js
|
||||
job.stop()
|
||||
```
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/cron",
|
||||
"version": "1.0.6",
|
||||
"license": "ISC",
|
||||
@@ -22,8 +23,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@isonoe.net"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -46,7 +47,7 @@
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# @xen-orchestra/defined [](https://travis-ci.org/${pkg.shortGitHubPath})
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
> ${pkg.description}
|
||||
# @xen-orchestra/defined
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/defined)  [](https://bundlephobia.com/result?p=@xen-orchestra/defined) [](https://npmjs.org/package/@xen-orchestra/defined)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -10,29 +12,6 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/defin
|
||||
> npm install --save @xen-orchestra/defined
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
**TODO**
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -46,4 +25,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
0
@xen-orchestra/defined/USAGE.md
Normal file
0
@xen-orchestra/defined/USAGE.md
Normal file
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/defined",
|
||||
"version": "0.0.0",
|
||||
"license": "ISC",
|
||||
@@ -12,8 +13,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -34,7 +35,7 @@
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# @xen-orchestra/emit-async [](https://travis-ci.org/${pkg.shortGitHubPath})
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
> ${pkg.description}
|
||||
# @xen-orchestra/emit-async
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/emit-async)  [](https://bundlephobia.com/result?p=@xen-orchestra/emit-async) [](https://npmjs.org/package/@xen-orchestra/emit-async)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -19,7 +21,7 @@ import emitAsync from '@xen-orchestra/emit-async'
|
||||
const ee = new EE()
|
||||
ee.emitAsync = emitAsync
|
||||
|
||||
ee.on('start', async function() {
|
||||
ee.on('start', async function () {
|
||||
// whatever
|
||||
})
|
||||
|
||||
@@ -39,25 +41,6 @@ await ee.emitAsync(
|
||||
)
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -71,4 +54,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
26
@xen-orchestra/emit-async/USAGE.md
Normal file
26
@xen-orchestra/emit-async/USAGE.md
Normal file
@@ -0,0 +1,26 @@
|
||||
```js
|
||||
import EE from 'events'
|
||||
import emitAsync from '@xen-orchestra/emit-async'
|
||||
|
||||
const ee = new EE()
|
||||
ee.emitAsync = emitAsync
|
||||
|
||||
ee.on('start', async function () {
|
||||
// whatever
|
||||
})
|
||||
|
||||
// similar to EventEmmiter#emit() but returns a promise which resolves when all
|
||||
// listeners have resolved
|
||||
await ee.emitAsync('start')
|
||||
|
||||
// by default, it will rejects as soon as one listener reject, you can customise
|
||||
// error handling though:
|
||||
await ee.emitAsync(
|
||||
{
|
||||
onError(error) {
|
||||
console.warn(error)
|
||||
},
|
||||
},
|
||||
'start'
|
||||
)
|
||||
```
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/emit-async",
|
||||
"version": "0.0.0",
|
||||
"license": "ISC",
|
||||
@@ -12,8 +13,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -33,7 +34,7 @@
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
30
@xen-orchestra/fs/README.md
Normal file
30
@xen-orchestra/fs/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/fs
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/fs)  [](https://bundlephobia.com/result?p=@xen-orchestra/fs) [](https://npmjs.org/package/@xen-orchestra/fs)
|
||||
|
||||
> The File System for Xen Orchestra backups.
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/fs):
|
||||
|
||||
```
|
||||
> npm install --global @xen-orchestra/fs
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
0
@xen-orchestra/fs/USAGE.md
Normal file
0
@xen-orchestra/fs/USAGE.md
Normal file
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/fs",
|
||||
"version": "0.10.2",
|
||||
"license": "AGPL-3.0",
|
||||
"version": "0.10.4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"description": "The File System for Xen Orchestra backups.",
|
||||
"keywords": [],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/fs",
|
||||
@@ -25,8 +26,8 @@
|
||||
"@sindresorhus/df": "^3.1.1",
|
||||
"@xen-orchestra/async-map": "^0.0.0",
|
||||
"decorator-synchronized": "^0.5.0",
|
||||
"execa": "^3.2.0",
|
||||
"fs-extra": "^8.0.1",
|
||||
"execa": "^4.0.2",
|
||||
"fs-extra": "^9.0.0",
|
||||
"get-stream": "^5.1.0",
|
||||
"limit-concurrency-decorator": "^0.4.0",
|
||||
"lodash": "^4.17.4",
|
||||
@@ -46,7 +47,7 @@
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"async-iterator-to-stream": "^1.1.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"dotenv": "^8.0.0",
|
||||
"index-modules": "^0.3.0",
|
||||
"rimraf": "^3.0.0"
|
||||
@@ -59,5 +60,9 @@
|
||||
"predev": "yarn run clean",
|
||||
"prepare": "yarn run build",
|
||||
"postversion": "npm publish"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,7 @@ export default class MountHandler extends LocalHandler {
|
||||
}
|
||||
this._realPath = join(
|
||||
mountsDir,
|
||||
remote.id ||
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.slice(2)
|
||||
remote.id || Math.random().toString(36).slice(2)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -75,9 +72,12 @@ export default class MountHandler extends LocalHandler {
|
||||
|
||||
try {
|
||||
const { type, device, options, env } = this._params
|
||||
|
||||
// Linux mount is more flexible in which order the mount arguments appear.
|
||||
// But FreeBSD requires this order of the arguments.
|
||||
await this._execa(
|
||||
'mount',
|
||||
['-t', type, device, realPath, '-o', options],
|
||||
['-o', options, '-t', type, device, realPath],
|
||||
{
|
||||
env: {
|
||||
LANG: 'C',
|
||||
|
||||
@@ -118,7 +118,7 @@ export default class RemoteHandlerAbstract {
|
||||
}
|
||||
|
||||
async closeFile(fd: FileDescriptor): Promise<void> {
|
||||
await timeout.call(this._closeFile(fd.fd), this._timeout)
|
||||
await this.__closeFile(fd)
|
||||
}
|
||||
|
||||
async createOutputStream(
|
||||
@@ -283,30 +283,15 @@ export default class RemoteHandlerAbstract {
|
||||
}
|
||||
|
||||
async mkdir(dir: string): Promise<void> {
|
||||
dir = normalizePath(dir)
|
||||
try {
|
||||
await this._mkdir(dir)
|
||||
} catch (error) {
|
||||
if (error == null || error.code !== 'EEXIST') {
|
||||
throw error
|
||||
}
|
||||
|
||||
// this operation will throw if it's not already a directory
|
||||
await this._list(dir)
|
||||
}
|
||||
await this.__mkdir(normalizePath(dir))
|
||||
}
|
||||
|
||||
async mktree(dir: string): Promise<void> {
|
||||
await this._mktree(normalizePath(dir))
|
||||
}
|
||||
|
||||
async openFile(path: string, flags: string): Promise<FileDescriptor> {
|
||||
path = normalizePath(path)
|
||||
|
||||
return {
|
||||
fd: await timeout.call(this._openFile(path, flags), this._timeout),
|
||||
path,
|
||||
}
|
||||
openFile(path: string, flags: string): Promise<FileDescriptor> {
|
||||
return this.__openFile(path, flags)
|
||||
}
|
||||
|
||||
async outputFile(
|
||||
@@ -455,6 +440,34 @@ export default class RemoteHandlerAbstract {
|
||||
await this._writeFile(normalizePath(file), data, { flags })
|
||||
}
|
||||
|
||||
// Methods that can be called by private methods to avoid parallel limit on public methods
|
||||
|
||||
async __closeFile(fd: FileDescriptor): Promise<void> {
|
||||
await timeout.call(this._closeFile(fd.fd), this._timeout)
|
||||
}
|
||||
|
||||
async __mkdir(dir: string): Promise<void> {
|
||||
try {
|
||||
await this._mkdir(dir)
|
||||
} catch (error) {
|
||||
if (error == null || error.code !== 'EEXIST') {
|
||||
throw error
|
||||
}
|
||||
|
||||
// this operation will throw if it's not already a directory
|
||||
await this._list(dir)
|
||||
}
|
||||
}
|
||||
|
||||
async __openFile(path: string, flags: string): Promise<FileDescriptor> {
|
||||
path = normalizePath(path)
|
||||
|
||||
return {
|
||||
fd: await timeout.call(this._openFile(path, flags), this._timeout),
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
// Methods that can be implemented by inheriting classes
|
||||
|
||||
async _closeFile(fd: mixed): Promise<void> {
|
||||
@@ -503,7 +516,7 @@ export default class RemoteHandlerAbstract {
|
||||
|
||||
async _mktree(dir: string): Promise<void> {
|
||||
try {
|
||||
return await this.mkdir(dir)
|
||||
return await this.__mkdir(dir)
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error
|
||||
@@ -586,13 +599,13 @@ export default class RemoteHandlerAbstract {
|
||||
async _write(file: File, buffer: Buffer, position: number): Promise<void> {
|
||||
const isPath = typeof file === 'string'
|
||||
if (isPath) {
|
||||
file = await this.openFile(file, 'r+')
|
||||
file = await this.__openFile(file, 'r+')
|
||||
}
|
||||
try {
|
||||
return await this._writeFd(file, buffer, position)
|
||||
} finally {
|
||||
if (isPath) {
|
||||
await this.closeFile(file)
|
||||
await this.__closeFile(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -635,7 +648,7 @@ function createPrefixWrapperMethods() {
|
||||
return
|
||||
}
|
||||
|
||||
descriptor.value = function() {
|
||||
descriptor.value = function () {
|
||||
let path
|
||||
if (arguments.length !== 0 && typeof (path = arguments[0]) === 'string') {
|
||||
arguments[0] = this._resolve(path)
|
||||
|
||||
@@ -28,7 +28,7 @@ const unsecureRandomBytes = n => {
|
||||
|
||||
const TEST_DATA_LEN = 1024
|
||||
const TEST_DATA = unsecureRandomBytes(TEST_DATA_LEN)
|
||||
const createTestDataStream = asyncIteratorToStream(function*() {
|
||||
const createTestDataStream = asyncIteratorToStream(function* () {
|
||||
yield TEST_DATA
|
||||
})
|
||||
|
||||
@@ -219,6 +219,12 @@ handlers.forEach(url => {
|
||||
const error = await rejectionOf(handler.outputFile('file', ''))
|
||||
expect(error.code).toBe('EEXIST')
|
||||
})
|
||||
|
||||
it("shouldn't timeout in case of the respect of the parallel execution restriction", async () => {
|
||||
const handler = getHandler({ url }, { maxParallelOperations: 1 })
|
||||
await handler.sync()
|
||||
await handler.outputFile(`xo-fs-tests-${Date.now()}/test`, '')
|
||||
}, 40)
|
||||
})
|
||||
|
||||
describe('#read()', () => {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# @xen-orchestra/log [](https://travis-ci.org/vatesfr/xen-orchestra)
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
> ${pkg.description}
|
||||
# @xen-orchestra/log
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/log)  [](https://bundlephobia.com/result?p=@xen-orchestra/log) [](https://npmjs.org/package/@xen-orchestra/log)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -135,25 +137,6 @@ configure(transportSyslog())
|
||||
configure(transportSyslog('tcp://syslog.company.lan'))
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -161,10 +144,10 @@ the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xo-web/issues/)
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
122
@xen-orchestra/log/USAGE.md
Normal file
122
@xen-orchestra/log/USAGE.md
Normal file
@@ -0,0 +1,122 @@
|
||||
Everywhere something should be logged:
|
||||
|
||||
```js
|
||||
import { createLogger } from '@xen-orchestra/log'
|
||||
|
||||
const log = createLogger('my-module')
|
||||
|
||||
log.debug('only useful for debugging')
|
||||
log.info('this information is relevant to the user')
|
||||
log.warn('something went wrong but did not prevent current action')
|
||||
log.error('something went wrong')
|
||||
log.fatal('service/app is going down')
|
||||
|
||||
// you can add contextual info
|
||||
log.debug('new API request', {
|
||||
method: 'foo',
|
||||
params: [ 'bar', 'baz' ]
|
||||
user: 'qux'
|
||||
})
|
||||
|
||||
// by convention, errors go into the `error` field
|
||||
log.error('could not join server', {
|
||||
error,
|
||||
server: 'example.org',
|
||||
})
|
||||
```
|
||||
|
||||
Then, at application level, configure the logs are handled:
|
||||
|
||||
```js
|
||||
import { createLogger } from '@xen-orchestra/log'
|
||||
import { configure, catchGlobalErrors } from '@xen-orchestra/log/configure'
|
||||
import transportConsole from '@xen-orchestra/log/transports/console'
|
||||
import transportEmail from '@xen-orchestra/log/transports/email'
|
||||
|
||||
const transport = transportEmail({
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: 'jane.smith@gmail.com',
|
||||
pass: 'H&NbECcpXF|pyXe#%ZEb',
|
||||
},
|
||||
from: 'jane.smith@gmail.com',
|
||||
to: ['jane.smith@gmail.com', 'sam.doe@yahoo.com'],
|
||||
})
|
||||
|
||||
configure([
|
||||
{
|
||||
// if filter is a string, then it is pattern
|
||||
// (https://github.com/visionmedia/debug#wildcards) which is
|
||||
// matched against the namespace of the logs
|
||||
filter: process.env.DEBUG,
|
||||
|
||||
transport: transportConsole(),
|
||||
},
|
||||
{
|
||||
// only levels >= warn
|
||||
level: 'warn',
|
||||
|
||||
transport,
|
||||
},
|
||||
])
|
||||
|
||||
// send all global errors (uncaught exceptions, warnings, unhandled rejections)
|
||||
// to this logger
|
||||
catchGlobalErrors(createLogger('app'))
|
||||
```
|
||||
|
||||
### Transports
|
||||
|
||||
#### Console
|
||||
|
||||
```js
|
||||
import transportConsole from '@xen-orchestra/log/transports/console'
|
||||
|
||||
configure(transportConsole())
|
||||
```
|
||||
|
||||
#### Email
|
||||
|
||||
Optional dependency:
|
||||
|
||||
```
|
||||
> yarn add nodemailer pretty-format
|
||||
```
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
import transportEmail from '@xen-orchestra/log/transports/email'
|
||||
|
||||
configure(
|
||||
transportEmail({
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: 'jane.smith@gmail.com',
|
||||
pass: 'H&NbECcpXF|pyXe#%ZEb',
|
||||
},
|
||||
from: 'jane.smith@gmail.com',
|
||||
to: ['jane.smith@gmail.com', 'sam.doe@yahoo.com'],
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
#### Syslog
|
||||
|
||||
Optional dependency:
|
||||
|
||||
```
|
||||
> yarn add split-host syslog-client
|
||||
```
|
||||
|
||||
Configuration:
|
||||
|
||||
```js
|
||||
import transportSyslog from '@xen-orchestra/log/transports/syslog'
|
||||
|
||||
// By default, log to udp://localhost:514
|
||||
configure(transportSyslog())
|
||||
|
||||
// But TCP, a different host, or a different port can be used
|
||||
configure(transportSyslog('tcp://syslog.company.lan'))
|
||||
```
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/log",
|
||||
"version": "0.2.0",
|
||||
"license": "ISC",
|
||||
@@ -12,8 +13,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -38,7 +39,7 @@
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"index-modules": "^0.3.0",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ const createTransport = config => {
|
||||
if (Array.isArray(config)) {
|
||||
const transports = config.map(createTransport)
|
||||
const { length } = transports
|
||||
return function() {
|
||||
return function () {
|
||||
for (let i = 0; i < length; ++i) {
|
||||
transports[i].apply(this, arguments)
|
||||
}
|
||||
@@ -30,14 +30,14 @@ const createTransport = config => {
|
||||
}
|
||||
|
||||
const orig = transport
|
||||
transport = function(log) {
|
||||
transport = function (log) {
|
||||
if ((level !== undefined && log.level >= level) || filter(log)) {
|
||||
return orig.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
} else if (level !== undefined) {
|
||||
const orig = transport
|
||||
transport = function(log) {
|
||||
transport = function (log) {
|
||||
if (log.level >= level) {
|
||||
return orig.apply(this, arguments)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ const { prototype } = Logger
|
||||
for (const name in LEVELS) {
|
||||
const level = LEVELS[name]
|
||||
|
||||
prototype[name.toLowerCase()] = function(message, data) {
|
||||
prototype[name.toLowerCase()] = function (message, data) {
|
||||
if (typeof message !== 'string') {
|
||||
if (message instanceof Error) {
|
||||
data = { error: message }
|
||||
@@ -54,13 +54,13 @@ for (const name in LEVELS) {
|
||||
}
|
||||
}
|
||||
|
||||
prototype.wrap = function(message, fn) {
|
||||
prototype.wrap = function (message, fn) {
|
||||
const logger = this
|
||||
const warnAndRethrow = error => {
|
||||
logger.warn(message, { error })
|
||||
throw error
|
||||
}
|
||||
return function() {
|
||||
return function () {
|
||||
try {
|
||||
const result = fn.apply(this, arguments)
|
||||
const then = result != null && result.then
|
||||
|
||||
@@ -1,6 +1,85 @@
|
||||
import LEVELS, { NAMES } from '../levels'
|
||||
|
||||
const { ERROR, INFO, WARN } = LEVELS
|
||||
const { DEBUG, ERROR, FATAL, INFO, WARN } = LEVELS
|
||||
|
||||
let formatLevel, formatNamespace
|
||||
if (
|
||||
process.stdout !== undefined &&
|
||||
process.stdout.isTTY &&
|
||||
process.stderr !== undefined &&
|
||||
process.stderr.isTTY
|
||||
) {
|
||||
const ansi = (style, str) => `\x1b[${style}m${str}\x1b[0m`
|
||||
|
||||
const LEVEL_STYLES = {
|
||||
[DEBUG]: '2',
|
||||
[ERROR]: '1;31',
|
||||
[FATAL]: '1;31',
|
||||
[INFO]: '1',
|
||||
[WARN]: '1;33',
|
||||
}
|
||||
formatLevel = level => {
|
||||
const style = LEVEL_STYLES[level]
|
||||
const name = NAMES[level]
|
||||
return style === undefined ? name : ansi(style, name)
|
||||
}
|
||||
|
||||
const NAMESPACE_COLORS = [
|
||||
196,
|
||||
202,
|
||||
208,
|
||||
214,
|
||||
220,
|
||||
226,
|
||||
190,
|
||||
154,
|
||||
118,
|
||||
82,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
45,
|
||||
39,
|
||||
33,
|
||||
27,
|
||||
21,
|
||||
57,
|
||||
93,
|
||||
129,
|
||||
165,
|
||||
201,
|
||||
200,
|
||||
199,
|
||||
198,
|
||||
197,
|
||||
]
|
||||
formatNamespace = namespace => {
|
||||
// https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
|
||||
let hash = 0
|
||||
for (let i = 0, n = namespace.length; i < n; ++i) {
|
||||
hash = ((hash << 5) - hash + namespace.charCodeAt(i)) | 0
|
||||
}
|
||||
// // select a hue (HSV)
|
||||
// const h = (Math.abs(hash) % 20) * 18
|
||||
// // convert to RGB
|
||||
// const f = (n, k = (n + h / 60) % 6) =>
|
||||
// Math.round(255 * (1 - Math.max(Math.min(k, 4 - k, 1), 0)))
|
||||
// const r = f(5)
|
||||
// const g = f(3)
|
||||
// const b = f(1)
|
||||
// return ansi(`38;2;${r};${g};${b}`, namespace)
|
||||
return ansi(
|
||||
`1;38;5;${NAMESPACE_COLORS[Math.abs(hash) % NAMESPACE_COLORS.length]}`,
|
||||
namespace
|
||||
)
|
||||
}
|
||||
} else {
|
||||
formatLevel = str => NAMES[str]
|
||||
formatNamespace = str => str
|
||||
}
|
||||
|
||||
const consoleTransport = ({ data, level, namespace, message, time }) => {
|
||||
const fn =
|
||||
@@ -14,7 +93,12 @@ const consoleTransport = ({ data, level, namespace, message, time }) => {
|
||||
: console.error
|
||||
/* eslint-enable no-console */
|
||||
|
||||
const args = [time.toISOString(), namespace, NAMES[level], message]
|
||||
const args = [
|
||||
time.toISOString(),
|
||||
formatNamespace(namespace),
|
||||
formatLevel(level),
|
||||
message,
|
||||
]
|
||||
if (data != null) {
|
||||
args.push(data)
|
||||
}
|
||||
|
||||
@@ -13,10 +13,7 @@ export const evalTemplate = (tpl, data) => {
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
const compileGlobPatternFragment = pattern =>
|
||||
pattern
|
||||
.split('*')
|
||||
.map(escapeRegExp)
|
||||
.join('.*')
|
||||
pattern.split('*').map(escapeRegExp).join('.*')
|
||||
|
||||
export const compileGlobPattern = pattern => {
|
||||
const no = []
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# @xen-orchestra/mixin [](https://travis-ci.org/${pkg.shortGitHubPath})
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
> ${pkg.description}
|
||||
# @xen-orchestra/mixin
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/mixin)  [](https://bundlephobia.com/result?p=@xen-orchestra/mixin) [](https://npmjs.org/package/@xen-orchestra/mixin)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -10,29 +12,6 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/mixin
|
||||
> npm install --save @xen-orchestra/mixin
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
**TODO**
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -46,4 +25,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
0
@xen-orchestra/mixin/USAGE.md
Normal file
0
@xen-orchestra/mixin/USAGE.md
Normal file
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/mixin",
|
||||
"version": "0.0.0",
|
||||
"license": "ISC",
|
||||
@@ -12,8 +13,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -36,7 +37,7 @@
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-plugin-dev": "^1.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
46
@xen-orchestra/self-signed/README.md
Normal file
46
@xen-orchestra/self-signed/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/self-signed
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/self-signed)  [](https://bundlephobia.com/result?p=@xen-orchestra/self-signed) [](https://npmjs.org/package/@xen-orchestra/self-signed)
|
||||
|
||||
> Minimalist wrapper around openssl to generate a self signed certificate
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/self-signed):
|
||||
|
||||
```
|
||||
> npm install --save @xen-orchestra/self-signed
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { genSelfSigned } from '@xen-orchestra/self-signed'
|
||||
|
||||
console.log(await genSelfSigned())
|
||||
// {
|
||||
// cert: '-----BEGIN CERTIFICATE-----\n' +
|
||||
// // content…
|
||||
// '-----END CERTIFICATE-----\n',
|
||||
// key: '-----BEGIN RSA PRIVATE KEY-----\n' +
|
||||
// // content…
|
||||
// '-----END RSA PRIVATE KEY-----\n'
|
||||
// }
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
13
@xen-orchestra/self-signed/USAGE.md
Normal file
13
@xen-orchestra/self-signed/USAGE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
```js
|
||||
import { genSelfSigned } from '@xen-orchestra/self-signed'
|
||||
|
||||
console.log(await genSelfSigned())
|
||||
// {
|
||||
// cert: '-----BEGIN CERTIFICATE-----\n' +
|
||||
// // content…
|
||||
// '-----END CERTIFICATE-----\n',
|
||||
// key: '-----BEGIN RSA PRIVATE KEY-----\n' +
|
||||
// // content…
|
||||
// '-----END RSA PRIVATE KEY-----\n'
|
||||
// }
|
||||
```
|
||||
25
@xen-orchestra/self-signed/index.js
Normal file
25
@xen-orchestra/self-signed/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const { execFile } = require('child_process')
|
||||
|
||||
const openssl = (cmd, args, { input, ...opts } = {}) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const child = execFile('openssl', [cmd, ...args], opts, (error, stdout) =>
|
||||
error != null ? reject(error) : resolve(stdout)
|
||||
)
|
||||
if (input !== undefined) {
|
||||
child.stdin.end(input)
|
||||
}
|
||||
})
|
||||
|
||||
exports.genSelfSignedCert = async () => {
|
||||
const key = await openssl('genrsa', ['2048'])
|
||||
return {
|
||||
cert: await openssl(
|
||||
'req',
|
||||
['-batch', '-new', '-key', '-', '-x509', '-days', '360', '-nodes'],
|
||||
{
|
||||
input: key,
|
||||
}
|
||||
),
|
||||
key,
|
||||
}
|
||||
}
|
||||
24
@xen-orchestra/self-signed/package.json
Normal file
24
@xen-orchestra/self-signed/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/self-signed",
|
||||
"description": "Minimalist wrapper around openssl to generate a self signed certificate",
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/self-signed",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@xen-orchestra/self-signed",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
},
|
||||
"license": "ISC",
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
# @xen-orchestra/template [](https://travis-ci.org/vatesfr/xen-orchestra)
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/template
|
||||
|
||||
[](https://npmjs.org/package/@xen-orchestra/template)  [](https://bundlephobia.com/result?p=@xen-orchestra/template) [](https://npmjs.org/package/@xen-orchestra/template)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -30,25 +34,6 @@ const newString = myReplacer(
|
||||
newString === 'foo_COPY_{name}_42_32%' // true
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
> yarn
|
||||
|
||||
# Run the tests
|
||||
> yarn test
|
||||
|
||||
# Continuously compile
|
||||
> yarn dev
|
||||
|
||||
# Continuously run the tests
|
||||
> yarn dev-test
|
||||
|
||||
# Build for production (automatically called by npm install)
|
||||
> yarn build
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
@@ -62,4 +47,4 @@ You may:
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](https://vates.fr)
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
|
||||
19
@xen-orchestra/template/USAGE.md
Normal file
19
@xen-orchestra/template/USAGE.md
Normal file
@@ -0,0 +1,19 @@
|
||||
Create a string replacer based on a pattern and a list of rules.
|
||||
|
||||
```js
|
||||
const myReplacer = compileTemplate('{name}_COPY_{name}_{id}_%%', {
|
||||
'{name}': vm => vm.name_label,
|
||||
'{id}': vm => vm.id,
|
||||
'%': (_, i) => i,
|
||||
})
|
||||
|
||||
const newString = myReplacer(
|
||||
{
|
||||
name_label: 'foo',
|
||||
id: 42,
|
||||
},
|
||||
32
|
||||
)
|
||||
|
||||
newString === 'foo_COPY_{name}_42_32%' // true
|
||||
```
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "@xen-orchestra/template",
|
||||
"version": "0.1.0",
|
||||
"license": "ISC",
|
||||
@@ -10,8 +11,8 @@
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
@@ -28,7 +29,7 @@
|
||||
"@babel/cli": "^7.0.0",
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
3
@xen-orchestra/upload-ova/.babelrc.js
Normal file
3
@xen-orchestra/upload-ova/.babelrc.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = require('../../@xen-orchestra/babel-config')(
|
||||
require('./package.json')
|
||||
)
|
||||
24
@xen-orchestra/upload-ova/.npmignore
Normal file
24
@xen-orchestra/upload-ova/.npmignore
Normal file
@@ -0,0 +1,24 @@
|
||||
/benchmark/
|
||||
/benchmarks/
|
||||
*.bench.js
|
||||
*.bench.js.map
|
||||
|
||||
/examples/
|
||||
example.js
|
||||
example.js.map
|
||||
*.example.js
|
||||
*.example.js.map
|
||||
|
||||
/fixture/
|
||||
/fixtures/
|
||||
*.fixture.js
|
||||
*.fixture.js.map
|
||||
*.fixtures.js
|
||||
*.fixtures.js.map
|
||||
|
||||
/test/
|
||||
/tests/
|
||||
*.spec.js
|
||||
*.spec.js.map
|
||||
|
||||
__snapshots__/
|
||||
63
@xen-orchestra/upload-ova/README.md
Normal file
63
@xen-orchestra/upload-ova/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @xen-orchestra/upload-ova
|
||||
|
||||
> Basic CLI to upload ova files to Xen-Orchestra
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
Usage:
|
||||
|
||||
xo-upload-ova --register [--expiresIn duration] <XO-Server URL> <username> [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
--expiresIn duration
|
||||
Can be used to change the validity duration of the
|
||||
authorization token (default: one month).
|
||||
|
||||
xo-upload-ova --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
xo-upload-ova --inspect <file>
|
||||
Displays the data that would be imported from the ova.
|
||||
|
||||
xo-upload-ova --upload <file> <sr> [--override <key>=<value> [<key>=<value>]+]
|
||||
Actually imports the VM contained in <file> to the Storage Repository <sr>.
|
||||
Some parameters can be overridden from the file, consult --inspect to get the list.
|
||||
Note: --override has to come last. By default arguments are string, prefix them with <json:> to type
|
||||
them, ex. " --override nameLabel='new VM' memory=json:67108864 disks.vmdisk1.capacity=json:134217728"
|
||||
|
||||
xo-upload-ova v0.1.0
|
||||
|
||||
```
|
||||
|
||||
#### Register your XO instance
|
||||
|
||||
```
|
||||
> xo-upload-ova --register http://xo.my-company.net admin@admin.net admin
|
||||
Successfully logged with admin@admin.net
|
||||
```
|
||||
|
||||
Note: only a token will be saved in the configuration file.
|
||||
|
||||
#### Import your .ova file
|
||||
|
||||
```
|
||||
> xo-upload-ova --upload dsl.ova a7c630bf-b38c-489e-d3c3-e62507948980 --override 'nameLabel=dsl ' descriptionLabel='short desc' memory=json:671088640 disks.vmdisk1.descriptionLabel='disk description' disks.vmdisk1.capacity=json:1342177280
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
|
||||
40
@xen-orchestra/upload-ova/USAGE.md
Normal file
40
@xen-orchestra/upload-ova/USAGE.md
Normal file
@@ -0,0 +1,40 @@
|
||||
```
|
||||
Usage:
|
||||
|
||||
xo-upload-ova --register [--expiresIn duration] <XO-Server URL> <username> [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
--expiresIn duration
|
||||
Can be used to change the validity duration of the
|
||||
authorization token (default: one month).
|
||||
|
||||
xo-upload-ova --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
xo-upload-ova --inspect <file>
|
||||
Displays the data that would be imported from the ova.
|
||||
|
||||
xo-upload-ova --upload <file> <sr> [--override <key>=<value> [<key>=<value>]+]
|
||||
Actually imports the VM contained in <file> to the Storage Repository <sr>.
|
||||
Some parameters can be overridden from the file, consult --inspect to get the list.
|
||||
Note: --override has to come last. By default arguments are string, prefix them with <json:> to type
|
||||
them, ex. " --override nameLabel='new VM' memory=json:67108864 disks.vmdisk1.capacity=json:134217728"
|
||||
|
||||
xo-upload-ova v0.1.0
|
||||
|
||||
```
|
||||
|
||||
#### Register your XO instance
|
||||
|
||||
```
|
||||
> xo-upload-ova --register http://xo.my-company.net admin@admin.net admin
|
||||
Successfully logged with admin@admin.net
|
||||
```
|
||||
|
||||
Note: only a token will be saved in the configuration file.
|
||||
|
||||
#### Import your .ova file
|
||||
|
||||
```
|
||||
> xo-upload-ova --upload dsl.ova a7c630bf-b38c-489e-d3c3-e62507948980 --override 'nameLabel=dsl ' descriptionLabel='short desc' memory=json:671088640 disks.vmdisk1.descriptionLabel='disk description' disks.vmdisk1.capacity=json:1342177280
|
||||
```
|
||||
75
@xen-orchestra/upload-ova/package.json
Normal file
75
@xen-orchestra/upload-ova/package.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "@xen-orchestra/upload-ova",
|
||||
"version": "0.1.3",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"description": "Basic CLI to upload ova files to Xen-Orchestra",
|
||||
"keywords": [
|
||||
"import",
|
||||
"orchestra",
|
||||
"ova",
|
||||
"xcp-ng",
|
||||
"xcp",
|
||||
"xen-orchestra",
|
||||
"xen-server",
|
||||
"xen",
|
||||
"xo"
|
||||
],
|
||||
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/upload-ova",
|
||||
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||
"repository": {
|
||||
"directory": "@xen-orchestra/upload-ova",
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"main": "dist/",
|
||||
"bin": {
|
||||
"xo-upload-ova": "dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^2.2.0",
|
||||
"exec-promise": "^0.7.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"fs-promise": "^2.0.3",
|
||||
"get-stream": "^4.1.0",
|
||||
"http-request-plus": "^0.8.0",
|
||||
"human-format": "^0.10.0",
|
||||
"l33teral": "^3.0.3",
|
||||
"lodash": "^4.17.4",
|
||||
"nice-pipe": "0.0.0",
|
||||
"pretty-ms": "^4.0.0",
|
||||
"progress-stream": "^2.0.0",
|
||||
"pw": "^0.0.4",
|
||||
"strip-indent": "^2.0.0",
|
||||
"xdg-basedir": "^3.0.0",
|
||||
"xo-lib": "^0.9.0",
|
||||
"xo-vmdk-to-vhd": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.0.0",
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"babel-plugin-lodash": "^3.3.2",
|
||||
"cross-env": "^7.0.2",
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
|
||||
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
|
||||
"prebuild": "rimraf dist/",
|
||||
"predev": "yarn run prebuild",
|
||||
"prepublishOnly": "yarn run build"
|
||||
},
|
||||
"private": true,
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
}
|
||||
}
|
||||
44
@xen-orchestra/upload-ova/src/config.js
Normal file
44
@xen-orchestra/upload-ova/src/config.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
import assign from 'lodash/assign'
|
||||
import l33t from 'l33teral'
|
||||
import xdgBasedir from 'xdg-basedir'
|
||||
|
||||
import { mkdirp, readFile, writeFile } from 'fs-extra'
|
||||
|
||||
const configPath = xdgBasedir.config + '/xo-upload-ova'
|
||||
const configFile = configPath + '/config.json'
|
||||
|
||||
export async function load() {
|
||||
try {
|
||||
return JSON.parse(await readFile(configFile))
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
export async function get(path) {
|
||||
const config = await load()
|
||||
return l33t(config).tap(path)
|
||||
}
|
||||
|
||||
export async function save(config) {
|
||||
await mkdirp(configPath)
|
||||
await writeFile(configFile, JSON.stringify(config))
|
||||
}
|
||||
|
||||
export async function set(data) {
|
||||
const config = await load()
|
||||
await save(assign(config, data))
|
||||
}
|
||||
|
||||
export async function unset(paths) {
|
||||
const config = await load()
|
||||
const l33tConfig = l33t(config)
|
||||
;[].concat(paths).forEach(function (path) {
|
||||
l33tConfig.purge(path, true)
|
||||
})
|
||||
return save(config)
|
||||
}
|
||||
308
@xen-orchestra/upload-ova/src/index.js
Executable file
308
@xen-orchestra/upload-ova/src/index.js
Executable file
@@ -0,0 +1,308 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/* eslint no-console: "off" */
|
||||
|
||||
import chalk from 'chalk'
|
||||
import execPromise from 'exec-promise'
|
||||
import { createReadStream } from 'fs'
|
||||
import { stat } from 'fs-promise'
|
||||
import getStream from 'get-stream'
|
||||
import hrp from 'http-request-plus'
|
||||
import humanFormat from 'human-format'
|
||||
import l33t from 'l33teral'
|
||||
import isObject from 'lodash/isObject'
|
||||
import getKeys from 'lodash/keys'
|
||||
import startsWith from 'lodash/startsWith'
|
||||
import nicePipe from 'nice-pipe'
|
||||
import prettyMs from 'pretty-ms'
|
||||
import progressStream from 'progress-stream'
|
||||
import pw from 'pw'
|
||||
import stripIndent from 'strip-indent'
|
||||
import { URL } from 'url'
|
||||
import Xo from 'xo-lib'
|
||||
import { parseOVAFile } from 'xo-vmdk-to-vhd'
|
||||
|
||||
import pkg from '../package'
|
||||
import {
|
||||
load as loadConfig,
|
||||
set as setConfig,
|
||||
unset as unsetConfig,
|
||||
} from './config'
|
||||
|
||||
function help() {
|
||||
return stripIndent(
|
||||
`
|
||||
Usage:
|
||||
|
||||
$name --register [--expiresIn duration] <XO-Server URL> <username> [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
--expiresIn duration
|
||||
Can be used to change the validity duration of the
|
||||
authorization token (default: one month).
|
||||
|
||||
$name --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
$name --inspect <file>
|
||||
Displays the data that would be imported from the ova.
|
||||
|
||||
$name --upload <file> <sr> [--override <key>=<value> [<key>=<value>]+]
|
||||
Actually imports the VM contained in <file> to the Storage Repository <sr>.
|
||||
Some parameters can be overridden from the file, consult --inspect to get the list.
|
||||
Note: --override has to come last. By default arguments are string, prefix them with <json:> to type
|
||||
them, ex. " --override nameLabel='new VM' memory=json:67108864 disks.vmdisk1.capacity=json:134217728"
|
||||
|
||||
$name v$version
|
||||
`
|
||||
).replace(/<([^>]+)>|\$(\w+)/g, function (_, arg, key) {
|
||||
if (arg) {
|
||||
return '<' + chalk.yellow(arg) + '>'
|
||||
}
|
||||
|
||||
if (key === 'name') {
|
||||
return chalk.bold(pkg[key])
|
||||
}
|
||||
|
||||
return pkg[key]
|
||||
})
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
const { server, token } = await loadConfig()
|
||||
if (server === undefined) {
|
||||
throw new Error('no server to connect to!')
|
||||
}
|
||||
|
||||
if (token === undefined) {
|
||||
throw new Error('no token available')
|
||||
}
|
||||
|
||||
const xo = new Xo({ url: server })
|
||||
await xo.open()
|
||||
await xo.signIn({ token })
|
||||
return xo
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
return unsetConfig(['server', 'token'])
|
||||
}
|
||||
|
||||
export async function register(args) {
|
||||
let expiresIn
|
||||
if (args[0] === '--expiresIn') {
|
||||
expiresIn = args[1]
|
||||
args = args.slice(2)
|
||||
}
|
||||
|
||||
const [
|
||||
url,
|
||||
email,
|
||||
password = await new Promise(resolve => {
|
||||
process.stdout.write('Password: ')
|
||||
pw(resolve)
|
||||
}),
|
||||
] = args
|
||||
|
||||
const xo = new Xo({ url })
|
||||
await xo.open()
|
||||
await xo.signIn({ email, password })
|
||||
console.log('Successfully logged with', xo.user.email)
|
||||
|
||||
await setConfig({
|
||||
server: url,
|
||||
token: await xo.call('token.create', { expiresIn }),
|
||||
})
|
||||
}
|
||||
|
||||
function nodeStringDecoder(buffer, encoder) {
|
||||
return Buffer.from(buffer).toString(encoder)
|
||||
}
|
||||
|
||||
export async function inspect(args) {
|
||||
const file = args[0]
|
||||
const data = await parseOVAFile(
|
||||
new NodeParsableFile(file, (await stat(file)).size),
|
||||
nodeStringDecoder,
|
||||
true
|
||||
)
|
||||
console.log('file metadata:', data)
|
||||
}
|
||||
|
||||
function parseOverride(args) {
|
||||
const flag = args.shift()
|
||||
if (flag !== '--override') {
|
||||
throw new Error('Third argument has to be --override')
|
||||
}
|
||||
|
||||
if (args.length === 0) {
|
||||
throw new Error('Missing actual override')
|
||||
}
|
||||
const overrides = {}
|
||||
for (const definition of args) {
|
||||
const index = definition.indexOf('=')
|
||||
const key = definition.slice(0, index)
|
||||
let value = definition.slice(index + 1)
|
||||
if (startsWith(value, 'json:')) {
|
||||
value = JSON.parse(value.slice(5))
|
||||
}
|
||||
overrides[key] = value
|
||||
}
|
||||
return overrides
|
||||
}
|
||||
|
||||
export async function upload(args) {
|
||||
const file = args.shift()
|
||||
const srId = args.shift()
|
||||
let overrides = {}
|
||||
if (args.length > 1) {
|
||||
overrides = parseOverride(args)
|
||||
}
|
||||
|
||||
const data = await parseOVAFile(
|
||||
new NodeParsableFile(file, (await stat(file)).size),
|
||||
nodeStringDecoder
|
||||
)
|
||||
const params = { sr: srId }
|
||||
const xo = await connect()
|
||||
const getXoObject = async filter =>
|
||||
Object.values(await xo.call('xo.getAllObjects', { filter }))[0]
|
||||
const sr = await getXoObject({ id: srId })
|
||||
const pool = await getXoObject({ id: sr.$poolId })
|
||||
const master = await getXoObject({ id: pool.master })
|
||||
const pif = await getXoObject({
|
||||
type: 'PIF',
|
||||
management: true,
|
||||
$host: master.id,
|
||||
})
|
||||
data.networks = data.networks.map(() => pif.$network)
|
||||
console.log('data', data)
|
||||
const l33tData = l33t(data)
|
||||
const overridesKeys = Object.keys(overrides)
|
||||
const missingKeys = overridesKeys.filter(k => !l33tData.probe(k))
|
||||
if (missingKeys.length) {
|
||||
// eslint-disable-next-line no-throw-literal
|
||||
throw `those override keys don't exist in the metadata: ${missingKeys}`
|
||||
}
|
||||
for (const key of overridesKeys) {
|
||||
l33tData.plant(key, overrides[key])
|
||||
}
|
||||
data.disks = Object.values(data.disks)
|
||||
params.data = l33tData.obj
|
||||
params.type = 'ova'
|
||||
const method = 'vm.import'
|
||||
|
||||
// FIXME: do not use private properties.
|
||||
const baseUrl = xo._url.replace(/^ws/, 'http')
|
||||
|
||||
const result = await xo.call(method, params)
|
||||
let keys, key, url
|
||||
if (isObject(result) && (keys = getKeys(result)).length === 1) {
|
||||
key = keys[0]
|
||||
|
||||
if (key === '$sendTo') {
|
||||
if (typeof file !== 'string') {
|
||||
// eslint-disable-next-line no-throw-literal
|
||||
throw 'file parameter should be a path'
|
||||
}
|
||||
url = new URL(result[key], baseUrl)
|
||||
|
||||
const { size: length } = await stat(file)
|
||||
const input = nicePipe([
|
||||
createReadStream(file),
|
||||
progressStream(
|
||||
{
|
||||
length,
|
||||
time: 1e3,
|
||||
},
|
||||
printProgress
|
||||
),
|
||||
])
|
||||
|
||||
try {
|
||||
return await hrp
|
||||
.post(url.toString(), {
|
||||
body: input,
|
||||
headers: {
|
||||
'content-length': length,
|
||||
},
|
||||
})
|
||||
.readAll('utf-8')
|
||||
} catch (e) {
|
||||
console.log('ERROR', e)
|
||||
console.log('ERROR content', await e.response.readAll('utf-8'))
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class NodeParsableFile {
|
||||
constructor(fileName, fileLength = Infinity) {
|
||||
this._fileName = fileName
|
||||
this._start = 0
|
||||
this._end = fileLength
|
||||
}
|
||||
|
||||
slice(start, end) {
|
||||
const newFile = new NodeParsableFile(this._fileName)
|
||||
newFile._start = start < 0 ? this._end + start : this._start + start
|
||||
newFile._end = end < 0 ? this._end + end : this._start + end
|
||||
return newFile
|
||||
}
|
||||
|
||||
async read() {
|
||||
const result = await getStream.buffer(
|
||||
createReadStream(this._fileName, {
|
||||
start: this._start,
|
||||
end: this._end - 1,
|
||||
})
|
||||
)
|
||||
// crazy stuff to get a browser-compatible ArrayBuffer from a node buffer
|
||||
// https://stackoverflow.com/a/31394257/72637
|
||||
return result.buffer.slice(
|
||||
result.byteOffset,
|
||||
result.byteOffset + result.byteLength
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const humanFormatOpts = {
|
||||
unit: 'B',
|
||||
scale: 'binary',
|
||||
}
|
||||
|
||||
function printProgress(progress) {
|
||||
if (progress.length) {
|
||||
console.warn(
|
||||
'%s% of %s @ %s/s - ETA %s',
|
||||
Math.round(progress.percentage),
|
||||
humanFormat(progress.length, humanFormatOpts),
|
||||
humanFormat(progress.speed, humanFormatOpts),
|
||||
prettyMs(progress.eta * 1e3)
|
||||
)
|
||||
} else {
|
||||
console.warn(
|
||||
'%s @ %s/s',
|
||||
humanFormat(progress.transferred, humanFormatOpts),
|
||||
humanFormat(progress.speed, humanFormatOpts)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default async function main(args) {
|
||||
if (!args || !args.length || args[0] === '-h' || args[0] === '--help') {
|
||||
return help()
|
||||
}
|
||||
const fnName = args[0].replace(/^--|-\w/g, match =>
|
||||
match === '--' ? '' : match[1].toUpperCase()
|
||||
)
|
||||
if (fnName in exports) {
|
||||
return exports[fnName](args.slice(1))
|
||||
}
|
||||
return help()
|
||||
}
|
||||
|
||||
if (!module.parent) {
|
||||
execPromise(main)
|
||||
}
|
||||
408
CHANGELOG.md
408
CHANGELOG.md
@@ -1,22 +1,307 @@
|
||||
# ChangeLog
|
||||
|
||||
## **next**
|
||||
## **5.47.1** (2020-06-02)
|
||||
|
||||
### Enhancements
|
||||

|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [auth-ldap] Sign in was broken in XO 5.47.0 (PR [#5039](https://github.com/vatesfr/xen-orchestra/pull/5039))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server-auth-ldap 0.8.1
|
||||
|
||||
## **5.47.0** (2020-05-29)
|
||||
|
||||
### Highlights
|
||||
|
||||
- [Proxy] Ability to start a trial if no license available (PR [#5022](https://github.com/vatesfr/xen-orchestra/pull/5022))
|
||||
- [Home/VM] Ability to list VMs which are (not) backed up [#4777](https://github.com/vatesfr/xen-orchestra/issues/4777) (PR [#4974](https://github.com/vatesfr/xen-orchestra/pull/4974))
|
||||
- [SDN Controller] Ability to choose host as preferred center at private network creation [#4991](https://github.com/vatesfr/xen-orchestra/issues/4991) (PR [#5000](https://github.com/vatesfr/xen-orchestra/pull/5000))
|
||||
- [Plugin/auth-ldap] Support `StartTLS` [#4999](https://github.com/vatesfr/xen-orchestra/issues/4999)
|
||||
- [XO config export] Ability to encrypt the exported file (PR [#4997](https://github.com/vatesfr/xen-orchestra/pull/4997))
|
||||
- [Backup] Improve listing performance (PR [#4985](https://github.com/vatesfr/xen-orchestra/pull/4985))
|
||||
- [Audit] Record failed connection attempts [#4844](https://github.com/vatesfr/xen-orchestra/issues/4844) (PR [#4900](https://github.com/vatesfr/xen-orchestra/pull/4900))
|
||||
- [OVA import] Add support for OVA 2.0 file format (PR [#4921](https://github.com/vatesfr/xen-orchestra/pull/4921))
|
||||
- [XOA/licenses] Display proxy licenses (PR [#4944](https://github.com/vatesfr/xen-orchestra/pull/4944))
|
||||
- [Usage report] Include CSV raw data files to the sent email [#4970](https://github.com/vatesfr/xen-orchestra/issues/4970) (PR [#4979](https://github.com/vatesfr/xen-orchestra/pull/4979))
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [VM] Move boot order setting from Disk tab to Advanced tab [#1523](https://github.com/vatesfr/xen-orchestra/issues/1523#issuecomment-563141573) (PR [#4975](https://github.com/vatesfr/xen-orchestra/pull/4975))
|
||||
- [Network selector] Display pool's name [#4885](https://github.com/vatesfr/xen-orchestra/issues/4885) (PR [#4990](https://github.com/vatesfr/xen-orchestra/pull/4990))
|
||||
- [Modal] Don't close pop-up forms when you click outside or press escape (PR [#5002](https://github.com/vatesfr/xen-orchestra/pull/5002))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix mounting of NFS remote in FreeBSD (PR [#4988](https://github.com/vatesfr/xen-orchestra/issues/4988))
|
||||
- [Remotes] Fix "remote is disabled" error on getting the remotes info (commit [eb2f429964d7adc264bf678c37e49a856454388e](https://github.com/vatesfr/xen-orchestra/commit/eb2f429964d7adc264bf678c37e49a856454388e))
|
||||
- Fix default filters not being set in all tables (PR [#4994](https://github.com/vatesfr/xen-orchestra/pull/4994))
|
||||
- [SDN Controller] Broken encrypted tunnels after host reboot [#4996](https://github.com/vatesfr/xen-orchestra/pull/4996)
|
||||
- Don't log server's credentials in case of `SESSION_AUTHENTICATION_FAILED` error (PR [#4995](https://github.com/vatesfr/xen-orchestra/pull/4995))
|
||||
- [Plugin/perf-alert] Fix compatibility of the alert messages with XenCenter (PR [#5004](https://github.com/vatesfr/xen-orchestra/pull/5004))
|
||||
- [Plugin/backup-reports] Fix `No recipients defined` error when recipients defined at plugin level (PR [#4998](https://github.com/vatesfr/xen-orchestra/pull/4998))
|
||||
- [Snapshots] Fix reverts sometimes being stuck (PR [#5027](https://github.com/vatesfr/xen-orchestra/pull/5027))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server-audit 0.4.0
|
||||
- xo-vmdk-to-vhd 1.2.0
|
||||
- xo-server-backup-reports 0.16.6
|
||||
- xo-server-perf-alert 0.2.2
|
||||
- xen-api 0.28.5
|
||||
- xo-server-auth-ldap 0.8.0
|
||||
- xo-server-sdn-controller 0.4.2
|
||||
- xo-server-usage-report 0.8.0
|
||||
- @xen-orchestra/fs 0.10.4
|
||||
- xo-server 5.60.0
|
||||
- xo-web 5.60.0
|
||||
|
||||
## **5.46.0** (2020-04-30)
|
||||
|
||||

|
||||
|
||||
### Highlights
|
||||
|
||||
- [Internationalization] Italian translation (Thanks [@infodavide](https://github.com/infodavide)!) [#4908](https://github.com/vatesfr/xen-orchestra/issues/4908) (PRs [#4931](https://github.com/vatesfr/xen-orchestra/pull/4931) [#4932](https://github.com/vatesfr/xen-orchestra/pull/4932))
|
||||
- [Proxy] Associate a license to the deployed proxy (PR [#4912](https://github.com/vatesfr/xen-orchestra/pull/4912))
|
||||
- [OVA import] Fix memory hogging behavior when the destination SR is slower than the file upload. (PR [#4920](https://github.com/vatesfr/xen-orchestra/pull/4920))
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [Snapshot] Confirmation message before creating a snapshot with memory [#4914](https://github.com/vatesfr/xen-orchestra/issues/4914) (PR [#4917](https://github.com/vatesfr/xen-orchestra/pull/4917))
|
||||
- Automatic generation of self signed certificate if `autoCert` is not `false` in `xo-server`'s configuration in the corresponding `http.listen` section (PR [#4954](https://github.com/vatesfr/xen-orchestra/pull/4954))
|
||||
- [Self] Better error when not enough available resources (PR [#4952](https://github.com/vatesfr/xen-orchestra/pull/4952))
|
||||
- [Backup/run job] Confirmation modal: show the number of VMs that will be backed up (PR [#4875](https://github.com/vatesfr/xen-orchestra/pull/4875))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Backup] Fix TLS error (`unsupported protocol`) when XenServer <= 6.5 is used as target
|
||||
- [Patches] Hide patch `CH81` (upgrade patch) from the pool patches (PR [#4942](https://github.com/vatesfr/xen-orchestra/pull/4942))
|
||||
- [Proxy] Fix some `operation timed out` errors on (re)deploy [#4927](https://github.com/vatesfr/xen-orchestra/issues/4927) (PR [#4928](https://github.com/vatesfr/xen-orchestra/pull/4928))
|
||||
- [Backup] Fix some `cannot get the proxy VM IP` errors on backup's execution [#4927](https://github.com/vatesfr/xen-orchestra/issues/4927) (PR [#4928](https://github.com/vatesfr/xen-orchestra/pull/4928))
|
||||
- [XOA] Allow to access the license page when a XOA trial has ended (PR [#4941](https://github.com/vatesfr/xen-orchestra/pull/4941))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-common 0.5.0
|
||||
- @xen-orchestra/self-signed 0.1.0
|
||||
- xo-vmdk-to-vhd 1.1.2
|
||||
- xo-server-audit 0.3.1
|
||||
- xen-api 0.28.4
|
||||
- xo-server 5.59.0
|
||||
- xo-web 5.59.0
|
||||
|
||||
## **5.45.1** (2020-04-08)
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [VDI migration]
|
||||
- Remove 'Migrate all VDIs' checkbox (PR [#4876](https://github.com/vatesfr/xen-orchestra/pull/4876))
|
||||
- [VM/disks]: Add bulk migration (PR [#4877](https://github.com/vatesfr/xen-orchestra/pull/4877))
|
||||
- [SAML] Possibility to pass [settings to the underlying library](https://github.com/bergie/passport-saml#config-parameter-details) via the `plugins.auth-saml.strategyOptions` section in `xo-server`'s configuration file
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix TLS error (`unsupported protocol`) with XenServer <= 6.5 and Node >= 12 for backups, consoles, and statistics [#4906](https://github.com/vatesfr/xen-orchestra/issues/4906)
|
||||
- [Audit] Fix "EACCES" error in case of changing the user that run "xo-server" [#4854](https://github.com/vatesfr/xen-orchestra/issues/4854) (PR [#4897](https://github.com/vatesfr/xen-orchestra/pull/4897))
|
||||
- [Patches] Reduce the amount of error logs related to missing patches (PR [#4911](https://github.com/vatesfr/xen-orchestra/pull/4911))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server-auth-saml 0.8.0
|
||||
- xo-server-audit 0.3.0
|
||||
- xo-server 5.58.2
|
||||
- xo-web 5.58.2
|
||||
|
||||
## **5.45.0** (2020-03-31)
|
||||
|
||||
### Highlights
|
||||
|
||||
- [Proxy / Deploy] Ability to select the destination network [#4825](https://github.com/vatesfr/xen-orchestra/issues/4825) (PR [#4855](https://github.com/vatesfr/xen-orchestra/pull/4855))
|
||||
- [VM/backup] Show backup jobs [#4623](https://github.com/vatesfr/xen-orchestra/issues/4623) (PR [#4860](https://github.com/vatesfr/xen-orchestra/pull/4860))
|
||||
- [SR / Disks] Ability to migrate VDIs [#4455](https://github.com/vatesfr/xen-orchestra/issues/4455) (PR [#4696](https://github.com/vatesfr/xen-orchestra/pull/4696))
|
||||
- [VM migration] Ability to choose network for migration within a pool [#2028](https://github.com/vatesfr/xen-orchestra/issues/2028) (PR [#4828](https://github.com/vatesfr/xen-orchestra/pull/4828))
|
||||
- [XOA] Manage the XOA licenses from the xoa/licenses page (PR [#3717](https://github.com/vatesfr/xen-orchestra/pull/3717))
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [Support] Link to create a new support ticket [#4234](https://github.com/vatesfr/xen-orchestra/issues/4234) (PR [#4833](https://github.com/vatesfr/xen-orchestra/pull/4833))
|
||||
- [Proxies] Ability to redeploy a proxy VM [#4825](https://github.com/vatesfr/xen-orchestra/issues/4825) (PR [#4725](https://github.com/vatesfr/xen-orchestra/pull/4725))
|
||||
- [Proxies/Deploy] Remove SRs not connected to an HVM-capable host from selection [#4825](https://github.com/vatesfr/xen-orchestra/issues/4825) (PR [#4849](https://github.com/vatesfr/xen-orchestra/pull/4849))
|
||||
- [Audit] Ability to export records [#4798](https://github.com/vatesfr/xen-orchestra/issues/4798) (PR [#4858](https://github.com/vatesfr/xen-orchestra/pull/4858))
|
||||
- [Audit] Improve integrity check feedback [#4798](https://github.com/vatesfr/xen-orchestra/issues/4798) (PR [#4879](https://github.com/vatesfr/xen-orchestra/pull/4879))
|
||||
- [Backup] **BETA** Ability to backup running VMs with their memory [#645](https://github.com/vatesfr/xen-orchestra/issues/645) (PR [#4252](https://github.com/vatesfr/xen-orchestra/pull/4252))
|
||||
- [Import] add CLI tool to import OVA files (PR [#3630](https://github.com/vatesfr/xen-orchestra/pull/3630))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [XOSAN] Fix the installer (PR [#4839](https://github.com/vatesfr/xen-orchestra/pull/4839))
|
||||
- [OVA Import] Fix _no host available_ error when starting for imported VMs with low memory (PR [#4866](https://github.com/vatesfr/xen-orchestra/pull/4866))
|
||||
- [Self] When a Self Service related operation fails, always revert the quotas to what they were before the operation (PR [#4861](https://github.com/vatesfr/xen-orchestra/pull/4861))
|
||||
- [auth-{github,google,saml}] Don't require manually reloading the plugin for configuration changes to take effect [#4863](https://github.com/vatesfr/xen-orchestra/issues/4863) (PR [#4864](https://github.com/vatesfr/xen-orchestra/pull/4864))
|
||||
- [auth-ldap] Fix reading certificate authorities files [#3873](https://github.com/vatesfr/xen-orchestra/issues/3873)
|
||||
- [Backup NG / logs] Replace successful backup job status by failed status in case of missing VMs [#4857](https://github.com/vatesfr/xen-orchestra/issues/4857) (PR [#4862](https://github.com/vatesfr/xen-orchestra/pull/4862))
|
||||
- [Jobs] Fix "no value for `user_ip`" error on jobs execution (PR [#4878](https://github.com/vatesfr/xen-orchestra/pull/4878))
|
||||
- [Self] Properly take IP pools into account when computing quotas (PR [#4871](https://github.com/vatesfr/xen-orchestra/pull/4871))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-vmdk-to-vhd 1.1.1
|
||||
- @xen-orchestra/upload-ova 0.1.3
|
||||
- @xen-orchestra/audit-core 0.1.1
|
||||
- xo-server-audit 0.2.0
|
||||
- xo-server-auth-github 0.2.2
|
||||
- xo-server-auth-google 0.2.2
|
||||
- xo-server-auth-ldap 0.7.1
|
||||
- xo-server-auth-saml 0.7.2
|
||||
- xo-server 5.58.1
|
||||
- xo-web 5.58.1
|
||||
|
||||
## **5.44.1** (2020-03-05)
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [Plugin] Show plugin description [#4569](https://github.com/vatesfr/xen-orchestra/issues/4569) (PR [#4832](https://github.com/vatesfr/xen-orchestra/pull/4832))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Backup reports] Fix backup report not sent in case of interrupted backup job (PR [#4772](https://github.com/vatesfr/xen-orchestra/pull/4772))
|
||||
- Fix TLS error (`unsupported protocol`) with XenServer <= 6.5 and Node >= 12 (PR [#8437](https://github.com/vatesfr/xen-orchestra/pull/8437))
|
||||
- [Metadata backup] Fix timeout when lots of pools are backed up [#4819](https://github.com/vatesfr/xen-orchestra/issues/4819) (PR [#4831](https://github.com/vatesfr/xen-orchestra/pull/4831))
|
||||
|
||||
### Released packages
|
||||
|
||||
- @xen-orchestra/fs v0.10.3
|
||||
- xen-api v0.28.3
|
||||
- xo-server-backup-reports v0.16.5
|
||||
- xo-server-perf-alert v0.2.1
|
||||
- xo-server-sdn-controller v0.4.1
|
||||
- xo-server-transport-icinga2 v0.1.1
|
||||
- xo-server-transport-nagios v0.1.1
|
||||
- xo-server-usage-report v0.7.5
|
||||
- xo-server-web-hooks v0.1.1
|
||||
- xo-server v5.57.3
|
||||
- xo-web v5.57.1
|
||||
|
||||
## **5.44.0** (2020-02-28)
|
||||
|
||||
### Highlights
|
||||
|
||||
- [Audit log] Record side effects triggered by users [#4653](https://github.com/vatesfr/xen-orchestra/issues/4653) [#701](https://github.com/vatesfr/xen-orchestra/issues/701) (PR [#4740](https://github.com/vatesfr/xen-orchestra/pull/4740))
|
||||
- [SR/general] Clickable SR usage graph: shows the corresponding disks when you click on one of the sections [#4747](https://github.com/vatesfr/xen-orchestra/issues/4747) (PR [#4754](https://github.com/vatesfr/xen-orchestra/pull/4754))
|
||||
- [New VM] Ability to copy host BIOS strings [#4204](https://github.com/vatesfr/xen-orchestra/issues/4204) (PR [4755](https://github.com/vatesfr/xen-orchestra/pull/4755))
|
||||
- [New VM] Ability to set VM max vCPUS [#4703](https://github.com/vatesfr/xen-orchestra/issues/4703) (PR [#4729](https://github.com/vatesfr/xen-orchestra/pull/4729))
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [SDN Controller] Automatically handle new, connected and disconnected servers (PR [#4677](https://github.com/vatesfr/xen-orchestra/pull/4677))
|
||||
- [Proxy] Support network configuration for the deployed proxy (PR [#4810](https://github.com/vatesfr/xen-orchestra/pull/4810))
|
||||
- [Menu] Display a warning icon in case of missing patches [#4475](https://github.com/vatesfr/xen-orchestra/issues/4475) (PR [#4683](https://github.com/vatesfr/xen-orchestra/pull/4683))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Usage Report] Fix wrong report date [#4779](https://github.com/vatesfr/xen-orchestra/issues/4779) (PR [#4799](https://github.com/vatesfr/xen-orchestra/pull/4799))
|
||||
- [SDN Controller] Fix plugin stuck loading [#4649](https://github.com/vatesfr/xen-orchestra/issues/4649) (PR [#4677](https://github.com/vatesfr/xen-orchestra/pull/4677))
|
||||
- [xo-server-logs] Fix `Cannot find module '../better-stacks'`
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-common v0.4.0
|
||||
- @xen-orchestra/audit-core v0.1.0
|
||||
- xo-server-audit v0.1.2
|
||||
- xo-server-auth-ldap v0.7.0
|
||||
- xo-server-usage-report v0.7.4
|
||||
- xo-server-sdn-controller v0.4.0
|
||||
- xo-server v5.57.2
|
||||
- xo-web v5.57.0
|
||||
|
||||
## **5.43.3** (2020-03-06)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Backups] Fix an issue where DR and CR could stay stuck (commit [63739df](https://github.com/vatesfr/xen-orchestra/commit/63739df90369798f16b61bf96d1a89513c7edc77))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server v5.56.3
|
||||
|
||||
## **5.43.2** (2020-02-11)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Proxy] Correctly call the proxy when running backups (PRs [#4791](https://github.com/vatesfr/xen-orchestra/pull/4791) & [#4792](https://github.com/vatesfr/xen-orchestra/pull/4792))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server v5.56.2
|
||||
|
||||
## **5.43.1** (2020-02-06)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Self,IP pools] Fixed the creation being stuck and freezing XO (PR [#4776](https://github.com/vatesfr/xen-orchestra/pull/4776))
|
||||
- [SDN Controller] Ensure the correct PIF is used to create private networks tunnels [#4737](https://github.com/vatesfr/xen-orchestra/issues/4737) (PR [#4757](https://github.com/vatesfr/xen-orchestra/pull/4757))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server-sdn-controller v0.3.2
|
||||
- xo-server-auth-saml 0.7.1
|
||||
- xo-server v5.56.1
|
||||
- xo-web v5.56.2
|
||||
|
||||
## **5.43.0** (2020-01-31)
|
||||
|
||||
### Highlights
|
||||
|
||||
- [Home] Allow to change the number of items per page [#4535](https://github.com/vatesfr/xen-orchestra/issues/4535) (PR [#4708](https://github.com/vatesfr/xen-orchestra/pull/4708))
|
||||
- [Tag] Adding a tag: ability to select from existing tags [#2810](https://github.com/vatesfr/xen-orchestra/issues/2810) (PR [#4530](https://github.com/vatesfr/xen-orchestra/pull/4530))
|
||||
- [Smart backup] Ability to manually add custom tags [#2810](https://github.com/vatesfr/xen-orchestra/issues/2810) (PR [#4648](https://github.com/vatesfr/xen-orchestra/pull/4648))
|
||||
- [Proxy] Ability to backup VMs via registered proxy [#4254](https://github.com/vatesfr/xen-orchestra/issues/4254) (PR [#4495](https://github.com/vatesfr/xen-orchestra/pull/4495))
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [VM/Migrate] Ask user before forcing migration [#2136](https://github.com/vatesfr/xen-orchestra/issues/2136) (PR [#4364](https://github.com/vatesfr/xen-orchestra/pull/4364))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [New network] Fix bonded network not linked to the slave hosts [#4529](https://github.com/vatesfr/xen-orchestra/issues/4529) (PR [#4756](https://github.com/vatesfr/xen-orchestra/pull/4756))
|
||||
|
||||
### Dropped features
|
||||
|
||||
- [Backup / Overview] Job cancellation will be disabled until we find a way to make it work [#4657](https://github.com/vatesfr/xen-orchestra/issues/4657) (PR [#4688](https://github.com/vatesfr/xen-orchestra/pull/4688))
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-common v0.3.0
|
||||
- xo-server v5.56.0
|
||||
- xo-web v5.56.1
|
||||
|
||||
## **5.42.1** (2020-01-17)
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [Snapshot] Fallback to normal snapshot if quiesce is not available [#4735](https://github.com/vatesfr/xen-orchestra/issues/4735) (PR [#4736](https://github.com/vatesfr/xen-orchestra/pull/4736)) \
|
||||
Fixes compatibility with **Citrix Hypervisor 8.1**.
|
||||
- [Uncompressed full backup] Quick healthcheck of downloaded XVAs in case there was an undetected issue (PR [#4741](https://github.com/vatesfr/xen-orchestra/pull/4741))
|
||||
- [Backup] Make built-in concurrency limits configurable (PR [#4743](https://github.com/vatesfr/xen-orchestra/pull/4743)) \
|
||||
Via the following entries in `xo-server`'s configuration file:
|
||||
- `xapiOptions.vdiExportConcurrency`
|
||||
- `xapiOptions.vmExportConcurrency`
|
||||
- `xapiOptions.vmSnapshotConcurrency`
|
||||
|
||||
### Released packages
|
||||
|
||||
- xo-server v5.55.0
|
||||
- xo-web v5.55.0
|
||||
|
||||
## **5.42.0** (2019-12-20)
|
||||
|
||||

|
||||
|
||||
### Highlights
|
||||
|
||||
- [SDN Controller] Allow private network creation on bond and VLAN (PR [#4682](https://github.com/vatesfr/xen-orchestra/pull/4682))
|
||||
- [Hub/recipes] [Ability to create a kubernetes cluster](https://xen-orchestra.com/blog/devblog-5-kubernetes-clutser-on-xo/) (PR [#4695](https://github.com/vatesfr/xen-orchestra/pull/4695))
|
||||
- [Hub/recipes][ability to create a kubernetes cluster](https://xen-orchestra.com/blog/devblog-5-kubernetes-clutser-on-xo/) (PR [#4695](https://github.com/vatesfr/xen-orchestra/pull/4695))
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -29,13 +314,11 @@
|
||||
|
||||
## **5.41.0** (2019-11-29)
|
||||
|
||||

|
||||
|
||||
### Highlights
|
||||
|
||||
- [Backup NG] Make report recipients configurable in the backup settings [#4581](https://github.com/vatesfr/xen-orchestra/issues/4581) (PR [#4646](https://github.com/vatesfr/xen-orchestra/pull/4646))
|
||||
- [Host] Advanced Live Telemetry (PR [#4680](https://github.com/vatesfr/xen-orchestra/pull/4680))
|
||||
- [Plugin] [Web hooks](https://xen-orchestra.com/docs/web-hooks.html) [#1946](https://github.com/vatesfr/xen-orchestra/issues/1946) (PR [#3155](https://github.com/vatesfr/xen-orchestra/pull/3155))
|
||||
- [Plugin][web hooks](https://xen-orchestra.com/docs/web-hooks.html) [#1946](https://github.com/vatesfr/xen-orchestra/issues/1946) (PR [#3155](https://github.com/vatesfr/xen-orchestra/pull/3155))
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -131,7 +414,6 @@
|
||||
|
||||
- xo-server-cloud : this package was useless for OpenSource installations because it required a complete XOA environment
|
||||
|
||||
|
||||
## **5.39.1** (2019-10-11)
|
||||
|
||||
### Enhancements
|
||||
@@ -147,7 +429,6 @@
|
||||
|
||||
- xo-web v5.50.3
|
||||
|
||||
|
||||
## **5.39.0** (2019-09-30)
|
||||
|
||||
### Highlights
|
||||
@@ -189,7 +470,6 @@
|
||||
- [Backup NG] Properly log and report if job is already running [#4497](https://github.com/vatesfr/xen-orchestra/issues/4497) (PR [4534](https://github.com/vatesfr/xen-orchestra/pull/4534))
|
||||
- [Host] Fix an issue where host was wrongly reporting time inconsistency (PR [#4540](https://github.com/vatesfr/xen-orchestra/pull/4540))
|
||||
|
||||
|
||||
### Released packages
|
||||
|
||||
- xen-api v0.27.2
|
||||
@@ -200,7 +480,6 @@
|
||||
- xo-server v5.50.1
|
||||
- xo-web v5.50.2
|
||||
|
||||
|
||||
## **5.38.0** (2019-08-29)
|
||||
|
||||
### Enhancements
|
||||
@@ -377,9 +656,9 @@
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- [Continuous Replication] Fix VHD size guess for empty files [#4105](https://github.com/vatesfr/xen-orchestra/issues/4105) (PR [#4107](https://github.com/vatesfr/xen-orchestra/pull/4107))
|
||||
- [Continuous Replication] Fix VHD size guess for empty files [#4105](https://github.com/vatesfr/xen-orchestra/issues/4105) (PR [#4107](https://github.com/vatesfr/xen-orchestra/pull/4107))
|
||||
- [Backup NG] Only display full backup interval in case of a delta backup (PR [#4125](https://github.com/vatesfr/xen-orchestra/pull/4107))
|
||||
- [Dashboard/Health] fix 'an error has occurred' on the storage state table [#4128](https://github.com/vatesfr/xen-orchestra/issues/4128) (PR [#4132](https://github.com/vatesfr/xen-orchestra/pull/4132))
|
||||
- [Dashboard/Health] fix 'an error has occurred' on the storage state table [#4128](https://github.com/vatesfr/xen-orchestra/issues/4128) (PR [#4132](https://github.com/vatesfr/xen-orchestra/pull/4132))
|
||||
- [Menu] XOA: Fixed empty slot when menu is collapsed [#4012](https://github.com/vatesfr/xen-orchestra/issues/4012) (PR [#4068](https://github.com/vatesfr/xen-orchestra/pull/4068)
|
||||
- [Self/New VM] Fix missing templates when refreshing page [#3265](https://github.com/vatesfr/xen-orchestra/issues/3265) (PR [#3565](https://github.com/vatesfr/xen-orchestra/pull/3565))
|
||||
- [Home] No more false positives when select Tag on Home page [#4087](https://github.com/vatesfr/xen-orchestra/issues/4087) (PR [#4112](https://github.com/vatesfr/xen-orchestra/pull/4112))
|
||||
@@ -415,7 +694,7 @@
|
||||
- Enable compression for HTTP requests (and initial objects fetch)
|
||||
- [VDI migration] Display same-pool SRs first in the selector [#3945](https://github.com/vatesfr/xen-orchestra/issues/3945) (PR [#3996](https://github.com/vatesfr/xen-orchestra/pull/3996))
|
||||
- [Home] Save the current page in url [#3993](https://github.com/vatesfr/xen-orchestra/issues/3993) (PR [#3999](https://github.com/vatesfr/xen-orchestra/pull/3999))
|
||||
- [VDI] Ensure suspend VDI is destroyed when destroying a VM [#4027](https://github.com/vatesfr/xen-orchestra/issues/4027) (PR [#4038](https://github.com/vatesfr/xen-orchestra/pull/4038))
|
||||
- [VDI] Ensure suspend VDI is destroyed when destroying a VM [#4027](https://github.com/vatesfr/xen-orchestra/issues/4027) (PR [#4038](https://github.com/vatesfr/xen-orchestra/pull/4038))
|
||||
- [VM/disk]: Warning when 2 VDIs are on 2 different hosts' local SRs [#3911](https://github.com/vatesfr/xen-orchestra/issues/3911) (PR [#3969](https://github.com/vatesfr/xen-orchestra/pull/3969))
|
||||
- [Remotes] Benchmarks (read and write rate speed) added when remote is tested [#3991](https://github.com/vatesfr/xen-orchestra/issues/3991) (PR [#4015](https://github.com/vatesfr/xen-orchestra/pull/4015))
|
||||
- [Cloud Config] Support both NoCloud and Config Drive 2 datasources for maximum compatibility (PR [#4053](https://github.com/vatesfr/xen-orchestra/pull/4053))
|
||||
@@ -490,7 +769,7 @@
|
||||
- [Home/VM] Show creation date of the VM on if it available [#3953](https://github.com/vatesfr/xen-orchestra/issues/3953) (PR [#3959](https://github.com/vatesfr/xen-orchestra/pull/3959))
|
||||
- [Notifications] Fix invalid notifications when not registered (PR [#3966](https://github.com/vatesfr/xen-orchestra/pull/3966))
|
||||
- [Import] Fix import of some OVA files [#3962](https://github.com/vatesfr/xen-orchestra/issues/3962) (PR [#3974](https://github.com/vatesfr/xen-orchestra/pull/3974))
|
||||
- [Servers] Fix *already connected error* after a server has been removed during connection [#3976](https://github.com/vatesfr/xen-orchestra/issues/3976) (PR [#3977](https://github.com/vatesfr/xen-orchestra/pull/3977))
|
||||
- [Servers] Fix _already connected error_ after a server has been removed during connection [#3976](https://github.com/vatesfr/xen-orchestra/issues/3976) (PR [#3977](https://github.com/vatesfr/xen-orchestra/pull/3977))
|
||||
- [Backup] Fix random _mount_ issues with NFS/SMB remotes [#3973](https://github.com/vatesfr/xen-orchestra/issues/3973) (PR [#4003](https://github.com/vatesfr/xen-orchestra/pull/4003))
|
||||
|
||||
### Released packages
|
||||
@@ -567,7 +846,7 @@
|
||||
- [Self] Display sorted Resource Sets [#3818](https://github.com/vatesfr/xen-orchestra/issues/3818) (PR [#3823](https://github.com/vatesfr/xen-orchestra/pull/3823))
|
||||
- [Servers] Correctly report connecting status (PR [#3838](https://github.com/vatesfr/xen-orchestra/pull/3838))
|
||||
- [Servers] Fix cannot reconnect to a server after connection has been lost [#3839](https://github.com/vatesfr/xen-orchestra/issues/3839) (PR [#3841](https://github.com/vatesfr/xen-orchestra/pull/3841))
|
||||
- [New VM] Fix `NO_HOSTS_AVAILABLE()` error when creating a VM on a local SR from template on another local SR [#3084](https://github.com/vatesfr/xen-orchestra/issues/3084) (PR [#3827](https://github.com/vatesfr/xen-orchestra/pull/3827))
|
||||
- [New VM] Fix `NO_HOSTS_AVAILABLE()` error when creating a VM on a local SR from template on another local SR [#3084](https://github.com/vatesfr/xen-orchestra/issues/3084) (PR [#3827](https://github.com/vatesfr/xen-orchestra/pull/3827))
|
||||
- [Backup NG] Fix typo in the form [#3854](https://github.com/vatesfr/xen-orchestra/issues/3854) (PR [#3855](https://github.com/vatesfr/xen-orchestra/pull/3855))
|
||||
- [New SR] No warning when creating a NFS SR on a path that is already used as NFS SR [#3844](https://github.com/vatesfr/xen-orchestra/issues/3844) (PR [#3851](https://github.com/vatesfr/xen-orchestra/pull/3851))
|
||||
- [New SR] No redirection if the SR creation failed or canceled [#3843](https://github.com/vatesfr/xen-orchestra/issues/3843) (PR [#3853](https://github.com/vatesfr/xen-orchestra/pull/3853))
|
||||
@@ -579,7 +858,7 @@
|
||||
- [VM creation] Broken CloudInit config drive when VM created on local SR
|
||||
- [Legacy Backup] Fix error when restoring a backup
|
||||
- [Home] Fix `user.getAll` error when user is not admin [#3573](https://github.com/vatesfr/xen-orchestra/issues/3573) (PR [#3918](https://github.com/vatesfr/xen-orchestra/pull/3918))
|
||||
- [Backup NG] Fix restore issue when a disk has grown [#3910](https://github.com/vatesfr/xen-orchestra/issues/3910) (PR [#3920](https://github.com/vatesfr/xen-orchestra/pull/3920))
|
||||
- [Backup NG] Fix restore issue when a disk has grown [#3910](https://github.com/vatesfr/xen-orchestra/issues/3910) (PR [#3920](https://github.com/vatesfr/xen-orchestra/pull/3920))
|
||||
- [Backup NG] Delete _importing_ VMs due to interrupted CR/DR (PR [#3923](https://github.com/vatesfr/xen-orchestra/pull/3923))
|
||||
|
||||
### Released packages
|
||||
@@ -807,7 +1086,7 @@
|
||||
### Enhancements
|
||||
|
||||
- [Remotes] Test the remote automatically on changes [#3323](https://github.com/vatesfr/xen-orchestra/issues/3323) (PR [#3397](https://github.com/vatesfr/xen-orchestra/pull/3397))
|
||||
- [Remotes] Use *WORKGROUP* as default domain for new SMB remote (PR [#3398](https://github.com/vatesfr/xen-orchestra/pull/3398))
|
||||
- [Remotes] Use _WORKGROUP_ as default domain for new SMB remote (PR [#3398](https://github.com/vatesfr/xen-orchestra/pull/3398))
|
||||
- [Backup NG form] Display a tip to encourage users to create vms on a thin-provisioned storage [#3334](https://github.com/vatesfr/xen-orchestra/issues/3334) (PR [#3402](https://github.com/vatesfr/xen-orchestra/pull/3402))
|
||||
- [Backup NG form] improve schedule's form [#3138](https://github.com/vatesfr/xen-orchestra/issues/3138) (PR [#3359](https://github.com/vatesfr/xen-orchestra/pull/3359))
|
||||
- [Backup NG Overview] Display transferred and merged data size for backup jobs [#3340](https://github.com/vatesfr/xen-orchestra/issues/3340) (PR [#3408](https://github.com/vatesfr/xen-orchestra/pull/3408))
|
||||
@@ -824,7 +1103,7 @@
|
||||
- [Backup NG] Don't fail on VMs with empty VBDs (like CDs or floppy disks) (PR [#3410](https://github.com/vatesfr/xen-orchestra/pull/3410))
|
||||
- [XOA updater] Fix issue where trial request would fail [#3407](https://github.com/vatesfr/xen-orchestra/issues/3407) (PR [#3412](https://github.com/vatesfr/xen-orchestra/pull/3412))
|
||||
- [Backup NG logs] Fix log's value not being updated in the copy and report button [#3273](https://github.com/vatesfr/xen-orchestra/issues/3273) (PR [#3360](https://github.com/vatesfr/xen-orchestra/pull/3360))
|
||||
- [Backup NG] Fix issue when *Delete first* was enabled for some of the remotes [#3424](https://github.com/vatesfr/xen-orchestra/issues/3424) (PR [#3427](https://github.com/vatesfr/xen-orchestra/pull/3427))
|
||||
- [Backup NG] Fix issue when _Delete first_ was enabled for some of the remotes [#3424](https://github.com/vatesfr/xen-orchestra/issues/3424) (PR [#3427](https://github.com/vatesfr/xen-orchestra/pull/3427))
|
||||
- [VM/host consoles] Work around a XenServer/XCP-ng issue which lead to some consoles not working [#3432](https://github.com/vatesfr/xen-orchestra/issues/3432) (PR [#3435](https://github.com/vatesfr/xen-orchestra/pull/3435))
|
||||
- [Backup NG] Remove extraneous snapshots in case of multiple schedules [#3132](https://github.com/vatesfr/xen-orchestra/issues/3132) (PR [#3439](https://github.com/vatesfr/xen-orchestra/pull/3439))
|
||||
- [Backup NG] Fix page reloaded on creating a schedule [#3461](https://github.com/vatesfr/xen-orchestra/issues/3461) (PR [#3462](https://github.com/vatesfr/xen-orchestra/pull/3462))
|
||||
@@ -1004,7 +1283,7 @@
|
||||
- Make cloud config templates available for all users [3147](https://github.com/vatesfr/xen-orchestra/issues/3147) (PR [3148](https://github.com/vatesfr/xen-orchestra/pull/3148))
|
||||
- [New VM] Only create the cloud config drive when its option is enabled [3161](https://github.com/vatesfr/xen-orchestra/issues/3161) (PR [3162](https://github.com/vatesfr/xen-orchestra/pull/3162))
|
||||
- Fix error when installing patches from the host or without a default SR (PR [3166](https://github.com/vatesfr/xen-orchestra/pull/3166))
|
||||
- [Backup NG] Fix SMB *Not implemented* issue [#3149](](https://github.com/vatesfr/xen-orchestra/issues/3149) (PR [3175](https://github.com/vatesfr/xen-orchestra/pull/3175))
|
||||
- [Backup NG] Fix SMB _Not implemented_ issue [#3149](<](https://github.com/vatesfr/xen-orchestra/issues/3149)> 'PR [3175](https://github.com/vatesfr/xen-orchestra/pull/3175')
|
||||
|
||||
### Released packages
|
||||
|
||||
@@ -1118,10 +1397,9 @@
|
||||
- Hook/action if an export stream is cut [#1929](https://github.com/vatesfr/xen-orchestra/issues/1929)
|
||||
- Backup paths should not contain tags but job ids [#1854](https://github.com/vatesfr/xen-orchestra/issues/1854)
|
||||
- Add a button to delete a backup [#1751](https://github.com/vatesfr/xen-orchestra/issues/1751)
|
||||
- Dashboard available for Pool and Host level [#1631](https://github.com/vatesfr/xen-orchestra/issues/1631)
|
||||
- UI Enhancement - VM list - Allways show the Toolbar [#1581](https://github.com/vatesfr/xen-orchestra/issues/1581)
|
||||
- xoa-updater --register: unable to define proxy using the CLI [#873](https://github.com/vatesfr/xen-orchestra/issues/873)
|
||||
|
||||
- Dashboard available for Pool and Host level [#1631](https://github.com/vatesfr/xen-orchestra/issues/1631)
|
||||
- UI Enhancement - VM list - Allways show the Toolbar [#1581](https://github.com/vatesfr/xen-orchestra/issues/1581)
|
||||
- xoa-updater --register: unable to define proxy using the CLI [#873](https://github.com/vatesfr/xen-orchestra/issues/873)
|
||||
|
||||
### Bugs
|
||||
|
||||
@@ -1162,7 +1440,7 @@
|
||||
- Set a self-service VM at "share" after creation [#2589](https://github.com/vatesfr/xen-orchestra/issues/2589)
|
||||
- [Backup logs] Improve Unhealthy VDI Chain message [#2586](https://github.com/vatesfr/xen-orchestra/issues/2586)
|
||||
- [SortedTable] Put sort criteria in URL like the filter [#2584](https://github.com/vatesfr/xen-orchestra/issues/2584)
|
||||
- Cant attach XenTools on User side. [#2503](https://github.com/vatesfr/xen-orchestra/issues/2503)
|
||||
- Cant attach XenTools on User side. [#2503](https://github.com/vatesfr/xen-orchestra/issues/2503)
|
||||
- Pool filter for health view [#2302](https://github.com/vatesfr/xen-orchestra/issues/2302)
|
||||
- [Smart Backup] Improve feedback [#2253](https://github.com/vatesfr/xen-orchestra/issues/2253)
|
||||
- Backup jobs stuck if no space left on NFS remote [#2116](https://github.com/vatesfr/xen-orchestra/issues/2116)
|
||||
@@ -1193,7 +1471,7 @@
|
||||
- Move VM In to/Out of Self Service Group [#1913](https://github.com/vatesfr/xen-orchestra/issues/1913)
|
||||
- Two factor auth [#1897](https://github.com/vatesfr/xen-orchestra/issues/1897)
|
||||
- token.create should accept an expiration [#1769](https://github.com/vatesfr/xen-orchestra/issues/1769)
|
||||
- Self Service User - User don't have quota in his dashboard [#1538](https://github.com/vatesfr/xen-orchestra/issues/1538)
|
||||
- Self Service User - User don't have quota in his dashboard [#1538](https://github.com/vatesfr/xen-orchestra/issues/1538)
|
||||
- Remove CoffeeScript in xo-server [#189](https://github.com/vatesfr/xen-orchestra/issues/189)
|
||||
- Better Handling of suspending VMs from the Home screen [#2547](https://github.com/vatesfr/xen-orchestra/issues/2547)
|
||||
- [xen-api] Stronger reconnection policy [#2410](https://github.com/vatesfr/xen-orchestra/issues/2410)
|
||||
@@ -1212,7 +1490,6 @@
|
||||
- TZ selector is not used for backup schedule preview [#2464](https://github.com/vatesfr/xen-orchestra/issues/2464)
|
||||
- Remove filter in VM/network view [#2548](https://github.com/vatesfr/xen-orchestra/issues/2548)
|
||||
|
||||
|
||||
## **5.15.0** (2017-12-29)
|
||||
|
||||
### Enhancements
|
||||
@@ -1221,7 +1498,7 @@
|
||||
- Smart replace VDI.pool_migrate removed from XenServer 7.3 Free [#2541](https://github.com/vatesfr/xen-orchestra/issues/2541)
|
||||
- New memory constraints in XenServer 7.3 [#2540](https://github.com/vatesfr/xen-orchestra/issues/2540)
|
||||
- Link to Settings/Logs for admins in error notifications [#2516](https://github.com/vatesfr/xen-orchestra/issues/2516)
|
||||
- [Self Service] Do not use placehodlers to describe inputs [#2509](https://github.com/vatesfr/xen-orchestra/issues/2509)
|
||||
- [Self Service] Do not use placehodlers to describe inputs [#2509](https://github.com/vatesfr/xen-orchestra/issues/2509)
|
||||
- Obfuscate password in log in LDAP plugin test [#2506](https://github.com/vatesfr/xen-orchestra/issues/2506)
|
||||
- Log rotation [#2492](https://github.com/vatesfr/xen-orchestra/issues/2492)
|
||||
- Continuous Replication TAG [#2473](https://github.com/vatesfr/xen-orchestra/issues/2473)
|
||||
@@ -1238,7 +1515,6 @@
|
||||
- Cloud config drive create fail on XenServer < 7 [#2478](https://github.com/vatesfr/xen-orchestra/issues/2478)
|
||||
- VM create fails due to missing vGPU id [#2466](https://github.com/vatesfr/xen-orchestra/issues/2466)
|
||||
|
||||
|
||||
## **5.14.0** (2017-10-31)
|
||||
|
||||
### Enhancements
|
||||
@@ -1288,9 +1564,9 @@
|
||||
- Warning on SMB remote creation [#2316](https://github.com/vatesfr/xen-orchestra/issues/2316)
|
||||
- [Home | SortedTable] Add link to syntax doc in the filter input [#2305](https://github.com/vatesfr/xen-orchestra/issues/2305)
|
||||
- [SortedTable] Add optional binding of filter to an URL query [#2301](https://github.com/vatesfr/xen-orchestra/issues/2301)
|
||||
- [Home][Keyboard navigation] Allow selecting the objects [#2214](https://github.com/vatesfr/xen-orchestra/issues/2214)
|
||||
- [Home][keyboard navigation] Allow selecting the objects [#2214](https://github.com/vatesfr/xen-orchestra/issues/2214)
|
||||
- SR view / Disks: option to display non managed VDIs [#1724](https://github.com/vatesfr/xen-orchestra/issues/1724)
|
||||
- Continuous Replication Retention [#1692](https://github.com/vatesfr/xen-orchestra/issues/1692)
|
||||
- Continuous Replication Retention [#1692](https://github.com/vatesfr/xen-orchestra/issues/1692)
|
||||
|
||||
### Bugs
|
||||
|
||||
@@ -1298,7 +1574,7 @@
|
||||
- Errors in VM copy are not properly reported [#2347](https://github.com/vatesfr/xen-orchestra/issues/2347)
|
||||
- Removing a PIF IP fails [#2346](https://github.com/vatesfr/xen-orchestra/issues/2346)
|
||||
- Review and fix creating a VM from a snapshot [#2343](https://github.com/vatesfr/xen-orchestra/issues/2343)
|
||||
- iSCSI LUN Detection fails with authentification [#2339](https://github.com/vatesfr/xen-orchestra/issues/2339)
|
||||
- iSCSI LUN Detection fails with authentification [#2339](https://github.com/vatesfr/xen-orchestra/issues/2339)
|
||||
- Fix PoolActionBar to add a new SR [#2307](https://github.com/vatesfr/xen-orchestra/issues/2307)
|
||||
- [VM migration] Error if default SR not accessible to target host [#2180](https://github.com/vatesfr/xen-orchestra/issues/2180)
|
||||
- A job shouldn't executable more than once at the same time [#2053](https://github.com/vatesfr/xen-orchestra/issues/2053)
|
||||
@@ -1316,9 +1592,9 @@
|
||||
- [SortedTable] Add grouped actions feature [#2276](https://github.com/vatesfr/xen-orchestra/issues/2276)
|
||||
- Add a filter to the backups' log [#2246](https://github.com/vatesfr/xen-orchestra/issues/2246)
|
||||
- It should not be possible to migrate a halted VM. [#2233](https://github.com/vatesfr/xen-orchestra/issues/2233)
|
||||
- [Home][Keyboard navigation] Allow selecting the objects [#2214](https://github.com/vatesfr/xen-orchestra/issues/2214)
|
||||
- [Home][keyboard navigation] Allow selecting the objects [#2214](https://github.com/vatesfr/xen-orchestra/issues/2214)
|
||||
- Allow to set pool master [#2213](https://github.com/vatesfr/xen-orchestra/issues/2213)
|
||||
- Continuous Replication Retention [#1692](https://github.com/vatesfr/xen-orchestra/issues/1692)
|
||||
- Continuous Replication Retention [#1692](https://github.com/vatesfr/xen-orchestra/issues/1692)
|
||||
|
||||
### Bugs
|
||||
|
||||
@@ -1399,8 +1675,7 @@
|
||||
- Select is "moving" [\#2142](https://github.com/vatesfr/xen-orchestra/issues/2142)
|
||||
- Select issue for affinity host [\#2141](https://github.com/vatesfr/xen-orchestra/issues/2141)
|
||||
- Dashboard Storage Usage incorrect [\#2123](https://github.com/vatesfr/xen-orchestra/issues/2123)
|
||||
- Detect unmerged *base copy* and prevent too long chains [\#2047](https://github.com/vatesfr/xen-orchestra/issues/2047)
|
||||
|
||||
- Detect unmerged _base copy_ and prevent too long chains [\#2047](https://github.com/vatesfr/xen-orchestra/issues/2047)
|
||||
|
||||
## **5.8.0** (2017-04-28)
|
||||
|
||||
@@ -1462,7 +1737,7 @@
|
||||
|
||||
- Missing objects should be displayed in backup edition [\#2052](https://github.com/vatesfr/xen-orchestra/issues/2052)
|
||||
- Search bar content changes while typing [\#2035](https://github.com/vatesfr/xen-orchestra/issues/2035)
|
||||
- VM.$guest_metrics.PV_drivers_up_to_date is deprecated in XS 7.1 [\#2024](https://github.com/vatesfr/xen-orchestra/issues/2024)
|
||||
- VM.\$guest_metrics.PV_drivers_up_to_date is deprecated in XS 7.1 [\#2024](https://github.com/vatesfr/xen-orchestra/issues/2024)
|
||||
- Bootable flag selection checkbox for extra disk not fetched [\#1994](https://github.com/vatesfr/xen-orchestra/issues/1994)
|
||||
- Home view − Changing type must reset paging [\#1993](https://github.com/vatesfr/xen-orchestra/issues/1993)
|
||||
- XOSAN menu item should only be displayed to admins [\#1968](https://github.com/vatesfr/xen-orchestra/issues/1968)
|
||||
@@ -1548,7 +1823,7 @@ File level restore.
|
||||
- Use paginated table for backup jobs [\#1726](https://github.com/vatesfr/xen-orchestra/issues/1726)
|
||||
- SR view / Disks: should display snapshot VDIs [\#1723](https://github.com/vatesfr/xen-orchestra/issues/1723)
|
||||
- Restored VM should have an identifiable name [\#1719](https://github.com/vatesfr/xen-orchestra/issues/1719)
|
||||
- If host reboot action returns NO\_HOSTS\_AVAILABLE, ask to force [\#1717](https://github.com/vatesfr/xen-orchestra/issues/1717)
|
||||
- If host reboot action returns NO_HOSTS_AVAILABLE, ask to force [\#1717](https://github.com/vatesfr/xen-orchestra/issues/1717)
|
||||
- Hide xo-server timezone in backups [\#1706](https://github.com/vatesfr/xen-orchestra/issues/1706)
|
||||
- Enable hyperlink for Hostname for Issues [\#1700](https://github.com/vatesfr/xen-orchestra/issues/1700)
|
||||
- Pool/network - Modify column [\#1696](https://github.com/vatesfr/xen-orchestra/issues/1696)
|
||||
@@ -1572,15 +1847,15 @@ File level restore.
|
||||
|
||||
- Should jobs be accessible to non admins? [\#1759](https://github.com/vatesfr/xen-orchestra/issues/1759)
|
||||
- Schedules deletion is not working [\#1737](https://github.com/vatesfr/xen-orchestra/issues/1737)
|
||||
- Editing a job from the jobs overview page does not work [\#1736](https://github.com/vatesfr/xen-orchestra/issues/1736)
|
||||
- Editing a schedule from jobs overview does not work [\#1728](https://github.com/vatesfr/xen-orchestra/issues/1728)
|
||||
- Editing a job from the jobs overview page does not work [\#1736](https://github.com/vatesfr/xen-orchestra/issues/1736)
|
||||
- Editing a schedule from jobs overview does not work [\#1728](https://github.com/vatesfr/xen-orchestra/issues/1728)
|
||||
- ACLs not correctly imported [\#1722](https://github.com/vatesfr/xen-orchestra/issues/1722)
|
||||
- Some Bootstrap style broken [\#1721](https://github.com/vatesfr/xen-orchestra/issues/1721)
|
||||
- Not properly sign out on auth token expiration [\#1711](https://github.com/vatesfr/xen-orchestra/issues/1711)
|
||||
- Hosts/<UUID>/network status is incorrect [\#1702](https://github.com/vatesfr/xen-orchestra/issues/1702)
|
||||
- Patches application fails "Found : Moved Temporarily" [\#1701](https://github.com/vatesfr/xen-orchestra/issues/1701)
|
||||
- Password generation for user creation is not working [\#1678](https://github.com/vatesfr/xen-orchestra/issues/1678)
|
||||
- \#/dashboard/health Remove All Orphaned VDIs [\#1622](https://github.com/vatesfr/xen-orchestra/issues/1622)
|
||||
- \#/dashboard/health Remove All Orphaned VDIs [\#1622](https://github.com/vatesfr/xen-orchestra/issues/1622)
|
||||
- Create a new SR - CIFS/SAMBA Broken [\#1615](https://github.com/vatesfr/xen-orchestra/issues/1615)
|
||||
- xo-cli --list-objects: truncated output ? 64k buffer limitation ? [\#1356](https://github.com/vatesfr/xen-orchestra/issues/1356)
|
||||
|
||||
@@ -1759,7 +2034,7 @@ File level restore.
|
||||
- Button to recompute resource sets limits [\#1287](https://github.com/vatesfr/xen-orchestra/issues/1287)
|
||||
- Credit scheduler CAP and weight configuration [\#1283](https://github.com/vatesfr/xen-orchestra/issues/1283)
|
||||
- Migration form problem on the /v5/vms/\_\_UUID\_\_ page when doing xenmotion inside a pool [\#1254](https://github.com/vatesfr/xen-orchestra/issues/1254)
|
||||
- /v5/\#/pools/\_\_UUID\_\_: patch table improvement [\#1246](https://github.com/vatesfr/xen-orchestra/issues/1246)
|
||||
- /v5/\#/pools/\_\_UUID\_\_: patch table improvement [\#1246](https://github.com/vatesfr/xen-orchestra/issues/1246)
|
||||
- /v5/\#/hosts/\_\_UUID\_\_: patch list improvements ? [\#1245](https://github.com/vatesfr/xen-orchestra/issues/1245)
|
||||
- F\*cking patches, how do they work? [\#1236](https://github.com/vatesfr/xen-orchestra/issues/1236)
|
||||
- Change Default Filter [\#1235](https://github.com/vatesfr/xen-orchestra/issues/1235)
|
||||
@@ -1814,7 +2089,7 @@ File level restore.
|
||||
- Scheduled jobs seems use GMT since 5.0 [\#1258](https://github.com/vatesfr/xen-orchestra/issues/1258)
|
||||
- Can't create a VM with disks on 2 different SRs [\#1257](https://github.com/vatesfr/xen-orchestra/issues/1257)
|
||||
- Graph display bug [\#1247](https://github.com/vatesfr/xen-orchestra/issues/1247)
|
||||
- /v5/#/hosts/__UUID__: Patch list not limited to the current pool [\#1244](https://github.com/vatesfr/xen-orchestra/issues/1244)
|
||||
- /v5/#/hosts/**UUID**: Patch list not limited to the current pool [\#1244](https://github.com/vatesfr/xen-orchestra/issues/1244)
|
||||
- Replication issues [\#1233](https://github.com/vatesfr/xen-orchestra/issues/1233)
|
||||
- VM creation install method disabled fields [\#1198](https://github.com/vatesfr/xen-orchestra/issues/1198)
|
||||
- Update icon shouldn't be displayed when menu is collapsed [\#1188](https://github.com/vatesfr/xen-orchestra/issues/1188)
|
||||
@@ -1852,10 +2127,10 @@ File level restore.
|
||||
- Show HVM, PVM, PVHVM modes in guest details [\#806](https://github.com/vatesfr/xen-orchestra/issues/806)
|
||||
- Tree view: display cpu available/total for each host [\#696](https://github.com/vatesfr/xen-orchestra/issues/696)
|
||||
- Greenkeeper integration [\#667](https://github.com/vatesfr/xen-orchestra/issues/667)
|
||||
- Clarify vCPUs and RAM editor [\#658](https://github.com/vatesfr/xen-orchestra/issues/658)
|
||||
- Clarify vCPUs and RAM editor [\#658](https://github.com/vatesfr/xen-orchestra/issues/658)
|
||||
- Backup LZ4 compression [\#647](https://github.com/vatesfr/xen-orchestra/issues/647)
|
||||
- Support enum in plugins configuration [\#638](https://github.com/vatesfr/xen-orchestra/issues/638)
|
||||
- Add configuration option to disable xoa-updater [\#535](https://github.com/vatesfr/xen-orchestra/issues/535)
|
||||
- Add configuration option to disable xoa-updater [\#535](https://github.com/vatesfr/xen-orchestra/issues/535)
|
||||
- Use cursors to add more context to actions [\#523](https://github.com/vatesfr/xen-orchestra/issues/523)
|
||||
- Review UI for flat view [\#354](https://github.com/vatesfr/xen-orchestra/issues/354)
|
||||
- Review UI for the tree view [\#353](https://github.com/vatesfr/xen-orchestra/issues/353)
|
||||
@@ -1865,7 +2140,7 @@ File level restore.
|
||||
- Ability to collapse pools/hosts in main view [\#173](https://github.com/vatesfr/xen-orchestra/issues/173)
|
||||
- Issue importing .xva VM via xo-web [\#1022](https://github.com/vatesfr/xen-orchestra/issues/1022)
|
||||
- Enhancement Proposal - Cancel In Progress Backups [\#1003](https://github.com/vatesfr/xen-orchestra/issues/1003)
|
||||
- Can't create VM with CloudConfigDrive [\#917](https://github.com/vatesfr/xen-orchestra/issues/917)
|
||||
- Can't create VM with CloudConfigDrive [\#917](https://github.com/vatesfr/xen-orchestra/issues/917)
|
||||
- Auth: LDAP User causes problems [\#893](https://github.com/vatesfr/xen-orchestra/issues/893)
|
||||
- No tags in Continuous Replication [\#838](https://github.com/vatesfr/xen-orchestra/issues/838)
|
||||
- Delta backup Depth not working [\#802](https://github.com/vatesfr/xen-orchestra/issues/802)
|
||||
@@ -1881,20 +2156,20 @@ File level restore.
|
||||
|
||||
- vCPUs number when no tools installed [\#1089](https://github.com/vatesfr/xen-orchestra/issues/1089)
|
||||
- Config Drive textbox disappears when content is deleted [\#1012](https://github.com/vatesfr/xen-orchestra/issues/1012)
|
||||
- storage status not changed in host view page after disconnect/connect [\#1009](https://github.com/vatesfr/xen-orchestra/issues/1009)
|
||||
- storage status not changed in host view page after disconnect/connect [\#1009](https://github.com/vatesfr/xen-orchestra/issues/1009)
|
||||
- Cannot Delete Logs From Backup Overview [\#1004](https://github.com/vatesfr/xen-orchestra/issues/1004)
|
||||
- \[v5.x\] Plugins configuration: optional non-used objects are sent [\#1000](https://github.com/vatesfr/xen-orchestra/issues/1000)
|
||||
- "@" char in remote password break the remote view [\#997](https://github.com/vatesfr/xen-orchestra/issues/997)
|
||||
- Handle MEMORY\_CONSTRAINT\_VIOLATION correctly [\#970](https://github.com/vatesfr/xen-orchestra/issues/970)
|
||||
- Handle MEMORY_CONSTRAINT_VIOLATION correctly [\#970](https://github.com/vatesfr/xen-orchestra/issues/970)
|
||||
- VM creation error on XenServer Dundee [\#964](https://github.com/vatesfr/xen-orchestra/issues/964)
|
||||
- Copy VMs doesn't display all SRs [\#945](https://github.com/vatesfr/xen-orchestra/issues/945)
|
||||
- Autopower\_on wrong value [\#937](https://github.com/vatesfr/xen-orchestra/issues/937)
|
||||
- Autopower_on wrong value [\#937](https://github.com/vatesfr/xen-orchestra/issues/937)
|
||||
- Correctly handle unknown users in group view [\#900](https://github.com/vatesfr/xen-orchestra/issues/900)
|
||||
- Importing into Dundee [\#887](https://github.com/vatesfr/xen-orchestra/issues/887)
|
||||
- update status - gui resize issue [\#803](https://github.com/vatesfr/xen-orchestra/issues/803)
|
||||
- Backup Remote Stores Problem [\#751](https://github.com/vatesfr/xen-orchestra/issues/751)
|
||||
- VM view is broken when changing a disk SR twice [\#670](https://github.com/vatesfr/xen-orchestra/issues/670)
|
||||
- console mouse sync [\#280](https://github.com/vatesfr/xen-orchestra/issues/280)
|
||||
- console mouse sync [\#280](https://github.com/vatesfr/xen-orchestra/issues/280)
|
||||
|
||||
## **4.16.0** (2016-04-29)
|
||||
|
||||
@@ -1902,7 +2177,7 @@ Maintenance release
|
||||
|
||||
### Enhancements
|
||||
|
||||
- TOO\_MANY\_PENDING\_TASKS [\#861](https://github.com/vatesfr/xen-orchestra/issues/861)
|
||||
- TOO_MANY_PENDING_TASKS [\#861](https://github.com/vatesfr/xen-orchestra/issues/861)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
@@ -1943,7 +2218,7 @@ Load balancing, SMB delta support, advanced network operations...
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Broken link to backup remote [\#821](https://github.com/vatesfr/xen-orchestra/issues/821)
|
||||
- Broken link to backup remote [\#821](https://github.com/vatesfr/xen-orchestra/issues/821)
|
||||
- Issue with self-signed cert for email plugin [\#817](https://github.com/vatesfr/xen-orchestra/issues/817)
|
||||
- Plugins view, reset form and errors [\#815](https://github.com/vatesfr/xen-orchestra/issues/815)
|
||||
- HVM recovery mode is broken [\#794](https://github.com/vatesfr/xen-orchestra/issues/794)
|
||||
@@ -2097,7 +2372,7 @@ Delta backup, CloudInit...
|
||||
- Allow editing PV args even when empty \(but only for PV VMs\) [\#557](https://github.com/vatesfr/xen-orchestra/issues/557)
|
||||
- Crashes when using legacy event system [\#556](https://github.com/vatesfr/xen-orchestra/issues/556)
|
||||
- XenServer patches check error for 6.1 [\#555](https://github.com/vatesfr/xen-orchestra/issues/555)
|
||||
- activation plugin xo-server-transport-email [\#553](https://github.com/vatesfr/xen-orchestra/issues/553)
|
||||
- activation plugin xo-server-transport-email [\#553](https://github.com/vatesfr/xen-orchestra/issues/553)
|
||||
- Server error with JSON on 32 bits Dom0 [\#552](https://github.com/vatesfr/xen-orchestra/issues/552)
|
||||
- Cloud Config drive shouldn't be created on default SR [\#548](https://github.com/vatesfr/xen-orchestra/issues/548)
|
||||
- Deep properties cannot be edited in plugins configuration form [\#521](https://github.com/vatesfr/xen-orchestra/issues/521)
|
||||
@@ -2365,7 +2640,7 @@ An issue in `xo-server` with the password of default admin account and also a UI
|
||||
|
||||
## **4.0.1** (2015-05-30)
|
||||
|
||||
An issue with the updater in HTTPS was left in the *4.0.0*. This patch release fixed
|
||||
An issue with the updater in HTTPS was left in the _4.0.0_. This patch release fixed
|
||||
it.
|
||||
|
||||
### Bug fixes
|
||||
@@ -2397,10 +2672,9 @@ it.
|
||||
- VM stats behavior more robust ([xo-web#250](https://github.com/vatesfr/xen-orchestra/issues/250))
|
||||
- XO not on the root of domain ([xo-web#254](https://github.com/vatesfr/xen-orchestra/issues/254))
|
||||
|
||||
|
||||
## **3.9.1** (2015-04-21)
|
||||
|
||||
A few bugs hve made their way into *3.9.0*, this minor release fixes
|
||||
A few bugs hve made their way into _3.9.0_, this minor release fixes
|
||||
them.
|
||||
|
||||
### Bug fixes
|
||||
@@ -2451,13 +2725,13 @@ them.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- fix *Invalid parameter(s)* message on the settings page ([xo-server#49](https://github.com/vatesfr/xo-server/issues/49))
|
||||
- fix _Invalid parameter(s)_ message on the settings page ([xo-server#49](https://github.com/vatesfr/xo-server/issues/49))
|
||||
- fix mouse clicks in console ([xo-web#205](https://github.com/vatesfr/xen-orchestra/issues/205))
|
||||
- fix user editing on the settings page ([xo-web#206](https://github.com/vatesfr/xen-orchestra/issues/206))
|
||||
|
||||
## **3.7.0** (2015-03-06)
|
||||
|
||||
*Highlights in this release are the [initial ACLs implementation](https://xen-orchestra.com/blog/xen-orchestra-3-7-is-out-acls-in-early-access), [live migration for VDIs](https://xen-orchestra.com/blog/moving-vdi-in-live) and the ability to [create a new storage repository](https://xen-orchestra.com/blog/create-a-storage-repository-with-xen-orchestra/).*
|
||||
_Highlights in this release are the [initial ACLs implementation](https://xen-orchestra.com/blog/xen-orchestra-3-7-is-out-acls-in-early-access), [live migration for VDIs](https://xen-orchestra.com/blog/moving-vdi-in-live) and the ability to [create a new storage repository](https://xen-orchestra.com/blog/create-a-storage-repository-with-xen-orchestra/)._
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -2484,7 +2758,7 @@ them.
|
||||
- fix console view on IE ([xo-web#184](https://github.com/vatesfr/xen-orchestra/issues/184))
|
||||
- fix out of sync objects in XO-Web ([xo-web#142](https://github.com/vatesfr/xen-orchestra/issues/142))
|
||||
- fix incorrect connection status displayed in login view ([xo-web#193](https://github.com/vatesfr/xen-orchestra/issues/193))
|
||||
- fix *flickering* tree view ([xo-web#194](https://github.com/vatesfr/xen-orchestra/issues/194))
|
||||
- fix _flickering_ tree view ([xo-web#194](https://github.com/vatesfr/xen-orchestra/issues/194))
|
||||
- single host pools should not have a dropdown menu in tree view ([xo-web#198](https://github.com/vatesfr/xen-orchestra/issues/198))
|
||||
|
||||
## **3.6.0** (2014-11-28)
|
||||
@@ -2528,7 +2802,7 @@ them.
|
||||
|
||||
## **3.5.0** (2014-08-14)
|
||||
|
||||
*[XO-Web](https://www.npmjs.org/package/xo-web) and [XO-Server](https://www.npmjs.org/package/xo-server) are now available as npm packages!*
|
||||
_[XO-Web](https://www.npmjs.org/package/xo-web) and [XO-Server](https://www.npmjs.org/package/xo-server) are now available as npm packages!_
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -2554,9 +2828,9 @@ them.
|
||||
|
||||
## **3.4.0** (2014-05-22)
|
||||
|
||||
*Highlight in this release is the new events system between XO-Web
|
||||
_Highlight in this release is the new events system between XO-Web
|
||||
and XO-Server which results in less bandwidth consumption as well as
|
||||
better performance and reactivity.*
|
||||
better performance and reactivity._
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -2590,8 +2864,8 @@ better performance and reactivity.*
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- *Snapshot* not working in VM view ([#95](https://github.com/vatesfr/xen-orchestra/issues/95))
|
||||
- Host *Reboot*/*Restart toolstack*/*Shutdown* not working in main view ([#97](https://github.com/vatesfr/xen-orchestra/issues/97))
|
||||
- _Snapshot_ not working in VM view ([#95](https://github.com/vatesfr/xen-orchestra/issues/95))
|
||||
- Host _Reboot_/_Restart toolstack_/_Shutdown_ not working in main view ([#97](https://github.com/vatesfr/xen-orchestra/issues/97))
|
||||
- Bower cannot install `angular` automatically due to a version conflict ([#101](https://github.com/vatesfr/xen-orchestra/issues/101))
|
||||
- Bower installs an incorrect version of `angular-animate` ([#102](https://github.com/vatesfr/xen-orchestra/issues/102))
|
||||
|
||||
@@ -2619,7 +2893,7 @@ better performance and reactivity.*
|
||||
|
||||
- in VM view, interfaces' network should be displayed ([#64](https://github.com/vatesfr/xen-orchestra/issues/64))
|
||||
- middle-click or `Ctrl`+click should open new windows (even on pseudo-links) ([#66](https://github.com/vatesfr/xen-orchestra/issues/66))
|
||||
- lists should use natural sorting (e.g. *VM 2* before *VM 10*) ([#69](https://github.com/vatesfr/xen-orchestra/issues/69))
|
||||
- lists should use natural sorting (e.g. _VM 2_ before _VM 10_) ([#69](https://github.com/vatesfr/xen-orchestra/issues/69))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
@@ -2627,7 +2901,7 @@ better performance and reactivity.*
|
||||
- it makes no sense to remove a stand-alone host from a pool (58)
|
||||
- in VM view, the migrate button is not working ([#59](https://github.com/vatesfr/xen-orchestra/issues/59))
|
||||
- pool and host names overflow their box in the main view ([#63](https://github.com/vatesfr/xen-orchestra/issues/63))
|
||||
- in host view, interfaces incorrectly named *networks* and VLAN not shown ([#70](https://github.com/vatesfr/xen-orchestra/issues/70))
|
||||
- in host view, interfaces incorrectly named _networks_ and VLAN not shown ([#70](https://github.com/vatesfr/xen-orchestra/issues/70))
|
||||
- VM suspended state is not properly handled ([#71](https://github.com/vatesfr/xen-orchestra/issues/71))
|
||||
- unauthenticated users should not be able to access to consoles ([#73](https://github.com/vatesfr/xen-orchestra/issues/73))
|
||||
- incorrect scroll (under the navbar) when the view changes ([#74](https://github.com/vatesfr/xen-orchestra/issues/74))
|
||||
|
||||
@@ -7,16 +7,50 @@
|
||||
|
||||
> Users must be able to say: “Nice enhancement, I'm eager to test it”
|
||||
|
||||
- [VM/Network] Show IP addresses in front of their VIFs [#4882](https://github.com/vatesfr/xen-orchestra/issues/4882) (PR [#5003](https://github.com/vatesfr/xen-orchestra/pull/5003))
|
||||
- [VM] Ability to protect VM from accidental deletion [#4773](https://github.com/vatesfr/xen-orchestra/issues/4773)
|
||||
- [Plugin] Disable test plugin action when the plugin is not loaded (PR [#5038](https://github.com/vatesfr/xen-orchestra/pull/5038))
|
||||
- [Home/Template] Ability to copy/clone VM templates [#4734](https://github.com/vatesfr/xen-orchestra/issues/4734) (PR [#5006](https://github.com/vatesfr/xen-orchestra/pull/5006))
|
||||
- [VM/bulk copy] Add fast clone option (PR [#5006](https://github.com/vatesfr/xen-orchestra/pull/5006))
|
||||
- [VM] Differentiate PV drivers detection from management agent detection [#4783](https://github.com/vatesfr/xen-orchestra/issues/4783) (PR [#5007](https://github.com/vatesfr/xen-orchestra/pull/5007))
|
||||
- [Home/VM] Homogenize the list of backed up VMs with the normal list (PR [#5046](https://github.com/vatesfr/xen-orchestra/pull/5046)
|
||||
- [SR/Disks] Add tooltip for disabled migration (PR [#4884](https://github.com/vatesfr/xen-orchestra/pull/4884))
|
||||
- [SR/Advanced, SR selector] Show thin/thick provisioning [#2208](https://github.com/vatesfr/xen-orchestra/issues/2208) (PR [#5081](https://github.com/vatesfr/xen-orchestra/pull/5081))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
> Users must be able to say: “I had this issue, happy to know it's fixed”
|
||||
|
||||
### Released packages
|
||||
- [VM/Creation] Fix `insufficient space` which could happened when moving and resizing disks (PR [#5044](https://github.com/vatesfr/xen-orchestra/pull/5044))
|
||||
- [VM/General] Fix displayed IPV6 instead of IPV4 in case of an old version of XenServer (PR [#5036](https://github.com/vatesfr/xen-orchestra/pull/5036)))
|
||||
- [Host/Load-balancer] Fix VM migration condition: free memory in the destination host must be greater or equal to used VM memory (PR [#5054](https://github.com/vatesfr/xen-orchestra/pull/5054))
|
||||
- [Home] Broken "Import VM" link [#5055](https://github.com/vatesfr/xen-orchestra/issues/5055) (PR [#5056](https://github.com/vatesfr/xen-orchestra/pull/5056))
|
||||
- [Home/SR] Fix inability to edit SRs' name [#5057](https://github.com/vatesfr/xen-orchestra/issues/5057) (PR [#5058](https://github.com/vatesfr/xen-orchestra/pull/5058))
|
||||
- [Backup] Fix huge logs in case of Continuous Replication or Disaster Recovery errors (PR [#5069](https://github.com/vatesfr/xen-orchestra/pull/5069))
|
||||
- [Notification] Fix same notification showing again as unread (PR [#5067](https://github.com/vatesfr/xen-orchestra/pull/5067))
|
||||
- [SDN Controller] Fix broken private network creation when specifiyng a preferred center [#5076](https://github.com/vatesfr/xen-orchestra/issues/5076) (PRs [#5079](https://github.com/vatesfr/xen-orchestra/pull/5079) & [#5080](https://github.com/vatesfr/xen-orchestra/pull/5080))
|
||||
- [Import/VMDK] Import of VMDK disks has been broken since 5.45.0 (PR [#5087](https://github.com/vatesfr/xen-orchestra/pull/5087))
|
||||
- [Remotes] Fix not displayed used/total disk (PR [#5093](https://github.com/vatesfr/xen-orchestra/pull/5093))
|
||||
|
||||
### Packages to release
|
||||
|
||||
> Packages will be released in the order they are here, therefore, they should
|
||||
> be listed by inverse order of dependency.
|
||||
>
|
||||
> Rule of thumb: add packages on top.
|
||||
>
|
||||
> The format is the following: - `$packageName` `$version`
|
||||
>
|
||||
> Where `$version` is
|
||||
>
|
||||
> - patch: if the change is a bug fix or a simple code improvement
|
||||
> - minor: if the change is a new feature
|
||||
> - major: if the change breaks compatibility
|
||||
>
|
||||
> In case of conflict, the highest (lowest in previous list) `$version` wins.
|
||||
|
||||
- xo-server v5.55.0
|
||||
- xo-web v5.55.0
|
||||
- xo-server-audit minor
|
||||
- xo-server-sdn-controller patch
|
||||
- xo-server-load-balancer patch
|
||||
- xo-server minor
|
||||
- xo-web minor
|
||||
|
||||
108
docs/.vuepress/config.js
Normal file
108
docs/.vuepress/config.js
Normal file
@@ -0,0 +1,108 @@
|
||||
module.exports = {
|
||||
title: 'XO documentation',
|
||||
description: 'Official Xen Orchestra documentation',
|
||||
head: [
|
||||
[
|
||||
'link',
|
||||
{
|
||||
rel: 'shortcut icon',
|
||||
href: 'https://xen-orchestra.com/assets/favicon.ico',
|
||||
},
|
||||
],
|
||||
],
|
||||
base: '/docs/',
|
||||
themeConfig: {
|
||||
smoothScroll: true,
|
||||
logo: 'https://xen-orchestra.com/blog/content/images/2017/05/xo-logo.png',
|
||||
lastUpdated: 'Last Updated', // add latest Git commit modification for each file
|
||||
repo: 'vatesfr/xen-orchestra', // point to the GH repo
|
||||
editLinks: true, // display link for people to edit a page
|
||||
editLinkText: 'Help us to improve this page!', // link text
|
||||
docsDir: 'docs',
|
||||
nav: [
|
||||
{ text: 'Home', link: 'https://xen-orchestra.com' },
|
||||
{ text: 'News', link: 'https://xen-orchestra.com/blog' },
|
||||
{ text: 'Documentation', link: '/' },
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
title: 'Xen Orchestra', // required
|
||||
path: '/', // optional, link of the title, which should be an absolute path and must exist
|
||||
collapsable: false, // optional, defaults to true
|
||||
sidebarDepth: 1, // optional, defaults to 1
|
||||
children: [
|
||||
['/releases', 'Releases'],
|
||||
['/supported_hosts', 'Host Compatibility List'],
|
||||
['/installation', 'Installation'],
|
||||
['/configuration', 'Configuration'],
|
||||
['/updater', 'Updates'],
|
||||
['/architecture', 'Architecture'],
|
||||
['/troubleshooting', 'Troubleshooting'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Management', // required
|
||||
path: '/manage', // optional, link of the title, which should be an absolute path and must exist
|
||||
collapsable: false, // optional, defaults to true
|
||||
sidebarDepth: 1, // optional, defaults to 1
|
||||
children: [
|
||||
['/manage_infrastructure', 'Infrastructure'],
|
||||
['/users', 'Users'],
|
||||
['/advanced', 'Advanced features'],
|
||||
['/load_balancing', 'VM Load Balancing'],
|
||||
['/sdn_controller', 'SDN Controller'],
|
||||
['/xosan', 'XOSANv1'],
|
||||
['/xosanv2', 'XOSANv2'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Backup', // required
|
||||
path: '/backup', // optional, link of the title, which should be an absolute path and must exist
|
||||
collapsable: false, // optional, defaults to true
|
||||
sidebarDepth: 1, // optional, defaults to 1
|
||||
children: [
|
||||
['/backups', 'Concepts'],
|
||||
['/proxy', 'Proxy'],
|
||||
['/rolling_snapshots', 'Snapshots'],
|
||||
['/full_backups', 'Full backup'],
|
||||
['/delta_backups', 'Delta Backup'],
|
||||
['/disaster_recovery.md', 'Disaster Recovery'],
|
||||
['/continuous_replication', 'Continuous Replication'],
|
||||
['/metadata_backup', 'Metadata Backup'],
|
||||
['/backup_reports', 'Backup Reports'],
|
||||
['/backup_troubleshooting', 'Backup Troubleshooting'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Support', // required
|
||||
path: '/support', // optional, link of the title, which should be an absolute path and must exist
|
||||
collapsable: false, // optional, defaults to true
|
||||
sidebarDepth: 1, // optional, defaults to 1
|
||||
children: [
|
||||
['/xoa', 'XOA Support'],
|
||||
['/purchase', 'Purchase XOA'],
|
||||
['/license_management', 'License Management'],
|
||||
['/reseller', 'Partner Program'],
|
||||
['/community', 'Community Support'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Project', // required
|
||||
path: '/project', // optional, link of the title, which should be an absolute path and must exist
|
||||
collapsable: false, // optional, defaults to true
|
||||
sidebarDepth: 1, // optional, defaults to 1
|
||||
children: [
|
||||
[
|
||||
'https://github.com/vatesfr/xen-orchestra/blob/master/CHANGELOG.md#changelog',
|
||||
'Changelog',
|
||||
],
|
||||
['/code_of_conduct', 'Code of Conduct'],
|
||||
['/contributing', 'Contributing'],
|
||||
['/licenses', 'Licenses'],
|
||||
['/roadmap', 'Roadmap'],
|
||||
['/glossary', 'Glossary'],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
1
docs/.vuepress/styles/palette.styl
Normal file
1
docs/.vuepress/styles/palette.styl
Normal file
@@ -0,0 +1 @@
|
||||
$accentColor = #cc584c
|
||||
@@ -8,23 +8,10 @@ XO is a web interface to visualize and administer your XenServer (or XAPI enable
|
||||
|
||||
It aims to be easy to use on any device supporting modern web technologies (HTML 5, CSS 3, JavaScript), such as your desktop computer or your smartphone.
|
||||
|
||||

|
||||
## Quick start
|
||||
|
||||
## XOA quick deploy
|
||||
Log in to your account and use the deploy form available on [Xen Orchestra website](https://xen-orchestra.com/#!/xoa).
|
||||
|
||||
Log in to your account and use the deploy form available on [this page](https://xen-orchestra.com/#!/xoa)
|
||||
More details available on the [installation section](installation.md#xoa).
|
||||
|
||||
> **Note:** no data will be sent to our servers, it's running only between your browser and your host!
|
||||
|
||||
[](https://xen-orchestra.com/#!/xoa)
|
||||
|
||||
### XOA credentials
|
||||
|
||||
- Web UI: `admin@admin.net` / `admin`
|
||||
- Console/SSH: `xoa` / `xoa` (first login)
|
||||
|
||||
## Must read
|
||||
|
||||
- [XOA installation](xoa.md)
|
||||
- [Main features](features.md)
|
||||
- [Pro Support](support.md)
|
||||

|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# Summary
|
||||
|
||||
- [Introduction](README.md)
|
||||
- [Architecture](architecture.md)
|
||||
- [xo-server](xo-server.md)
|
||||
- [xo-web](xo-web.md)
|
||||
- [xo-cli](xo-cli.md)
|
||||
- [others](others.md)
|
||||
- [Installation](installation.md)
|
||||
- [XOA](xoa.md)
|
||||
- [Updater](updater.md)
|
||||
- [Trial activation](trial_activation.md)
|
||||
- [Plugins](plugins.md)
|
||||
- [Logs](logs.md)
|
||||
- [Compatibility](supported-version.md)
|
||||
- [Troubleshooting](troubleshooting.md)
|
||||
- [From the sources](from_the_sources.md)
|
||||
- [Configuration](configuration.md)
|
||||
- [Features](features.md)
|
||||
- [Administration](administration.md)
|
||||
- [Home view](user_interface.md)
|
||||
- [Search and filters](search.md)
|
||||
- [VM management](vm_management.md)
|
||||
- [VM creation](vm_creation.md)
|
||||
- [VM import and export](vm_import_export.md)
|
||||
- [XenServer Patching](patching.md)
|
||||
- [Docker support](docker_support.md)
|
||||
- [Backup and DR](backups.md)
|
||||
- [Full backups](full_backups.md)
|
||||
- [Rolling snapshots](rolling_snapshots.md)
|
||||
- [Continuous Delta backups](delta_backups.md)
|
||||
- [Continuous Replication](continuous_replication.md)
|
||||
- [Disaster recovery](disaster_recovery.md)
|
||||
- [Smart Backup](smart_backup.md)
|
||||
- [File level Restore](file_level_restore.md)
|
||||
- [Metadata Backup](metadata_backup.md)
|
||||
- [Backup Concurrency](concurrency.md)
|
||||
- [Configure backup reports](backup_reports.md)
|
||||
- [Backup troubleshooting](backup_troubleshooting.md)
|
||||
- [User authentication](authentication.md)
|
||||
- [Built-in](built-in.md)
|
||||
- [LDAP](ldap.md)
|
||||
- [SAML](saml.md)
|
||||
- [GitHub](github.md)
|
||||
- [Google](google.md)
|
||||
- [Resources delegation](resources_delegation.md)
|
||||
- [ACLs](acls.md)
|
||||
- [CloudInit](cloudinit.md)
|
||||
- [Self Service](self_service.md)
|
||||
- [Visualizations](visualizations.md)
|
||||
- [Health](health.md)
|
||||
- [Job manager](scheduler.md)
|
||||
- [Alerts](alerts.md)
|
||||
- [Web hooks](web-hooks.md)
|
||||
- [Load balancing](load_balancing.md)
|
||||
- [Emergency Shutdown](emergency_shutdown.md)
|
||||
- [Auto scalability](auto_scalability.md)
|
||||
- [Forecaster](forecaster.md)
|
||||
- [SDN Controller](sdn_controller.md)
|
||||
- [Recipes](recipes.md)
|
||||
- [Reverse proxy](reverse_proxy.md)
|
||||
- [How to contribute?](contributing.md)
|
||||
- [Support](support.md)
|
||||
- [Roadmap](roadmap.md)
|
||||
- [Purchase](purchase.md)
|
||||
- [Direct purchase](directpurchase.md)
|
||||
- [Through purchase department](through_purchase_department.md)
|
||||
- [Reseller](reseller.md)
|
||||
- [Editions](editions.md)
|
||||
- [Trial](trial.md)
|
||||
- [Invoices](invoices.md)
|
||||
- [Upgrade](upgrade.md)
|
||||
- [XOSAN](xosan.md)
|
||||
- [Requirements](xosan_requirements.md)
|
||||
- [Types](xosan_types.md)
|
||||
- [Replicated](xosan_replicated.md)
|
||||
- [Disperse](xosan_disperse.md)
|
||||
- [Creation](xosan_create.md)
|
||||
- [Trial](xosan_trial.md)
|
||||
- [General Troubleshooting](general-troubleshooting.md)
|
||||
- [Glossary](glossary.md)
|
||||
@@ -1,6 +1,6 @@
|
||||
# ACLs
|
||||
|
||||
> ACLs are permissions that apply to pre-existing objects. Only a super admin (XO administrator) can create objects.
|
||||
ACLs are permissions that apply to pre-existing objects. Only a super admin (XO administrator) can create objects.
|
||||
|
||||
ACLs are the permissions for your users or groups. The ACLs view can be accessed in the "Settings" panel.
|
||||
|
||||
@@ -11,7 +11,9 @@ ACLs are the permissions for your users or groups. The ACLs view can be accessed
|
||||
|
||||

|
||||
|
||||
> Pro tip: you can click to add multiple objects at the same time!
|
||||
:::tip
|
||||
You can click to add multiple objects at the same time!
|
||||
:::
|
||||
|
||||
Your ACL is now available in the right list:
|
||||
|
||||
|
||||
313
docs/advanced.md
Normal file
313
docs/advanced.md
Normal file
@@ -0,0 +1,313 @@
|
||||
# Advanced features
|
||||
|
||||
This section is dedicated to all others Xen Orchestra "advanced features".
|
||||
|
||||
## Live Telemetry
|
||||
|
||||
When you are working on your virtualized infrastructure, you might need a very detailed view on what's going on. From resource consumption analysis (CPU/RAM) to network traffic, but also storage, having a kind of very detailed dashboard per host can be really useful.
|
||||
|
||||
:::tip
|
||||
This feature will be only available in XCP-ng+XOA. If you are a hardcore Citrix Hypervisor user, let us know if you want this.
|
||||
:::
|
||||
|
||||
### Enable Advanced Live Telemtry for a host
|
||||
|
||||
Go into the Advanced host view:
|
||||
|
||||

|
||||
|
||||
By clicking here, XOA will handle everything: installing netdata on the host, and configure a secured/encrypted streaming toward your XOA.
|
||||
|
||||
As soon it's installed, the button will now be replaced by a "Go to Advanced Live Telemetry". As soon you'll click on it, you'll be redirected to the netdata page of the host. If you have multiple host, you can access any of them directly from the top menu of the netdata UI.
|
||||
|
||||
### Examples
|
||||
|
||||
IMPI info (power, temperatures, voltages, fans…):
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
This feature is only available in one-click in your XOA. However, all sources and packages to do it yourself are available!
|
||||
:::
|
||||
|
||||
Memory details:
|
||||
|
||||

|
||||
|
||||
Firewall:
|
||||
|
||||

|
||||
|
||||
## Cloud init
|
||||
|
||||
Cloud-init is a program "that handles the early initialization of a cloud instance"[^n]. In other words, you can, on a "cloud-init"-ready template VM, pass a lot of data at first boot:
|
||||
|
||||
- setting the hostname
|
||||
- add ssh keys
|
||||
- automatically grow the file system
|
||||
- create users
|
||||
- and a lot more!
|
||||
|
||||
This tool is pretty standard and used everywhere. A lot of existing cloud templates are using it.
|
||||
|
||||
So it means very easily customizing your VM when you create it from a compatible template. It brings you closer to the "instance" principle, like in Amazon cloud or OpenStack.
|
||||
|
||||
### Requirements
|
||||
|
||||
You only need to use a template of a VM with CloudInit installed inside it. [Check this blog post to learn how to install CloudInit](https://xen-orchestra.com/blog/centos-cloud-template-for-xenserver/).
|
||||
|
||||
:::tip
|
||||
In XOA 5.31, we changed the cloud-init config drive type from [OpenStack](https://cloudinit.readthedocs.io/en/latest/topics/datasources/configdrive.html) to the [NoCloud](https://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html) type. This will allow us to pass network configuration to VMs in the future. For 99% of users, including default cloud-init installs, this change will have no effect. However if you have previously modified your cloud-init installation in a VM template to only look for `openstack` drive types (for instance with the `datasource_list` setting in `/etc/cloud/cloud.cfg`) you need to modify it to also look for `nocloud`.
|
||||
:::
|
||||
|
||||
### Usage
|
||||
|
||||
First, select your compatible template (CloudInit ready) and name it:
|
||||
|
||||

|
||||
|
||||
Then, activate the config drive and insert your SSH key. Or you can also use a custom CloudInit configuration:
|
||||
|
||||

|
||||
|
||||
> CloudInit configuration examples are [available here](http://cloudinit.readthedocs.org/en/latest/topics/examples.html).
|
||||
|
||||
You can extend the disk size (**in this case, the template disk was 8 GiB originally**). We'll extend it to 20GiB:
|
||||
|
||||

|
||||
|
||||
Finally, create the VM:
|
||||
|
||||

|
||||
|
||||
Now start the VM and SSH to its IP:
|
||||
|
||||
- **the system has the right VM hostname** (from VM name)
|
||||
- you don't need to use a password to access it (thanks to your SSH key):
|
||||
|
||||
```
|
||||
$ ssh centos@192.168.100.226
|
||||
[centos@tmp-app1 ~]$
|
||||
```
|
||||
|
||||
The default `cloud-init` configuration can allow you to be to be a sudoer directly:
|
||||
|
||||
```
|
||||
[centos@tmp-app1 ~]$ sudo -s
|
||||
[root@tmp-app1 centos]#
|
||||
```
|
||||
|
||||
Check the root file system size: indeed, **it was automatically increased** to what you need:
|
||||
|
||||
```
|
||||
[centos@tmp-app1 ~]$ df -h
|
||||
/dev/xvda1 20G 1,2G 18G 6% /
|
||||
```
|
||||
|
||||
## Web hooks
|
||||
|
||||
:::warning
|
||||
We need your feedback on this feature!
|
||||
:::
|
||||
|
||||
### Configuration
|
||||
|
||||
The plugin "web-hooks" needs to be installed and loaded for this feature to work.
|
||||
|
||||
You can trigger an HTTP POST request to a URL when a Xen Orchestra API method is called.
|
||||
|
||||
- Go to Settings > Plugins > Web hooks
|
||||
- Add new hooks
|
||||
- For each hook, configure:
|
||||
- Method: the XO API method that will trigger the HTTP request when called
|
||||
- Type:
|
||||
- pre: the request will be sent when the method is called
|
||||
- post: the request will be sent after the method action is completed
|
||||
- pre/post: both
|
||||
- URL: the full URL which the requests will be sent to
|
||||
- Save the plugin configuration
|
||||
|
||||
From now on, a request will be sent to the corresponding URLs when a configured method is called by an XO client.
|
||||
|
||||
### Request content
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
The request's body is a JSON string representing an object with the following properties:
|
||||
|
||||
- `type`: `"pre"` or `"post"`
|
||||
- `callId`: unique ID for this call to help match a pre-call and a post-call
|
||||
- `userId`: unique internal ID of the user who performed the call
|
||||
- `userName`: login/e-mail address of the user who performed the call
|
||||
- `method`: name of the method that was called (e.g. `"vm.start"`)
|
||||
- `params`: call parameters (object)
|
||||
- `timestamp`: epoch timestamp of the beginning ("pre") or end ("post") of the call in ms
|
||||
- `duration`: duration of the call in ms ("post" hooks only)
|
||||
- `result`: call result on success ("post" hooks only)
|
||||
- `error`: call result on error ("post" hooks only)
|
||||
|
||||
### Request handling
|
||||
|
||||
_Quick Node.js example of how you may want to handle the requests_
|
||||
|
||||
```js
|
||||
const http = require('http')
|
||||
const { exec } = require('child_process')
|
||||
|
||||
http
|
||||
.createServer((req, res) => {
|
||||
let body = ''
|
||||
req.on('data', chunk => {
|
||||
body += chunk
|
||||
})
|
||||
req.on('end', () => handleHook(body))
|
||||
res.end()
|
||||
})
|
||||
.listen(3000)
|
||||
|
||||
const handleHook = data => {
|
||||
const { method, params, type, result, error, timestamp } = JSON.parse(data)
|
||||
|
||||
// Log it
|
||||
console.log(
|
||||
`${new Date(timestamp).toISOString()} [${method}|${type}] ${params} → ${
|
||||
result || error
|
||||
}`
|
||||
)
|
||||
|
||||
// Run scripts
|
||||
exec(`./hook-scripts/${method}-${type}.sh`)
|
||||
}
|
||||
```
|
||||
|
||||
## Alerts
|
||||
|
||||
Alerts are a way to warn the administrator about various events. The first kind of alerts will be emails and also in a dedicated area of `xo-web` to display them.
|
||||
|
||||
### Performances alerts
|
||||
|
||||
The administrator will configure alerts based on performance thresholds.
|
||||
|
||||
The configurable metrics are:
|
||||
|
||||
- CPU usage (VM, host)
|
||||
- RAM usage (VM, host)
|
||||
- network bandwidth (VM, host)
|
||||
- load average (host)
|
||||
- disk IO (VM)
|
||||
- total IO (SR, only for XenServer Dundee and higher)
|
||||
|
||||
If any configured values exceed the threshold during a selected period of time, an alert will be sent.
|
||||
|
||||
Those alerts will be also stored and accessible in the web interface, and also later for the load balancing feature (helping it to solve those performance problems).
|
||||
|
||||
### Updates alerts
|
||||
|
||||
:::warning
|
||||
:construction_worker: This feature might be missing. We are investigating. :construction_worker:
|
||||
:::
|
||||
|
||||
When your XOA detects new packages, you'll be notified by email.
|
||||
|
||||
### Backup alerts
|
||||
|
||||
Same story for backups: if a backup fails, you'll receive an email.
|
||||
|
||||
You can choose to be notified only if it fails or even after each backup job.
|
||||
|
||||
Current supported alerts system:
|
||||
|
||||
- Email
|
||||
- XMPP
|
||||
|
||||
## Job manager
|
||||
|
||||
The key idea is to be able to schedule any action (migrate, reboot etc.), for things like backups, snapshots or DR actions.
|
||||
|
||||
In the main menu, go to the "Job Manager" section:
|
||||
|
||||

|
||||
|
||||
You can now **schedule all actions** on your hosts, VMs, or ACLs. It's configured in 2 steps:
|
||||
|
||||
1. Create a job
|
||||
1. Schedule it!
|
||||
|
||||
Real example, step by step: **Creating a job called "security reboot"** (in this case, restarting "nfs" and "Core1" VMs):
|
||||
|
||||

|
||||
|
||||
Note that you can execute this job **now** by clicking on the orange play button (to test it for instance):
|
||||
|
||||

|
||||
|
||||
**Schedule the job** (every Sunday at 5:00 AM):
|
||||
|
||||

|
||||
|
||||
And that's it! The job is listed in the Overview:
|
||||
|
||||

|
||||
|
||||
The possibilities are infinite! You can schedule a **lot** of things (any actions on a VM, like migrate, start, clone, suspend etc. Same thing also applies to hosts).
|
||||
|
||||
### Examples
|
||||
|
||||
#### Save on your electric bill
|
||||
|
||||
- plan a live migration of your VMs at 11:00PM to a less powerful host, then shutdown the big one
|
||||
- start the big server at 6:00AM and migrate the VMs back 15 minutes later
|
||||
|
||||
#### Scale when needed
|
||||
|
||||
- schedule the boot of extra VMs during your usual activity spikes (horizontal scaling)
|
||||
- also add more vCPUs or RAM to these VMs at the same time
|
||||
- go back to the previous state when your planned load is low (e.g: during the night)
|
||||
|
||||
#### Planned reboot
|
||||
|
||||
- For example: your client app is not very stable, or you need to reboot every month after kernel updates: schedule this during the weekend!
|
||||
|
||||
#### Add or Remove ACLs
|
||||
|
||||
- revoke your user ACLs Friday at 11:00PM (e.g: no access on the weekend)
|
||||
- restore them Monday at 6:00AM
|
||||
|
||||
## Emergency Shutdown
|
||||
|
||||
If you have a UPS for your hosts, and lose power, you may have a limited amount of time to shut down all of your VM infrastructure before the batteries run out. If you find yourself in this situation, or any other situation requiring the fast shutdown of everything, you can use the **Emergency Shutdown** feature.
|
||||
|
||||
### How to activate
|
||||
|
||||
On the host view, clicking on this button will trigger the _Emergency Shutdown_ procedure:
|
||||
|
||||

|
||||
|
||||
1. **All running VMs will be suspended** (think of it like "hibernate" on your laptop: the RAM will be stored in the storage repository).
|
||||
2. Only after this is complete, the host will be halted.
|
||||
|
||||
Here, you can see the running VMs are being suspended:
|
||||
|
||||

|
||||
|
||||
And finally, that's it. They are cleanly shut down with the RAM saved to disk to be resumed later:
|
||||
|
||||

|
||||
|
||||
Now the host is halted automatically.
|
||||
|
||||
### Powering back on
|
||||
|
||||
When the power outage is over, all you need to do is:
|
||||
|
||||
1. Start your host.
|
||||
2. All your VMs can be resumed, your RAM is preserved and therefore your VMs will be in the exact same state as they were before the power outage.
|
||||
|
||||
## Recipes
|
||||
|
||||
:::tip
|
||||
TODO: this section is still a work in progress!
|
||||
:::
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
Xen Orchestra (XO) is software built with a server and clients, such as the web client `xo-web`, but also a CLI capable client, called `xo-cli`.
|
||||
|
||||
> XO is totally agent-less: you don't have to install any program on your hosts to get it working!
|
||||
:::tip
|
||||
XO is totally agent-less: you don't have to install any program on your hosts to get it working!
|
||||
:::
|
||||
|
||||
## XOA
|
||||
|
||||
@@ -10,7 +12,7 @@ _Xen Orchestra Virtual Appliance_ (XOA) is a virtual machine with Xen Orchestra
|
||||
|
||||
This is the easiest way to try Xen Orchestra quickly.
|
||||
|
||||
Your XOA is connected to all your hosts, or the pool master only if you are using Pools in XenServer:
|
||||
Your XOA is connected to all your hosts, or the pool master only if you are using Pools in XCP-ng/Citrix Hypervisor:
|
||||
|
||||

|
||||
|
||||
@@ -18,10 +20,248 @@ Your XOA is connected to all your hosts, or the pool master only if you are usin
|
||||
|
||||

|
||||
|
||||
Xen Orchestra itself is built as a modular solution. Each part has its role:
|
||||
Xen Orchestra itself is built as a modular solution. Each part has its role.
|
||||
|
||||
- The core is "[xo-server](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server/)" - a daemon dealing directly with XenServer or XAPI capable hosts. This is where users are stored, and it's the center point for talking to your whole Xen infrastructure.
|
||||
- The web interface is "[xo-web](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-web)" - it runs directly from your browser. The connection with `xo-server` is done via _WebSockets_.
|
||||
- "[xo-cli](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-cli)" is a module allowing you to send commands directly from the command line.
|
||||
## xo-server (server)
|
||||
|
||||
We have other modules as well (like the LDAP plugin for example). It allows us to use this modular architecture to add further parts as we need them. It's completely flexible, allowing us to adapt Xen Orchestra to every existing workflow.
|
||||
The core is "[xo-server](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server/)" - a daemon dealing directly with XenServer or XAPI capable hosts. This is where users are stored, and it's the center point for talking to your whole Xen infrastructure.
|
||||
|
||||
XO-Server is the core of Xen Orchestra. Its central role opens a lot of possibilities versus other solutions - let's see why.
|
||||
|
||||
### Daemon mode
|
||||
|
||||
As a daemon, XO-Server is always up. Because of this, it can listen and record every event occurring on your entire Xen infrastructure. Connections are always open and it can cache information before serving it to another client (CLI, Web or anything else).
|
||||
|
||||
### Central point
|
||||
|
||||
Contrary to XenCenter, each Xen Orchestra's client is connected to one XO-Server, and not all the Xen servers. With a traditional architecture:
|
||||
|
||||

|
||||
|
||||
You can see how we avoid a lot of resource and bandwidth waste with a central point:
|
||||
|
||||

|
||||
|
||||
### Events
|
||||
|
||||
Legacy interfaces use the "pull" model, requesting data every "x" seconds:
|
||||
|
||||

|
||||
|
||||
It's **not scalable** and **slow**.
|
||||
|
||||
Previously with XO < 3.4, we used events in the following way:
|
||||
|
||||

|
||||
|
||||
But the interface was still lagging behind the server. With XO 3.4 and beyond, we now have a full event system, allowing instant display of what's happening on your infrastructure:
|
||||
|
||||

|
||||
|
||||
### A proxy for your hosts
|
||||
|
||||
XO-Server will act as a proxy for all your clients. This opens a lot of possibilities!
|
||||
|
||||
#### Console proxy
|
||||
|
||||
A good example is the console: you can now expose your consoles even if your clients are outside the network!
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### VM streaming
|
||||
|
||||
Another possibility is to stream a VM from one host to another.
|
||||
|
||||
To do that previously, you needed to export your VM somewhere, then re-import it:
|
||||
|
||||

|
||||
|
||||
Thanks to our architecture, it's now far easier:
|
||||
|
||||

|
||||
|
||||
#### Patching on the fly
|
||||
|
||||
To install a patch manually, it requires a lot of steps: find, download, extract and apply the patch, sequentially.
|
||||
|
||||
"xo-server" can do all these steps at once:
|
||||
|
||||
1. automatically download the patch from Citrix servers
|
||||
2. unzip it and upload it on the fly to your host
|
||||
3. apply it as soon it's done
|
||||
|
||||
### Pluggable
|
||||
|
||||
It's really easy to connect other modules to XO-server, and extend or adapt the solution to your needs (see XO-web and XO-cli for real examples).
|
||||
|
||||
#### ACLs
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### NodeJS under the hood
|
||||
|
||||
[NodeJS](https://en.wikipedia.org/wiki/Nodejs) is a software platform for scalable server-side and networking applications. It's famous for its efficiency, scalability and its asynchronous capabilities. Exactly what we need! Thus, XO-server is written in JavaScript.
|
||||
|
||||
## xo-web (web UI)
|
||||
|
||||
The web interface is "[xo-web](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-web)" - it runs directly from your browser. The connection with `xo-server` is done via _WebSockets_.
|
||||
|
||||
This is probably the first part of Xen Orchestra you'll see. The Web interface allows you to interact with your virtual infrastructure. As a module of XO-Web it facilitates everyday Xen administrator work, but also provides a solution to delegate parts of your infrastructure to other people.
|
||||
|
||||

|
||||
|
||||
[Read the manage section](./manage.md) to discover what you can do in XO-web.
|
||||
|
||||
### ReactJS
|
||||
|
||||
We stay consistent from the back-end to the front-end with one main language: [ReactJS](https://reactjs.org/)
|
||||
|
||||

|
||||
|
||||
## xo-cli (CLI)
|
||||
|
||||
"[xo-cli](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-cli)" is a module allowing you to send commands directly from the command line.
|
||||
|
||||
Thanks to introspection, `xo-cli` will detect all the available features exposed in the `xo-server` API.
|
||||
|
||||
:::warning
|
||||
This CLI is mainly used as a debug tool, there's no 100% guarantee on its stability. Use it only if you really know what you do.
|
||||
:::
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
> xo-cli --help
|
||||
Usage:
|
||||
|
||||
xo-cli --register <XO-Server URL> <username> [<password>]
|
||||
Registers the XO instance to use.
|
||||
|
||||
xo-cli --unregister
|
||||
Remove stored credentials.
|
||||
|
||||
xo-cli --list-commands [--json] [<pattern>]...
|
||||
Returns the list of available commands on the current XO instance.
|
||||
|
||||
The patterns can be used to filter on command names.
|
||||
|
||||
xo-cli --list-objects [--<property>]… [<property>=<value>]...
|
||||
Returns a list of XO objects.
|
||||
|
||||
--<property>
|
||||
Restricts displayed properties to those listed.
|
||||
|
||||
<property>=<value>
|
||||
Restricted displayed objects to those matching the patterns.
|
||||
|
||||
xo-cli <command> [<name>=<value>]...
|
||||
Executes a command on the current XO instance.
|
||||
|
||||
```
|
||||
|
||||
#### Register your XO instance
|
||||
|
||||
```
|
||||
> xo-cli --register http://xo.my-company.net admin@admin.net admin
|
||||
Successfully logged with admin@admin.net
|
||||
```
|
||||
|
||||
Note: only a token will be saved in the configuration file.
|
||||
|
||||
#### List available objects
|
||||
|
||||
Prints all objects:
|
||||
|
||||
```
|
||||
> xo-cli --list-objects
|
||||
```
|
||||
|
||||
It is possible to filter on object properties, for instance to print
|
||||
all VM templates:
|
||||
|
||||
```
|
||||
> xo-cli --list-objects type=VM-template
|
||||
```
|
||||
|
||||
#### List available commands
|
||||
|
||||
```
|
||||
> xo-cli --list-commands
|
||||
```
|
||||
|
||||
Commands can be filtered using patterns:
|
||||
|
||||
```
|
||||
> xo-cli --list-commands '{user,group}.*'
|
||||
```
|
||||
|
||||
#### Execute a command
|
||||
|
||||
The same syntax is used for all commands: `xo-cli <command> <param name>=<value>...`
|
||||
|
||||
E.g., adding a new server:
|
||||
|
||||
```
|
||||
> xo-cli server.add host=my.server.net username=root password=secret-password
|
||||
42
|
||||
```
|
||||
|
||||
The return value is the identifier of this new server in XO.
|
||||
|
||||
Parameters (except `true` and `false` which are correctly parsed as
|
||||
booleans) are assumed to be strings. For other types, you may use JSON
|
||||
encoding by prefixing with `json:`:
|
||||
|
||||
```
|
||||
> xo-cli foo.bar baz='json:[1, 2, 3]'
|
||||
```
|
||||
|
||||
##### VM export
|
||||
|
||||
```
|
||||
> xo-cli vm.export vm=a01667e0-8e29-49fc-a550-17be4226783c @=vm.xva
|
||||
```
|
||||
|
||||
##### VM import
|
||||
|
||||
```
|
||||
> xo-cli vm.import sr=60a6939e-8b0a-4352-9954-5bde44bcdf7d @=vm.xva
|
||||
```
|
||||
|
||||
> Note: `xo-cli` only supports the import of XVA files. It will not import OVA files. To import OVA images, you must use the XOA web UI or use `xo-upload-ova` [available here](https://github.com/vatesfr/xen-orchestra/blob/master/@xen-orchestra/upload-ova/README.md#xo-upload-ova).
|
||||
|
||||
## API
|
||||
|
||||
Because `xo-server` is already requested by our web UI (`xo-web`) or CLI (`xo-cli`), there's an API. You can use it directly to have advanced integration in your IT infrastructure (automation, or as a VPS vendor etc.).
|
||||
|
||||
:::warning
|
||||
However, this API isn't 100% guarantee to be stable. Use it with caution.
|
||||
:::
|
||||
|
||||
If you need assistance on how to use it:
|
||||
|
||||
1. Try to use [xo-cli](./architecture.md#xo-cli-cli) first. You'll learn all the available calls
|
||||
2. A good intro can be find within [xo-lib](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-lib#xo-lib-)
|
||||
3. Create a support ticket asking us for precise call you want to make, we'll help you!
|
||||
|
||||
## Plugins
|
||||
|
||||
Xen Orchestra plugins allow you to extend features without rewriting the core of the application.
|
||||
|
||||
You can see your installed plugins in "Settings" then the "Plugins" page:
|
||||
|
||||

|
||||
|
||||
All plugin configuration should be done in the web interface:
|
||||
|
||||

|
||||
|
||||
A plugin can be:
|
||||
|
||||
- activated/deactivated
|
||||
- loaded on start of the application
|
||||
- configured (extend the plugin settings by clicking on the "+" icon
|
||||
|
||||
BIN
docs/assets/activate-confirm.png
Normal file
BIN
docs/assets/activate-confirm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
BIN
docs/assets/activate-license.png
Normal file
BIN
docs/assets/activate-license.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
BIN
docs/assets/delta_final.png
Normal file
BIN
docs/assets/delta_final.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 196 KiB |
BIN
docs/assets/deltamerge1.png
Normal file
BIN
docs/assets/deltamerge1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
BIN
docs/assets/deltamerge2.png
Normal file
BIN
docs/assets/deltamerge2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user