safesight/scripts/prepare-image.sh
tian 227dc04004 feat(edge): 断电保护(overlayroot+/data)与产品镜像批量生产流程
- 新增 setup-overlayroot.sh: 一键断电保护
  - overlayroot(tmpfs) 保护根分区, 断电不再损坏文件系统
  - 自动建 /data 独立分区 + fstab bind 挂载运行数据
  - 迁移存量数据, journald 内存日志限容
  - disable/enable 一键切换维护模式(适配香橙派 U-Boot/extlinux, 无 GRUB)
- 新增 prepare-image.sh: 母卡出厂化清理
  - 清 machine-id/SSH 密钥/device_id/hostname/日志
  - 防误: 检测 overlayroot 启用状态, 保证镜像为可写出厂状态
- 新增 init-device.sh: 每台初始化
  - 主机名/静态IP(netplan)/身份验证
  - /data 自动 growpart 扩容到整卡剩余空间(64G 产品卡)
  - 统一启用断电保护
- deploy.sh/ops.sh/package-offline.sh: 集成新脚本
  - ops.sh 新增 overlay-status/disable/enable/verify
- docs/deployment.md: 重写为主流程文档
  - 产品镜像批量生产(16G 母卡->小镜像->Etcher 批量烧录->每台初始化)
  - 移除废弃的克隆卡流程
2026-08-01 16:45:47 +08:00

139 lines
7.1 KiB
Bash
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.

