Add repository initialization action
This commit is contained in:
-1
@@ -1 +0,0 @@
|
||||
22d71250e0e7336fa9cc6a1a09115c9b7740ab21275163694ca3986b76a81a21 backupper-0.1.6-x86_64-1.txz
|
||||
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
39bbc54f47b643569b81d1d1fc7b65c49b8387ea03d8d8889c8db1427fbfafe4 backupper-0.1.7-x86_64-1.txz
|
||||
Vendored
+5
-2
@@ -2,13 +2,16 @@
|
||||
<!DOCTYPE PLUGIN [
|
||||
<!ENTITY name "backupper">
|
||||
<!ENTITY author "Backupper Project">
|
||||
<!ENTITY version "0.1.6">
|
||||
<!ENTITY version "0.1.7">
|
||||
<!ENTITY pluginURL "https://git.casaderoll.de/michael/BackUpper/raw/branch/main/dist/backupper.plg">
|
||||
<!ENTITY packageURL "https://git.casaderoll.de/michael/BackUpper/raw/branch/main/dist/backupper-&version;-x86_64-1.txz">
|
||||
<!ENTITY packageSHA256 "22d71250e0e7336fa9cc6a1a09115c9b7740ab21275163694ca3986b76a81a21">
|
||||
<!ENTITY packageSHA256 "39bbc54f47b643569b81d1d1fc7b65c49b8387ea03d8d8889c8db1427fbfafe4">
|
||||
]>
|
||||
<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;" min="7.0.0" support="https://git.casaderoll.de/michael/BackUpper/issues">
|
||||
<CHANGES>
|
||||
### 0.1.7
|
||||
- Add an explicit repository initialization action and a clear error for uninitialized destinations.
|
||||
|
||||
### 0.1.6
|
||||
- Fix false CSRF errors by relying on Unraid's native request validation.
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@ func (r *Runner) run(ctx context.Context, repo model.Repository, args []string,
|
||||
if errors.Is(ctx.Err(), context.Canceled) {
|
||||
return fmt.Errorf("cancelled: %w", ctx.Err())
|
||||
}
|
||||
if strings.Contains(message, "repository does not exist") || strings.Contains(message, "Is there a repository at the following location?") {
|
||||
return errors.New("repository: destination is not initialized; open Repositories and select Initialize")
|
||||
}
|
||||
return fmt.Errorf("restic: %s: %w", strings.TrimSpace(message), err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
<!DOCTYPE PLUGIN [
|
||||
<!ENTITY name "backupper">
|
||||
<!ENTITY author "Backupper Project">
|
||||
<!ENTITY version "0.1.6">
|
||||
<!ENTITY version "0.1.7">
|
||||
<!ENTITY pluginURL "https://git.casaderoll.de/michael/BackUpper/raw/branch/main/dist/backupper.plg">
|
||||
<!ENTITY packageURL "https://git.casaderoll.de/michael/BackUpper/raw/branch/main/dist/backupper-&version;-x86_64-1.txz">
|
||||
<!ENTITY packageSHA256 "REPLACE_DURING_RELEASE">
|
||||
]>
|
||||
<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;" min="7.0.0" support="https://git.casaderoll.de/michael/BackUpper/issues">
|
||||
<CHANGES>
|
||||
### 0.1.7
|
||||
- Add an explicit repository initialization action and a clear error for uninitialized destinations.
|
||||
|
||||
### 0.1.6
|
||||
- Fix false CSRF errors by relying on Unraid's native request validation.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Tag="backup restic snapshots restore"
|
||||
<?php
|
||||
$pluginRoot = '/plugins/backupper';
|
||||
?>
|
||||
<link rel="stylesheet" href="<?= $pluginRoot ?>/assets/backupper.css?v=6">
|
||||
<link rel="stylesheet" href="<?= $pluginRoot ?>/assets/backupper.css?v=7">
|
||||
<div id="backupper-app" data-api="<?= $pluginRoot ?>/api.php">
|
||||
<header class="bu-header">
|
||||
<div><h1>Backupper</h1><p>Encrypted Restic backups for Unraid</p></div>
|
||||
@@ -29,4 +29,4 @@ $pluginRoot = '/plugins/backupper';
|
||||
<div id="bu-tooltip" role="tooltip" aria-hidden="true"></div>
|
||||
</div>
|
||||
<script>window.BACKUPPER_CSRF = <?= json_encode($var['csrf_token'] ?? '') ?>;</script>
|
||||
<script src="<?= $pluginRoot ?>/assets/backupper.js?v=6"></script>
|
||||
<script src="<?= $pluginRoot ?>/assets/backupper.js?v=7"></script>
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
'submit-job': 'Prüft und speichert diesen Backup-Job.',
|
||||
'new-repo': 'Legt ein neues, isoliertes Restic-Speicherziel an.',
|
||||
'submit-repo': 'Speichert Ziel und Zugangsdaten. Das Repository wird dadurch noch nicht automatisch initialisiert.',
|
||||
'init-repo': 'Initialisiert am konfigurierten Ziel ein neues, leeres Restic-Repository. Beispiel: nach dem erstmaligen Speichern eines neuen Backup-Ziels. Nicht für ein bereits vorhandenes Repository verwenden.',
|
||||
'load-snapshots': 'Lädt alle Sicherungsstände des ausgewählten Repositorys.',
|
||||
'restore-selected': 'Übernimmt die markierten Dateien oder Ordner in den Restore-Assistenten.',
|
||||
'submit-restore': 'Stellt den Restore in die globale Warteschlange; Backups und Restores laufen nacheinander.',
|
||||
@@ -88,6 +89,7 @@
|
||||
'duplicate-job': 'Erstellt eine deaktivierte Kopie als Vorlage. Danach Name, Repository und Quellen anpassen.',
|
||||
'delete-job': 'Löscht die Job-Konfiguration. Vorhandene Restic-Snapshots im Repository bleiben erhalten.',
|
||||
'test-repo': 'Prüft Erreichbarkeit, Passwort und Restic-Zugriff, ohne ein Backup zu starten.',
|
||||
'init-repo': 'Erstellt die Restic-Struktur am Speicherziel. Diese Aktion ist einmalig für ein neues, leeres Ziel erforderlich.',
|
||||
'repo-snapshots': 'Wechselt zu den Sicherungsständen dieses Repositorys.',
|
||||
'maint': action.includes(':check:') ? 'Prüft Struktur und Integrität des Restic-Repositorys.' : 'Entfernt nach Retention nicht mehr benötigte Datenblöcke und gibt Speicher frei.',
|
||||
'edit-repo': 'Öffnet Ziel-, Mount- und Zugangseinstellungen dieses Repositorys.',
|
||||
@@ -225,7 +227,7 @@
|
||||
}
|
||||
|
||||
function renderRepositories() {
|
||||
const rows = state.config.repositories.map(r => `<tr><td><strong>${esc(r.name)}</strong><br><span class="bu-muted">${esc(r.id)}</span></td><td>${esc(r.type)}</td><td>${esc(r.location)}</td><td>${r.mount?.managed?'Managed':'Direct / external'}</td><td class="bu-actions">${button('Test',`test-repo:${r.id}`)}${button('Snapshots',`repo-snapshots:${r.id}`)}${button('Check',`maint:check:${r.id}`)}${button('Prune',`maint:prune:${r.id}`)}${button('Edit',`edit-repo:${r.id}`)}${button('Delete',`delete-repo:${r.id}`,'danger')}</td></tr>`).join('');
|
||||
const rows = state.config.repositories.map(r => `<tr><td><strong>${esc(r.name)}</strong><br><span class="bu-muted">${esc(r.id)}</span></td><td>${esc(r.type)}</td><td>${esc(r.location)}</td><td>${r.mount?.managed?'Managed':'Direct / external'}</td><td class="bu-actions">${button('Initialize',`init-repo:${r.id}`,'primary')}${button('Test',`test-repo:${r.id}`)}${button('Snapshots',`repo-snapshots:${r.id}`)}${button('Check',`maint:check:${r.id}`)}${button('Prune',`maint:prune:${r.id}`)}${button('Edit',`edit-repo:${r.id}`)}${button('Delete',`delete-repo:${r.id}`,'danger')}</td></tr>`).join('');
|
||||
return `<div class="bu-toolbar"><div><h2>Repositories</h2><div class="bu-muted">Local, SMB, NFS and SFTP destinations.</div></div>${button('New repository','new-repo','primary')}</div><section class="bu-card">${rows ? `<table class="bu-table"><thead><tr><th>Name</th><th>Type</th><th>Location</th><th>Mount</th><th>Actions</th></tr></thead><tbody>${rows}</tbody></table>` : '<div class="bu-empty">No repositories configured.</div>'}</section>`;
|
||||
}
|
||||
|
||||
@@ -286,6 +288,7 @@
|
||||
if (name === 'run-job') { await api(`/v1/jobs/${a}/run`,{method:'POST'}); notify('Backup queued'); return load(); }
|
||||
if (name === 'cancel-run') { await api(`/v1/runs/${a}/cancel`,{method:'POST'}); return load(); }
|
||||
if (name === 'test-repo') { await api(`/v1/repositories/${a}/test`,{method:'POST'}); return notify('Repository connection succeeded'); }
|
||||
if (name === 'init-repo') { if(confirm('Initialize a new Restic repository at this destination? Use this only for a new, empty backup destination.')) { await api(`/v1/repositories/${a}/init`,{method:'POST'}); notify('Repository initialized successfully'); } return; }
|
||||
if (name === 'maint') { await api(`/v1/repositories/${b}/${a}`,{method:'POST'}); notify(`${a} queued`); return load(); }
|
||||
if (name === 'repo-snapshots') { state.view='snapshots'; document.querySelector('[data-view="snapshots"]').click(); render(); setTimeout(()=>{document.getElementById('bu-snapshot-repo').value=a; handle('load-snapshots');},0); return; }
|
||||
if (name === 'load-snapshots') { const repo=document.getElementById('bu-snapshot-repo').value; state.snapshots=await api(`/v1/repositories/${repo}/snapshots`); state.snapshotRepo=repo; return render(); }
|
||||
|
||||
Reference in New Issue
Block a user