Files
MoShiro/packaging/update/install-updater.sh
T
justme 8dd3209a65 feat!: probes link to the panel; signed release updates for container nodes [CI]
Probes connect to the panel directly and get the agent list as desired state.
CI signs the image digest of agent and probe releases, the panel forwards the
manifest, and a host updater verifies it with a local public key, pulls by
digest and rolls back when the new version is unhealthy.
2026-10-06 22:42:12 +08:00

90 lines
3.5 KiB
Bash

#!/bin/sh
# 在容器节点的宿主机上安装更新器:
# install-updater.sh <agent|probe> --data-dir <挂载到容器 /etc/monitor 的宿主机目录> --image-repo <镜像仓库,不带 tag> --unit <容器的 systemd 单元名>
# [--policy auto|manual] [--authfile <拉镜像用的 Registry 认证文件>]
# 需要 root、systemd、podman、openssl。做的事:装脚本和发布公钥,写本机配置,装两个 systemd 单元(有新清单就检查,有「更新」请求就更新)。
# 容器的单元要从 EnvironmentFile=/etc/monitor-update/<组件>.image 读 IMAGE=…,并用 ${IMAGE} 启动容器(没有这个文件时先写一份当前镜像)。
set -eu
COMPONENT="${1:-}"; shift || true
case "$COMPONENT" in agent|probe) ;; *) echo "usage: install-updater.sh <agent|probe> --data-dir D --image-repo R --unit U [--policy auto|manual] [--authfile F]" >&2; exit 2 ;; esac
DATA_DIR=""; IMAGE_REPO=""; UNIT=""; POLICY="manual"; AUTHFILE=""
while [ $# -gt 0 ]; do
case "$1" in
--data-dir) DATA_DIR="$2"; shift 2 ;;
--image-repo) IMAGE_REPO="$2"; shift 2 ;;
--unit) UNIT="$2"; shift 2 ;;
--policy) POLICY="$2"; shift 2 ;;
--authfile) AUTHFILE="$2"; shift 2 ;;
*) echo "unknown option: $1" >&2; exit 2 ;;
esac
done
[ -n "$DATA_DIR" ] && [ -n "$IMAGE_REPO" ] && [ -n "$UNIT" ] || { echo "--data-dir, --image-repo and --unit are required" >&2; exit 2; }
case "$POLICY" in auto|manual) ;; *) echo "--policy must be auto or manual" >&2; exit 2 ;; esac
[ "$(id -u)" -eq 0 ] || { echo "run as root" >&2; exit 1; }
HERE="$(cd "$(dirname "$0")" && pwd)"
install -d -m 755 /etc/monitor-update /var/lib/monitor-update
install -m 755 "$HERE/monitor-update.sh" /usr/local/sbin/monitor-update
install -m 644 "$HERE/release-key.pub.pem" /etc/monitor-update/release-key.pub.pem
# 容器用户(UID 1654)能写 update/(放清单和请求);update-status/ 归 root,业务进程只读
install -d -m 755 -o 1654 -g 1654 "$DATA_DIR/update"
install -d -m 755 "$DATA_DIR/update-status"
cat > "/etc/monitor-update/$COMPONENT.conf" <<CONF
DATA_DIR=$DATA_DIR
IMAGE_REPO=$IMAGE_REPO
UNIT=$UNIT
PUBKEY=/etc/monitor-update/release-key.pub.pem
ENV_FILE=/etc/monitor-update/$COMPONENT.image
STATE_DIR=/var/lib/monitor-update
POLICY=$POLICY
AUTHFILE=$AUTHFILE
CONF
chmod 644 "/etc/monitor-update/$COMPONENT.conf"
cat > "/etc/systemd/system/monitor-update-check-$COMPONENT.service" <<UNITFILE
[Unit]
Description=Check the signed update offer for monitor-$COMPONENT
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/monitor-update check $COMPONENT
UNITFILE
cat > "/etc/systemd/system/monitor-update-apply-$COMPONENT.service" <<UNITFILE
[Unit]
Description=Apply the verified update for monitor-$COMPONENT
[Service]
Type=oneshot
TimeoutStartSec=300
ExecStart=/usr/local/sbin/monitor-update apply $COMPONENT
UNITFILE
cat > "/etc/systemd/system/monitor-update-check-$COMPONENT.path" <<UNITFILE
[Unit]
Description=Watch for a new update offer for monitor-$COMPONENT
[Path]
PathChanged=$DATA_DIR/update/offer.sig
Unit=monitor-update-check-$COMPONENT.service
[Install]
WantedBy=multi-user.target
UNITFILE
cat > "/etc/systemd/system/monitor-update-apply-$COMPONENT.path" <<UNITFILE
[Unit]
Description=Watch for an update request for monitor-$COMPONENT
[Path]
PathChanged=$DATA_DIR/update/apply.request
Unit=monitor-update-apply-$COMPONENT.service
[Install]
WantedBy=multi-user.target
UNITFILE
systemctl daemon-reload
systemctl enable --now "monitor-update-check-$COMPONENT.path" "monitor-update-apply-$COMPONENT.path"
echo "updater installed for $COMPONENT (policy: $POLICY)"