mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-11-07 00:05:14 +00:00
64 lines
2.2 KiB
Go
64 lines
2.2 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
|
"github.com/1Panel-dev/1Panel/agent/global"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
|
)
|
|
|
|
func prepareAIGatewayAppRecover(install *model.AppInstall, recoverFile, secret string) (string, func(), error) {
|
|
noop := func() {}
|
|
if !isAIGatewayApp(install.App.Key) {
|
|
return "", noop, nil
|
|
}
|
|
tmpDir, err := os.MkdirTemp(global.Dir.TmpDir, "ai-gateway-recover-")
|
|
if err != nil {
|
|
return "", noop, err
|
|
}
|
|
cleanup := func() { _ = os.RemoveAll(tmpDir) }
|
|
fail := func(err error) (string, func(), error) {
|
|
cleanup()
|
|
return "", noop, err
|
|
}
|
|
if err := files.NewFileOp().TarGzExtractPro(recoverFile, tmpDir, secret); err != nil {
|
|
return fail(err)
|
|
}
|
|
backupDir := filepath.Join(tmpDir, strings.ReplaceAll(filepath.Base(recoverFile), ".tar.gz", ""))
|
|
for _, name := range []string{"app.json", "app.tar.gz"} {
|
|
info, err := os.Lstat(filepath.Join(backupDir, name))
|
|
if err != nil || !info.Mode().IsRegular() {
|
|
return fail(buserr.New("AppBackupFileIncomplete"))
|
|
}
|
|
}
|
|
metadata, err := os.ReadFile(filepath.Join(backupDir, "app.json"))
|
|
if err != nil {
|
|
return fail(err)
|
|
}
|
|
var backup model.AppInstall
|
|
if err := json.Unmarshal(metadata, &backup); err != nil {
|
|
return fail(fmt.Errorf("unmarshal app.json failed: %w", err))
|
|
}
|
|
if backup.App.Key != install.App.Key || backup.Name != install.Name {
|
|
return fail(buserr.New("AppAttributesNotMatch"))
|
|
}
|
|
// Historical backups already include Version. Unsuffixed releases are
|
|
// SQLite; no new metadata field is required. Missing versions are invalid,
|
|
// not evidence that an archive contains SQLite data.
|
|
if strings.TrimSpace(backup.Version) == "" || strings.TrimSpace(install.Version) == "" {
|
|
return fail(buserr.New("AppBackupFileIncomplete"))
|
|
}
|
|
// Deliberately do not compare version order: restoring an older version of
|
|
// the same database type is required for failed-upgrade rollbacks.
|
|
if !isAIGatewayUpgradeVersionAllowed(install.App.Key, install.Version, backup.Version) {
|
|
return fail(buserr.New("ErrAIGatewayRecoverDatabaseTypeMismatch"))
|
|
}
|
|
return backupDir, cleanup, nil
|
|
}
|