Files
肆月 e5f6dfabaa fix(ota): isolate updates in persistent workspaces (#863)
* fix(ota): isolate updates in persistent workspaces

Stage online and offline update archives under /root/.kvmcache/nanokvm-update-* and validate storage, manifests, and archive contents before changing the installed application.

* fix(ota): harden storage safety and release gates

Preserve the last rollback backup when update storage is insufficient, and verify the actual application mount point before installation.

Move the shared transfer sentinel from /tmp to /run, enforce device package limits in release verification, and run that verification in package CI.
2026-08-10 14:49:29 +08:00

72 lines
1.3 KiB
Go

package application
import (
"fmt"
"os"
"sync"
"NanoKVM-Server/utils"
log "github.com/sirupsen/logrus"
)
var (
mutex sync.Mutex
isUpdating bool
)
func acquireUpdateLock() bool {
mutex.Lock()
defer mutex.Unlock()
if isUpdating {
return false
}
isUpdating = true
return true
}
func releaseUpdateLock() {
mutex.Lock()
defer mutex.Unlock()
isUpdating = false
}
func installPreparedPackage(sourceDir string) error {
if err := backupCurrentApp(); err != nil {
return err
}
if err := applyUpdate(sourceDir); err != nil {
return err
}
if err := utils.ChmodRecursively(AppDir, 0o755); err != nil {
return fmt.Errorf("failed to chmod: %w", err)
}
return nil
}
func backupCurrentApp() error {
if err := os.RemoveAll(BackupDir); err != nil {
return fmt.Errorf("failed to remove backup: %w", err)
}
if err := utils.MoveFilesRecursively(AppDir, BackupDir); err != nil {
return fmt.Errorf("failed to backup app: %w", err)
}
return nil
}
func applyUpdate(sourceDir string) error {
if err := utils.MoveFilesRecursively(sourceDir, AppDir); err != nil {
// Try to restore backup on failure
if restoreErr := utils.MoveFilesRecursively(BackupDir, AppDir); restoreErr != nil {
log.Errorf("Failed to restore backup after update failure: %v", restoreErr)
}
return fmt.Errorf("failed to move update in place: %w", err)
}
return nil
}