feat: add upgrade and migration flow for native fnOS
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
构建过程不再引用 `F:\Fonu-main\havline`。
|
构建过程不再引用 `F:\Fonu-main\havline`。
|
||||||
|
|
||||||
阶段三范围:
|
阶段四范围:
|
||||||
|
|
||||||
- Go 主程序原生运行
|
- Go 主程序原生运行
|
||||||
- 统一网关 `/app/havline`
|
- 统一网关 `/app/havline`
|
||||||
@@ -22,6 +22,10 @@
|
|||||||
- Nginx 依赖库与 `mime.types`
|
- Nginx 依赖库与 `mime.types`
|
||||||
- HTTP 18080 与 HTTPS 9443
|
- HTTP 18080 与 HTTPS 9443
|
||||||
- frpc 与 cloudflared 按需下载,不打包进 FPK
|
- frpc 与 cloudflared 按需下载,不打包进 FPK
|
||||||
|
- Native 版本 1.9.1
|
||||||
|
- Docker 版数据目录兼容
|
||||||
|
- 旧 `data/` 布局自动迁移
|
||||||
|
- 升级前数据库备份
|
||||||
|
|
||||||
按需下载位置:
|
按需下载位置:
|
||||||
|
|
||||||
@@ -44,6 +48,28 @@ havline:1.9.0 arm64
|
|||||||
|
|
||||||
如果本地没有对应架构镜像,先加载 amd64 与 arm64 镜像归档。
|
如果本地没有对应架构镜像,先加载 amd64 与 arm64 镜像归档。
|
||||||
|
|
||||||
|
Nginx 提取镜像版本默认固定为 `1.9.0`,与应用版本解耦。需要时可传入:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\build.ps1 -NginxImageVersion 1.9.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 升级与迁移
|
||||||
|
|
||||||
|
详细步骤见:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/upgrade-and-migration.md
|
||||||
|
```
|
||||||
|
|
||||||
|
推荐路径:
|
||||||
|
|
||||||
|
```text
|
||||||
|
卸载 Docker 版时保留数据
|
||||||
|
安装 Native 1.9.1
|
||||||
|
启动后自动迁移数据库和旧数据布局
|
||||||
|
```
|
||||||
|
|
||||||
## 构建
|
## 构建
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -54,7 +80,7 @@ cd F:\Fonu-main\fnos-native
|
|||||||
输出:
|
输出:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
dist/havline-native-1.9.0.fpk
|
dist/havline-native-1.9.1.fpk
|
||||||
```
|
```
|
||||||
|
|
||||||
构建脚本会:
|
构建脚本会:
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
1.9.0
|
1.9.1
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
param(
|
param(
|
||||||
[string]$FnpackPath = "",
|
[string]$FnpackPath = "",
|
||||||
[string]$GoBin = "go"
|
[string]$GoBin = "go",
|
||||||
|
[string]$NginxImageVersion = "1.9.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -88,6 +89,7 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$env:VITE_BASE_PATH = "/app/havline/"
|
$env:VITE_BASE_PATH = "/app/havline/"
|
||||||
|
$env:VITE_APP_VERSION = $version
|
||||||
npm run build
|
npm run build
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
throw "前端构建失败,退出码:$LASTEXITCODE"
|
throw "前端构建失败,退出码:$LASTEXITCODE"
|
||||||
@@ -118,8 +120,8 @@ Copy-Tree -Source (Join-Path $mainRepo "web\assets\image") -Destination (Join-Pa
|
|||||||
|
|
||||||
$serverDir = Join-Path $stage "app\server"
|
$serverDir = Join-Path $stage "app\server"
|
||||||
$dockerBin = Resolve-DockerCli
|
$dockerBin = Resolve-DockerCli
|
||||||
Export-Nginx -DockerBin $dockerBin -Platform "linux/amd64" -Arch "amd64" -Image "jayhub.top/mrlee/havline:$version" -OutputDir $serverDir
|
Export-Nginx -DockerBin $dockerBin -Platform "linux/amd64" -Arch "amd64" -Image "jayhub.top/mrlee/havline:$NginxImageVersion" -OutputDir $serverDir
|
||||||
Export-Nginx -DockerBin $dockerBin -Platform "linux/arm64" -Arch "arm64" -Image "havline:$version" -OutputDir $serverDir
|
Export-Nginx -DockerBin $dockerBin -Platform "linux/arm64" -Arch "arm64" -Image "havline:$NginxImageVersion" -OutputDir $serverDir
|
||||||
|
|
||||||
$env:CGO_ENABLED = "0"
|
$env:CGO_ENABLED = "0"
|
||||||
$env:GOOS = "linux"
|
$env:GOOS = "linux"
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# Havline Native 升级与迁移
|
||||||
|
|
||||||
|
> 适用版本:Native 1.9.1 及以后
|
||||||
|
> 迁移来源:飞牛 Docker 应用版 Havline
|
||||||
|
|
||||||
|
## 一、数据目录
|
||||||
|
|
||||||
|
Docker 版和 Native 版使用同一个飞牛应用数据目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
${TRIM_PKGVAR}
|
||||||
|
```
|
||||||
|
|
||||||
|
主要数据:
|
||||||
|
|
||||||
|
```text
|
||||||
|
havline.db
|
||||||
|
session_secret
|
||||||
|
nginx/
|
||||||
|
certs/
|
||||||
|
frp/
|
||||||
|
cloudflared/
|
||||||
|
logs/
|
||||||
|
ssh_known_hosts
|
||||||
|
```
|
||||||
|
|
||||||
|
Native 版启动时设置:
|
||||||
|
|
||||||
|
```text
|
||||||
|
HAVLINE_DATA_DIR=${TRIM_PKGVAR}
|
||||||
|
```
|
||||||
|
|
||||||
|
因此正常情况下不需要复制数据。
|
||||||
|
|
||||||
|
## 二、推荐迁移路径
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 在飞牛应用中心备份或导出重要配置
|
||||||
|
2. 卸载 Docker 版 Havline,选择“保留数据”
|
||||||
|
3. 确认旧容器已停止,6893/18080/9443 端口已释放
|
||||||
|
4. 安装 havline-native-1.9.1.fpk
|
||||||
|
5. Native 安装回调检查数据目录
|
||||||
|
6. 启动后主程序自动执行数据库迁移
|
||||||
|
7. 登录验证反向代理、证书、FRP、Cloudflare 配置
|
||||||
|
```
|
||||||
|
|
||||||
|
卸载时不要选择“删除全部数据”。
|
||||||
|
|
||||||
|
## 三、直接覆盖升级
|
||||||
|
|
||||||
|
如果飞牛应用中心允许同一 `appname=havline` 直接升级:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Docker 版 1.9.0
|
||||||
|
-> Native 版 1.9.1
|
||||||
|
```
|
||||||
|
|
||||||
|
升级回调会执行:
|
||||||
|
|
||||||
|
```text
|
||||||
|
检查 havline.db 可读
|
||||||
|
检查 session_secret 可读
|
||||||
|
迁移旧数据布局
|
||||||
|
备份数据库到 ${TRIM_PKGVAR}/backups
|
||||||
|
保留全部数据
|
||||||
|
```
|
||||||
|
|
||||||
|
如果应用中心不允许跨包类型直接升级,请使用推荐迁移路径。
|
||||||
|
|
||||||
|
## 四、旧数据布局兼容
|
||||||
|
|
||||||
|
部分早期 Docker 包可能使用:
|
||||||
|
|
||||||
|
```text
|
||||||
|
${TRIM_PKGVAR}/data/havline.db
|
||||||
|
```
|
||||||
|
|
||||||
|
Native 版检测到该布局且根目录没有 `havline.db` 时,会把
|
||||||
|
`${TRIM_PKGVAR}/data` 下的内容迁移到 `${TRIM_PKGVAR}`。
|
||||||
|
|
||||||
|
迁移规则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
只迁移目标不存在的文件
|
||||||
|
不覆盖已有数据
|
||||||
|
保留原数据目录中的未迁移内容
|
||||||
|
```
|
||||||
|
|
||||||
|
## 五、升级前备份
|
||||||
|
|
||||||
|
`upgrade_callback` 会把数据库复制到:
|
||||||
|
|
||||||
|
```text
|
||||||
|
${TRIM_PKGVAR}/backups/havline-pre-upgrade-<时间戳>.db
|
||||||
|
```
|
||||||
|
|
||||||
|
备份失败会导致升级失败,不会静默继续。
|
||||||
|
|
||||||
|
## 六、回滚
|
||||||
|
|
||||||
|
如果需要回滚到 Docker 版:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 停止 Native 版 Havline
|
||||||
|
2. 保留 ${TRIM_PKGVAR}
|
||||||
|
3. 安装旧 Docker 版 FPK
|
||||||
|
4. 启动后验证数据
|
||||||
|
```
|
||||||
|
|
||||||
|
`session_secret` 必须保持不变,否则已加密的 API Token、DDNS 凭据、
|
||||||
|
通知密码和 Cloudflare 凭据将无法解密。
|
||||||
|
|
||||||
|
## 七、验证清单
|
||||||
|
|
||||||
|
```text
|
||||||
|
[ ] 旧应用已停止
|
||||||
|
[ ] 端口 6893/18080/9443 已释放
|
||||||
|
[ ] ${TRIM_PKGVAR}/havline.db 存在
|
||||||
|
[ ] ${TRIM_PKGVAR}/session_secret 存在
|
||||||
|
[ ] Native 安装成功
|
||||||
|
[ ] Native 启动成功
|
||||||
|
[ ] 数据库迁移成功
|
||||||
|
[ ] 升级前备份已生成
|
||||||
|
[ ] 管理员可以登录
|
||||||
|
[ ] 反向代理规则保留
|
||||||
|
[ ] 证书保留
|
||||||
|
[ ] FRP 配置保留
|
||||||
|
[ ] Cloudflare 配置保留
|
||||||
|
```
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/migrate_legacy.sh"
|
||||||
|
|
||||||
mkdir -p "$TRIM_PKGVAR/logs"
|
mkdir -p "$TRIM_PKGVAR/logs"
|
||||||
chown -R "$TRIM_USERNAME:$TRIM_GROUPNAME" "$TRIM_PKGVAR"
|
chown -R "$TRIM_USERNAME:$TRIM_GROUPNAME" "$TRIM_PKGVAR"
|
||||||
|
|
||||||
|
migrate_legacy_data
|
||||||
|
|
||||||
ARCH="$(uname -m)"
|
ARCH="$(uname -m)"
|
||||||
case "$ARCH" in
|
case "$ARCH" in
|
||||||
x86_64|amd64) ARCH_DIR="amd64" ;;
|
x86_64|amd64) ARCH_DIR="amd64" ;;
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
migrate_legacy_data() {
|
||||||
|
local legacy_root="$TRIM_PKGVAR/data"
|
||||||
|
local legacy_db="$legacy_root/havline.db"
|
||||||
|
local target_db="$TRIM_PKGVAR/havline.db"
|
||||||
|
|
||||||
|
if [ ! -f "$legacy_db" ] || [ -f "$target_db" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "检测到旧版数据布局:$legacy_root"
|
||||||
|
mkdir -p "$TRIM_PKGVAR/backups"
|
||||||
|
|
||||||
|
for item in "$legacy_root"/* "$legacy_root"/.[!.]* "$legacy_root"/..?*; do
|
||||||
|
[ -e "$item" ] || continue
|
||||||
|
local name
|
||||||
|
name="$(basename "$item")"
|
||||||
|
if [ -e "$TRIM_PKGVAR/$name" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
mv "$item" "$TRIM_PKGVAR/$name"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "旧版数据已迁移到:$TRIM_PKGVAR"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_database() {
|
||||||
|
local db="$TRIM_PKGVAR/havline.db"
|
||||||
|
if [ ! -f "$db" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$TRIM_PKGVAR/backups"
|
||||||
|
cp -f "$db" "$TRIM_PKGVAR/backups/havline-pre-upgrade-$(date +%Y%m%d%H%M%S).db"
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/migrate_legacy.sh"
|
||||||
|
|
||||||
if [ -f "$TRIM_PKGVAR/havline.db" ] && [ ! -r "$TRIM_PKGVAR/havline.db" ]; then
|
if [ -f "$TRIM_PKGVAR/havline.db" ] && [ ! -r "$TRIM_PKGVAR/havline.db" ]; then
|
||||||
echo "数据库不可读:$TRIM_PKGVAR/havline.db" > "$TRIM_TEMP_LOGFILE"
|
echo "数据库不可读:$TRIM_PKGVAR/havline.db" > "$TRIM_TEMP_LOGFILE"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -11,4 +14,7 @@ if [ -f "$TRIM_PKGVAR/session_secret" ] && [ ! -r "$TRIM_PKGVAR/session_secret"
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
migrate_legacy_data
|
||||||
|
backup_database
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
appname = havline
|
appname = havline
|
||||||
version = 1.9.0
|
version = 1.9.1
|
||||||
display_name = Havline
|
display_name = Havline
|
||||||
desc = NAS 公网访问管理:原生应用阶段三
|
desc = NAS 公网访问管理:原生应用阶段四
|
||||||
platform = all
|
platform = all
|
||||||
source = thirdparty
|
source = thirdparty
|
||||||
maintainer = Havline
|
maintainer = Havline
|
||||||
@@ -11,4 +11,4 @@ desktop_uidir = ui
|
|||||||
desktop_applaunchname = havline.main
|
desktop_applaunchname = havline.main
|
||||||
ctl_stop = true
|
ctl_stop = true
|
||||||
os_min_version = 1.1.3100
|
os_min_version = 1.1.3100
|
||||||
changelog = 原生应用阶段三:frpc 与 cloudflared 按需下载
|
changelog = 原生应用阶段四:升级迁移、旧数据布局兼容和升级前备份
|
||||||
|
|||||||
Reference in New Issue
Block a user