added keep_hourly
This commit is contained in:
@@ -3,6 +3,7 @@ AWS_SECRET_ACCESS_KEY="your_s3_secret"
|
||||
RESTIC_REPOSITORY="s3:https://s3.eu-central-1.amazonaws.com/bucket-name"
|
||||
RESTIC_PASSWORD="restic_encryption_password"
|
||||
ZFS_POOL_NAME="incus-pool"
|
||||
RESTIC_KEEP_HOURLY=0
|
||||
RESTIC_KEEP_DAILY=7
|
||||
RESTIC_KEEP_WEEKLY=0
|
||||
RESTIC_KEEP_MONTHLY=0
|
||||
|
||||
@@ -25,6 +25,7 @@ export const config = {
|
||||
RESTIC_PASSWORD: process.env.RESTIC_PASSWORD || '',
|
||||
},
|
||||
retention: {
|
||||
keepHourly: Number(process.env.RESTIC_KEEP_HOURLY || 0),
|
||||
keepDaily: Number(process.env.RESTIC_KEEP_DAILY || 7),
|
||||
keepWeekly: Number(process.env.RESTIC_KEEP_WEEKLY || 0),
|
||||
keepMonthly: Number(process.env.RESTIC_KEEP_MONTHLY || 0),
|
||||
@@ -37,6 +38,7 @@ export const editableEnv = [
|
||||
{ key: 'RESTIC_REPOSITORY', label: 'Restic repository', required: true, secret: false },
|
||||
{ key: 'RESTIC_PASSWORD', label: 'Restic password', required: true, secret: true },
|
||||
{ key: 'ZFS_POOL_NAME', label: 'ZFS pool name', required: true, secret: false },
|
||||
{ key: 'RESTIC_KEEP_HOURLY', label: 'Keep hourly snapshots', required: false, secret: false },
|
||||
{ key: 'RESTIC_KEEP_DAILY', label: 'Keep daily snapshots', required: false, secret: false },
|
||||
{ key: 'RESTIC_KEEP_WEEKLY', label: 'Keep weekly snapshots', required: false, secret: false },
|
||||
{ key: 'RESTIC_KEEP_MONTHLY', label: 'Keep monthly snapshots', required: false, secret: false },
|
||||
@@ -111,6 +113,7 @@ function applyRuntimeEnv(values) {
|
||||
config.resticEnv.AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY || '';
|
||||
config.resticEnv.RESTIC_REPOSITORY = process.env.RESTIC_REPOSITORY || '';
|
||||
config.resticEnv.RESTIC_PASSWORD = process.env.RESTIC_PASSWORD || '';
|
||||
config.retention.keepHourly = Number(process.env.RESTIC_KEEP_HOURLY || 0);
|
||||
config.retention.keepDaily = Number(process.env.RESTIC_KEEP_DAILY || 7);
|
||||
config.retention.keepWeekly = Number(process.env.RESTIC_KEEP_WEEKLY || 0);
|
||||
config.retention.keepMonthly = Number(process.env.RESTIC_KEEP_MONTHLY || 0);
|
||||
|
||||
@@ -117,14 +117,16 @@ function formatBytes(value) {
|
||||
|
||||
function retentionArgs(vmName) {
|
||||
const args = ['forget', '--tag', vmName, '--prune'];
|
||||
const keepHourly = positiveInteger(config.retention.keepHourly);
|
||||
const keepDaily = positiveInteger(config.retention.keepDaily);
|
||||
const keepWeekly = positiveInteger(config.retention.keepWeekly);
|
||||
const keepMonthly = positiveInteger(config.retention.keepMonthly);
|
||||
|
||||
if (keepHourly) args.push('--keep-hourly', String(keepHourly));
|
||||
if (keepDaily) args.push('--keep-daily', String(keepDaily));
|
||||
if (keepWeekly) args.push('--keep-weekly', String(keepWeekly));
|
||||
if (keepMonthly) args.push('--keep-monthly', String(keepMonthly));
|
||||
if (!keepDaily && !keepWeekly && !keepMonthly) args.push('--keep-daily', '7');
|
||||
if (!keepHourly && !keepDaily && !keepWeekly && !keepMonthly) args.push('--keep-daily', '7');
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
import { listSnapshotsForVm } from '../validators.js';
|
||||
import { runRestic } from '../executor.js';
|
||||
import { assertSnapshotIdShape, listSnapshotsForVm, validateSnapshotForVm } from '../validators.js';
|
||||
|
||||
export const snapshotsRouter = Router();
|
||||
|
||||
@@ -10,3 +11,27 @@ snapshotsRouter.get('/:vmName', async (req, res, next) => {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
snapshotsRouter.get('/:vmName/:snapshotId/files', async (req, res, next) => {
|
||||
try {
|
||||
const snapshot = await validateSnapshotForVm(req.params.vmName, req.params.snapshotId);
|
||||
assertSnapshotIdShape(snapshot.id);
|
||||
const result = await runRestic(['ls', '--json', snapshot.id]);
|
||||
const entries = result.stdout
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
.map((line) => JSON.parse(line))
|
||||
.filter((entry) => entry.struct_type === 'node')
|
||||
.map((entry) => ({
|
||||
name: entry.name,
|
||||
path: entry.path,
|
||||
type: entry.type,
|
||||
size: entry.size || 0,
|
||||
mode: entry.mode || '',
|
||||
mtime: entry.mtime || null,
|
||||
}));
|
||||
res.json(entries);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user