mirror of
https://github.com/wolfydw/backup_OBS.git
synced 2026-05-08 06:37:02 +08:00
Add automated install and stable updates
This commit is contained in:
Executable
+132
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}"
|
||||
SCRIPT_DIR="$(cd "$(dirname -- "$SCRIPT_PATH")" && pwd -P)"
|
||||
INSTALL_MODE="system"
|
||||
INSTALL_USER="root"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
DRY_RUN=false
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
用法:
|
||||
./install.sh [--user=NAME] [--mode=system|user] [--dry-run]
|
||||
|
||||
说明:
|
||||
- system 模式会安装到 /etc/systemd/system
|
||||
- user 模式会安装到 ~/.config/systemd/user
|
||||
- 不会覆盖已有 env.conf 和 exclude.user.list
|
||||
- dry-run 只打印将执行的动作,不实际写入 systemd
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--user=*) INSTALL_USER="${1#*=}"; shift;;
|
||||
--mode=*) INSTALL_MODE="${1#*=}"; shift;;
|
||||
--dry-run) DRY_RUN=true; shift;;
|
||||
-h|--help) usage; exit 0;;
|
||||
*) echo "未知参数:$1" >&2; usage; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "缺少命令:$1" >&2
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
need_cmd systemctl
|
||||
need_cmd install
|
||||
need_cmd sed
|
||||
|
||||
if [[ "$INSTALL_MODE" != "system" && "$INSTALL_MODE" != "user" ]]; then
|
||||
echo "无效 --mode:$INSTALL_MODE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ "$INSTALL_MODE" == "system" && "$(id -u)" -ne 0 ]]; then
|
||||
echo "system 模式需要 root 权限" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ "$INSTALL_MODE" == "user" ]]; then
|
||||
HOME_DIR="$(getent passwd "$INSTALL_USER" | cut -d: -f6)"
|
||||
if [[ -z "$HOME_DIR" ]]; then
|
||||
echo "无法找到用户:$INSTALL_USER" >&2
|
||||
exit 2
|
||||
fi
|
||||
SYSTEMD_DIR="${HOME_DIR}/.config/systemd/user"
|
||||
fi
|
||||
|
||||
mkdir -p "${SCRIPT_DIR}/systemd"
|
||||
|
||||
if [[ ! -f "${SCRIPT_DIR}/env.conf" ]]; then
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] 将创建 ${SCRIPT_DIR}/env.conf"
|
||||
else
|
||||
cp "${SCRIPT_DIR}/env.conf.example" "${SCRIPT_DIR}/env.conf"
|
||||
echo "已创建 ${SCRIPT_DIR}/env.conf"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -f "${SCRIPT_DIR}/exclude.user.list" ]]; then
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] 将创建 ${SCRIPT_DIR}/exclude.user.list"
|
||||
else
|
||||
cp "${SCRIPT_DIR}/exclude.user.list.example" "${SCRIPT_DIR}/exclude.user.list"
|
||||
echo "已创建 ${SCRIPT_DIR}/exclude.user.list"
|
||||
fi
|
||||
fi
|
||||
|
||||
chmod 755 \
|
||||
"${SCRIPT_DIR}/backup.sh" \
|
||||
"${SCRIPT_DIR}/clean_backups.sh" \
|
||||
"${SCRIPT_DIR}/lib/telegram.sh" \
|
||||
"${SCRIPT_DIR}/install.sh" \
|
||||
"${SCRIPT_DIR}/update.sh"
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] 目标 systemd 目录:$SYSTEMD_DIR"
|
||||
else
|
||||
mkdir -p "$SYSTEMD_DIR"
|
||||
fi
|
||||
|
||||
render_unit() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] 将渲染 $(basename "$src") -> $dst"
|
||||
return 0
|
||||
fi
|
||||
sed \
|
||||
-e "s|__WORKDIR__|${SCRIPT_DIR}|g" \
|
||||
-e "s|__RUN_USER__|${INSTALL_USER}|g" \
|
||||
"$src" > "$dst"
|
||||
|
||||
if [[ "$INSTALL_MODE" == "user" ]]; then
|
||||
sed -i '/^User=__RUN_USER__$/d;/^User=/d' "$dst"
|
||||
fi
|
||||
}
|
||||
|
||||
render_unit "${SCRIPT_DIR}/systemd/backup-obs-update.service" "${SYSTEMD_DIR}/backup-obs-update.service"
|
||||
render_unit "${SCRIPT_DIR}/systemd/backup-obs-update.timer" "${SYSTEMD_DIR}/backup-obs-update.timer"
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] 将执行 systemctl daemon-reload"
|
||||
echo "[dry-run] 将启用 backup-obs-update.timer"
|
||||
elif [[ "$INSTALL_MODE" == "system" ]]; then
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now backup-obs-update.timer
|
||||
echo "已启用 system timer:backup-obs-update.timer"
|
||||
echo "查看状态:systemctl status backup-obs-update.timer"
|
||||
echo "查看日志:journalctl -u backup-obs-update.service -n 100"
|
||||
else
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now backup-obs-update.timer
|
||||
echo "已启用 user timer:backup-obs-update.timer"
|
||||
echo "查看状态:systemctl --user status backup-obs-update.timer"
|
||||
echo "查看日志:journalctl --user -u backup-obs-update.service -n 100"
|
||||
fi
|
||||
@@ -61,6 +61,111 @@ EOF
|
||||
./clean_backups.sh --retain-days=5
|
||||
```
|
||||
|
||||
## 首次部署
|
||||
|
||||
新机器首次部署推荐流程:
|
||||
|
||||
```bash
|
||||
git clone <你的仓库地址> /root/backup_OBS
|
||||
cd /root/backup_OBS
|
||||
./install.sh
|
||||
```
|
||||
|
||||
`install.sh` 会自动完成:
|
||||
|
||||
- 如果不存在,则创建 `env.conf`
|
||||
- 如果不存在,则创建 `exclude.user.list`
|
||||
- 修正脚本执行权限
|
||||
- 安装 `systemd` 更新任务
|
||||
- 启用 `backup-obs-update.timer`
|
||||
|
||||
默认使用 system 模式,也就是安装到 `/etc/systemd/system`。
|
||||
|
||||
可选参数:
|
||||
|
||||
```bash
|
||||
./install.sh --mode=system
|
||||
./install.sh --mode=user --user=root
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `system` 模式需要 root 权限
|
||||
- `user` 模式会安装到 `~/.config/systemd/user`
|
||||
- 安装脚本不会覆盖已有的 `env.conf` 和 `exclude.user.list`
|
||||
|
||||
常用查看命令:
|
||||
|
||||
```bash
|
||||
systemctl status backup-obs-update.timer
|
||||
journalctl -u backup-obs-update.service -n 100
|
||||
```
|
||||
|
||||
## 自动更新
|
||||
|
||||
仓库内提供了一个统一更新脚本:
|
||||
|
||||
```bash
|
||||
./update.sh
|
||||
```
|
||||
|
||||
它会执行:
|
||||
|
||||
- `git fetch --tags origin`
|
||||
- 默认更新 `stable` 分支,或切换到你指定的 tag / 分支
|
||||
- 修正脚本执行权限
|
||||
- 自动执行一次 `./backup.sh --dry-run` 自检
|
||||
|
||||
也可以手动指定版本:
|
||||
|
||||
```bash
|
||||
./update.sh
|
||||
./update.sh stable
|
||||
./update.sh main
|
||||
./update.sh v1.2.0
|
||||
```
|
||||
|
||||
配合 `systemd timer` 后,机器会定时自动执行 `update.sh`。
|
||||
|
||||
## GitHub 多机发布流程
|
||||
|
||||
推荐流程:
|
||||
|
||||
1. 在一台测试机或开发环境修改脚本并提交到 GitHub。
|
||||
2. 在测试机手动运行:
|
||||
- `./update.sh main`
|
||||
- `./backup.sh --dry-run`
|
||||
- `./backup.sh`
|
||||
- `./clean_backups.sh --retain-days=100000`
|
||||
3. 确认备份、清理、Telegram 通知都正常。
|
||||
4. 打稳定版本标签,例如:
|
||||
|
||||
```bash
|
||||
git tag v1.2.0
|
||||
git push origin v1.2.0
|
||||
```
|
||||
|
||||
5. 生产机器可以手动执行:
|
||||
|
||||
```bash
|
||||
./update.sh v1.2.0
|
||||
```
|
||||
|
||||
或者让 `systemd` 定时器长期跟随 `stable` 分支。
|
||||
|
||||
更稳的做法是:
|
||||
|
||||
- `main` 用来持续迭代
|
||||
- `stable` 用来给其他机器自动更新
|
||||
- tag 用来留档和回滚
|
||||
|
||||
推荐的发布方式:
|
||||
|
||||
1. 日常修改提交到 `main`
|
||||
2. 测试机验证 `main`
|
||||
3. 验证通过后,把 `main` 合并到 `stable`
|
||||
4. 其他机器的 `systemd timer` 自动执行 `./update.sh stable`
|
||||
|
||||
## 排除规则
|
||||
|
||||
脚本会同时读取两个排除文件:
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Update backup_OBS scripts from Git
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=__RUN_USER__
|
||||
WorkingDirectory=__WORKDIR__
|
||||
ExecStart=__WORKDIR__/update.sh stable
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run backup_OBS updater periodically
|
||||
|
||||
[Timer]
|
||||
OnBootSec=10m
|
||||
OnUnitActiveSec=1h
|
||||
Persistent=true
|
||||
Unit=backup-obs-update.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}"
|
||||
SCRIPT_DIR="$(cd "$(dirname -- "$SCRIPT_PATH")" && pwd -P)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
用法:
|
||||
./update.sh [branch-or-tag]
|
||||
|
||||
说明:
|
||||
- 不带参数时,默认更新 stable 分支
|
||||
- 带参数时,可以切换到指定分支或 tag
|
||||
- 更新后会自动执行一次 ./backup.sh --dry-run 自检
|
||||
USAGE
|
||||
}
|
||||
|
||||
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "缺少命令:$1" >&2
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
need_cmd git
|
||||
need_cmd bash
|
||||
|
||||
TARGET_REF="${1:-}"
|
||||
if [[ -z "$TARGET_REF" ]]; then
|
||||
TARGET_REF="stable"
|
||||
fi
|
||||
|
||||
git fetch --tags origin
|
||||
|
||||
if git show-ref --verify --quiet "refs/tags/${TARGET_REF}"; then
|
||||
git checkout "${TARGET_REF}"
|
||||
else
|
||||
git checkout "${TARGET_REF}"
|
||||
git pull --ff-only origin "${TARGET_REF}"
|
||||
fi
|
||||
|
||||
chmod 755 \
|
||||
"${SCRIPT_DIR}/backup.sh" \
|
||||
"${SCRIPT_DIR}/clean_backups.sh" \
|
||||
"${SCRIPT_DIR}/lib/telegram.sh" \
|
||||
"${SCRIPT_DIR}/install.sh" \
|
||||
"${SCRIPT_DIR}/update.sh"
|
||||
|
||||
bash "${SCRIPT_DIR}/backup.sh" --dry-run
|
||||
Reference in New Issue
Block a user