release: harden plugin deployment and recovery
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
ROOT=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
ROOT=$(CDPATH=; cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
PREFIX=${PLUGIN_INSTALL_PREFIX:-/opt/sub2api-add}
|
||||
ETC_DIR=${PLUGIN_ETC_DIR:-/etc/sub2api-add}
|
||||
VAR_DIR=${PLUGIN_VAR_DIR:-/var/lib/sub2api-add}
|
||||
@@ -94,28 +94,67 @@ validate_install_root() {
|
||||
[[ "$component" != "." && "$component" != ".." ]] || die "$label 不能包含 . 或 .. 路径组件"
|
||||
current="$current/$component"
|
||||
[[ ! -L "$current" ]] || die "$label 的路径组件不能是符号链接:$current"
|
||||
[[ ! -e "$current" || -d "$current" ]] || die "$label 的路径组件不是目录:$current"
|
||||
done
|
||||
if [[ "$value" != */sub2api-add && "${PLUGIN_ALLOW_CUSTOM_PATHS:-false}" != "true" ]]; then
|
||||
die "$label 必须位于受管的 sub2api-add 目录;如确需自定义路径请显式设置 PLUGIN_ALLOW_CUSTOM_PATHS=true"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_real_dir_tree() {
|
||||
local value=$1 label=$2 component current=""
|
||||
IFS='/' read -r -a parts <<< "${value#/}"
|
||||
for component in "${parts[@]}"; do
|
||||
[[ -z "$component" ]] && continue
|
||||
current="$current/$component"
|
||||
if [[ -L "$current" ]]; then
|
||||
die "$label 的路径组件不能是符号链接:$current"
|
||||
elif [[ -e "$current" ]]; then
|
||||
[[ -d "$current" ]] || die "$label 的路径组件不是目录:$current"
|
||||
else
|
||||
mkdir -- "$current"
|
||||
[[ -d "$current" && ! -L "$current" ]] || die "$label 创建了不安全的路径组件:$current"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
ensure_real_parent() {
|
||||
local path=$1 label=$2 parent
|
||||
parent=$(dirname -- "$path")
|
||||
[[ -d "$parent" && ! -L "$parent" ]] || die "$label 的父目录必须是已存在的真实目录:$parent"
|
||||
}
|
||||
|
||||
ensure_regular_target() {
|
||||
local path=$1 label=$2
|
||||
[[ ! -L "$path" ]] || die "$label 不能是符号链接:$path"
|
||||
}
|
||||
|
||||
validate_install_root "$PREFIX" PLUGIN_INSTALL_PREFIX
|
||||
validate_install_root "$ETC_DIR" PLUGIN_ETC_DIR
|
||||
validate_install_root "$VAR_DIR" PLUGIN_VAR_DIR
|
||||
ensure_real_dir_tree "$PREFIX" PLUGIN_INSTALL_PREFIX
|
||||
ensure_real_dir_tree "$ETC_DIR" PLUGIN_ETC_DIR
|
||||
ensure_real_dir_tree "$VAR_DIR" PLUGIN_VAR_DIR
|
||||
ensure_real_dir_tree /etc/systemd/system SYSTEMD_UNIT_DIR
|
||||
|
||||
install_one() {
|
||||
local name=$1 source="$ROOT/plugins/$1" env_file="$ETC_DIR/$1.env"
|
||||
local binary_dir="$PREFIX/$1/bin" data_dir="$VAR_DIR/$1"
|
||||
[[ -d "$source" ]] || die "插件目录不存在:$source"
|
||||
install -d -m 0755 "$binary_dir" "$data_dir" "$ETC_DIR"
|
||||
ensure_real_dir_tree "$binary_dir" PLUGIN_INSTALL_PREFIX
|
||||
ensure_real_dir_tree "$data_dir" PLUGIN_VAR_DIR
|
||||
ensure_real_parent "$env_file" PLUGIN_ETC_DIR
|
||||
ensure_regular_target "$env_file" PLUGIN_ETC_DIR
|
||||
chmod 0755 "$binary_dir" "$data_dir"
|
||||
if [[ ! -f "$env_file" ]]; then
|
||||
install -m 0600 "$source/.env.example" "$env_file"
|
||||
fi
|
||||
|
||||
if [[ "$name" == plugin-admin ]]; then
|
||||
ensure_env_value "$env_file" PLUGIN_REGISTRY_DIR "$data_dir"
|
||||
install -d -m 0700 "$data_dir/marketplace"
|
||||
ensure_real_dir_tree "$data_dir/marketplace" PLUGIN_VAR_DIR
|
||||
chmod 0700 "$data_dir/marketplace"
|
||||
ensure_regular_target "$data_dir/marketplace/index.json" PLUGIN_MARKETPLACE_INDEX
|
||||
if [[ ! -f "$data_dir/marketplace/index.json" && -f "$source/marketplace/index.example.json" ]]; then
|
||||
install -m 0600 "$source/marketplace/index.example.json" "$data_dir/marketplace/index.json"
|
||||
fi
|
||||
@@ -126,14 +165,19 @@ install_one() {
|
||||
fi
|
||||
|
||||
local tmp="$binary_dir/.${name}.tmp"
|
||||
ensure_real_parent "$tmp" PLUGIN_INSTALL_PREFIX
|
||||
ensure_regular_target "$tmp" PLUGIN_INSTALL_PREFIX
|
||||
info "构建 $name"
|
||||
(cd "$source" && CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o "$tmp" .)
|
||||
chmod 0755 "$tmp"
|
||||
ensure_regular_target "$binary_dir/$name" PLUGIN_INSTALL_PREFIX
|
||||
mv -f "$tmp" "$binary_dir/$name"
|
||||
chown -R "$RUN_USER:$RUN_USER" "$data_dir"
|
||||
chown "$RUN_USER:$RUN_USER" "$binary_dir/$name"
|
||||
chmod 0600 "$env_file"
|
||||
|
||||
ensure_real_parent "/etc/systemd/system/sub2api-$name.service" SYSTEMD_UNIT_DIR
|
||||
ensure_regular_target "/etc/systemd/system/sub2api-$name.service" SYSTEMD_UNIT_DIR
|
||||
cat > "/etc/systemd/system/sub2api-$name.service" <<EOF
|
||||
[Unit]
|
||||
Description=Sub2API ${name} business plugin
|
||||
|
||||
Reference in New Issue
Block a user