Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f2d3101c7 | ||
|
|
bb3c0e5c13 | ||
|
|
e70655189c | ||
|
|
0a01666de3 | ||
|
|
458105e611 | ||
|
|
8549cfd4da | ||
|
|
81086a7628 | ||
|
|
02ff1b58f7 | ||
|
|
8eab92841f | ||
|
|
fb4e872990 | ||
|
|
e3893f594e | ||
|
|
2457617bdc | ||
|
|
8ae7880d6b | ||
|
|
81ab7be40c | ||
|
|
422a36bbeb | ||
|
|
e49b1d9a4b | ||
|
|
a8a23db940 | ||
|
|
c7443470a2 | ||
|
|
1f2bc5e153 | ||
|
|
ae7d31f72d | ||
|
|
248203186f | ||
|
|
b35025d6ad | ||
|
|
f327412bf6 | ||
|
|
c7ea8f86ce |
+2
-2
@@ -16,8 +16,8 @@ for (const target of targets) {
|
||||
sugoiSpawn('deno', 'compile',
|
||||
'--target', target,
|
||||
'--include', 'src/snapper-template.txt',
|
||||
'--include', 'src/snapper@.service',
|
||||
'--include', 'src/snapback@.service',
|
||||
'--output', 'dist/snapback-'+target,
|
||||
'src/main.ts'
|
||||
'--permission-set','src/main.ts'
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/denoland/deno/refs/heads/main/cli/schemas/config-file.v1.json",
|
||||
"nodeModulesDir":"none"
|
||||
"nodeModulesDir": "none",
|
||||
"compile": {
|
||||
"permissions": {
|
||||
"read": true,
|
||||
"write": true,
|
||||
"run": ["tar","chmod"],
|
||||
"env": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
-15
@@ -3,11 +3,12 @@
|
||||
import { program } from "commander"
|
||||
import { parseJSON, parseTOML, stringifyJSON } from "confbox"
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
import strftime from 'strftime'
|
||||
import { spawnSync } from "node:child_process"
|
||||
|
||||
let config: { [key: string]: string } = {}
|
||||
let index: { [key: string]: { [key: string]: string } } = {}
|
||||
let config: { [key: string]: string|undefined } = {}
|
||||
let index: { [key: string]: { [key: string]: string|undefined }|undefined } = {}
|
||||
|
||||
function sugoiSpawn(...command: string[]) {
|
||||
const result = spawnSync(command.shift()!, command, { stdio: 'inherit' })
|
||||
@@ -34,46 +35,58 @@ program.command('*').description('snapback ignores unknown commands')
|
||||
|
||||
program.command('install').description('installs snapback on your system')
|
||||
.action(function () {
|
||||
const template = fs.readFileSync(import.meta.dirname + '/snapper-template.txt')
|
||||
const service = fs.readFileSync(import.meta.dirname + '/snapback@.service')
|
||||
let lib_snapper = '/usr/libexec/snapper'
|
||||
if (!fs.existsSync(lib_snapper)) lib_snapper = '/usr/lib/snapper'
|
||||
console.debug(`${import.meta.url} will be moved to ${lib_snapper}/99-snapback`)
|
||||
const template = fs.readFileSync(import.meta.dirname + '/snapper-template.txt')
|
||||
const service = fs.readFileSync(import.meta.dirname + '/snapper@.service')
|
||||
fs.writeFileSync('/etc/systemd/system/snapper@.service', service, 'utf8')
|
||||
if (!fs.existsSync('/etc/snapper/config-templates')) fs.mkdirSync('/etc/snapper/config-templates')
|
||||
fs.writeFileSync('/etc/snapper/config-templates/snapback', template, 'utf8')
|
||||
fs.writeFileSync('/etc/systemd/system/snapback@.service', service, 'utf8')
|
||||
fs.mkdirSync(lib_snapper + '/plugins', { recursive: true })
|
||||
fs.renameSync(import.meta.url, lib_snapper + '/plugins/99-snapback')
|
||||
let argv0 = process.argv0
|
||||
if (['node','deno','bun'].includes(path.basename(argv0).replace('.exe',''))) {
|
||||
argv0 = import.meta.url
|
||||
}
|
||||
fs.renameSync(argv0, lib_snapper + '/plugins/99-snapback')
|
||||
sugoiSpawn('chmod', '+x', lib_snapper + '/plugins/99-snapback')
|
||||
sugoiSpawn('systemctl','daemon-reload')
|
||||
console.log('snapback installed')
|
||||
})
|
||||
|
||||
program.command('create-snapshot-post <subvolume> <fstype> <number>')
|
||||
.description('create a backup after a snapshot')
|
||||
.action(function (subvolume, fstype, number) {
|
||||
if (!config[subvolume]) return
|
||||
if (!config[subvolume]) {console.log(subvolume + ' not configured for snapback'); return}
|
||||
const destination = strftime(config[subvolume])
|
||||
const dirname = path.dirname(destination)
|
||||
try { fs.mkdirSync(dirname, { 'recursive': true }) } catch {}
|
||||
sugoiSpawn('tar',
|
||||
`--directory=${subvolume}/.snapshots/${number}/snapshot`,
|
||||
'--create', '--file', destination,
|
||||
'--auto-compress', '--dereference', '.'
|
||||
)
|
||||
if(!index[subvolume]) index[subvolume]={}
|
||||
index[subvolume][number] = destination
|
||||
console.log('created backup at '+destination)
|
||||
})
|
||||
|
||||
program.command('delete-snapshot-post <subvolume> <fstype> <number>')
|
||||
.description('delete a backup after deleting a snapshot')
|
||||
.action(function (subvolume, fstype, number) {
|
||||
if (!index[subvolume]) {
|
||||
console.log('no backups indexed for ' + subvolume)
|
||||
return
|
||||
}
|
||||
const destination = index[subvolume][number]
|
||||
if (!destination) {
|
||||
console.log('no backup indexed for ' + subvolume + ':' + number)
|
||||
return
|
||||
}
|
||||
fs.unlinkSync(destination)
|
||||
delete index[subvolume][number]
|
||||
})
|
||||
|
||||
program.command('delete-config-post <subvolume> <fstype>')
|
||||
.description('delete metadata of deleted subvolume, retaining backups')
|
||||
.action(function (subvolume, fstype) {
|
||||
delete index[subvolume]
|
||||
console.log('deleted backup at '+destination)
|
||||
})
|
||||
|
||||
program.parse()
|
||||
|
||||
if (Object.keys(index).length) fs.writeFileSync(program.opts().indexFile,stringifyJSON(index), 'utf8')
|
||||
fs.writeFileSync(program.opts().indexFile,stringifyJSON(index), 'utf8')
|
||||
@@ -0,0 +1,6 @@
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStartPre=-btrfs subvolume create %I
|
||||
ExecStartPre=-snapper --no-dbus --config %i create-config --template snapback %I
|
||||
ExecStartPre=chown 0 %I/.snapshots
|
||||
ExecStart=snapper --no-dbus --config %i create --cleanup-algorithm number
|
||||
@@ -1,5 +0,0 @@
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStartPre=-btrfs subvolume create %I
|
||||
ExecStartPre=-snapper --config %i create-config %I --template snapback
|
||||
ExecStart=snapper --config %i create --cleanup-algorithm number
|
||||
Reference in New Issue
Block a user