Files
Deploy-Laboratory/scripts/verify.sh
2026-03-27 16:58:41 +08:00

272 lines
9.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 验证入口(以 ansible/playbooks/verify/<doc_id>.yml 为唯一执行真源):
# - run <XX-YY>:执行单篇验证 playbook
# - run-all按 verify 目录中存在的 <doc_id>.yml 顺序执行仅执行域XX>0 && YY>0
# - fullpreflight + run-all
#
# 说明:
# - 本脚本不再解析任何“矩阵/状态板”文档;验证清单从 verify playbook 自动得出。
# - 步骤 13接入、环境/轻量清理、部署)由操作者或 scripts/deploy-lab.sh 完成;本脚本不执行 k3s-uninstall。
# - 推荐在 Linux 工作机或控制节点仓库根执行。
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck disable=SC1091
source "${ROOT}/scripts/lib-ansible-lab.sh"
ansible_lab_export_config
# 默认与 §2 一致:验证后清理临时资源
export VERIFY_TEARDOWN="${VERIFY_TEARDOWN:-1}"
load_env() {
if [[ -f "${ROOT}/scripts/.env.verify" ]]; then
set -a
# shellcheck disable=SC1091
source "${ROOT}/scripts/.env.verify"
set +a
echo "[OK] 已加载 scripts/.env.verify"
fi
export VERIFY_TEARDOWN="${VERIFY_TEARDOWN:-1}"
}
DOC_ID_EXEC_RE='^(0[1-9]|[1-9][0-9])-(0[1-9]|[1-9][0-9])$'
is_exec_doc_id() {
local doc_id="$1"
[[ "$doc_id" =~ $DOC_ID_EXEC_RE ]]
}
list_doc_ids_from_verify_dir() {
# 只列出执行域XX>0 && YY>0的 verify 清单;支持筛选
local series="${1:-}"
local id_regex="${2:-}"
local exclude_noop="${3:-0}"
local require_teardown="${4:-0}"
ROOT="${ROOT}" SERIES="${series}" ID_REGEX="${id_regex}" EXCLUDE_NOOP="${exclude_noop}" REQUIRE_TEARDOWN="${require_teardown}" python3 - <<'PY'
import os
import re
from pathlib import Path
root = Path(os.environ["ROOT"])
verify_dir = root / "ansible" / "playbooks" / "verify"
series = os.environ.get("SERIES", "").strip()
id_regex = os.environ.get("ID_REGEX", "").strip()
exclude_noop = os.environ.get("EXCLUDE_NOOP", "0") == "1"
require_teardown = os.environ.get("REQUIRE_TEARDOWN", "0") == "1"
pat = re.compile(r"^(?P<id>(0[1-9]|[1-9][0-9])-(0[1-9]|[1-9][0-9]))\.yml$")
id_pat = re.compile(id_regex) if id_regex else None
ids = []
for p in verify_dir.iterdir():
m = pat.match(p.name)
if not m:
continue
doc_id = m.group("id")
if series and not doc_id.startswith(f"{series}-"):
continue
if id_pat and not id_pat.search(doc_id):
continue
if exclude_noop or require_teardown:
content = p.read_text(encoding="utf-8", errors="ignore")
if exclude_noop and "noop verify" in content:
continue
if require_teardown and ("VERIFY_TEARDOWN" not in content and "verify_teardown" not in content):
continue
ids.append(doc_id)
for x in sorted(set(ids)):
print(x)
PY
}
print_flow() {
cat <<EOF
与 docs/00-04-待验证项-验证前准备.md / docs/00-03-测试与验证框架.md 的「验证流程」对应:
1 接入目标环境 inventory + 仓库同步;可选 source scripts/.env.verify本脚本 run/run-all 会自动加载)
2 环境与前置清理 轻量:各 verify playbook 的 teardown重度 k3s 重装勿混进 run-all
3 部署 ./scripts/deploy-lab.sh k3s | longhorn | nginx-matrix* 或手工 ansible-playbook
4 断言 本脚本 run <XX-YY> / run-all → ansible/playbooks/verify/<doc_id>.yml
5 收尾与记录 VERIFY_TEARDOWN验证结论建议写回对应实验篇文档或单独记录日志
6 一键串联 $0 full推荐或 $0 run-all
相关脚本deploy-lab.sh安装/铺栈)
EOF
}
run_preflight() {
local inv="${ANSIBLE_INVENTORY:-${ROOT}/ansible/inventory.ini}"
if ! command -v ansible-playbook >/dev/null 2>&1; then
echo "[ERR] 未找到 ansible-playbook" >&2
exit 1
fi
[[ -f "$inv" ]] || { echo "[ERR] inventory 不存在:$inv" >&2; exit 1; }
ansible_lab_check_inventory_keys "$inv" || exit 1
echo "[RUN] ansible k3s_server -m ping"
ansible k3s_server -i "$inv" -m ping
if [[ "${VERIFY_PREFLIGHT_CLUSTER:-0}" == "1" ]]; then
echo "[RUN] kubectl get nodes控制节点需已安装 K3s"
ansible k3s_server -i "$inv" -b -m ansible.builtin.shell -a \
'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get nodes' \
|| {
echo "[WARN] 集群侧检查失败:若尚未 deploy k3s可忽略装好后设 VERIFY_PREFLIGHT_CLUSTER=1 再测" >&2
exit 1
}
else
echo "[TIP] 跳过 kubectl 检查。已装 K3s 时可执行VERIFY_PREFLIGHT_CLUSTER=1 $0 preflight"
fi
echo "[OK] preflight 通过"
}
run_all_verify() {
local series="${1:-}"
local id_regex="${2:-}"
local exclude_noop="${3:-0}"
local require_teardown="${4:-0}"
local id
while IFS= read -r id; do
echo ""
echo "########################################## $id"
ansible_verify "$id"
done < <(list_doc_ids_from_verify_dir "$series" "$id_regex" "$exclude_noop" "$require_teardown")
}
usage() {
cat <<'EOF'
用法scripts/verify.sh <命令> [...]
命令:
flow 打印与 docs/00-05 §2 对齐的「验证流程」说明(不接 Ansible
preflight 检查 ansible-playbook 与 inventory对 k3s_server 做 ping
若 VERIFY_PREFLIGHT_CLUSTER=1额外 kubectl get nodes未装集群会失败
full 先 preflight再按 doc_id 顺序运行全部 verify= preflight + run-all推荐
list [筛选参数] 列出可执行 doc_id仅执行域
run <XX-YY> 运行指定 doc_idansible/playbooks/verify/<doc_id>.yml
run-all [筛选参数] 按 doc_id 顺序运行 verify playbookfail-fast不做 preflight
筛选参数(可用于 list / run-all / full
--series <XX> 只运行某个主序列(例如 04
--id-regex <regex> 仅保留匹配 doc_id 的条目(例如 '^04-(0[2-9]|1[0-4])$'
--exclude-noop 排除 noop verify
--require-teardown 仅保留包含 teardown gate 的条目
环境变量:
VERIFY_TEARDOWN=1 验证后清理本篇资源(默认 1对应 §2 轻量 teardown
VERIFY_PREFLIGHT_CLUSTER 为 1 时 preflight 额外执行 kubectl get nodes
ANSIBLE_INVENTORY 默认 <仓库>/ansible/inventory.ini其中 ansible_ssh_private_key_file 须在本机存在)
nginx_entry_base 例如 http://192.168.2.6102-xx / 03-02 等 HTTP 校验)
nodejs_entry_base 例如 http://192.168.2.6104-01
SKIP_ARMV7 默认 1为 0 时 01-03/01-05 若未配 ARMV7_SSH01-05 可用 ARMV7_NFS_SSH会失败
ARMV7_SSH / ARMV7_NFS_SSH 一行 ssh 命令;与 SKIP_ARMV7=0 配合时 01-03/01-05 经 SSH 在 arm 上 dnf 安装(见 docs/00-07 §E
与「部署」分工:安装 K3s / Longhorn / nginx 铺栈请用 ./scripts/deploy-lab.sh验收请用本脚本。
示例:
./scripts/verify.sh flow
./scripts/verify.sh full
./scripts/verify.sh preflight
export nginx_entry_base=http://192.168.2.61
./scripts/verify.sh run 02-05
EOF
}
ansible_verify() {
local doc_id="$1"
if ! is_exec_doc_id "$doc_id"; then
echo "[ERR] 非执行域 doc_id$doc_id(仅允许 XX>0 且 YY>0" >&2
exit 1
fi
local inv="${ANSIBLE_INVENTORY:-${ROOT}/ansible/inventory.ini}"
local pb_single="${ROOT}/ansible/playbooks/verify/${doc_id}.yml"
if [[ ! -f "$pb_single" ]]; then
echo "[ERR] verify playbook 不存在:$pb_single" >&2
echo "[TIP] 可用 '$0 list' 查看可执行 doc_id" >&2
exit 1
fi
if [[ ! -f "$inv" ]]; then
echo "[ERR] inventory 不存在:$inv" >&2
exit 1
fi
local td="${VERIFY_TEARDOWN:-1}"
echo "[RUN] ansible-playbook -i $inv -e VERIFY_TEARDOWN=$td $pb_single"
ansible-playbook -i "$inv" -e "VERIFY_TEARDOWN=$td" "$pb_single"
}
main() {
load_env
local cmd="${1:-}"
shift || true
local series=""
local id_regex=""
local exclude_noop=0
local require_teardown=0
parse_filter_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--series)
series="${2:-}"
[[ -n "$series" ]] || { echo "[ERR] --series 需要参数" >&2; exit 1; }
[[ "$series" =~ ^(0[1-9]|[1-9][0-9])$ ]] || { echo "[ERR] --series 仅允许 01..99" >&2; exit 1; }
shift 2
;;
--id-regex)
id_regex="${2:-}"
[[ -n "$id_regex" ]] || { echo "[ERR] --id-regex 需要参数" >&2; exit 1; }
shift 2
;;
--exclude-noop)
exclude_noop=1
shift
;;
--require-teardown)
require_teardown=1
shift
;;
*)
echo "[ERR] 未知参数:$1" >&2
exit 1
;;
esac
done
}
case "$cmd" in
""|-h|--help) usage ;;
flow) print_flow ;;
preflight) run_preflight ;;
full)
parse_filter_args "$@"
run_preflight
echo ""
echo "########################################## run-all"
run_all_verify "$series" "$id_regex" "$exclude_noop" "$require_teardown"
;;
list)
parse_filter_args "$@"
list_doc_ids_from_verify_dir "$series" "$id_regex" "$exclude_noop" "$require_teardown"
;;
run)
local doc_id="${1:?need doc_id like 02-05}"
ansible_verify "$doc_id"
;;
run-all)
parse_filter_args "$@"
run_all_verify "$series" "$id_regex" "$exclude_noop" "$require_teardown"
;;
*)
echo "[ERR] unknown cmd: $cmd" >&2
usage
exit 1
;;
esac
}
main "$@"