自动保活 SAP #308
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |