feat(backups-cli/info): compute the used space per job
This commit is contained in:
parent
4575b98fd5
commit
0f42f032e4
@ -3,6 +3,17 @@ const { dirname } = require('path')
|
|||||||
const fs = require('promise-toolbox/promisifyAll')(require('fs'))
|
const fs = require('promise-toolbox/promisifyAll')(require('fs'))
|
||||||
module.exports = fs
|
module.exports = fs
|
||||||
|
|
||||||
|
fs.getSize = path =>
|
||||||
|
fs.stat(path).then(
|
||||||
|
_ => _.size,
|
||||||
|
error => {
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
fs.mktree = async function mkdirp(path) {
|
fs.mktree = async function mkdirp(path) {
|
||||||
try {
|
try {
|
||||||
await fs.mkdir(path)
|
await fs.mkdir(path)
|
||||||
|
58
@xen-orchestra/backups-cli/commands/info.js
Normal file
58
@xen-orchestra/backups-cli/commands/info.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
const groupBy = require('lodash/groupBy')
|
||||||
|
const { createHash } = require('crypto')
|
||||||
|
const { dirname, resolve } = require('path')
|
||||||
|
|
||||||
|
const asyncMap = require('../_asyncMap')
|
||||||
|
const { readdir2, readFile, getSize } = require('../_fs')
|
||||||
|
|
||||||
|
const sha512 = str => createHash('sha512').update(str).digest('hex')
|
||||||
|
const sum = values => values.reduce((a, b) => a + b)
|
||||||
|
|
||||||
|
module.exports = async function info(vmDirs) {
|
||||||
|
const jsonFiles = (
|
||||||
|
await asyncMap(vmDirs, async vmDir =>
|
||||||
|
(await readdir2(vmDir)).filter(_ => _.endsWith('.json'))
|
||||||
|
)
|
||||||
|
).flat()
|
||||||
|
|
||||||
|
const hashes = { __proto__: null }
|
||||||
|
|
||||||
|
const info = (
|
||||||
|
await asyncMap(jsonFiles, async jsonFile => {
|
||||||
|
try {
|
||||||
|
const jsonDir = dirname(jsonFile)
|
||||||
|
const json = await readFile(jsonFile)
|
||||||
|
|
||||||
|
const hash = sha512(json)
|
||||||
|
if (hash in hashes) {
|
||||||
|
console.log(jsonFile, 'duplicate of', hashes[hash])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hashes[hash] = jsonFile
|
||||||
|
|
||||||
|
const metadata = JSON.parse(json)
|
||||||
|
|
||||||
|
return {
|
||||||
|
jsonDir,
|
||||||
|
jsonFile,
|
||||||
|
metadata,
|
||||||
|
size:
|
||||||
|
json.length +
|
||||||
|
(await (metadata.mode === 'delta'
|
||||||
|
? asyncMap(Object.values(metadata.vhds), _ =>
|
||||||
|
getSize(resolve(jsonDir, _))
|
||||||
|
).then(sum)
|
||||||
|
: getSize(resolve(jsonDir, metadata.xva)))),
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(jsonFile, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
).filter(_ => _ !== undefined)
|
||||||
|
const byJobs = groupBy(info, 'metadata.jobId')
|
||||||
|
Object.keys(byJobs)
|
||||||
|
.sort()
|
||||||
|
.forEach(jobId => {
|
||||||
|
console.log(jobId, sum(byJobs[jobId].map(_ => _.size)))
|
||||||
|
})
|
||||||
|
}
|
@ -13,6 +13,12 @@ require('./_composeCommands')({
|
|||||||
},
|
},
|
||||||
usage: 'xo-vm-backups <field path>',
|
usage: 'xo-vm-backups <field path>',
|
||||||
},
|
},
|
||||||
|
info: {
|
||||||
|
get main() {
|
||||||
|
return require('./commands/info')
|
||||||
|
},
|
||||||
|
usage: 'xo-vm-backups/*',
|
||||||
|
},
|
||||||
})(process.argv.slice(2), 'xo-backups').catch(error => {
|
})(process.argv.slice(2), 'xo-backups').catch(error => {
|
||||||
console.error('main', error)
|
console.error('main', error)
|
||||||
process.exitCode = 1
|
process.exitCode = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user