Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
# GORELEASER
########################################
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@v7
with:
version: latest
workdir: ${{ github.workspace }}
Expand Down
59 changes: 0 additions & 59 deletions cmd/prefilter-manual/main.go

This file was deleted.

7 changes: 0 additions & 7 deletions cmd/proxsave/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1302,13 +1302,6 @@

fmt.Println()

if !cfg.EnableGoBackup && !args.Support {
logging.Warning("ENABLE_GO_BACKUP=false is ignored; the Go backup pipeline is always used.")
} else {
logging.Debug("Go backup pipeline enabled")
}
fmt.Println()

// Storage info
logging.Info("Storage configuration:")
logging.Info(" Primary: %s", formatStorageLabel(cfg.BackupPath, localFS))
Expand Down Expand Up @@ -1570,7 +1563,7 @@
}
fmt.Printf("\r Remaining: %ds ", int(remaining.Seconds()))

select {

Check failure on line 1566 in cmd/proxsave/main.go

View workflow job for this annotation

GitHub Actions / security

should use a simple channel send/receive instead of select with a single case (S1000)
case <-ticker.C:
continue
}
Expand Down
5 changes: 0 additions & 5 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ Complete reference for all 200+ configuration variables in `configs/backup.env`.
# Enable/disable backup system
BACKUP_ENABLED=true # true | false

# Enable Go pipeline (vs legacy Bash)
ENABLE_GO_BACKUP=true # true | false

# Colored output in terminal
USE_COLOR=true # true | false

Expand Down Expand Up @@ -922,8 +919,6 @@ METRICS_ENABLED=false # true | false
METRICS_PATH=${BASE_DIR}/metrics # Empty = /var/lib/prometheus/node-exporter
```

> ℹ️ Metrics export is available only for the Go pipeline (`ENABLE_GO_BACKUP=true`).

**Output**: Creates `proxmox_backup.prom` in `METRICS_PATH` with:
- Backup duration and start/end timestamps
- Archive size and raw bytes collected
Expand Down
1 change: 0 additions & 1 deletion docs/EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,6 @@ CLOUD_LOG_PATH=
# configs/backup.env
SYSTEM_ROOT_PREFIX=/mnt/snapshot-root # points to the alternate root
BACKUP_ENABLED=true
ENABLE_GO_BACKUP=true
# /etc, /var, /root, /home are resolved under the prefix
```

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
)

