- 每次推送到飞牛 Gitea(3000 端口)的代码 10 秒内自动镜像到 GitHub 7 个私有仓库 (SMB_Android / DCU_APP / GD32E50X_BOOT / DCU_DesktopController / Motor_v2 / DCU_ECAT_Master / GD32_BOOT),真镜像语义(删分支/标签同步删) - 标准 .fpk 原生应用:不进 Docker,依赖 python312,安装后进入应用中心已安装列表 和桌面启动台,支持启动/停止/重启/卸载,NAS 重启自动恢复 - 控制面板(:8899):自动同步开关、立即同步、仓库状态、同步日志、打开 Gitea - GitHub 推送走 SSH 22 端口直连(HTTPS 443 本地网络被断),部署私钥随应用本地分发 - 附 fnos-install.js(命令行自动安装)、build.sh(重新构建 fpk)、genicon.py(图标生成) 注意:GitHub 部署私钥(GiteaHubSync/app/ssh/id_ed25519)与打包产物 .fpk 按 .gitignore 规则不进仓库,仅保留在工作目录本地分发。
104 lines
3.2 KiB
Bash
104 lines
3.2 KiB
Bash
#!/bin/bash
|
||
# GiteaHubSync service control(由 fnOS 应用中心在 启动/停止/查询状态 时调用)
|
||
# 守护进程以 setsid nohup 方式后台运行,pidfile 位于持久数据目录(@appdata/GiteaHubSync)
|
||
|
||
PYBIN=""
|
||
for candidate in \
|
||
/var/apps/python312/target/bin/python3 \
|
||
/vol1/@appcenter/python312/target/bin/python3 \
|
||
/var/apps/python311/target/bin/python3 \
|
||
/var/apps/python310/target/bin/python3 \
|
||
/usr/bin/python3 \
|
||
/usr/local/bin/python3; do
|
||
if [ -x "$candidate" ]; then PYBIN="$candidate"; break; fi
|
||
done
|
||
|
||
# TRIM_APPDEST 由 fnOS 注入;若缺失或指向其他应用,则回退到脚本自身位置
|
||
APPDEST="${TRIM_APPDEST:-}"
|
||
if [ -z "$APPDEST" ] || [ ! -d "$APPDEST/cmd" ]; then
|
||
APPDEST="$(cd "$(dirname "$0")/.." && pwd)"
|
||
fi
|
||
BACKEND_DIR="${APPDEST}/backend"
|
||
[ -d "$BACKEND_DIR" ] || BACKEND_DIR="${APPDEST}/target/backend"
|
||
[ -d "$BACKEND_DIR" ] || BACKEND_DIR="${APPDEST}/app/backend"
|
||
DAEMON="${BACKEND_DIR}/panel.py"
|
||
|
||
# 持久数据目录(TRIM_PKGVAR 由 fnOS 注入,通常为 /vol{n}/@appdata/GiteaHubSync)
|
||
if [ -n "${TRIM_PKGVAR}" ] && [ -d "${TRIM_PKGVAR}" ]; then
|
||
DATA_DIR="${TRIM_PKGVAR}"
|
||
else
|
||
DATA_DIR=""
|
||
for candidate in \
|
||
"${APPDEST}/../../@appdata/GiteaHubSync" \
|
||
"${APPDEST}/var" \
|
||
"/var/apps/GiteaHubSync/var" \
|
||
"/vol1/@appdata/GiteaHubSync" \
|
||
"/vol2/@appdata/GiteaHubSync"; do
|
||
if [ -d "$candidate" ]; then DATA_DIR="$candidate"; break; fi
|
||
done
|
||
if [ -z "$DATA_DIR" ]; then
|
||
DATA_DIR="${APPDEST}/../../@appdata/GiteaHubSync"
|
||
fi
|
||
fi
|
||
PIDFILE="${DATA_DIR}/daemon.pid"
|
||
|
||
daemon_alive() {
|
||
[ -f "$PIDFILE" ] || return 1
|
||
local pid
|
||
pid="$(cat "$PIDFILE" 2>/dev/null)"
|
||
[ -n "$pid" ] || return 1
|
||
kill -0 "$pid" 2>/dev/null
|
||
}
|
||
|
||
case "$1" in
|
||
start)
|
||
if daemon_alive; then
|
||
echo "GiteaHubSync daemon already running (pid $(cat "$PIDFILE"))"
|
||
exit 0
|
||
fi
|
||
if [ -z "$PYBIN" ]; then
|
||
echo "python3 runtime not found (install_dep_apps=python312)" > "${TRIM_TEMP_LOGFILE:-/dev/stderr}"
|
||
exit 1
|
||
fi
|
||
mkdir -p "$DATA_DIR"
|
||
# fnOS 解包可能放宽密钥权限,ssh 会拒绝;启动前收紧
|
||
[ -f "${APPDEST}/ssh/id_ed25519" ] && chmod 600 "${APPDEST}/ssh/id_ed25519" 2>/dev/null
|
||
[ -f "${DATA_DIR}/id_ed25519" ] && chmod 600 "${DATA_DIR}/id_ed25519" 2>/dev/null
|
||
GHS_DATA_DIR="$DATA_DIR" setsid nohup "$PYBIN" "$DAEMON" >> "${DATA_DIR}/daemon.out" 2>&1 &
|
||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||
if daemon_alive; then
|
||
echo "GiteaHubSync daemon started (pid $(cat "$PIDFILE"))"
|
||
exit 0
|
||
fi
|
||
sleep 0.5
|
||
done
|
||
echo "GiteaHubSync daemon failed to start; see ${DATA_DIR}/daemon.out" > "${TRIM_TEMP_LOGFILE:-/dev/stderr}"
|
||
exit 1
|
||
;;
|
||
stop)
|
||
if daemon_alive; then
|
||
pid="$(cat "$PIDFILE")"
|
||
kill "$pid" 2>/dev/null
|
||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||
kill -0 "$pid" 2>/dev/null || break
|
||
sleep 0.5
|
||
done
|
||
kill -9 "$pid" 2>/dev/null
|
||
echo "GiteaHubSync daemon stopped (pid $pid)"
|
||
else
|
||
echo "GiteaHubSync daemon not running"
|
||
fi
|
||
rm -f "$PIDFILE"
|
||
exit 0
|
||
;;
|
||
status)
|
||
if daemon_alive; then
|
||
exit 0
|
||
fi
|
||
exit 3
|
||
;;
|
||
*)
|
||
exit 1
|
||
;;
|
||
esac
|