Files
ttstd-infinite-canvas/scripts/install-host-updater.sh

122 lines
4.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
INSTALL_DIR="${INSTALL_DIR:-/opt/open-ai-canvas}"
REPOSITORY="${REPOSITORY:-ddcat-ai/open-ai-canvas}"
SOCKET_DIR="${CANVAS_UPDATER_SOCKET_DIR:-/run/open-ai-canvas-updater}"
UPDATER_BIN="/usr/local/bin/open-ai-canvas-host-updater"
UPDATER_ENV="/etc/open-ai-canvas-updater.env"
UPDATER_SERVICE="/etc/systemd/system/open-ai-canvas-updater.service"
fail() {
printf 'Host Updater 安装失败:%s\n' "$1" >&2
exit 1
}
require_root() {
[[ "${EUID}" -eq 0 ]] || fail "请使用 sudo 运行"
[[ "$(uname -s)" == "Linux" ]] || fail "仅支持 Linux 服务器"
command -v systemctl >/dev/null 2>&1 || fail "服务器必须使用 systemd"
command -v curl >/dev/null 2>&1 || fail "缺少 curl"
command -v sha256sum >/dev/null 2>&1 || fail "缺少 sha256sum"
command -v openssl >/dev/null 2>&1 || fail "缺少 openssl"
[[ -f "${INSTALL_DIR}/.env" ]] || fail "未找到 ${INSTALL_DIR}/.env"
[[ -f "${INSTALL_DIR}/docker-compose.deploy.yml" ]] || fail "未找到部署 Compose"
}
read_image_tag() {
local configured
configured="$(sed -n 's/^CANVAS_IMAGE_TAG=//p' "${INSTALL_DIR}/.env" | tail -n 1)"
[[ -n "$configured" && "$configured" != "latest" ]] || fail "请先把 CANVAS_IMAGE_TAG 固定为已发布版本"
if [[ "$configured" == v* ]]; then
RELEASE_TAG="$configured"
else
RELEASE_TAG="v${configured}"
fi
}
install_binary() {
local arch asset temporary checksum_file expected
case "$(uname -m)" in
x86_64|amd64) arch="amd64" ;;
aarch64|arm64) arch="arm64" ;;
*) fail "不支持的 CPU 架构:$(uname -m)" ;;
esac
asset="open-ai-canvas-host-updater-linux-${arch}"
temporary="$(mktemp)"
checksum_file="$(mktemp)"
curl -fsSL "https://github.com/${REPOSITORY}/releases/download/${RELEASE_TAG}/${asset}" -o "$temporary"
curl -fsSL "https://github.com/${REPOSITORY}/releases/download/${RELEASE_TAG}/SHA256SUMS" -o "$checksum_file"
expected="$(awk -v asset="$asset" '$2 == asset { print $1 }' "$checksum_file")"
[[ "$expected" =~ ^[a-f0-9]{64}$ ]] || fail "Release 校验清单缺少 ${asset}"
printf '%s %s\n' "$expected" "$temporary" | sha256sum -c - >/dev/null || fail "Host Updater SHA-256 校验失败"
install -m 0755 "$temporary" "$UPDATER_BIN"
rm -f "$temporary" "$checksum_file"
}
ensure_token() {
local token temporary
token="$(sed -n 's/^CANVAS_UPDATER_TOKEN=//p' "${INSTALL_DIR}/.env" | tail -n 1)"
if [[ -z "$token" ]]; then
token="$(openssl rand -hex 32)"
temporary="$(mktemp "${INSTALL_DIR}/.env.XXXXXX")"
awk -v token="$token" '
BEGIN { updated=0 }
/^CANVAS_UPDATER_TOKEN=/ { print "CANVAS_UPDATER_TOKEN=" token; updated=1; next }
{ print }
END { if (!updated) print "CANVAS_UPDATER_TOKEN=" token }
' "${INSTALL_DIR}/.env" > "$temporary"
chmod --reference="${INSTALL_DIR}/.env" "$temporary"
mv "$temporary" "${INSTALL_DIR}/.env"
fi
[[ ${#token} -ge 32 ]] || fail "CANVAS_UPDATER_TOKEN 长度不足"
umask 077
printf 'CANVAS_UPDATER_TOKEN=%s\nCANVAS_UPDATER_INSTALL_DIR=%s\nCANVAS_UPDATER_SOCKET=%s/updater.sock\n' "$token" "$INSTALL_DIR" "$SOCKET_DIR" > "$UPDATER_ENV"
}
install_service() {
local temporary_service
install -d -m 0755 "$SOCKET_DIR"
install -d -m 0700 /var/lib/open-ai-canvas-updater "${INSTALL_DIR}/backups"
temporary_service="$(mktemp)"
printf '%s\n' \
'[Unit]' \
'Description=Open AI Canvas Host Updater' \
'After=docker.service network-online.target' \
'Requires=docker.service' \
'Wants=network-online.target' \
'' \
'[Service]' \
'Type=simple' \
"EnvironmentFile=${UPDATER_ENV}" \
"ExecStart=${UPDATER_BIN}" \
'Restart=on-failure' \
'RestartSec=5s' \
'NoNewPrivileges=true' \
'PrivateTmp=true' \
'ProtectHome=true' \
'ProtectSystem=full' \
"ReadWritePaths=${INSTALL_DIR} /var/lib/open-ai-canvas-updater ${SOCKET_DIR} ${UPDATER_BIN}" \
'' \
'[Install]' \
'WantedBy=multi-user.target' > "$temporary_service"
install -m 0644 "$temporary_service" "$UPDATER_SERVICE"
rm -f "$temporary_service"
systemctl daemon-reload
systemctl enable --now open-ai-canvas-updater.service
systemctl restart open-ai-canvas-updater.service
}
main() {
require_root
read_image_tag
install_binary
ensure_token
install_service
printf 'Host Updater 已安装,Socket:%s/updater.sock\n' "$SOCKET_DIR"
printf '请重建 backend 容器,使 Token 与 Socket 挂载生效。\n'
}
main "$@"