Rename visible product to URBM

This commit is contained in:
Mikei386
2026-06-14 14:05:10 +02:00
parent 449647be12
commit 7cae5dc168
14 changed files with 38 additions and 28 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2026 Backupper Project
Copyright (C) 2026 Michael Roll
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
+4 -2
View File
@@ -1,6 +1,8 @@
# Backupper for Unraid
# URBM - Unraid Restic Backup Manager
Backupper is a native Unraid 7 plugin that manages encrypted, deduplicated and versioned backups through Restic. The MVP supports shares, appdata, Docker metadata and data, VM definitions and disks, and the Unraid flash drive. Destinations can be local, SFTP, SMB or NFS.
URBM is a native Unraid 7 plugin that manages encrypted, deduplicated and versioned backups through Restic. It supports shares, appdata, Docker metadata and data, VM definitions and disks, and the Unraid boot drive. Destinations can be local, SFTP, SMB or NFS.
URBM is an independent community plugin and is not affiliated with or endorsed by Lime Technology, Inc.
## Architecture
-1
View File
@@ -1 +0,0 @@
8440c745eb052c38ce853789d10c1663e6dc0e77ad07b99079341bd4249546a6 backupper-2026.06.14.9.2-x86_64-1.txz
+1
View File
@@ -0,0 +1 @@
10324922ef4211fa691d4f0c659c3e4574c915d04826d57e1adfa86bc5de007d backupper-2026.06.14.9.3-x86_64-1.txz
+6 -2
View File
@@ -2,13 +2,17 @@
<!DOCTYPE PLUGIN [
<!ENTITY name "backupper">
<!ENTITY author "Michael Roll">
<!ENTITY version "2026.06.14.9.2">
<!ENTITY version "2026.06.14.9.3">
<!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 "8440c745eb052c38ce853789d10c1663e6dc0e77ad07b99079341bd4249546a6">
<!ENTITY packageSHA256 "10324922ef4211fa691d4f0c659c3e4574c915d04826d57e1adfa86bc5de007d">
]>
<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;" min="7.0.0" support="https://git.casaderoll.de/michael/BackUpper/issues" icon="backupper.png">
<CHANGES>
### 2026.06.14.9.3
- Rename the visible product to URBM - Unraid Restic Backup Manager.
- Show Backup in the Unraid navigation while preserving the existing plugin identifier and configuration paths.
### 2026.06.14.9.2
- Include duration, new and changed files, added data, total backup size, file count, and snapshot ID in backup notifications.
+1 -1
View File
@@ -39,7 +39,7 @@ func (s *Sender) Send(ctx context.Context, target model.NotificationTarget, titl
if path == "" {
path = "/usr/local/emhttp/webGui/scripts/notify"
}
args := []string{"-e", "Backupper", "-s", title, "-d", message, "-i", importance, "-l", "/Tools/Backupper"}
args := []string{"-e", "URBM", "-s", title, "-d", message, "-i", importance, "-l", "/Tools/Backupper"}
if s.RunCommand != nil {
return s.RunCommand(ctx, path, args...)
}
+1 -1
View File
@@ -56,7 +56,7 @@ func TestSendUnraid(t *testing.T) {
if command != "/usr/local/emhttp/webGui/scripts/notify" {
t.Fatalf("unexpected command %q", command)
}
want := []string{"-e", "Backupper", "-s", "Backup warning", "-d", "completed with warnings", "-i", "warning", "-l", "/Tools/Backupper"}
want := []string{"-e", "URBM", "-s", "Backup warning", "-d", "completed with warnings", "-i", "warning", "-l", "/Tools/Backupper"}
if !reflect.DeepEqual(args, want) {
t.Fatalf("arguments = %#v, want %#v", args, want)
}
+1 -1
View File
@@ -328,7 +328,7 @@ func (s *Service) notify(name string, run model.Run) {
for _, target := range s.Config().Notifications {
for _, event := range target.Events {
if event == run.Status {
if err := s.notifier.Send(context.Background(), target, "Backupper: "+name, message, run.Status); err != nil {
if err := s.notifier.Send(context.Background(), target, "URBM: "+name, message, run.Status); err != nil {
s.log.Warn("send notification failed", "target", target.ID, "type", target.Type, "error", err)
}
break
+5 -1
View File
@@ -2,13 +2,17 @@
<!DOCTYPE PLUGIN [
<!ENTITY name "backupper">
<!ENTITY author "Michael Roll">
<!ENTITY version "2026.06.14.9.2">
<!ENTITY version "2026.06.14.9.3">
<!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" icon="backupper.png">
<CHANGES>
### 2026.06.14.9.3
- Rename the visible product to URBM - Unraid Restic Backup Manager.
- Show Backup in the Unraid navigation while preserving the existing plugin identifier and configuration paths.
### 2026.06.14.9.2
- Include duration, new and changed files, added data, total backup size, file count, and snapshot ID in backup notifications.
+1 -1
View File
@@ -1,4 +1,4 @@
backupper: Backupper for Unraid
backupper: URBM - Unraid Restic Backup Manager
backupper:
backupper: Native Restic backup management for Unraid 7.
backupper: Provides encrypted, deduplicated and versioned backups,
+8 -8
View File
@@ -1,24 +1,24 @@
Menu="Tasks:55"
Name="Backupper"
Name="Backup"
Icon="backupper.png"
Type="xmenu"
Tabs="true"
Code="f0c7"
Tag="backup restic snapshots restore"
Tag="URBM Unraid Restic Backup Manager backup snapshots restore"
---
<?php
$pluginRoot = '/plugins/backupper';
?>
<link rel="stylesheet" href="<?= $pluginRoot ?>/assets/backupper.css?v=2026061492">
<link rel="stylesheet" href="<?= $pluginRoot ?>/assets/backupper.css?v=2026061493">
<div id="backupper-app" data-api="<?= $pluginRoot ?>/api.php">
<header class="bu-header">
<div class="bu-brand">
<img class="bu-logo" src="<?= $pluginRoot ?>/images/backupper.png?v=2026061492" alt="Backupper logo">
<div><h1>Backupper <span class="bu-version">2026.06.14.9.2</span></h1><p>Encrypted Restic backups for Unraid</p></div>
<img class="bu-logo" src="<?= $pluginRoot ?>/images/backupper.png?v=2026061493" alt="URBM logo">
<div><h1>URBM <span class="bu-version">2026.06.14.9.3</span></h1><p>Restic Backup Manager for Unraid</p></div>
</div>
<div id="bu-health" class="bu-health" tabindex="0" data-tooltip="Zeigt, ob die Backupper-Hintergrundkomponente erreichbar ist. Beispiel: 'Daemon online' bedeutet, dass Jobs gestartet werden können.">Connecting...</div>
<div id="bu-health" class="bu-health" tabindex="0" data-tooltip="Zeigt, ob die URBM-Hintergrundkomponente erreichbar ist. Beispiel: 'Daemon online' bedeutet, dass Jobs gestartet werden können.">Connecting...</div>
</header>
<nav class="bu-tabs" aria-label="Backupper sections">
<nav class="bu-tabs" aria-label="URBM sections">
<button data-view="dashboard" class="active" data-tooltip="Übersicht über konfigurierte Jobs, Ziele, laufende Aufgaben und Fehler.">Dashboard</button>
<button data-view="jobs" data-tooltip="Hier legst du fest, welche Daten wann gesichert werden. Beispiel: Appdata täglich um 02:00 Uhr.">Backup Jobs</button>
<button data-view="repositories" data-tooltip="Verwaltet die Speicherziele für Restic. Beispiel: lokaler Pfad, SMB-Freigabe oder SFTP-Server.">Repositories</button>
@@ -32,4 +32,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-2026.06.14.9.2.js"></script>
<script src="<?= $pluginRoot ?>/assets/backupper-2026.06.14.9.3.js"></script>
+1 -1
View File
@@ -15,7 +15,7 @@ if (!preg_match('#^/v1/[A-Za-z0-9_./?=&%:-]*$#', $path) || str_contains($path, '
if (!file_exists($socket)) {
http_response_code(503);
echo json_encode(['error' => 'Backupper daemon is not running']);
echo json_encode(['error' => 'URBM daemon is not running']);
exit;
}
+8 -8
View File
@@ -29,7 +29,7 @@
location: 'Restic-Ziel. Lokal: /mnt/user/backups/job1. SFTP: user@server:/backup/job1. Bei SMB/NFS mit Mount wird hier der Mount-Pfad verwendet.',
passwordRef: 'Interne ID des verschlüsselt gespeicherten Restic-Passworts. Beispiel: repo-password-appdata. Keine Leerzeichen verwenden.',
password: 'Passwort zur Restic-Verschlüsselung. Beispiel: eine lange zufällige Passphrase. Leer lassen, wenn ein vorhandenes Passwort unverändert bleiben soll.',
managed: 'Wenn aktiv, mountet Backupper SMB/NFS vor dem Job selbst. Wenn aus, muss der angegebene Pfad bereits durch Unraid oder Unassigned Devices gemountet sein.',
managed: 'Wenn aktiv, mountet URBM SMB/NFS vor dem Job selbst. Wenn aus, muss der angegebene Pfad bereits durch Unraid oder Unassigned Devices gemountet sein.',
remote: 'Adresse der Netzwerkfreigabe. SMB-Beispiel: //192.168.1.20/backup. NFS-Beispiel: 192.168.1.20:/volume1/backup.',
mountPoint: 'Lokaler Einhängepunkt auf Unraid. Beispiel: /mnt/remotes/backup-nas. Erlaubt sind Pfade unter /mnt/remotes oder /mnt/disks.',
credentialRef: 'Interne ID für SMB-Zugangsdaten oder einen SFTP-Schlüssel. Beispiel: nas-login oder sftp-backup-key.',
@@ -61,10 +61,10 @@
'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.',
'submit-settings': 'Speichert die globalen Backupper-Einstellungen.',
'submit-settings': 'Speichert die globalen URBM-Einstellungen.',
'submit-unraid-notify': 'Speichert native Unraid-Benachrichtigungen. Die Zustellung erfolgt über die in Unraid eingerichteten Notification Agents.',
'submit-gotify-notify': 'Speichert den Gotify-Kanal und das App-Token verschlüsselt.',
'refresh': 'Lädt Laufstatus und Historie erneut vom Backupper-Daemon.',
'refresh': 'Lädt Laufstatus und Historie erneut vom URBM-Daemon.',
'cancel-form': 'Verwirft ungespeicherte Eingaben und kehrt zur Übersicht zurück.',
'browser-up': 'Öffnet im Snapshot-Browser das übergeordnete Verzeichnis.',
'source-up': 'Öffnet im Ordner-Browser das übergeordnete Verzeichnis.',
@@ -105,7 +105,7 @@
'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.',
'delete-repo': 'Löscht nur die Backupper-Konfiguration. Die Backupdaten am Speicherziel werden nicht gelöscht.',
'delete-repo': 'Löscht nur die URBM-Konfiguration. Die Backupdaten am Speicherziel werden nicht gelöscht.',
'browse': 'Öffnet den Dateibaum dieses Snapshots, um einzelne Dateien oder Ordner auszuwählen.',
'open-dir': 'Öffnet dieses Verzeichnis innerhalb des schreibgeschützten Snapshots.',
'open-source-dir': 'Öffnet diesen Ordner, um darin weitere Unterordner auszuwählen.',
@@ -188,12 +188,12 @@
const dashboardHelp = {
'Enabled jobs': 'Anzahl aktivierter Backup-Jobs, die nach Zeitplan laufen dürfen. Beispiel: 3 bedeutet drei aktive Sicherungspläne.',
'Repositories': 'Anzahl konfigurierter Restic-Speicherziele. Im MVP gehört jedes Repository genau zu einem Job.',
'Queued / running': 'Aufgaben in der Warteschlange oder in Ausführung. Backupper führt immer nur eine Aufgabe gleichzeitig aus.',
'Queued / running': 'Aufgaben in der Warteschlange oder in Ausführung. URBM führt immer nur eine Aufgabe gleichzeitig aus.',
'Recent failures': 'Fehlgeschlagene Läufe in der jüngsten Historie. Details stehen unter Activity.',
};
container.querySelectorAll('.bu-card .bu-muted').forEach(element => setTooltip(element.closest('.bu-card') || element, dashboardHelp[element.textContent.trim()]));
const headerHelp = {
Job: 'Name und interne ID des Backup-Jobs.', Type: 'Art der gesicherten Daten.', Repository: 'Verwendetes Restic-Speicherziel.', Schedule: 'Wochentage und Uhrzeit des automatischen Backups.', Enabled: 'Zeigt, ob der Job automatisch laufen darf.', Actions: 'Verfügbare Aktionen für diesen Eintrag.', Name: 'Anzeigename und interne ID.', Location: 'Pfad oder Adresse des Restic-Ziels.', Mount: 'Zeigt, ob Backupper das Netzwerkziel selbst mountet.', Snapshot: 'Eindeutiger Sicherungsstand.', Time: 'Erstellungszeitpunkt des Snapshots.', Host: 'Hostname des Systems, das den Snapshot erstellt hat.', Paths: 'Im Snapshot enthaltene Quellpfade.', Task: 'Art und Ziel der Aufgabe.', Status: 'Aktueller oder endgültiger Laufstatus.', Created: 'Zeitpunkt, an dem die Aufgabe eingereiht wurde.', Message: 'Ergebnis oder Fehlerbeschreibung.', Size: 'Gespeicherte Dateigröße im Snapshot.'
Job: 'Name und interne ID des Backup-Jobs.', Type: 'Art der gesicherten Daten.', Repository: 'Verwendetes Restic-Speicherziel.', Schedule: 'Wochentage und Uhrzeit des automatischen Backups.', Enabled: 'Zeigt, ob der Job automatisch laufen darf.', Actions: 'Verfügbare Aktionen für diesen Eintrag.', Name: 'Anzeigename und interne ID.', Location: 'Pfad oder Adresse des Restic-Ziels.', Mount: 'Zeigt, ob URBM das Netzwerkziel selbst mountet.', Snapshot: 'Eindeutiger Sicherungsstand.', Time: 'Erstellungszeitpunkt des Snapshots.', Host: 'Hostname des Systems, das den Snapshot erstellt hat.', Paths: 'Im Snapshot enthaltene Quellpfade.', Task: 'Art und Ziel der Aufgabe.', Status: 'Aktueller oder endgültiger Laufstatus.', Created: 'Zeitpunkt, an dem die Aufgabe eingereiht wurde.', Message: 'Ergebnis oder Fehlerbeschreibung.', Size: 'Gespeicherte Dateigröße im Snapshot.'
};
container.querySelectorAll('.bu-table th').forEach(th => setTooltip(th, headerHelp[th.textContent.trim()] || 'Informationen zu dieser Tabellenspalte.'));
const snapshotSelect = container.querySelector('#bu-snapshot-repo');
@@ -204,7 +204,7 @@
'Repositories': 'Speicherziele und verschlüsselte Zugangsdaten für Restic.',
'Snapshots': 'Unveränderliche Sicherungsstände, die durchsucht und wiederhergestellt werden können.',
'Restore': 'Wiederherstellung ausgewählter Dateien oder Ordner. Staging ist die sichere Standardmethode.',
'Activity': 'Globale Warteschlange und Historie aller Backupper-Aufgaben.',
'Activity': 'Globale Warteschlange und Historie aller URBM-Aufgaben.',
'Settings': 'Globale Pfade sowie Zeitpläne für Check, Prune und Nachholläufe.',
'Unraid notifications': 'Native Meldungen im Unraid-Webinterface und über alle unter Einstellungen > Benachrichtigungen aktivierten Agenten.',
'Gotify notification': 'Optionaler direkter Push-Kanal zu deinem eigenen Gotify-Server.',
@@ -315,7 +315,7 @@
loadWorkloads(type);
} else {
state.backupSelections = ['/boot'];
host.innerHTML = `<div class="bu-info-card"><h3>Unraid USB flash backup</h3><p>The complete <strong>/boot</strong> configuration drive is backed up. No additional source selection is required.</p></div>`;
host.innerHTML = `<div class="bu-info-card"><h3>Unraid boot backup</h3><p>The complete <strong>/boot</strong> configuration drive is backed up. No additional source selection is required.</p></div>`;
}
enhanceTooltips(host);
}