From 0ead3cf91e3c9ac3828dc4ec7b2bb7d719ddbd69 Mon Sep 17 00:00:00 2001 From: seaHi Date: Fri, 9 Oct 2026 14:50:40 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E8=8A=82=E7=82=B9=E8=87=AA=E6=B5=8B=E4=B8=8E=E8=AF=84?= =?UTF-8?q?=E5=88=86=E8=84=9A=E6=9C=AC=E7=9A=84=E6=8F=90=E7=A4=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3-5-controller.sh | 60 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/3-5-controller.sh b/3-5-controller.sh index d0b4e64..b072ecd 100755 --- a/3-5-controller.sh +++ b/3-5-controller.sh @@ -34,7 +34,7 @@ banner() { } section() { TASK_CNT=$((TASK_CNT+1)) - printf '%b[➜] %d. 检查任务:%s%b\n' "$BLUE" "$TASK_CNT" "$1" "$NC" + printf '%b[➜] %d. %s%b\n' "$BLUE" "$TASK_CNT" "$1" "$NC" } error() { printf '%b[✘ 失败] %s%b\n' "$RED" "$1" "$NC" @@ -47,28 +47,26 @@ check() { TOTAL=$((TOTAL+points)) if "$@" >/dev/null 2>&1; then SCORE=$((SCORE+points)); PASS_CNT=$((PASS_CNT+1)) - printf '%b[✔ 通过] %s(得 %d 分)%b\n' "$GREEN" "$success_message" "$points" "$NC" + printf '%b[✔ 通过] %s%b\n' "$GREEN" "$success_message" "$NC" else FAIL_CNT=$((FAIL_CNT+1)) - printf '%b[✘ 失败] %s(扣 %d 分)%b\n' "$RED" "$failure_message" "$points" "$NC" + printf '%b[✘ 失败] %s%b\n' "$RED" "$failure_message" "$NC" fi } finish() { printf '\n' separator - printf '实验自测检查完毕!通过项: %b%d%b,失败项: %b%d%b\n' "$GREEN" "$PASS_CNT" "$NC" "$RED" "$FAIL_CNT" "$NC" - printf '%b总成绩:%d/100 分%b\n' "$YELLOW" "$SCORE" "$NC" + printf '%b总成绩:%d/100 分%b | 通过: %b%d%b | 失败: %b%d%b\n' "$YELLOW" "$SCORE" "$NC" "$GREEN" "$PASS_CNT" "$NC" "$RED" "$FAIL_CNT" "$NC" if [ "$TOTAL" -ne 100 ]; then error "评分项总分异常:$TOTAL,请联系教师检查脚本。" separator exit 2 fi if [ "$FAIL_CNT" -eq 0 ]; then - printf '%b所有检查项均已通过,实验自测完成!%b\n' "$GREEN" "$NC" separator exit 0 fi - printf '%b你有 %d 处检查未通过,请根据上方红字提示核对实验步骤并修正!%b\n' "$RED" "$FAIL_CNT" "$NC" + printf '%b请按红字提示修正。%b\n' "$RED" "$NC" separator exit 1 } @@ -115,7 +113,7 @@ ini_value() { enabled_service() { [ "$(timeout 10 systemctl is-enabled "$1" 2>/dev/null)" = enabled ]; } active_service() { timeout 10 systemctl is-active --quiet "$1"; } -banner 'OpenStack 控制节点实验自测与自动化评分脚本' +banner 'OpenStack 控制节点评分' preflight # 自动检测失败(例如 hosts 冲突)仍继续评分,让解析项正常扣分。 CONTROLLER_IP=${CHECK_CONTROLLER_IP:-$(hosts_ip controller)} @@ -158,7 +156,7 @@ for row in rows: ' "$@" 2>/dev/null } -section '控制节点主机与网络(20分)' +section '主机与网络(20分)' hostname_ok() { [ "$(hostname)" = controller ] && [ "$(tr -d '[:space:]' < /etc/hostname)" = controller ]; } controller_mapping() { [ "$(hosts_ip controller)" = "$CONTROLLER_IP" ] && @@ -166,16 +164,16 @@ controller_mapping() { } compute_mapping() { valid_ipv4 "$COMPUTE_IP" && [ "$COMPUTE_IP" != "$CONTROLLER_IP" ] && [ "$(hosts_ip compute)" = "$COMPUTE_IP" ]; } both_resolve() { resolved_as controller "$CONTROLLER_IP" && resolved_as compute "$COMPUTE_IP"; } -check 4 '运行中及持久主机名均为 controller' '运行中及持久主机名都应为 controller' hostname_ok -check 4 'controller 的 hosts 映射唯一,且指向本机管理 IP' '/etc/hosts 中 controller 应唯一映射到本机管理 IP' controller_mapping -check 4 'compute 的 hosts 映射唯一,管理 IPv4 配置正确' '/etc/hosts 中 compute 应唯一映射到计算节点管理 IPv4' compute_mapping -check 4 'controller 和 compute 的系统解析与 hosts 配置一致' 'controller/compute 的系统解析应与 hosts 一致' both_resolve -check 4 '可通过主机名 ping 通 compute' '应能通过主机名 ping 通 compute' timeout 8 ping -4 -c 2 -W 2 compute +check 4 '主机名 controller' '主机名应为 controller' hostname_ok +check 4 'controller hosts 映射' 'controller hosts 应指向本机管理 IP' controller_mapping +check 4 'compute hosts 映射' 'compute hosts 映射缺失或冲突' compute_mapping +check 4 '主机名解析' '主机名解析与 hosts 不一致' both_resolve +check 4 'ping compute' 'ping compute 不通' timeout 8 ping -4 -c 2 -W 2 compute -section 'Keystone 管理员认证(10分)' +section '管理员认证(10分)' AUTH_OK=0 if os_cli token issue >/dev/null; then AUTH_OK=1; fi -check 10 'Keystone 管理员认证成功,可获取 Token' '管理员认证失败,检查 Keystone 或 CHECK_ADMIN_PASSWORD(默认 admin)' test "$AUTH_OK" -eq 1 +check 10 '管理员认证' '管理员认证失败,检查 Keystone 和密码' test "$AUTH_OK" -eq 1 # 只认完整 Host=compute 的行,避免 controller 上克隆遗留的 nova-compute 冒充。 # 使用 JSON 字段名,避免依赖表格边框或列位置。 @@ -194,12 +192,12 @@ compute_ready() { $1=="nova-compute" && $2=="compute" {n++; if($3=="enabled" && $4=="up")good++} END{exit !(n==1 && good==1)}' } -section '计算节点注册(10分)' -check 10 '计算服务已唯一注册,Host 为 compute,Binary 为 nova-compute' '应唯一注册 Host=compute 的 nova-compute(认证或服务列表查询失败也不得分)' compute_registered -section '计算节点可用状态(10分)' -check 10 'compute 的 nova-compute 状态为 enabled/up' 'compute 的 nova-compute 应为 enabled/up' compute_ready +section 'compute 注册(10分)' +check 10 'compute 服务注册' 'compute 未唯一注册或查询失败' compute_registered +section 'compute 状态(10分)' +check 10 'nova-compute enabled/up' 'nova-compute 未处于 enabled/up' compute_ready -section '所有计算服务状态(15分)' +section '服务状态(15分)' control_component() { [ "$SERVICES_OK" -eq 1 ] && printf '%s\n' "$SERVICES" | awk -v binary="$1" ' $1==binary && $2=="controller" {n++; if($3=="enabled" && $4=="up")good++} @@ -210,11 +208,11 @@ all_services_up() { NF {n++; if(NF!=4 || $3!="enabled" || $4!="up")bad=1} END{exit !(n>0 && !bad)}' } -check 5 'controller 的 nova-scheduler 已注册,且全部为 enabled/up' 'controller 的 nova-scheduler 应存在且全部为 enabled/up' control_component nova-scheduler -check 5 'controller 的 nova-conductor 已注册,且全部为 enabled/up' 'controller 的 nova-conductor 应存在且全部为 enabled/up' control_component nova-conductor -check 5 '计算服务列表查询成功,所有服务均为 enabled/up' '计算服务列表不能为空,且所有列出的服务应为 enabled/up' all_services_up +check 5 'nova-scheduler enabled/up' 'nova-scheduler 缺失或未处于 enabled/up' control_component nova-scheduler +check 5 'nova-conductor enabled/up' 'nova-conductor 缺失或未处于 enabled/up' control_component nova-conductor +check 5 '全部计算服务 enabled/up' '服务列表为空、查询失败或有异常服务' all_services_up -section '计算节点 Cell 数据库映射(15分)' +section 'Cell 映射(15分)' # discover_hosts 会写数据库,评分时仅查询 host_mappings,避免替学生完成实验。 cell_mapping() { local result @@ -225,9 +223,9 @@ cell_mapping() { /^[0-9a-fA-F-]+$/ && length($0)==36 && $0!="00000000-0000-0000-0000-000000000000" {good++} END{exit !(NR==1 && good==1)}' } -check 15 'compute 已唯一映射到有效的非 cell0 Cell' 'compute 未唯一映射到有效的非 cell0 Cell,或 nova_api 数据库查询失败;检查 discover_hosts 结果及 nova 账号' cell_mapping +check 15 'compute Cell 映射' 'Cell 映射异常,检查数据库和 discover_hosts' cell_mapping -section 'Keystone 服务目录和 API 端点(10分)' +section '服务目录(10分)' CATALOG_OK=0 if [ "$AUTH_OK" -eq 1 ] && os_cli catalog list >/dev/null; then CATALOG_OK=1; fi catalog_endpoints() { @@ -243,10 +241,10 @@ catalog_endpoints() { } END{exit !(seen["public"] && seen["internal"] && seen["admin"])}' } -check 5 '服务目录可查询,compute 的三个 RegionOne API 端点均配置正确' '服务目录查询失败,或 compute 在 RegionOne 的 public/internal/admin 端点不完整或 URL 错误' catalog_endpoints compute 8774 -check 5 '服务目录可查询,placement 的三个 RegionOne API 端点均配置正确' '服务目录查询失败,或 placement 在 RegionOne 的 public/internal/admin 端点不完整或 URL 错误' catalog_endpoints placement 8778 +check 5 'compute 服务目录与端点' 'compute 服务目录或端点异常' catalog_endpoints compute 8774 +check 5 'placement 服务目录与端点' 'placement 服务目录或端点异常' catalog_endpoints placement 8778 -section 'Nova 整体检查(10分)' +section '部署检查(10分)' # Rocky 返回码:0=全部成功,1=警告,2=失败;仅 0 得分,命令缺失/超时也失败。 -check 10 'nova-status upgrade check 的所有检查项均成功' 'nova-status upgrade check 未全部成功(警告也扣分),请手工运行查看详细结果' timeout 40 su -s /bin/sh -c 'nova-status upgrade check' nova +check 10 'nova-status upgrade check' 'nova-status 检查未全部成功' timeout 40 su -s /bin/sh -c 'nova-status upgrade check' nova finish