Skip to content

Commit

Permalink
new implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeauchamp committed Dec 15, 2023
1 parent 7f60b45 commit 6d83b84
Show file tree
Hide file tree
Showing 18 changed files with 237 additions and 854 deletions.
2 changes: 1 addition & 1 deletion @xen-orchestra/backups/_backupType.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const isMetadataFile = filename => filename.endsWith('.json') && !filename.endsWith('.json.noncrypted.json')
export const isMetadataFile = filename => filename.endsWith('.json')
export const isVhdFile = filename => filename.endsWith('.vhd')
export const isXvaFile = filename => filename.endsWith('.xva')
export const isXvaSumFile = filename => filename.endsWith('.xva.checksum')
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ export class IncrementalRemoteWriter extends MixinRemoteWriter(AbstractIncrement
)

metadataContent = {
differentialVhds,
jobId,
mode: job.mode,
scheduleId,
Expand All @@ -172,7 +171,7 @@ export class IncrementalRemoteWriter extends MixinRemoteWriter(AbstractIncrement
vifs: deltaExport.vifs,
vhds,
vm,
vmSnapshot
vmSnapshot,
}
const { size } = await Task.run({ name: 'transfer' }, async () => {
let transferSize = 0
Expand Down
1 change: 0 additions & 1 deletion @xen-orchestra/backups/formatVmBackups.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ function formatVmBackup(backup) {
}),

id: backup.id,
immutable: backup.immutable,
jobId: backup.jobId,
mode: backup.mode,
scheduleId: backup.scheduleId,
Expand Down
4 changes: 2 additions & 2 deletions @xen-orchestra/fs/src/abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,9 @@ export default class RemoteHandlerAbstract {
return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)
}

async __readFile(file, { flags = 'r' , ignoreEncryption = false} = {}) {
async __readFile(file, { flags = 'r' } = {}) {
const data = await this._readFile(normalizePath(file), { flags })
return ignoreEncryption ? data : this.#encryptor.decryptData(data)
return this.#encryptor.decryptData(data)
}

async #rename(oldPath, newPath, { checksum }, createTree = true) {
Expand Down
68 changes: 0 additions & 68 deletions @xen-orchestra/immutable-backups/backup.integ.mjs

This file was deleted.

144 changes: 0 additions & 144 deletions @xen-orchestra/immutable-backups/backup.mjs

This file was deleted.

6 changes: 6 additions & 0 deletions @xen-orchestra/immutable-backups/computeCacheFilePath.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { basename } from 'node:path'
import { sha256 } from './directory.mjs'

export function computeCacheFilePath(path, immutabilityCachePath, isFile) {
return path.join(immutabilityCachePath, `${sha256(path)}.${isFile ? 'file' : 'dir'}.${basename(path)}`)
}
24 changes: 19 additions & 5 deletions @xen-orchestra/immutable-backups/directory.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import execa from 'execa'
export async function makeImmutable(path){
return execa('chattr', ['+i', '-R', path])
import { createHash } from 'node:crypto'
import fs from 'node:fs/promises'
import { computeCacheFilePath } from './computeCacheFilePath.mjs'

export function sha256(content) {
return createHash('sha256').update(content).digest('hex')
}

export async function makeImmutable(dirPath, immutabilityCachePath) {
const cacheFileName = computeCacheFilePath(dirPath, immutabilityCachePath, false)
await fs.writeFile(cacheFileName, dirPath)
await execa('chattr', ['+i', '-R', dirPath])
await execa('chattr', ['+i', cacheFileName])
}

export async function liftImmutability(path){
return execa('chattr', ['-i','-R', path])
}
export async function liftImmutability(dirPath, immutabilityCachePath) {
const cacheFileName = computeCacheFilePath(dirPath, immutabilityCachePath, false)
await execa('chattr', ['-i', cacheFileName])
await execa('chattr', ['-i', '-R', dirPath])
await fs.unlink(cacheFileName)
}
22 changes: 11 additions & 11 deletions @xen-orchestra/immutable-backups/file.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import execa from 'execa'
import fs from 'node:fs/promises'
import { computeCacheFilePath } from './computeCacheFilePath.mjs'

// this work only on linux like systems
// this could wokr on windwos : https://4sysops.com/archives/set-and-remove-the-read-only-file-attribute-with-powershell/

export async function makeImmutable(path){
await execa('chattr', ['+i', path])
export async function makeImmutable(path, immutabilityCachePath) {
const cacheFileName = computeCacheFilePath(path, immutabilityCachePath, true)
await fs.writeFile(cacheFileName, path)
await execa('chattr', ['+i', path])
await execa('chattr', ['+i', cacheFileName])
}

export async function liftImmutability(path){
console.log('lift', path)
return execa('chattr', ['-i', path])
}

export async function isImmutable(path){
const {stdout} = await execa('lsattr', [path])
const [flags] = stdout.split(' ')
return flags.includes('i')
export async function liftImmutability(filePath, immutabilityCachePath) {
const cacheFileName = computeCacheFilePath(filePath, immutabilityCachePath, false)
await execa('chattr', ['-i', cacheFileName])
await execa('chattr', ['-i', filePath])
await fs.unlink(cacheFileName)
}
22 changes: 22 additions & 0 deletions @xen-orchestra/immutable-backups/newFileWatcher.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { asyncEach } from '@vates/async-each'
import fs from 'node:fs/promises'

export async function watchForExistingAndNew(path, callback) {
asyncEach(fs.readdir(path, entry => callback(entry, false, watcher)))

const watcher = fs.watch(path)

for await (const { eventType, filename } of watcher) {
if (eventType === 'change') {
continue
}
if (filename.startsWith('.')) {
// temp file during upload
continue
}
const stat = await fs.stat(path)
if (stat.mtimeMs === stat.birthtimeMs) {
await callback(filename, true, watcher)
}
}
}
1 change: 1 addition & 0 deletions @xen-orchestra/immutable-backups/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"node": ">=14.0.0"
},
"dependencies": {
"@vates/async-each": "^1.0.0",
"@xen-orchestra/backups": "^0.44.2",
"@xen-orchestra/log": "^0.6.0",
"execa": "^5.0.0",
Expand Down
26 changes: 26 additions & 0 deletions @xen-orchestra/immutable-backups/poolOrMetadata.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { join } from 'node:path'
import * as Directory from './file.mjs'
import { watchForExistingAndNew } from './newFileWatcher.mjs'

async function waitForCompletion(path) {
await watchForExistingAndNew(path, (pathInDirectory, isNew, watcher) => {
if (!isNew) {
return
}
if (pathInDirectory === 'metadata.json') {
watcher.close()
// will end the watcher, stop this loop and return
}
})
}

export async function watch(basePath, immutabilityCachePath) {
await watchForExistingAndNew(basePath, async (pathInDirectory, isNew) => {
if (!isNew) {
return
}
const path = join(basePath, pathInDirectory)
await waitForCompletion(path)
await Directory.makeImmutable(path, immutabilityCachePath)
})
}
Loading

0 comments on commit 6d83b84

Please sign in to comment.