#!/bin/bash
# =============================================================================
# prepare-image.sh — 产品镜像出厂化清理(母卡制作镜像前运行)
# -----------------------------------------------------------------------------
# 用法母卡上root:
# sudo ./prepare-image.sh 出厂化清理
# sudo ./prepare-image.sh --zero 额外清零空闲空间(压缩镜像体积,较慢)
#
# 作用:把"部署完成、验证通过"的母卡变成干净的出厂状态:
# - 清除设备个体身份machine-id / SSH 密钥 / device_id / hostname
# - 清空 /data 与运行时数据(日志/告警/HLS保留分区与 fstab
# - 保留:已部署的 safesight、已装的依赖、overlayroot 配置能力(出厂即带断电保护)
#
# 重要:本脚本后【不要】启用 overlayrootsetup-overlayroot.sh enable
# 保持"可写出厂状态"overlayroot 留到每台设备初始化最后一步启用。
# 否则 /etc/machine-id 无法固化,每台重启后设备 ID 漂移。
# =============================================================================
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}${NC} $*"; }
warn() { echo -e "${YELLOW}${NC} $*"; }
die() { echo -e "${RED}${NC} $*" >&2; exit 1; }
ZERO=0
for arg in "$@"; do
case "$arg" in
--zero) ZERO=1 ;;
*) warn "未知参数: $arg" ;;
esac
done
[ "$(id -u)" -eq 0 ] || die "请使用 sudo 运行"
RUNTIME_ROOT="/var/lib/safesight-edge-server"
AGENT_LIB="/var/lib/safesight-edge-agent"
DATA_MOUNT="/data"
OVERLAY_CONF="/etc/overlayroot.conf"
# ---------------------------------------------------------------------------
# 安全检查
# ---------------------------------------------------------------------------
if grep -qs 'overlay' /proc/mounts; then
die "当前处于 overlayroot 保护模式请先进入维护模式setup-overlayroot.sh disable + 重启)再运行。"
fi
if grep -qE '^overlayroot="[^"]+"' "$OVERLAY_CONF" 2>/dev/null; then
die "检测到 $OVERLAY_CONF 已启用 overlayroot保护模式配置。出厂镜像必须保持可写状态\n 请先运行 setup-overlayroot.sh disable设置 overlayroot=\"\")后再执行出厂化。"
fi
echo -e "${YELLOW}════════════════════════════════════════════════════════════════${NC}"
echo -e "${YELLOW} 即将把母卡重置为出厂状态,此操作不可恢复!${NC}"
echo -e "${YELLOW}════════════════════════════════════════════════════════════════${NC}"
echo ""
echo "将清除:"
echo " - /etc/machine-id、SSH 主机密钥、hostname、device_id首次启动自动重建"
echo " - /data 与 /var/lib/safesight-edge-server 下所有日志/告警/HLS 数据"
echo ""
echo "将保留:"
echo " - safesight 程序与配置模板、全部依赖、/data 分区与 fstab断电保护能力"
echo ""
read -r -p "继续? [y/N]: " yn
[ "${yn:-n}" = "y" ] || [ "${yn:-n}" = "Y" ] || die "已取消"
# ---------------------------------------------------------------------------
# 1. 停止服务
# ---------------------------------------------------------------------------
info "停止服务 ..."
systemctl stop safesight-edge-server safesight-edge-agent 2>/dev/null || true
ok "服务已停止"
# ---------------------------------------------------------------------------
# 2. 清空数据(保留目录结构)
# ---------------------------------------------------------------------------
info "清空运行数据 ..."
for d in hls logs alarms clips; do
rm -rf "$RUNTIME_ROOT/$d"/*
rm -rf "$DATA_MOUNT/safesight/$d"/* 2>/dev/null || true
done
rm -rf "$AGENT_LIB"/* /data/safesight/agent/* 2>/dev/null || true
[ -f "$AGENT_LIB/device_id" ] && rm -f "$AGENT_LIB/device_id"
ok "运行数据已清空(目录保留)"
# ---------------------------------------------------------------------------
# 3. 设备身份重置(首次启动自动重建)
# ---------------------------------------------------------------------------
info "重置设备身份 ..."
rm -f /etc/machine-id /var/lib/dbus/machine-id
rm -f /etc/ssh/ssh_host_*_key* /etc/ssh/ssh_host_*_key*.pub
rm -f "$AGENT_LIB/device_id"
hostnamectl set-hostname orangepi 2>/dev/null || true
ok "machine-id / SSH 密钥 / hostname / device_id 已重置(首次启动自动生成唯一值)"
# ---------------------------------------------------------------------------
# 4. 日志与缓存清理
# ---------------------------------------------------------------------------
info "清理日志与缓存 ..."
journalctl --vacuum-size=1M >/dev/null 2>&1 || true
rm -rf /var/log/journal/* 2>/dev/null || true
find /var/log -type f -name "*.log" -delete 2>/dev/null || true
apt-get clean 2>/dev/null || true
rm -f /root/.bash_history /home/orangepi/.bash_history 2>/dev/null || true
ok "日志与缓存已清理"
# ---------------------------------------------------------------------------
# 5. 清零空闲空间(可选,压缩镜像体积)
# ---------------------------------------------------------------------------
if [ "$ZERO" = "1" ]; then
info "清零空闲空间SD 卡写入较慢,请耐心等待)..."
for target in /data / ; do
fill="$target/zero.fill"
echo " $target ..."
dd if=/dev/zero of="$fill" bs=4M 2>/dev/null || true
rm -f "$fill"
done
ok "空闲空间已清零"
else
warn "未清零空闲空间。如需缩小镜像体积,可加 --zero 重新执行。"
fi
# ---------------------------------------------------------------------------
# 6. 完成
# ---------------------------------------------------------------------------
echo ""
echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
echo -e "${GREEN} 出厂化完成!可以关机、摘卡、制作产品镜像${NC}"
echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
echo ""
echo "下一步:"
echo " 1) sudo poweroff # 关机(确保文件系统一致)"
echo " 2) 摘卡,在主机上制作镜像:"
echo " Windows: Win32DiskImager 读取 → img"
echo " Linux: sudo dd if=/dev/sdX bs=4M status=progress | gzip > safesight-product.img.gz"
echo " 3) 每台烧录后首次启动会自动生成唯一 machine-id / SSH 密钥 / device_id"
echo " 4) 每台初始化: sudo ./init-device.sh --hostname ... --ip ...(见脚本说明)"
echo ""
echo "注意: 此状态【尚未启用 overlayroot】——出厂镜像故意如此。"
echo " overlayroot 由 init-device.sh 在每台初始化最后一步统一启用。"