@xen-orchestra/backups 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,304 +0,0 @@
1
- // @ts-check
2
-
3
- /**
4
- * @typedef {import('./RemoteVhdDisk.mjs').VhdFooter} VhdFooter
5
- * @typedef {import('./RemoteVhdDisk.mjs').RemoteVhdDisk} RemoteVhdDisk
6
- * @typedef {import('@xen-orchestra/disk-transform').DiskBlock} DiskBlock
7
- * @typedef {import('@xen-orchestra/disk-transform').FileAccessor} FileAccessor
8
- */
9
-
10
- import { RemoteDisk } from './RemoteDisk.mjs'
11
-
12
- export class RemoteVhdDiskChain extends RemoteDisk {
13
- /**
14
- * @type {RemoteVhdDisk[]}
15
- */
16
- #disks
17
-
18
- /**
19
- * @type {number}
20
- */
21
- #blockSize = 2 * 1024 * 1024
22
-
23
- /**
24
- * @type {number}
25
- */
26
- #headerSize = 1024
27
-
28
- /**
29
- * @type {number}
30
- */
31
- #footerSize = 512
32
-
33
- /**
34
- * @type {number}
35
- */
36
- #bitmapSize = 512
37
-
38
- /**
39
- * @param {Object} params
40
- * @param {FileAccessor} params.handler
41
- * @param {RemoteVhdDisk[]} params.disks
42
- */
43
- constructor({ disks }) {
44
- super()
45
- this.#disks = disks
46
- }
47
-
48
- /**
49
- * Initializes the VHD chain
50
- * @param {Object} options
51
- * @param {boolean} options.force
52
- * @returns {Promise<void>}
53
- */
54
- async init(options) {
55
- try {
56
- await Promise.all(this.#disks.map(disk => disk.init(options)))
57
- let parentUuid = ''
58
- for (const [index, disk] of this.#disks.entries()) {
59
- if (index !== 0) {
60
- if (!disk.isDifferencing()) {
61
- throw Object.assign(new Error("Can't init vhd directory with non differencing child disks"), {
62
- code: 'NOT_SUPPORTED',
63
- })
64
- }
65
- if (disk.getParentUuid() !== parentUuid) {
66
- throw Object.assign(new Error("Can't init vhd directory with incorrect parentage"), {
67
- code: 'NOT_SUPPORTED',
68
- })
69
- }
70
- }
71
-
72
- parentUuid = disk.getUuid()
73
- }
74
- } catch (error) {
75
- await this.close()
76
- throw error
77
- }
78
- }
79
-
80
- /**
81
- * Closes the VHD.
82
- * @returns {Promise<void>}
83
- */
84
- async close() {
85
- await Promise.all(this.#disks.map(disk => disk.close()))
86
- }
87
-
88
- /**
89
- * @returns {number}
90
- */
91
- getVirtualSize() {
92
- return this.#disks[this.#disks.length - 1].getVirtualSize()
93
- }
94
-
95
- /**
96
- * @returns {number} size
97
- */
98
- getSizeOnDisk() {
99
- const batEntrySize = 4
100
- const sectorSize = 512
101
- const batSize = Math.ceil((this.getMaxBlockCount() * batEntrySize) / sectorSize) * sectorSize
102
-
103
- return (
104
- this.#footerSize +
105
- this.#headerSize +
106
- batSize +
107
- this.getBlockIndexes().length * (this.#blockSize + this.#bitmapSize) +
108
- this.#footerSize
109
- )
110
- }
111
-
112
- /**
113
- * @returns {number}
114
- */
115
- getBlockSize() {
116
- return this.#disks[this.#disks.length - 1].getBlockSize()
117
- }
118
-
119
- /**
120
- * @returns {string}
121
- */
122
- getPath() {
123
- return this.#disks[this.#disks.length - 1].getPath()
124
- }
125
-
126
- /**
127
- * Disk chains return an array of disk paths.
128
- *
129
- * @returns {string[]}
130
- */
131
- getPaths() {
132
- return this.#disks.map(disk => disk.getPath())
133
- }
134
-
135
- /**
136
- * @returns {string}
137
- */
138
- getUuid() {
139
- return this.#disks[this.#disks.length - 1].getUuid()
140
- }
141
-
142
- /**
143
- * @returns {Promise<boolean>} canMergeConcurently
144
- */
145
- async canMergeConcurently() {
146
- return this.isDirectory()
147
- }
148
-
149
- /**
150
- * @returns {number} getMaxBlockCount
151
- */
152
- getMaxBlockCount() {
153
- return this.#disks[this.#disks.length - 1].getMaxBlockCount()
154
- }
155
-
156
- /**
157
- * Checks if the VHD contains a specific block.
158
- * @param {number} index
159
- * @returns {boolean}
160
- */
161
- hasBlock(index) {
162
- for (const disk of this.#disks) {
163
- if (disk.hasBlock(index)) {
164
- return true
165
- }
166
- }
167
-
168
- return false
169
- }
170
-
171
- /**
172
- * Gets the indexes of all blocks in the VHD.
173
- * @returns {Array<number>}
174
- */
175
- getBlockIndexes() {
176
- const indexes = new Set()
177
- for (const disk of this.#disks) {
178
- for (const index of disk.getBlockIndexes()) {
179
- indexes.add(index)
180
- }
181
- }
182
- return [...indexes]
183
- }
184
-
185
- /**
186
- * Returns the parent non inizialized instance
187
- * @returns {RemoteDisk}
188
- */
189
- instantiateParent() {
190
- return this.#disks[0].instantiateParent()
191
- }
192
-
193
- /**
194
- * Writes a full block into this VHD.
195
- * @param {DiskBlock} diskBlock
196
- * @return {Promise<number>} blockSize
197
- */
198
- async writeBlock(diskBlock) {
199
- throw new Error(`Can't write blocks into a disk chain`)
200
- }
201
-
202
- /**
203
- * Reads a specific block from the VHD.
204
- * @param {number} index
205
- * @returns {Promise<DiskBlock>} diskBlock
206
- */
207
- async readBlock(index) {
208
- const reversedDisks = this.#disks.slice().reverse()
209
- for (const disk of reversedDisks) {
210
- if (disk.hasBlock(index)) {
211
- return disk.readBlock(index)
212
- }
213
- }
214
- throw new Error(`Block ${index} not found in chain `)
215
- }
216
-
217
- /**
218
- * Reads a specific block from the child disk to copy/move it to this disk.
219
- * @param {RemoteDisk} childDisk
220
- * @param {number} index
221
- * @param {boolean} isResumingMerge
222
- * @returns {Promise<number>} blockSize
223
- */
224
- async mergeBlock(childDisk, index, isResumingMerge) {
225
- throw new Error(`Can't merge block into a disk chain`)
226
- }
227
-
228
- /**
229
- * Gets a specific block path from the VHD directory disk.
230
- * @param {number} index
231
- * @returns {string} blockPath
232
- */
233
- getBlockPath(index) {
234
- for (const disk of [...this.#disks].reverse()) {
235
- if (disk.hasBlock(index)) {
236
- return disk.getBlockPath(index)
237
- }
238
- }
239
-
240
- throw new Error(`Block ${index} not found in chain`)
241
- }
242
-
243
- /**
244
- * @returns {VhdFooter}
245
- */
246
- getMetadata() {
247
- return this.#disks[this.#disks.length - 1].getMetadata()
248
- }
249
-
250
- /**
251
- * @param {RemoteVhdDisk} childDisk
252
- * @returns {Promise<void>}
253
- */
254
- async flushMetadata(childDisk) {
255
- throw new Error(`Can't flush metadata on a disk chain`)
256
- }
257
-
258
- /**
259
- * @param {RemoteVhdDisk} childDisk
260
- * @returns {Promise<void>}
261
- */
262
- mergeMetadata(childDisk) {
263
- throw new Error(`Can't merge metadata on a disk chain`)
264
- }
265
-
266
- /**
267
- * Checks if the VHD is a differencing disk.
268
- * @returns {boolean}
269
- */
270
- isDifferencing() {
271
- return this.#disks[0].isDifferencing()
272
- }
273
-
274
- /**
275
- * Abstract
276
- * Rename alias/disk
277
- * @param {string} newPath
278
- */
279
- async rename(newPath) {
280
- throw new Error(`Can't rename a disk chain`)
281
- }
282
-
283
- /**
284
- * Deletes all the disks
285
- */
286
- async unlink() {
287
- for (const disk of this.#disks) {
288
- await disk.unlink()
289
- }
290
- }
291
-
292
- /**
293
- * Check if all the disks in the chain are VHD directories.
294
- * @returns {Promise<boolean>}
295
- */
296
- async isDirectory() {
297
- for (const disk of this.#disks) {
298
- if (!(await disk.isDirectory())) {
299
- return false
300
- }
301
- }
302
- return true
303
- }
304
- }
package/disks/index.mjs DELETED
@@ -1,49 +0,0 @@
1
- import { RemoteVhdDisk } from './RemoteVhdDisk.mjs'
2
-
3
- export { RemoteDisk } from './RemoteDisk.mjs'
4
- export { openDiskChain } from './openDiskChain.mjs'
5
-
6
- /**
7
- * @typedef {import('../../disk-transform/src/FileAccessor.mjs').FileAccessor} FileAccessor
8
- * @typedef {import('./RemoteDisk.mjs').RemoteDisk} RemoteDisk
9
- */
10
-
11
- /**
12
- * @param {Object} params
13
- * @param {FileAccessor} params.handler
14
- * @param {string} params.path
15
- * @returns {Promise<RemoteDisk>}
16
- */
17
- export async function openDisk({ handler, path }) {
18
- const disk = new RemoteVhdDisk({ handler, path })
19
- await disk.init()
20
- return disk
21
- }
22
- /**
23
- *
24
- * @param {Object} params
25
- * @param {FileAccessor} params.handler
26
- * @param {string} params.path
27
- * @returns {Promise<Disposable<RemoteDisk>>}
28
- */
29
- export async function openDisposableDisk({ handler, path }) {
30
- const disk = new RemoteVhdDisk({ handler, path })
31
- await disk.init()
32
- return {
33
- value: disk,
34
- dispose: () => disk.close(),
35
- }
36
- }
37
-
38
- const DISK_EXTENSIONS = ['.vhd']
39
-
40
- /**
41
- * Returns true if the path points to a supported disk format.
42
- *
43
- * @param {FileAccessor} _handler - Remote file handler (reserved for future use)
44
- * @param {string} path - Path to check
45
- * @returns {boolean}
46
- */
47
- export function isDisk(_handler, path) {
48
- return DISK_EXTENSIONS.some(ext => path.endsWith(ext))
49
- }
@@ -1,40 +0,0 @@
1
- // @ts-check
2
- /**
3
- *
4
- * @typedef {import('../../disk-transform/src/FileAccessor.mjs').FileAccessor} FileAccessor
5
- * @typedef {import('./RemoteDisk.mjs').RemoteDisk} RemoteDisk
6
- */
7
- import { DiskChain } from '@xen-orchestra/disk-transform'
8
- import { RemoteVhdDisk } from './RemoteVhdDisk.mjs'
9
-
10
- import { defer } from 'golike-defer'
11
- /**
12
- * @param {any} $defer
13
- * @param {Object} params
14
- * @param {FileAccessor} params.handler
15
- * @param {string} params.path
16
- * @param {string | undefined} params.until
17
- */
18
- async function _openDiskChain($defer, { handler, path, until }) {
19
- let disk
20
- /**
21
- * @type {Array<RemoteDisk>}
22
- */
23
- const disks = []
24
- $defer.onFailure(() => Promise.all(disks.map(disk => disk.close())))
25
- disk = new RemoteVhdDisk({ handler, path })
26
-
27
- await disk.init()
28
- disks.push(disk)
29
- while (disk.isDifferencing()) {
30
- disk = await disk.openParent()
31
- if (disk.getPath() === until) {
32
- break
33
- }
34
- disks.unshift(disk)
35
- }
36
- // the root disk
37
- return new DiskChain({ disks })
38
- }
39
-
40
- export const openDiskChain = defer(_openDiskChain)