#!/usr/bin/env bash # 部署环境体检脚本 - 判断阶段 0-1 是否已完成 # # 用法:bash check-prereqs.sh # # 退出码:0 = 全部 OK;1 = 有必须修复的项目(MISS) # 不开启 set -e:需要继续检查所有项目 B='\033[34m'; G='\033[32m'; Y='\033[33m'; R='\033[31m'; N='\033[0m' OK_COUNT=0 WARN_COUNT=0 MISS_COUNT=0 FIX_CMDS=() ok() { echo -e "${G}[OK]${N} $1"; OK_COUNT=$((OK_COUNT+1)); } warn() { echo -e "${Y}[WARN]${N} $1"; WARN_COUNT=$((WARN_COUNT+1)); [ -n "${2:-}" ] && { echo " 修复: $2"; FIX_CMDS+=("$2"); }; } miss() { echo -e "${R}[MISS]${N} $1"; MISS_COUNT=$((MISS_COUNT+1)); [ -n "${2:-}" ] && { echo " 修复: $2"; FIX_CMDS+=("$2"); }; } echo -e "${B}=== datahub 部署环境体检 ===${N}" echo "用户: $USER ($(id -u))" echo "主机: $(hostname)" echo "OS: $(. /etc/os-release 2>/dev/null && echo "$PRETTY_NAME" || echo unknown)" echo # ---------- 1. 必需的可执行程序 ---------- # podman + 版本 if command -v podman >/dev/null 2>&1; then VER=$(podman --version | awk '{print $3}') MAJOR=$(echo "$VER" | cut -d. -f1) MINOR=$(echo "$VER" | cut -d. -f2) if [[ "$MAJOR" =~ ^[0-9]+$ ]] && { (( MAJOR > 4 )) || { (( MAJOR == 4 )) && (( MINOR >= 4 )); }; }; then ok "podman v$VER (≥ 4.4 支持 Quadlet)" else miss "podman v$VER 版本过旧(需 ≥ 4.4)" "升级 podman 到 4.4+(Ubuntu 22.04 用 22.10 PPA,或装 podman-stable)" fi else miss "podman 未安装" "sudo apt install -y podman" fi # systemctl command -v systemctl >/dev/null 2>&1 \ && ok "systemctl 可用" \ || miss "systemctl 不可用(非 systemd 系统?)" # systemctl --user 是否可用(rootless 关键) if systemctl --user list-units >/dev/null 2>&1; then ok "systemctl --user 可用(rootless 必需)" else miss "systemctl --user 不可用" "确保用 SSH 直连登录(非 sudo su 切来),并且 XDG_RUNTIME_DIR=/run/user/\$(id -u) 已设置" fi # uidmap command -v newuidmap >/dev/null 2>&1 \ && ok "uidmap (newuidmap) 已安装" \ || miss "uidmap 未安装(rootless 必需)" "sudo apt install -y uidmap" # slirp4netns command -v slirp4netns >/dev/null 2>&1 \ && ok "slirp4netns 已安装" \ || miss "slirp4netns 未安装" "sudo apt install -y slirp4netns" # fuse-overlayfs(推荐) command -v fuse-overlayfs >/dev/null 2>&1 \ && ok "fuse-overlayfs 已安装(rootless 存储驱动推荐)" \ || warn "fuse-overlayfs 未安装(不影响功能,但 rootless 性能更好)" "sudo apt install -y fuse-overlayfs" # git command -v git >/dev/null 2>&1 \ && ok "git $(git --version | awk '{print $3}')" \ || miss "git 未安装" "sudo apt install -y git" # ---------- 2. rootless 用户配置 ---------- # subuid if grep -q "^${USER}:" /etc/subuid 2>/dev/null; then ok "/etc/subuid: $(grep "^${USER}:" /etc/subuid)" else miss "/etc/subuid 缺少 $USER 映射" "sudo usermod --add-subuids 100000-165535 $USER" fi # subgid if grep -q "^${USER}:" /etc/subgid 2>/dev/null; then ok "/etc/subgid: $(grep "^${USER}:" /etc/subgid)" else miss "/etc/subgid 缺少 $USER 映射" "sudo usermod --add-subgids 100000-165535 $USER" fi # lingering if loginctl show-user "$USER" 2>/dev/null | grep -q "Linger=yes"; then ok "lingering 已启用(登出 / 重启后服务依然运行)" else warn "lingering 未启用(用户登出后服务停 + 开机不自启)" "sudo loginctl enable-linger $USER" fi # ---------- 3. 数据目录可达性 ---------- if [ -d /var/container/data/datahub ]; then if [ -w /var/container/data/datahub ]; then ok "/var/container/data/datahub 已存在且可写" else warn "/var/container/data/datahub 存在但当前用户不可写" "sudo chown $USER:$USER /var/container/data/datahub" fi else if sudo -n true 2>/dev/null; then ok "/var/container/data/datahub 不存在(setup-data-dirs.sh 会创建,sudo 免密可用)" else warn "/var/container/data/datahub 不存在(setup-data-dirs.sh 将提示输入 sudo 密码)" fi fi # ---------- 4. 网络端口(仅提示) ---------- for port in 8080 9501; do if ss -ltn 2>/dev/null | awk '{print $4}' | grep -qE ":${port}\$"; then warn "端口 $port 已被占用" "lsof -i :$port 查看占用进程" fi done # ---------- 汇总 ---------- echo echo "────────────────────────────────────" echo -e "结果: ${G}${OK_COUNT} OK${N} / ${Y}${WARN_COUNT} WARN${N} / ${R}${MISS_COUNT} MISS${N}" echo if (( MISS_COUNT > 0 )); then echo -e "${R}存在必须修复的项目${N},请按上面的'修复:'命令处理后重新运行本脚本。" if (( ${#FIX_CMDS[@]} > 0 )); then echo echo -e "${B}--- 一键复制修复命令 ---${N}" # 去重 printf '%s\n' "${FIX_CMDS[@]}" | awk '!seen[$0]++' echo -e "${B}--- end ---${N}" fi exit 1 fi if (( WARN_COUNT > 0 )); then echo -e "${Y}有警告项${N}(不阻止部署,建议处理)" echo "可执行 install.sh,但部分功能可能受限(例如 lingering 未启用 → 不自启)" exit 0 fi echo -e "${G}环境已就绪,可以执行:${N}" echo -e " ${B}bash deploy/podman/scripts/install.sh${N}" exit 0