Skip to content

Commit 1b58810

Browse files
authored
Sync dev to main (#71)
* Add and improve orchestrator tests, refactor config paths Added new tests for directory recreation and secure memory functions. Refactored config file paths in directory_recreation.go to use package-level variables for easier testing. Improved parsing logic for storage and datastore configs. Enhanced orchestrator_test.go with additional coverage for logging and stats reporting. * Improve cron migration to preserve valid entries Refactored migrateLegacyCronEntries to only remove legacy Bash script and outdated binary references, while preserving existing cron entries that already point to the correct Go binary. Updated CLI and installation documentation to clarify that valid cron entries are retained during upgrade. * Use go.mod for Go version in GitHub workflows Updated codecov.yml, release.yml, and security-ultimate.yml to use the go-version-file option with go.mod instead of hardcoding the Go version. This ensures workflows automatically use the Go version specified in go.mod for consistency and easier maintenance. * Refactor TUI prompts for testability and add tests Introduces indirection for TUI prompt functions in decrypt and restore workflows to enable stubbing in unit tests. Adds comprehensive tests for path selection, overwrite, abort, and bundle preparation in decrypt_tui, and for restore wizard page and prompt flows in restore_tui. Removes unused dummy symbol from embed.go and cleans up runCommand indirection in restore.go.
1 parent a5a6ff7 commit 1b58810

20 files changed

+811
-53
lines changed

.github/workflows/codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Setup Go
1717
uses: actions/setup-go@v6
1818
with:
19-
go-version: '1.25'
19+
go-version-file: 'go.mod'
2020

2121
- name: Run tests with coverage
2222
run: |

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
- name: Set up Go
4848
uses: actions/setup-go@v6
4949
with:
50-
go-version: "1.25"
50+
go-version-file: 'go.mod'
5151

5252
- name: Show Go version
5353
run: go version

.github/workflows/security-ultimate.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ jobs:
2626
########################################
2727
# GO 1.25 — MAIN TOOLCHAIN
2828
########################################
29-
- name: Set up Go 1.25
29+
- name: Set up Go (from go.mod)
3030
uses: actions/setup-go@v6
3131
with:
32-
go-version: "1.25"
32+
go-version-file: 'go.mod'
3333

3434
- name: Show Go version
3535
run: go version

cmd/proxsave/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import (
3636
const (
3737
defaultLegacyEnvPath = "/opt/proxsave/env/backup.env"
3838
legacyEnvFallbackPath = "/opt/proxmox-backup/env/backup.env"
39-
goRuntimeMinVersion = "1.25.4"
39+
goRuntimeMinVersion = "1.25.5"
4040
networkPreflightTimeout = 2 * time.Second
4141
bytesPerMegabyte int64 = 1024 * 1024
4242
defaultDirPerm = 0o755

cmd/proxsave/runtime_helpers.go

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -700,29 +700,58 @@ func migrateLegacyCronEntries(ctx context.Context, baseDir, execPath string, boo
700700

701701
updatedLines := make([]string, 0, len(lines)+1)
702702

703-
containsAny := func(line string) bool {
703+
correctPaths := []string{strings.TrimSpace(newCommandToken)}
704+
if execPath != "" && execPath != newCommandToken {
705+
correctPaths = append(correctPaths, execPath)
706+
}
707+
708+
containsLegacy := func(line string) bool {
704709
if strings.Contains(line, "proxmox-backup.sh") {
705710
return true
706711
}
707-
if strings.Contains(line, "proxmox-backup") || strings.Contains(line, "proxsave") {
708-
return true
709-
}
710712
for _, p := range legacyPaths {
711-
if strings.Contains(line, p) {
713+
if p != "" && strings.Contains(line, p) {
714+
return true
715+
}
716+
}
717+
return false
718+
}
719+
720+
containsCorrectPath := func(line string) bool {
721+
for _, p := range correctPaths {
722+
if p != "" && strings.Contains(line, p) {
712723
return true
713724
}
714725
}
715726
return false
716727
}
717728

729+
containsBinaryReference := func(line string) bool {
730+
if strings.Contains(line, "proxsave") || strings.Contains(line, "proxmox-backup") {
731+
return true
732+
}
733+
return false
734+
}
735+
736+
hasCurrentEntry := false
737+
718738
for _, line := range lines {
719739
trimmed := strings.TrimSpace(line)
720740
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
721741
updatedLines = append(updatedLines, line)
722742
continue
723743
}
724-
if containsAny(line) {
725-
// Skip all existing proxmox-backup entries (bash or go) to recreate cleanly.
744+
if containsLegacy(line) {
745+
// Remove cron entries that still reference the legacy Bash script paths.
746+
continue
747+
}
748+
if containsCorrectPath(line) {
749+
hasCurrentEntry = true
750+
updatedLines = append(updatedLines, line)
751+
continue
752+
}
753+
if containsBinaryReference(line) {
754+
// Remove proxsave/proxmox-backup entries that point to outdated binaries.
726755
continue
727756
}
728757
updatedLines = append(updatedLines, line)
@@ -732,17 +761,23 @@ func migrateLegacyCronEntries(ctx context.Context, baseDir, execPath string, boo
732761
if schedule == "" {
733762
schedule = "0 2 * * *"
734763
}
735-
// Always append a fresh default entry pointing to the Go binary (or fallback).
736-
defaultLine := fmt.Sprintf("%s %s", schedule, newCommandToken)
737-
updatedLines = append(updatedLines, defaultLine)
764+
// Append a fresh default entry pointing to the Go binary (or fallback) if one doesn't exist already.
765+
if !hasCurrentEntry {
766+
defaultLine := fmt.Sprintf("%s %s", schedule, newCommandToken)
767+
updatedLines = append(updatedLines, defaultLine)
768+
}
738769

739770
newCron := strings.Join(updatedLines, "\n") + "\n"
740771
if err := writeCron(newCron); err != nil {
741772
bootstrap.Warning("WARNING: Failed to update cron entries: %v", err)
742773
return
743774
}
744775

745-
bootstrap.Debug("Recreated cron entry for proxsave at 02:00: %s", newCommandToken)
776+
if hasCurrentEntry {
777+
bootstrap.Debug("Existing cron entry already targets %s; no changes made.", newCommandToken)
778+
} else {
779+
bootstrap.Debug("Recreated cron entry for proxsave at schedule %s: %s", schedule, newCommandToken)
780+
}
746781
}
747782

748783
func logBootstrapWarning(bootstrap *logging.BootstrapLogger, format string, args ...interface{}) {

docs/CLI_REFERENCE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Some interactive commands support two interface modes:
182182
7. Atomically replaces current binary (write to .tmp, then rename)
183183
8. Updates symlinks in `/usr/local/bin/` (proxsave, proxmox-backup)
184184
9. Cleans up legacy Bash script symlinks
185-
10. Migrates cron entries and fixes file permissions
185+
10. Migrates cron entries (legacy entries are replaced, existing ones using the Go binary are preserved) and fixes file permissions
186186

187187
**Post-upgrade steps**:
188188
1. Configuration file automatically compatible with new version
@@ -196,7 +196,7 @@ Some interactive commands support two interface modes:
196196
- **No configuration changes**: `backup.env` is never modified during `--upgrade`
197197
- **Platform support**: Linux only (amd64, arm64)
198198
- **Incompatible flags**: Cannot use with `--install` or `--new-install`
199-
- **Automatic maintenance**: Symlinks, cron, and permissions updated automatically
199+
- **Automatic maintenance**: Symlinks, cron (without touching entries already pointing to proxsave/proxmox-backup), and permissions updated automatically
200200
- **Safe replacement**: Old binary is replaced atomically (no backup created)
201201
- **Separate config upgrade**: Use `--upgrade-config` separately to update configuration
202202

docs/INSTALL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ The `--upgrade` command:
9393
- ✅ Atomically replaces current binary
9494
- ✅ Updates symlinks (`/usr/local/bin/proxsave`, `/usr/local/bin/proxmox-backup`)
9595
- ✅ Cleans up legacy Bash script symlinks
96-
- ✅ Migrates cron entries to new binary
96+
- ✅ Migrates cron entries to new binary while preserving entries that already point to the Go executable
9797
- ✅ Fixes file permissions
9898
-**Does NOT modify** your `backup.env` configuration
9999

@@ -416,4 +416,4 @@ Run first backup
416416
| **Code size** | 20,370 lines | ~3,000 lines Go code |
417417
| **Memory usage** | Higher (multiple processes) | Lower (single binary) |
418418
| **Maintenance** | Archived, critical fixes only | Active development |
419-
| **Compatibility** | Can coexist with Go version | Can coexist with Bash version |
419+
| **Compatibility** | Can coexist with Go version | Can coexist with Bash version |

embed.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,3 @@ func collectEmbeddedDocs() ([]DocAsset, error) {
6868
})
6969
return assets, nil
7070
}
71-
72-
// Dummy symbol so that Go Report Card recognizes this package as valid.
73-
const _goreportcardFix = true

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module github.com/tis24dev/proxsave
22

33
go 1.25
44

5-
toolchain go1.25.4
5+
toolchain go1.25.5
66

77
require (
88
filippo.io/age v1.2.1

internal/orchestrator/.backup.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
pid=230863
1+
pid=324942
22
host=pbs1
3-
time=2025-12-02T16:24:15+01:00
3+
time=2025-12-02T20:27:27+01:00

0 commit comments

Comments
 (0)