mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-04-04 16:27:29 +00:00
82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
import { Writer } from 'clitastic'
|
|
import { resolve } from 'path'
|
|
|
|
import { config } from './autorestic'
|
|
import { getEnvFromBackend } from './backend'
|
|
import { LocationFromPrefixes } from './config'
|
|
import { Backend } from './types'
|
|
import {
|
|
checkIfDockerVolumeExistsOrFail,
|
|
ConfigError,
|
|
decodeLocationFromPrefix,
|
|
exec,
|
|
execPlain,
|
|
getPathFromVolume,
|
|
} from './utils'
|
|
|
|
|
|
|
|
export const restoreToFilesystem = (from: string, to: string, backend: Backend) => {
|
|
exec(
|
|
'restic',
|
|
['restore', 'latest', '--path', resolve(from), '--target', to],
|
|
{ env: getEnvFromBackend(backend) },
|
|
)
|
|
}
|
|
|
|
export const restoreToVolume = (volume: string, backend: Backend) => {
|
|
const tmp = getPathFromVolume(volume)
|
|
try {
|
|
restoreToFilesystem(tmp, tmp, backend)
|
|
try {
|
|
checkIfDockerVolumeExistsOrFail(volume)
|
|
} catch {
|
|
execPlain(`docker volume create ${volume}`)
|
|
}
|
|
|
|
// For incremental backups. Unfortunately due to how the docker mounts work the permissions get lost.
|
|
// execPlain(`docker run --rm -v ${volume}:/data -v ${tmp}:/backup alpine cp -aT /backup /data`)
|
|
execPlain(`docker run --rm -v ${volume}:/data -v ${tmp}:/backup alpine tar xf /backup/archive.tar -C /data`)
|
|
} finally {
|
|
execPlain(`rm -rf ${tmp}`)
|
|
}
|
|
}
|
|
|
|
export const restoreSingle = (locationName: string, from: string, to?: string) => {
|
|
if (!config) throw ConfigError
|
|
|
|
const location = config.locations[locationName]
|
|
|
|
const baseText = locationName.green + '\t\t'
|
|
const w = new Writer(baseText + `Restoring...`)
|
|
|
|
let backendName: string = Array.isArray(location.to) ? location.to[0] : location.to
|
|
if (from) {
|
|
if (!location.to.includes(from)) {
|
|
w.done(baseText + `Backend ${from} is not a valid location for ${locationName}`.red)
|
|
return
|
|
}
|
|
backendName = from
|
|
w.replaceLn(baseText + `Restoring from ${backendName.blue}...`)
|
|
} else if (Array.isArray(location.to) && location.to.length > 1) {
|
|
w.replaceLn(baseText + `Restoring from ${backendName.blue}...\tTo select a specific backend pass the ${'--from'.blue} flag`)
|
|
}
|
|
const backend = config.backends[backendName]
|
|
|
|
const [type, value] = decodeLocationFromPrefix(location.from)
|
|
switch (type) {
|
|
|
|
case LocationFromPrefixes.Filesystem:
|
|
if (!to) throw new Error(`You need to specify the restore path with --to`.red)
|
|
restoreToFilesystem(value, to, backend)
|
|
break
|
|
|
|
case LocationFromPrefixes.DockerVolume:
|
|
restoreToVolume(value, backend)
|
|
break
|
|
|
|
}
|
|
w.done(locationName.green + '\t\tDone 🎉')
|
|
}
|
|
|