mirror of
https://github.com/okxlin/appstore.git
synced 2026-11-14 16:05:48 +00:00
Merge PR #8315
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
exec "$SCRIPT_DIR/init.sh"
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
bichon:
|
||||
image: "rustmailer/bichon:1.6.2"
|
||||
image: "rustmailer/bichon:2.3.0"
|
||||
container_name: ${CONTAINER_NAME}
|
||||
restart: always
|
||||
user: "1000:1000"
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
ENV_FILE="${ENV_FILE:-$APP_DIR/.env}"
|
||||
ADMIN_IMAGE="rustmailer/bichon:2.3.0"
|
||||
|
||||
read_env_value() {
|
||||
local key="$1"
|
||||
local value
|
||||
[[ -f "$ENV_FILE" ]] || return 0
|
||||
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
|
||||
value="${value%$'\r'}"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s\n' "$value"
|
||||
}
|
||||
|
||||
"$SCRIPT_DIR/init.sh"
|
||||
|
||||
APP_DATA_DIR="${APP_DATA_DIR:-$(read_env_value APP_DATA_DIR)}"
|
||||
APP_DATA_DIR="${APP_DATA_DIR:-./data}"
|
||||
if [[ "$APP_DATA_DIR" = /* ]]; then
|
||||
RESOLVED_DATA_DIR="$(realpath -m -- "$APP_DATA_DIR")"
|
||||
else
|
||||
RESOLVED_DATA_DIR="$(realpath -m -- "$APP_DIR/${APP_DATA_DIR#./}")"
|
||||
case "$RESOLVED_DATA_DIR" in
|
||||
"$APP_DIR"/*) ;;
|
||||
*)
|
||||
printf 'Relative APP_DATA_DIR must remain inside the application directory\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
[[ -d "$RESOLVED_DATA_DIR" ]] || {
|
||||
printf 'APP_DATA_DIR does not exist: %s\n' "$RESOLVED_DATA_DIR" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
docker_args=(docker run --rm --network none --user 1000:1000 --mount "type=bind,source=$RESOLVED_DATA_DIR,target=/data" --env BICHON_ROOT_DIR=/data)
|
||||
if [[ -n "${BICHON_INDEX_DIR:-$(read_env_value BICHON_INDEX_DIR)}" ]]; then
|
||||
docker_args+=(--env "BICHON_INDEX_DIR=${BICHON_INDEX_DIR:-$(read_env_value BICHON_INDEX_DIR)}")
|
||||
fi
|
||||
|
||||
storage_state() {
|
||||
"${docker_args[@]}" --entrypoint sh "$ADMIN_IMAGE" -c '
|
||||
set -eu
|
||||
root=/data
|
||||
storage="$root/bichon-storage"
|
||||
version=0
|
||||
if [ -f "$root/STORAGE_VERSION" ]; then
|
||||
version="$(cat "$root/STORAGE_VERSION")"
|
||||
fi
|
||||
case "$version" in
|
||||
""|*[!0-9]*) echo INVALID; exit 0 ;;
|
||||
esac
|
||||
if [ -d "$storage/blobs" ]; then
|
||||
if [ "$version" -ge 2 ]; then echo CURRENT; else echo PARTIAL; fi
|
||||
elif [ -d "$storage" ]; then
|
||||
if [ "$version" -lt 2 ]; then echo LEGACY; else echo INVALID; fi
|
||||
elif [ "$version" -eq 0 ]; then
|
||||
echo CLEAN
|
||||
else
|
||||
echo INVALID
|
||||
fi
|
||||
'
|
||||
}
|
||||
|
||||
state="$(storage_state)"
|
||||
case "$state" in
|
||||
CLEAN|CURRENT)
|
||||
;;
|
||||
LEGACY)
|
||||
if ! command -v script >/dev/null 2>&1; then
|
||||
printf 'The util-linux script command is required for the Bichon v1 storage migration\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf -v admin_command '%q ' "${docker_args[@]}" --interactive --tty --entrypoint bichon-admin "$ADMIN_IMAGE"
|
||||
{
|
||||
sleep 0.2
|
||||
printf '\033[B\033[B\r'
|
||||
sleep 0.2
|
||||
printf '/data\r'
|
||||
sleep 0.2
|
||||
printf '\r'
|
||||
sleep 0.2
|
||||
printf '\r'
|
||||
sleep 0.2
|
||||
printf '\r'
|
||||
} | script -qefc "$admin_command" /dev/null
|
||||
|
||||
state="$(storage_state)"
|
||||
if [[ "$state" != CURRENT ]]; then
|
||||
printf 'Bichon v1 storage migration did not reach storage version 2 (state: %s)\n' "$state" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
printf 'Unrecognized or incomplete Bichon storage layout (state: %s); refusing to start the upgraded app\n' "$state" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+11
-1
@@ -49,7 +49,17 @@ Bichon is a self-hosted email archiving service written in Rust. It downloads ma
|
||||
|
||||
升级或迁移前,应停止 Bichon 并备份 `APP_DATA_DIR` 指向的完整目录以及安装时使用的加密口令。默认 `./data` 位于 1Panel 应用版本目录内,卸载时会随应用目录移除;若需要跨卸载保留归档,请选择独立绝对路径,并预先保证其所有权为 UID/GID `1000:1000`。
|
||||
|
||||
本应用只打包稳定版 `1.6.2`。截至本批次适配时,上游 `latest` 已指向 `2.0.0-alpha.1` 预发布镜像,因此没有将 `latest` 作为稳定版本交付。
|
||||
从 `1.6.2` 升级到 `2.x` 时,升级脚本会调用上游管理工具将 Fjall 邮件对象存储迁移到新格式;现有索引和元数据保持不变。迁移会保留旧存储供验证;确认新版运行正常前,不要手动删除旧数据。`APP_DATA_DIR` 挂载路径保持不变,也支持自定义绝对路径。
|
||||
|
||||
本应用提供固定版本 `1.6.2` 和 `2.3.0`。上游 `latest` 可能先于稳定版指向预发布镜像,因此不作为固定稳定版本交付。
|
||||
|
||||
## Backup and upgrades
|
||||
|
||||
Before upgrading or migrating, stop Bichon and back up the full `APP_DATA_DIR` directory and the encryption password used at installation. The default `./data` is inside the 1Panel app directory and is removed when the app is uninstalled; choose a separate absolute path to retain archives across uninstall, owned by UID/GID `1000:1000`.
|
||||
|
||||
When upgrading from `1.6.2` to `2.x`, the upgrade script runs the upstream admin migration from Fjall blob storage to the new format; existing indexes and metadata are left unchanged. The migration keeps the old storage for verification; do not remove it until the upgraded app works. The `APP_DATA_DIR` mount remains unchanged, including custom absolute paths.
|
||||
|
||||
The app provides fixed versions `1.6.2` and `2.3.0`. Upstream `latest` may point to a prerelease before a stable release, so it is not used as a fixed stable version.
|
||||
|
||||
## 参考资料
|
||||
|
||||
|
||||
Reference in New Issue
Block a user