mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2024-10-31 18:54:12 +01:00
add cron command
This commit is contained in:
parent
82f6942ff1
commit
9acb6296e4
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,4 +16,5 @@ Dockerfile
|
|||||||
|
|
||||||
# Config
|
# Config
|
||||||
.autorestic.yml
|
.autorestic.yml
|
||||||
|
.autorestic.lock
|
||||||
.docker.yml
|
.docker.yml
|
@ -37,7 +37,7 @@ async function main() {
|
|||||||
config = init()
|
config = init()
|
||||||
|
|
||||||
// For dev
|
// For dev
|
||||||
// return await handlers['check']([], { ...flags, all: true })
|
// return await handlers['cron']([], { ...flags, all: true })
|
||||||
|
|
||||||
if (commands.length < 1 || commands[0] === 'help') return help()
|
if (commands.length < 1 || commands[0] === 'help') return help()
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { Writer } from 'clitastic'
|
|||||||
|
|
||||||
import { config, VERBOSE } from './autorestic'
|
import { config, VERBOSE } from './autorestic'
|
||||||
import { Backend, Backends, Locations } from './types'
|
import { Backend, Backends, Locations } from './types'
|
||||||
import { exec, pathRelativeToConfigFile } from './utils'
|
import { exec, pathRelativeToConfigFile, filterObjectByKey } from './utils'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -67,3 +67,9 @@ export const checkAndConfigureBackends = (backends?: Backends) => {
|
|||||||
for (const [name, backend] of Object.entries(backends))
|
for (const [name, backend] of Object.entries(backends))
|
||||||
checkAndConfigureBackend(name, backend)
|
checkAndConfigureBackend(name, backend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const checkAndConfigureBackendsForLocations = (locations: Locations) => {
|
||||||
|
checkAndConfigureBackends(
|
||||||
|
filterObjectByKey(config.backends, getBackendsFromLocations(locations)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
61
src/cron.ts
Normal file
61
src/cron.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
import CronParser from 'cron-parser'
|
||||||
|
|
||||||
|
import { config } from './autorestic'
|
||||||
|
import { checkAndConfigureBackendsForLocations } from './backend'
|
||||||
|
import { Location, Lockfile } from './types'
|
||||||
|
import { backupLocation } from './backup'
|
||||||
|
import { pathRelativeToConfigFile } from './utils'
|
||||||
|
|
||||||
|
|
||||||
|
const getLockFileName = () => {
|
||||||
|
const LOCK_FILE = '.autorestic.lock'
|
||||||
|
return pathRelativeToConfigFile(LOCK_FILE)
|
||||||
|
}
|
||||||
|
|
||||||
|
const readLock = (): Lockfile => {
|
||||||
|
const name = getLockFileName()
|
||||||
|
let lock = {}
|
||||||
|
try {
|
||||||
|
lock = JSON.parse(fs.readFileSync(name, { encoding: 'utf-8' }))
|
||||||
|
} catch { }
|
||||||
|
return lock
|
||||||
|
}
|
||||||
|
const writeLock = (diff: Lockfile = {}) => {
|
||||||
|
const name = getLockFileName()
|
||||||
|
const newLock = Object.assign(
|
||||||
|
readLock(),
|
||||||
|
diff
|
||||||
|
)
|
||||||
|
fs.writeFileSync(name, JSON.stringify(newLock, null, 2), { encoding: 'utf-8' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const runCronForLocation = (name: string, location: Location) => {
|
||||||
|
const lock = readLock()[name]
|
||||||
|
const parsed = CronParser.parseExpression(location.cron || '')
|
||||||
|
const last = parsed.prev()
|
||||||
|
|
||||||
|
if (!lock || last.toDate().getTime() > lock.lastRun) {
|
||||||
|
backupLocation(name, location)
|
||||||
|
writeLock({
|
||||||
|
[name]: {
|
||||||
|
...lock,
|
||||||
|
lastRun: Date.now()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log(`${name.yellow} ▶ Skipping. Sheduled for: ${parsed.next().toString().underline.blue}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const runCron = () => {
|
||||||
|
const locationsWithCron = Object.entries(config.locations).filter(([name, { cron }]) => !!cron)
|
||||||
|
checkAndConfigureBackendsForLocations(Object.fromEntries(locationsWithCron))
|
||||||
|
|
||||||
|
console.log('\nRunning cron jobs'.underline.gray)
|
||||||
|
for (const [name, location] of locationsWithCron)
|
||||||
|
runCronForLocation(name, location)
|
||||||
|
|
||||||
|
console.log('\nFinished!'.underline + ' 🎉')
|
||||||
|
}
|
@ -6,8 +6,9 @@ import axios from 'axios'
|
|||||||
import { Writer } from 'clitastic'
|
import { Writer } from 'clitastic'
|
||||||
|
|
||||||
import { config, INSTALL_DIR, VERSION } from './autorestic'
|
import { config, INSTALL_DIR, VERSION } from './autorestic'
|
||||||
import { checkAndConfigureBackends, getBackendsFromLocations, getEnvFromBackend } from './backend'
|
import { checkAndConfigureBackends, getEnvFromBackend, checkAndConfigureBackendsForLocations } from './backend'
|
||||||
import { backupAll } from './backup'
|
import { backupAll } from './backup'
|
||||||
|
import { runCron } from './cron'
|
||||||
import { forgetAll } from './forget'
|
import { forgetAll } from './forget'
|
||||||
import showAll from './info'
|
import showAll from './info'
|
||||||
import { restoreSingle } from './restore'
|
import { restoreSingle } from './restore'
|
||||||
@ -72,14 +73,15 @@ const handlers: Handlers = {
|
|||||||
backup(args, flags) {
|
backup(args, flags) {
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
const locations: Locations = parseLocations(flags)
|
const locations: Locations = parseLocations(flags)
|
||||||
|
checkAndConfigureBackendsForLocations(locations)
|
||||||
checkAndConfigureBackends(
|
|
||||||
filterObjectByKey(config.backends, getBackendsFromLocations(locations)),
|
|
||||||
)
|
|
||||||
backupAll(locations)
|
backupAll(locations)
|
||||||
|
|
||||||
console.log('\nFinished!'.underline + ' 🎉')
|
console.log('\nFinished!'.underline + ' 🎉')
|
||||||
},
|
},
|
||||||
|
cron(args, flags) {
|
||||||
|
checkIfResticIsAvailable()
|
||||||
|
runCron()
|
||||||
|
},
|
||||||
restore(args, flags) {
|
restore(args, flags) {
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
|
|
||||||
@ -93,10 +95,7 @@ const handlers: Handlers = {
|
|||||||
forget(args, flags) {
|
forget(args, flags) {
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
const locations: Locations = parseLocations(flags)
|
const locations: Locations = parseLocations(flags)
|
||||||
|
checkAndConfigureBackendsForLocations(locations)
|
||||||
checkAndConfigureBackends(
|
|
||||||
filterObjectByKey(config.backends, getBackendsFromLocations(locations)),
|
|
||||||
)
|
|
||||||
forgetAll(locations, flags)
|
forgetAll(locations, flags)
|
||||||
|
|
||||||
console.log('\nFinished!'.underline + ' 🎉')
|
console.log('\nFinished!'.underline + ' 🎉')
|
||||||
|
@ -92,4 +92,10 @@ export type Config = {
|
|||||||
backends: Backends
|
backends: Backends
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Lockfile = {
|
||||||
|
[name: string]: {
|
||||||
|
lastRun: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type Flags = { [arg: string]: any }
|
export type Flags = { [arg: string]: any }
|
||||||
|
Loading…
Reference in New Issue
Block a user