编写脚本
This commit is contained in:
11
README.md
11
README.md
@@ -2,13 +2,22 @@
|
||||
|
||||
## 功能
|
||||
每天从https://git.ociflab.icu/Laplace/backup-list拉取whitelist.md
|
||||
如果没拉取到,则使用前一天拉取并保存的whitelist文件。
|
||||
如果超过三分之一的仓库都拉取错误,则给脚本中设置的server酱3 Pushkey推送警告信息。
|
||||
然后根据whitelist.md拉取对应的仓库到backup文件夹进行备份
|
||||
压缩成zip,每天定时备份一次,保留7天。
|
||||
使用Python。
|
||||
使用bash。
|
||||
|
||||
## whitelist.md文件结构:
|
||||
|
||||
~~~
|
||||
https://git.ociflab.icu/userA/projectA
|
||||
https://git.ociflab.icu/userB/projectB
|
||||
~~~
|
||||
|
||||
|
||||
## server酱3参考
|
||||
~~~bash
|
||||
# 一行代码即可调用,中文参数需要UrlEncode,长内容建议使用POST
|
||||
curl "https://<uid>.push.ft07.com/send/<sendkey>.send?title=<title>&desp=<desp>"
|
||||
~~~
|
||||
192
ociflab-backup.sh
Normal file
192
ociflab-backup.sh
Normal file
@@ -0,0 +1,192 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# ============================================================
|
||||
# OCIFLAB 仓库备份脚本
|
||||
# 每天从 whitelist.md 拉取仓库列表,克隆/更新仓库,压缩备份
|
||||
# ============================================================
|
||||
|
||||
# ---------- 配置区 ----------
|
||||
WHITELIST_URL=""
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BACKUP_DIR="${SCRIPT_DIR}/backup"
|
||||
WORK_DIR="${SCRIPT_DIR}/work"
|
||||
ARCHIVE_DIR="${SCRIPT_DIR}/archives"
|
||||
WHITELIST_CACHE="${SCRIPT_DIR}/whitelist_cache.md"
|
||||
RETENTION_DAYS=7
|
||||
DATE_STAMP="$(date +%Y%m%d)"
|
||||
|
||||
# server酱3 配置
|
||||
SERVERCHAN_UID="" # 填写你的 UID
|
||||
SERVERCHAN_SENDKEY="" # 填写你的 SendKey
|
||||
|
||||
# ---------- 函数区 ----------
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
|
||||
}
|
||||
|
||||
send_warning() {
|
||||
local title="$1"
|
||||
local desp="$2"
|
||||
if [[ -z "${SERVERCHAN_UID}" ]] || [[ -z "${SERVERCHAN_SENDKEY}" ]]; then
|
||||
log "server酱未配置,跳过推送: ${title}"
|
||||
return 0
|
||||
fi
|
||||
local resp
|
||||
resp=$(curl -s -o /dev/null -w "%{http_code}" --data-urlencode "title=${title}" --data-urlencode "desp=${desp}" "https://${SERVERCHAN_UID}.push.ft07.com/send/${SERVERCHAN_SENDKEY}.send")
|
||||
if [[ "${resp}" == "200" ]]; then
|
||||
log "警告推送成功: ${title}"
|
||||
else
|
||||
log "警告推送失败(HTTP ${resp}): ${title}"
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_whitelist() {
|
||||
log "正在拉取 whitelist.md ..."
|
||||
local http_code
|
||||
http_code=$(curl -s -o "${WHITELIST_CACHE}" -w "%{http_code}" --connect-timeout 10 --max-time 30 "${WHITELIST_URL}")
|
||||
|
||||
if [[ "${http_code}" == "200" ]] && [[ -s "${WHITELIST_CACHE}" ]]; then
|
||||
log "whitelist.md 拉取成功 (HTTP ${http_code})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "whitelist.md 拉取失败 (HTTP ${http_code}),尝试使用前一天缓存..."
|
||||
if [[ -f "${SCRIPT_DIR}/whitelist_cache.md.yesterday" ]]; then
|
||||
cp "${SCRIPT_DIR}/whitelist_cache.md.yesterday" "${WHITELIST_CACHE}"
|
||||
log "已使用前一天缓存"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "前一天缓存也不存在,无法继续"
|
||||
return 1
|
||||
}
|
||||
|
||||
parse_whitelist() {
|
||||
grep -Eo 'https://git\.ociflab\.icu/[^[:space:]]+' "${WHITELIST_CACHE}" | sed 's/[[:space:]]*$//'
|
||||
}
|
||||
|
||||
clone_or_pull_repo() {
|
||||
local repo_url="$1"
|
||||
local repo_name
|
||||
repo_name=$(echo "${repo_url}" | sed 's|https://git\.ociflab\.icu/||' | tr '/' '_')
|
||||
local repo_path="${WORK_DIR}/${repo_name}"
|
||||
|
||||
if [[ -d "${repo_path}/.git" ]]; then
|
||||
log " 更新: ${repo_url}"
|
||||
if ! git -C "${repo_path}" pull --ff-only 2>&1; then
|
||||
log " 更新失败: ${repo_url},尝试重新克隆..."
|
||||
rm -rf "${repo_path}"
|
||||
if ! git clone --depth 1 "${repo_url}" "${repo_path}" 2>&1; then
|
||||
log " 重新克隆也失败: ${repo_url}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log " 克隆: ${repo_url}"
|
||||
rm -rf "${repo_path}"
|
||||
if ! git clone --depth 1 "${repo_url}" "${repo_path}" 2>&1; then
|
||||
log " 克隆失败: ${repo_url}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
backup_repos() {
|
||||
local whitelist=("$@")
|
||||
local total=${#whitelist[@]}
|
||||
local failed=0
|
||||
local failed_list=""
|
||||
|
||||
log "共 ${total} 个仓库待备份"
|
||||
|
||||
for repo_url in "${whitelist[@]}"; do
|
||||
[[ -z "${repo_url}" ]] && continue
|
||||
if ! clone_or_pull_repo "${repo_url}"; then
|
||||
failed=$((failed + 1))
|
||||
failed_list="${failed_list}${repo_url}\n"
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查错误率:超过三分之一则发送警告
|
||||
if [[ ${total} -gt 0 ]]; then
|
||||
local threshold=$((total / 3))
|
||||
if [[ ${failed} -gt ${threshold} ]]; then
|
||||
local warn_desp="备份失败 ${failed}/${total} 个仓库,超过三分之一。\n失败列表:\n${failed_list}"
|
||||
send_warning "OCIFLAB备份异常 - ${failed}/${total} 仓库失败" "${warn_desp}"
|
||||
fi
|
||||
fi
|
||||
|
||||
log "备份完成: 成功 $((total - failed)) 个, 失败 ${failed} 个"
|
||||
}
|
||||
|
||||
create_archive() {
|
||||
log "正在压缩备份..."
|
||||
mkdir -p "${ARCHIVE_DIR}"
|
||||
|
||||
local archive_name="ociflab-backup-${DATE_STAMP}.zip"
|
||||
local archive_path="${ARCHIVE_DIR}/${archive_name}"
|
||||
|
||||
if [[ -d "${WORK_DIR}" ]] && [[ -n "$(ls -A "${WORK_DIR}" 2>/dev/null)" ]]; then
|
||||
cd "${WORK_DIR}"
|
||||
zip -r "${archive_path}" . -q
|
||||
cd "${SCRIPT_DIR}"
|
||||
log "压缩完成: ${archive_path}"
|
||||
else
|
||||
log "工作目录为空,跳过压缩"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_old_archives() {
|
||||
log "清理 ${RETENTION_DAYS} 天前的备份..."
|
||||
find "${ARCHIVE_DIR}" -name "ociflab-backup-*.zip" -type f -mtime +${RETENTION_DAYS} -delete 2>/dev/null || true
|
||||
log "清理完成"
|
||||
}
|
||||
|
||||
persist_yesterday_whitelist() {
|
||||
if [[ -f "${WHITELIST_CACHE}" ]]; then
|
||||
cp "${WHITELIST_CACHE}" "${SCRIPT_DIR}/whitelist_cache.md.yesterday"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------- 主流程 ----------
|
||||
|
||||
main() {
|
||||
log "========== OCIFLAB 备份开始 =========="
|
||||
|
||||
mkdir -p "${WORK_DIR}" "${ARCHIVE_DIR}"
|
||||
|
||||
# 1. 拉取白名单
|
||||
if ! fetch_whitelist; then
|
||||
log "无法获取白名单,退出"
|
||||
send_warning "OCIFLAB备份失败" "无法拉取 whitelist.md 且无前一天缓存"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 解析仓库列表
|
||||
mapfile -t repos < <(parse_whitelist)
|
||||
|
||||
if [[ ${#repos[@]} -eq 0 ]]; then
|
||||
log "白名单为空,退出"
|
||||
send_warning "OCIFLAB备份失败" "whitelist.md 中无有效仓库地址"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 克隆/更新仓库
|
||||
backup_repos "${repos[@]}"
|
||||
|
||||
# 4. 压缩归档
|
||||
create_archive
|
||||
|
||||
# 5. 清理旧备份
|
||||
cleanup_old_archives
|
||||
|
||||
# 6. 保存今天的白名单供明天备用
|
||||
persist_yesterday_whitelist
|
||||
|
||||
log "========== OCIFLAB 备份完成 =========="
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user