require (
filippo.io/edwards25519 v1.1.0 // indirect
filippo.io/edwards25519 v1.1.1 // indirect
filippo.io/hpke v0.4.0 // indirect
github.com/gdamore/encoding v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAw
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo=
filippo.io/age v1.3.1 h1:hbzdQOJkuaMEpRCLSN1/C5DX74RPcNCk6oqhKMXmZi0=
filippo.io/age v1.3.1/go.mod h1:EZorDTYUxt836i3zdori5IJX/v2Lj6kWFU0cfh6C0D4=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=
filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A=
filippo.io/hpke v0.4.0/go.mod h1:EmAN849/P3qdeK+PCMkDpDm83vRHM5cDipBJ8xbQLVY=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
Expand Down
2 changes: 0 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ type Config struct {
DebugLevel types.LogLevel
UseColor bool
ColorizeStepLogs bool
EnableGoBackup bool
ProfilingEnabled bool
BaseDir string
DryRun bool
Expand Down Expand Up @@ -423,7 +422,6 @@ func (c *Config) parseOptimizationSettings() {
}

func (c *Config) parseSecuritySettings() {
c.EnableGoBackup = c.getBoolWithFallback([]string{"ENABLE_GO_BACKUP", "ENABLE_GO_PIPELINE"}, true)
c.DisableNetworkPreflight = c.getBool("DISABLE_NETWORK_PREFLIGHT", false)

// Base directory
Expand Down
27 changes: 0 additions & 27 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,38 +427,11 @@ func TestConfigDefaults(t *testing.T) {
t.Errorf("Default LocalRetentionDays = %d; want 7", cfg.LocalRetentionDays)
}

if !cfg.EnableGoBackup {
t.Error("Expected default EnableGoBackup to be true")
}

if cfg.BaseDir != "/defaults/base" {
t.Errorf("Default BaseDir = %q; want %q", cfg.BaseDir, "/defaults/base")
}
}

func TestEnableGoBackupFlag(t *testing.T) {
tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "go_pipeline.env")

content := `ENABLE_GO_BACKUP=false
`
if err := os.WriteFile(configPath, []byte(content), 0644); err != nil {
t.Fatalf("Failed to create test config: %v", err)
}

cleanup := setBaseDirEnv(t, "/flag/base")
defer cleanup()

cfg, err := LoadConfig(configPath)
if err != nil {
t.Fatalf("LoadConfig() error = %v", err)
}

if cfg.EnableGoBackup {
t.Error("Expected EnableGoBackup to be false when explicitly disabled")
}
}

func TestLoadConfigBaseDirFromConfig(t *testing.T) {
tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "base_dir.env")
Expand Down
1 change: 0 additions & 1 deletion internal/config/templates/backup.env
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# General settings
# ----------------------------------------------------------------------
BACKUP_ENABLED=true
ENABLE_GO_BACKUP=true
PROFILING_ENABLED=true # Enable CPU/heap profiling (pprof) for Go pipeline
USE_COLOR=true
COLORIZE_STEP_LOGS=true # Highlight "Step N/8" lines (requires USE_COLOR=true)
Expand Down
19 changes: 0 additions & 19 deletions internal/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,6 @@ func collectMACCandidates(logger *logging.Logger) ([]macCandidate, []string) {
return candidates, macs
}

func collectMACAddresses() []string {
_, macs := collectMACCandidates(nil)
return macs
}

func selectPreferredMAC(candidates []macCandidate) (string, string) {
var best *macCandidate
for i := range candidates {
Expand Down Expand Up @@ -469,10 +464,6 @@ func buildSystemData(macs []string, logger *logging.Logger) string {
return builder.String()
}

func encodeProtectedServerID(serverID, primaryMAC string, logger *logging.Logger) (string, error) {
return encodeProtectedServerIDWithMACs(serverID, []string{primaryMAC}, primaryMAC, logger)
}

func encodeProtectedServerIDWithMACs(serverID string, macs []string, primaryMAC string, logger *logging.Logger) (string, error) {
logDebug(logger, "Identity: encodeProtectedServerID: start (serverID=%s primaryMAC=%s)", serverID, primaryMAC)
keyField := buildIdentityKeyField(macs, primaryMAC, logger)
Expand Down Expand Up @@ -574,16 +565,6 @@ func decodeProtectedServerID(fileContent, primaryMAC string, logger *logging.Log
return serverID, matchedByMAC, nil
}

func generateSystemKey(primaryMAC string, logger *logging.Logger) string {
machineID := readMachineID(logger)
hostnamePart := readHostnamePart(logger)

macPart := strings.ReplaceAll(primaryMAC, ":", "")
key := computeSystemKey(machineID, hostnamePart, macPart)
logDebug(logger, "Identity: generateSystemKey: systemKey=%s", key)
return key
}

func buildIdentityKeyField(macs []string, primaryMAC string, logger *logging.Logger) string {
machineID := readMachineID(logger)
hostnamePart := readHostnamePart(logger)
Expand Down
42 changes: 18 additions & 24 deletions internal/identity/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
"github.com/tis24dev/proxsave/internal/types"
)

func encodeProtectedServerIDForTest(serverID, primaryMAC string, logger *logging.Logger) (string, error) {
return encodeProtectedServerIDWithMACs(serverID, []string{primaryMAC}, primaryMAC, logger)
}

func TestEncodeDecodeProtectedServerIDRoundTrip(t *testing.T) {
const serverID = "1234567890123456"
const mac = "aa:bb:cc:dd:ee:ff"

content, err := encodeProtectedServerID(serverID, mac, nil)
content, err := encodeProtectedServerIDForTest(serverID, mac, nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -57,7 +61,7 @@
}

const serverID = "1111222233334444"
content, err := encodeProtectedServerID(serverID, "aa:bb:cc:dd:ee:ff", nil)
content, err := encodeProtectedServerIDForTest(serverID, "aa:bb:cc:dd:ee:ff", nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -95,7 +99,7 @@
}

const serverID = "1111222233334444"
content, err := encodeProtectedServerID(serverID, "aa:bb:cc:dd:ee:ff", nil)
content, err := encodeProtectedServerIDForTest(serverID, "aa:bb:cc:dd:ee:ff", nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -147,7 +151,7 @@
const serverID = "5555666677778888"
const mac = "aa:aa:aa:aa:aa:aa"

content, err := encodeProtectedServerID(serverID, mac, nil)
content, err := encodeProtectedServerIDForTest(serverID, mac, nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -204,14 +208,14 @@
}
identityPath := filepath.Join(identityDir, identityFileName)

macs := collectMACAddresses()
_, macs := collectMACCandidates(nil)
if len(macs) == 0 {
t.Skip("no non-loopback MACs available on this system")
}
primary := macs[0]

const serverID = "1234567890123456"
content, err := encodeProtectedServerID(serverID, primary, nil)
content, err := encodeProtectedServerIDForTest(serverID, primary, nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -354,21 +358,8 @@
}
}

func TestGenerateSystemKeyStableAndLength(t *testing.T) {
const mac = "aa:bb:cc:dd:ee:ff"
k1 := generateSystemKey(mac, nil)
k2 := generateSystemKey(mac, nil)

if len(k1) != 16 {
t.Fatalf("generateSystemKey length = %d, want 16", len(k1))
}
if k1 != k2 {
t.Fatalf("generateSystemKey should be stable, got %q and %q", k1, k2)
}
}

func TestCollectMACAddressesSortedAndUnique(t *testing.T) {
macs := collectMACAddresses()
_, macs := collectMACCandidates(nil)
for i := 0; i < len(macs); i++ {
if macs[i] == "" {
t.Fatalf("unexpected empty MAC at index %d", i)
Expand Down Expand Up @@ -413,7 +404,7 @@

func TestDecodeProtectedServerIDInvalidServerIDFormat(t *testing.T) {
const mac = "aa:bb:cc:dd:ee:ff"
content, err := encodeProtectedServerID("AAAAAAAAAAAAAAAA", mac, nil)
content, err := encodeProtectedServerIDForTest("AAAAAAAAAAAAAAAA", mac, nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -446,7 +437,7 @@
path := filepath.Join(dir, "identity.conf")

const serverID = "1234567890123456"
content, err := encodeProtectedServerID(serverID, "", nil)
content, err := encodeProtectedServerIDForTest(serverID, "", nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down Expand Up @@ -487,7 +478,10 @@
}

func encodeProtectedServerIDLegacy(serverID, primaryMAC string) (string, error) {
systemKey := generateSystemKey(primaryMAC, nil)
machineID := readMachineID(nil)
hostnamePart := readHostnamePart(nil)
macPart := strings.ReplaceAll(primaryMAC, ":", "")
systemKey := computeSystemKey(machineID, hostnamePart, macPart)
timestamp := time.Unix(1700000000, 0).Unix()
data := fmt.Sprintf("%s:%d:%s", serverID, timestamp, systemKey[:systemKeyPrefixLength])
checksum := sha256.Sum256([]byte(data))
Expand Down Expand Up @@ -968,7 +962,7 @@

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := isWirelessInterface(tt.name)

Check failure on line 965 in internal/identity/identity_test.go

View workflow job for this annotation

GitHub Actions / security

this value of got is never used (SA4006)
// Check name-based fallback behavior
if strings.HasPrefix(strings.ToLower(tt.name), "wl") && !got {
// May or may not work depending on sysfs
Expand Down Expand Up @@ -1588,7 +1582,7 @@
}

const serverID = "1234567890123456"
content, err := encodeProtectedServerID(serverID, "aa:bb:cc:dd:ee:ff", nil)
content, err := encodeProtectedServerIDForTest(serverID, "aa:bb:cc:dd:ee:ff", nil)
if err != nil {
t.Fatalf("encodeProtectedServerID() error = %v", err)
}
Expand Down
35 changes: 0 additions & 35 deletions internal/orchestrator/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,41 +121,6 @@ func TestCreateBundle_CreatesValidTarArchive(t *testing.T) {
}
}

func TestLegacyCreateBundleWrapper_DelegatesToMethod(t *testing.T) {
logger := logging.New(logging.GetDefaultLogger().GetLevel(), false)
tempDir := t.TempDir()
archive := filepath.Join(tempDir, "backup.tar")

// Minimal associated files required by createBundle
required := map[string]string{
"": "archive-content",
".sha256": "checksum",
".metadata": "metadata-json",
}
for suffix, content := range required {
if err := os.WriteFile(archive+suffix, []byte(content), 0o640); err != nil {
t.Fatalf("write %s: %v", suffix, err)
}
}

ctx := context.Background()

// Call legacy wrapper
bundlePath, err := createBundle(ctx, logger, archive)
if err != nil {
t.Fatalf("legacy createBundle returned error: %v", err)
}

expectedPath := archive + ".bundle.tar"
if bundlePath != expectedPath {
t.Fatalf("bundle path = %s, want %s", bundlePath, expectedPath)
}

if _, err := os.Stat(bundlePath); err != nil {
t.Fatalf("expected bundle file to exist, got %v", err)
}
}

func TestRemoveAssociatedFiles_RemovesAll(t *testing.T) {
logger := logging.New(logging.GetDefaultLogger().GetLevel(), false)
tempDir := t.TempDir()
Expand Down
Loading
Loading