diff --git a/dist/urbm-2026.06.15.r012-x86_64-1.txz.sha256 b/dist/urbm-2026.06.15.r012-x86_64-1.txz.sha256 deleted file mode 100644 index bd35dd6..0000000 --- a/dist/urbm-2026.06.15.r012-x86_64-1.txz.sha256 +++ /dev/null @@ -1 +0,0 @@ -5503027a5ce2c20162e16786a1892d13046fa8002fca2f156fc13b2ef66bf89f urbm-2026.06.15.r012-x86_64-1.txz diff --git a/dist/urbm-2026.06.15.r012-x86_64-1.txz b/dist/urbm-2026.06.15.r013-x86_64-1.txz similarity index 55% rename from dist/urbm-2026.06.15.r012-x86_64-1.txz rename to dist/urbm-2026.06.15.r013-x86_64-1.txz index a51b8cc..197a55d 100644 Binary files a/dist/urbm-2026.06.15.r012-x86_64-1.txz and b/dist/urbm-2026.06.15.r013-x86_64-1.txz differ diff --git a/dist/urbm-2026.06.15.r013-x86_64-1.txz.sha256 b/dist/urbm-2026.06.15.r013-x86_64-1.txz.sha256 new file mode 100644 index 0000000..fea4adb --- /dev/null +++ b/dist/urbm-2026.06.15.r013-x86_64-1.txz.sha256 @@ -0,0 +1 @@ +250d5afee9c2939738b74f0f6f719db12d9399068bf9452e08e2b03a67d381ad urbm-2026.06.15.r013-x86_64-1.txz diff --git a/dist/urbm.plg b/dist/urbm.plg index ee5a58a..4004918 100644 --- a/dist/urbm.plg +++ b/dist/urbm.plg @@ -2,13 +2,17 @@ - + - + ]> +### 2026.06.15.r013 +- Replace invalid USB raw-image percentages, file counts, and multi-million-hour ETAs with streaming progress. +- Show bytes read and transfer rate while the final image size remains unknown until EOF. + ### 2026.06.15.r012 - Allow multiple backup jobs to share one Restic repository while retaining per-job snapshot tags and retention policies. - Catch asynchronous form submission errors so save failures are shown in the WebGUI instead of only in the browser console. diff --git a/internal/service/service.go b/internal/service/service.go index 9dba8dc..1d6ea56 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -375,11 +375,15 @@ func (s *Service) executeBackup(ctx context.Context, run model.Run) (result mode } appendLiveLog(&live, "USB-Rohabbild wird direkt aus "+device+" zu Restic übertragen") s.updateActive(live) + imageStarted := time.Now() imageSummary, err = s.restic.BackupImage(ctx, mounted.Repository, job, image, func(progress restic.Progress) { - live.ProgressPercent = progress.PercentDone * 100 - live.ProgressBytes, live.ProgressTotal = progress.BytesDone, progress.TotalBytes - live.ProgressFiles, live.ProgressFileTotal = progress.FilesDone, progress.TotalFiles - live.SecondsRemaining = progress.SecondsRemaining + live.ProgressPercent = 0 + live.ProgressBytes, live.ProgressTotal = progress.BytesDone, 0 + live.ProgressFiles, live.ProgressFileTotal = 0, 0 + live.SecondsRemaining = 0 + if elapsed := time.Since(imageStarted).Seconds(); elapsed > 0 { + live.BytesPerSecond = float64(progress.BytesDone) / elapsed + } live.CurrentFile = "urbm-usb-flash.img" s.updateActive(live) }) diff --git a/plugin/urbm.plg b/plugin/urbm.plg index 7ec0cef..2051d4d 100644 --- a/plugin/urbm.plg +++ b/plugin/urbm.plg @@ -2,13 +2,17 @@ - + ]> +### 2026.06.15.r013 +- Replace invalid USB raw-image percentages, file counts, and multi-million-hour ETAs with streaming progress. +- Show bytes read and transfer rate while the final image size remains unknown until EOF. + ### 2026.06.15.r012 - Allow multiple backup jobs to share one Restic repository while retaining per-job snapshot tags and retention policies. - Catch asynchronous form submission errors so save failures are shown in the WebGUI instead of only in the browser console. diff --git a/webgui/URBM.page b/webgui/URBM.page index 9059da8..0950361 100644 --- a/webgui/URBM.page +++ b/webgui/URBM.page @@ -9,12 +9,12 @@ Tag="URBM Unraid Restic Backup Manager backup snapshots restore" - +
- -

URBM 2026.06.15.r012

Restic Backup Manager für Unraid

+ +

URBM 2026.06.15.r013

Restic Backup Manager für Unraid

Verbindung wird hergestellt...
@@ -32,4 +32,4 @@ $pluginRoot = '/plugins/urbm';
- + diff --git a/webgui/assets/urbm.js b/webgui/assets/urbm.js index 4d6e43e..3930b24 100644 --- a/webgui/assets/urbm.js +++ b/webgui/assets/urbm.js @@ -528,6 +528,13 @@ function progressView(run) { if(run.status==='queued') return 'Wartet in der Warteschlange'; if(run.taskType!=='backup'&&!run.progressPercent) return 'Kein Prozentwert verfügbar'; + const usbImage=run.status==='running'&&run.currentFile==='urbm-usb-flash.img'; + if(usbImage) { + const details=[]; + if(run.progressBytes) details.push(`${formatBytes(run.progressBytes)} gelesen`); + if(run.bytesPerSecond) details.push(`${formatBytes(run.bytesPerSecond)}/s`); + return `
USB-Abbild wird übertragen…${esc(details.join(' · '))}
urbm-usb-flash.img · Gesamtgröße bis zum Abschluss unbekannt
`; + } const percent=Math.max(0,Math.min(100,Number(run.progressPercent)||0)); const scanning=run.status==='running'&&percent===0; const details=[];