Compare commits
8 Commits
xo-server-
...
vhd-lib-v0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e14fda6e8a | ||
|
|
ec48b77af3 | ||
|
|
c7d6a19864 | ||
|
|
7d714c8ce4 | ||
|
|
f70989c3a2 | ||
|
|
70490988b0 | ||
|
|
d0795fdded | ||
|
|
1c736e9910 |
@@ -29,7 +29,7 @@
|
||||
"@xen-orchestra/fs": "^0.1.0",
|
||||
"exec-promise": "^0.7.0",
|
||||
"struct-fu": "^1.2.0",
|
||||
"vhd-lib": "^0.1.2"
|
||||
"vhd-lib": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.0.0-beta.49",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vhd-lib",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Primitives for VHD file handling",
|
||||
"keywords": [],
|
||||
|
||||
@@ -33,7 +33,7 @@ export function createFooter (
|
||||
currentSize: size,
|
||||
diskGeometry: geometry,
|
||||
diskType,
|
||||
uuid: generateUuid(null, []),
|
||||
uuid: generateUuid(null, Buffer.allocUnsafe(16)),
|
||||
})
|
||||
checksumStruct(footer, fuFooter)
|
||||
return footer
|
||||
|
||||
@@ -40,7 +40,7 @@ export const fuFooter = fu.struct([
|
||||
]),
|
||||
fu.uint32('diskType'), // 60 Disk type, must be equal to HARD_DISK_TYPE_DYNAMIC/HARD_DISK_TYPE_DIFFERENCING.
|
||||
fu.uint32('checksum'), // 64
|
||||
fu.uint8('uuid', 16), // 68
|
||||
fu.byte('uuid', 16), // 68
|
||||
fu.char('saved'), // 84
|
||||
fu.char('hidden'), // 85 TODO: should probably be merged in reserved
|
||||
fu.char('reserved', 426), // 86
|
||||
@@ -55,7 +55,7 @@ export const fuHeader = fu.struct([
|
||||
fu.uint32('maxTableEntries'), // Max entries in the Block Allocation Table.
|
||||
fu.uint32('blockSize'), // Block size in bytes. Default (2097152 => 2MB)
|
||||
fu.uint32('checksum'),
|
||||
fu.uint8('parentUuid', 16),
|
||||
fu.byte('parentUuid', 16),
|
||||
fu.uint32('parentTimestamp'),
|
||||
fu.uint32('reserved1'),
|
||||
fu.char16be('parentUnicodeName', 512),
|
||||
|
||||
@@ -96,6 +96,7 @@ class XapiError extends BaseError {
|
||||
// slots than can be assigned later
|
||||
this.method = undefined
|
||||
this.url = undefined
|
||||
this.task = undefined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +189,9 @@ const getTaskResult = task => {
|
||||
return Promise.reject(new Cancel('task canceled'))
|
||||
}
|
||||
if (status === 'failure') {
|
||||
return Promise.reject(wrapError(task.error_info))
|
||||
const error = wrapError(task.error_info)
|
||||
error.task = task
|
||||
return Promise.reject(error)
|
||||
}
|
||||
if (status === 'success') {
|
||||
// the result might be:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xo-server",
|
||||
"version": "5.20.1",
|
||||
"version": "5.20.2",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Server part of Xen-Orchestra",
|
||||
"keywords": [
|
||||
@@ -111,7 +111,7 @@
|
||||
"tmp": "^0.0.33",
|
||||
"uuid": "^3.0.1",
|
||||
"value-matcher": "^0.2.0",
|
||||
"vhd-lib": "^0.1.2",
|
||||
"vhd-lib": "^0.1.3",
|
||||
"ws": "^5.0.0",
|
||||
"xen-api": "^0.16.10",
|
||||
"xml2js": "^0.4.19",
|
||||
|
||||
@@ -255,6 +255,10 @@ const importers: $Dict<
|
||||
},
|
||||
}
|
||||
|
||||
const PARSE_UUID_RE = /-/g
|
||||
const parseUuid = (uuid: string) =>
|
||||
Buffer.from(uuid.replace(PARSE_UUID_RE, ''), 'hex')
|
||||
|
||||
const parseVmBackupId = (id: string) => {
|
||||
const i = id.indexOf('/')
|
||||
return {
|
||||
@@ -687,7 +691,7 @@ export default class BackupNg {
|
||||
// - [ ] display queued VMs
|
||||
// - [ ] snapshots and files of an old job should be detected and removed
|
||||
// - [ ] delta import should support mapVdisSrs
|
||||
// - [ ] size of the path? (base64url(Buffer.from(uuid.split('-').join(''), 'hex')))
|
||||
// - [ ] size of the path? (base64url(parseUuid(uuid)))
|
||||
// - [ ] what does mean the vmTimeout with the new concurrency? a VM can take
|
||||
// a very long time to finish if there are other VMs before…
|
||||
// - [ ] detect and gc uncomplete replications
|
||||
@@ -911,7 +915,7 @@ export default class BackupNg {
|
||||
xva = xva.pipe(createSizeStream())
|
||||
|
||||
const forkExport =
|
||||
nTargets === 0
|
||||
nTargets === 1
|
||||
? () => xva
|
||||
: () => {
|
||||
const fork = xva.pipe(new PassThrough())
|
||||
@@ -1049,6 +1053,29 @@ export default class BackupNg {
|
||||
$defer.onFailure.call(xapi, 'deleteVm', snapshot)
|
||||
}
|
||||
|
||||
// JFT: TODO: remove when enough time has passed (~2018-09)
|
||||
//
|
||||
// Fix VHDs UUID (= VDI.uuid), which was not done before 2018-06-16.
|
||||
await asyncMap(remotes, async ({ handler }) =>
|
||||
asyncMap(
|
||||
this._listVmBackups(handler, vmUuid, _ => _.mode === 'delta'),
|
||||
({ _filename, vdis, vhds }) => {
|
||||
const vmDir = dirname(_filename)
|
||||
return asyncMap(vhds, async (vhdPath, vdiId) => {
|
||||
const uuid = parseUuid(vdis[vdiId].uuid)
|
||||
|
||||
const vhd = new Vhd(handler, `${vmDir}/${vhdPath}`)
|
||||
await vhd.readHeaderAndFooter()
|
||||
if (!vhd.footer.uuid.equals(uuid)) {
|
||||
vhd.footer.uuid = uuid
|
||||
await vhd.readBlockAllocationTable()
|
||||
await vhd.writeFooter()
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
let baseSnapshot, fullVdisRequired
|
||||
await (async () => {
|
||||
baseSnapshot = (last(snapshots): Vm | void)
|
||||
@@ -1096,10 +1123,7 @@ export default class BackupNg {
|
||||
const vhd = new Vhd(handler, `${dir}/${file}`)
|
||||
await vhd.readHeaderAndFooter()
|
||||
|
||||
if (
|
||||
Buffer.from(vhd.footer.uuid).toString('hex') ===
|
||||
vdi.uuid.split('-').join('')
|
||||
) {
|
||||
if (vhd.footer.uuid.equals(parseUuid(vdi.uuid))) {
|
||||
full = false
|
||||
}
|
||||
|
||||
@@ -1277,10 +1301,7 @@ export default class BackupNg {
|
||||
// set the correct UUID in the VHD
|
||||
const vhd = new Vhd(handler, path)
|
||||
await vhd.readHeaderAndFooter()
|
||||
vhd.footer.uuid = Buffer.from(
|
||||
vdi.uuid.split('-').join(''),
|
||||
'hex'
|
||||
)
|
||||
vhd.footer.uuid = parseUuid(vdi.uuid)
|
||||
await vhd.readBlockAllocationTable() // required by writeFooter()
|
||||
await vhd.writeFooter()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"pipette": "^0.9.3",
|
||||
"promise-toolbox": "^0.9.5",
|
||||
"tmp": "^0.0.33",
|
||||
"vhd-lib": "^0.1.2"
|
||||
"vhd-lib": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.0.0-beta.49",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": false,
|
||||
"name": "xo-web",
|
||||
"version": "5.20.1",
|
||||
"version": "5.20.2",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Web interface client for Xen-Orchestra",
|
||||
"keywords": [
|
||||
|
||||
Reference in New Issue
Block a user