ci/woodpecker/push/main-amd64-build Pipeline was successful
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.
90 lines
3.5 KiB
Bash
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)"
|