Skip to content

自动保活 SAP

自动保活 SAP #289

name: 自动保活 SAP
on:
schedule:
- cron: '45 23 * * *'
workflow_dispatch: # 允许手动触发
jobs:
restart-sg-apps:
runs-on: ubuntu-latest
name: 重启新加坡(SG)区域应用
if: always()
continue-on-error: true
timeout-minutes: 120
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 安装 CF CLI
run: |
wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install -y cf8-cli
- name: 设置 SG 区域 API 端点
run: |
echo "CF_API=https://api.cf.ap21.hana.ondemand.com" >> $GITHUB_ENV
echo "使用API端点: $CF_API (区域: SG)"
- name: 登录并自动检测组织和空间
run: |
cf login -a ${{ env.CF_API }} -u "${{ secrets.EMAIL }}" -p "${{ secrets.PASSWORD }}"
echo "自动检测SG区域可用的组织和空间..."
SELECTED_ORG=$(cf orgs | grep -v "^name$" | grep -v "^Getting orgs" | grep -v "^$" | head -n 1 | awk '{print $1}')
if [ -z "$SELECTED_ORG" ]; then echo "错误: 未找到可用的组织"; exit 1; fi
cf target -o "$SELECTED_ORG"
SELECTED_SPACE=$(cf spaces | grep -v "^name$" | grep -v "^Getting spaces" | grep -v "^$" | head -n 1 | awk '{print $1}')
if [ -z "$SELECTED_SPACE" ]; then echo "错误: 未找到可用的空间"; exit 1; fi
cf target -s "$SELECTED_SPACE"
echo "当前SG区域目标:"
cf target
- name: '[仅定时任务] 等待 UTC 00:00 开始任务'
if: github.event_name == 'schedule'
run: |
echo "等待 UTC 时间到达 00:00 以开始重启流程..."
target_time="00:00"
deadline_time="01:00"
while true; do
date_header=$(curl -sI https://www.ntp.org/ | grep -i '^date:')
if [ -z "$date_header" ]; then
echo "无法获取 ntp.org 时间,15秒后重试..."
sleep 15
continue
fi
current_time=$(echo "$date_header" | awk '{print $6}' | cut -c 1-5)
current_hour=$(echo "$current_time" | cut -c 1-2)
if [[ "$current_hour" == "23" ]]; then
echo "等待午夜... 当前 UTC 时间: $current_time"
sleep 60
continue
fi
if [[ "$current_time" > "$deadline_time" ]]; then
echo "错误:已超过安全时间窗口 ($deadline_time UTC)。"
exit 1
fi
if [[ "$current_time" > "$target_time" || "$current_time" == "$target_time" ]]; then
echo "时间到达或超过 00:00 UTC (北京时间 08:00),开始执行重启任务。"
break
fi
echo "时间未到 (当前 $current_time),将在 1 分钟后再次检查..."
sleep 60
done
- name: 等待应用自行停止后,再尝试启动(直至成功)
run: |
apps=$(cf apps | awk 'NR>3 {print $1}' | grep -v '^$')
if [ -z "$apps" ]; then
echo "在SG区域中未发现任何应用,无需操作。"
exit 0
fi
echo "发现应用列表:"
echo "$apps"
for app in $apps; do
echo "----------------------------------------"
echo "开始处理应用: $app"
# 步骤 1: 等待应用自行停止
echo "等待应用 $app 自行停止..."
wait_timeout=3600 # 1小时的等待超时
elapsed=0
is_stopped=false
while [[ $elapsed -lt $wait_timeout ]]; do
if [[ "$(cf app "$app" | grep 'requested state:' | awk '{print $3}')" != "started" ]]; then
echo "应用 $app 已确认停止。"
is_stopped=true
break
fi
echo "应用 $app 仍在运行,15秒后再次检查..."
sleep 15
elapsed=$((elapsed + 15))
done
if [[ "$is_stopped" == "false" ]]; then
echo "错误: 等待应用 $app 自行停止超时 (1小时)。跳过此应用。"
continue
fi
# 步骤 2: 无限次尝试启动应用,直到成功
echo "开始启动应用: $app"
attempt=1
while true; do
echo "正在进行第 $attempt 次启动尝试..."
if cf start "$app"; then
echo "应用 $app 成功启动。"
break # 成功则跳出循环
else
echo "启动失败。将在 1 分钟后重试..."
sleep 60
fi
((attempt++))
done
# 步骤 3: 输出应用URL
app_url=$(cf app "$app" | grep "urls:" | awk '{print $2}')
if [ -n "$app_url" ]; then
echo "应用 $app 的访问地址是: $app_url"
fi
done
echo "----------------------------------------"
echo "成功: SG区域所有应用均已处理完毕。"
- name: 验证最终应用状态
run: |
echo "验证SG区域最终应用状态..."
cf apps
restart-us-apps:
runs-on: ubuntu-latest
name: 重启美国(US)区域应用
if: always()
continue-on-error: true
timeout-minutes: 120 #
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 安装 CF CLI
run: |
wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -
echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install -y cf8-cli
- name: 设置 US 区域 API 端点
run: |
echo "CF_API=https://api.cf.us10-001.hana.ondemand.com" >> $GITHUB_ENV
echo "使用API端点: $CF_API (区域: US)"
- name: 登录并自动检测组织和空间
run: |
cf login -a ${{ env.CF_API }} -u "${{ secrets.EMAIL }}" -p "${{ secrets.PASSWORD }}"
echo "自动检测US区域可用的组织和空间..."
SELECTED_ORG=$(cf orgs | grep -v "^name$" | grep -v "^Getting orgs" | grep -v "^$" | head -n 1 | awk '{print $1}')
if [ -z "$SELECTED_ORG" ]; then echo "错误: 未找到可用的组织"; exit 1; fi
cf target -o "$SELECTED_ORG"
SELECTED_SPACE=$(cf spaces | grep -v "^name$" | grep -v "^Getting spaces" | grep -v "^$" | head -n 1 | awk '{print $1}')
if [ -z "$SELECTED_SPACE" ]; then echo "错误: 未找到可用的空间"; exit 1; fi
cf target -s "$SELECTED_SPACE"
echo "当前US区域目标:"
cf target
- name: '[仅定时任务] 等待 UTC 00:00 开始任务'
if: github.event_name == 'schedule'
run: |
echo "等待 UTC 时间到达 00:00 以开始重启流程..."
target_time="00:00"
deadline_time="01:00"
while true; do
date_header=$(curl -sI https://www.ntp.org/ | grep -i '^date:')
if [ -z "$date_header" ]; then
echo "无法获取 ntp.org 时间,15秒后重试..."
sleep 15
continue
fi
current_time=$(echo "$date_header" | awk '{print $6}' | cut -c 1-5)
current_hour=$(echo "$current_time" | cut -c 1-2)
if [[ "$current_hour" == "23" ]]; then
echo "等待午夜... 当前 UTC 时间: $current_time"
sleep 60
continue
fi
if [[ "$current_time" > "$deadline_time" ]]; then
echo "错误:已超过安全时间窗口 ($deadline_time UTC)。"
exit 1
fi
if [[ "$current_time" > "$target_time" || "$current_time" == "$target_time" ]]; then
echo "时间到达或超过 00:00 UTC (北京时间 08:00),开始执行重启任务。"
break
fi
echo "时间未到 (当前 $current_time),将在 1 分钟后再次检查..."
sleep 60
done
- name: 等待应用自行停止后,再尝试启动(直至成功)
run: |
apps=$(cf apps | awk 'NR>3 {print $1}' | grep -v '^$')
if [ -z "$apps" ]; then
echo "在US区域中未发现任何应用,无需操作。"
exit 0
fi
echo "发现应用列表:"
echo "$apps"
for app in $apps; do
echo "----------------------------------------"
echo "开始处理应用: $app"
echo "等待应用 $app 自行停止..."
wait_timeout=3600 # 1小时的等待超时
elapsed=0
is_stopped=false
while [[ $elapsed -lt $wait_timeout ]]; do
if [[ "$(cf app "$app" | grep 'requested state:' | awk '{print $3}')" != "started" ]]; then
echo "应用 $app 已确认停止。"
is_stopped=true
break
fi
echo "应用 $app 仍在运行,15秒后再次检查..."
sleep 15
elapsed=$((elapsed + 15))
done
if [[ "$is_stopped" == "false" ]]; then
echo "错误: 等待应用 $app 自行停止超时 (1小时)。跳过此应用。"
continue
fi
echo "开始启动应用: $app"
attempt=1
while true; do
echo "正在进行第 $attempt 次启动尝试..."
if cf start "$app"; then
echo "应用 $app 成功启动。"
break
else
echo "启动失败。将在 1 分钟后重试..."
sleep 60
fi
((attempt++))
done
# 步骤 3: 输出应用URL
app_url=$(cf app "$app" | grep "urls:" | awk '{print $2}')
if [ -n "$app_url" ]; then
echo "应用 $app 的访问地址是: $app_url"
fi
done
echo "----------------------------------------"
echo "成功: US区域所有应用均已处理完毕。"
- name: 验证最终应用状态
run: |
echo "验证US区域最终应用状态..."
cf apps