refactor!: rename the project from Monitor to MoShiro [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful

Namespaces, assemblies, solution, binaries, images, systemd units, config paths, environment variables, protocol methods and the Linux user are all renamed. Breaking: existing databases, node identities and installed units must be recreated.
This commit is contained in:
justme committed 2026-10-07 02:03:25 +08:00
1 parent 27ac7fb787
commit 2e146d4da7
309 files changed
+1565 -1572

No files matched your search

+6 -6
View File
@@ -3,15 +3,15 @@
# 首次注册、配置导入和自动更新见 docs/deployment.md。
services:
agent:
image: ${MONITOR_IMAGE:-registry.oeo.one/monitor/monitor-agent}:${MONITOR_VERSION:-0.1.1}
container_name: monitor-agent
image: ${MOSHIRO_IMAGE:-registry.oeo.one/moshiro/moshiro-agent}:${MOSHIRO_VERSION:-0.1.1}
container_name: moshiro-agent
restart: unless-stopped
init: true
# Probe 要直连 Agent 的 7443(TCP+UDP)和 7444(TCP),用宿主网络,不做端口映射
network_mode: host
volumes:
- agent-config:/etc/monitor
- agent-status:/etc/monitor/update-status:ro
- agent-config:/etc/moshiro
- agent-status:/etc/moshiro/update-status:ro
- /etc/os-release:/etc/os-release:ro
# 系统目录只读,不加 :z/:Z;SELinux 隔离在容器级别禁用。
- /proc:/host/proc:ro
@@ -36,6 +36,6 @@ services:
volumes:
agent-config:
name: monitor-agent-config
name: moshiro-agent-config
agent-status:
name: monitor-agent-status
name: moshiro-agent-status
+4 -4
View File
@@ -1,15 +1,15 @@
# Docker / Podman 共用,数据库和原始数据保存在命名 volume 中。
services:
backend:
image: ${MONITOR_IMAGE:-registry.oeo.one/monitor/monitor-backend}:${MONITOR_VERSION:-0.1.1}
container_name: monitor-backend
image: ${MOSHIRO_IMAGE:-registry.oeo.one/moshiro/moshiro-backend}:${MOSHIRO_VERSION:-0.1.1}
container_name: moshiro-backend
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
Monitor__InitialAdminPassword: ${MONITOR_INITIAL_ADMIN_PASSWORD:?Set MONITOR_INITIAL_ADMIN_PASSWORD}
MoShiro__InitialAdminPassword: ${MOSHIRO_INITIAL_ADMIN_PASSWORD:?Set MOSHIRO_INITIAL_ADMIN_PASSWORD}
volumes:
- backend-data:/data
volumes:
backend-data:
name: monitor-backend-data
name: moshiro-backend-data
+6 -6
View File
@@ -3,14 +3,14 @@
# 首次注册、配置导入和自动更新见 docs/deployment.md。
services:
probe:
image: ${MONITOR_IMAGE:-registry.oeo.one/monitor/monitor-probe}:${MONITOR_VERSION:-0.1.1}
container_name: monitor-probe
image: ${MOSHIRO_IMAGE:-registry.oeo.one/moshiro/moshiro-probe}:${MOSHIRO_VERSION:-0.1.1}
container_name: moshiro-probe
restart: unless-stopped
init: true
network_mode: host
volumes:
- probe-config:/etc/monitor
- probe-status:/etc/monitor/update-status:ro
- probe-config:/etc/moshiro
- probe-status:/etc/moshiro/update-status:ro
- /etc/os-release:/etc/os-release:ro
read_only: true
tmpfs:
@@ -27,6 +27,6 @@ services:
volumes:
probe-config:
name: monitor-probe-config
name: moshiro-probe-config
probe-status:
name: monitor-probe-status
name: moshiro-probe-status
+8 -8
View File
@@ -1,17 +1,17 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
ARG APP_VERSION=unknown
LABEL org.opencontainers.image.title="Monitor Agent" \
org.opencontainers.image.description="MyMonitor node agent for Linux" \
LABEL org.opencontainers.image.title="MoShiro Agent" \
org.opencontainers.image.description="MoShiro node agent for Linux" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.version="$APP_VERSION"
COPY --chown=1654:1654 app/monitor-agent /usr/local/bin/monitor-agent
COPY --chown=1654:1654 app/moshiro-agent /usr/local/bin/moshiro-agent
COPY --chown=1654:1654 app/fleet-enroll /usr/local/bin/fleet-enroll
COPY --chown=1654:1654 config/ /etc/monitor/
COPY --chown=1654:1654 config/ /etc/moshiro/
USER 1654:1654
WORKDIR /etc/monitor
VOLUME ["/etc/monitor"]
ENTRYPOINT ["/usr/local/bin/monitor-agent"]
CMD ["--config", "/etc/monitor/agent.json"]
WORKDIR /etc/moshiro
VOLUME ["/etc/moshiro"]
ENTRYPOINT ["/usr/local/bin/moshiro-agent"]
CMD ["--config", "/etc/moshiro/agent.json"]
@@ -3,16 +3,16 @@ FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine-aot AS build
WORKDIR /src/backend
COPY restore/backend/ ./
# restore 也要带 PublishAot:不然不会还原 ILCompiler,之后 --no-restore 的发布就悄悄变成「裁剪过的框架依赖程序」
RUN dotnet restore agent/src/Monitor.Agent -r linux-musl-x64 -p:PublishAot=true --artifacts-path /artifacts \
RUN dotnet restore agent/src/MoShiro.Agent -r linux-musl-x64 -p:PublishAot=true --artifacts-path /artifacts \
&& dotnet restore fleet/tools/fleet-enroll -r linux-musl-x64 -p:PublishAot=true --artifacts-path /artifacts
COPY source/backend/ ./
# 构建信息:CI 通过 --build-arg 传入;不传就是空(放在 restore 之后,每次构建都变的时间不会让依赖还原的缓存失效)
ARG MONITOR_TAG=
ARG MONITOR_COMMIT=
ARG MONITOR_BUILT_AT=
ENV MONITOR_TAG=$MONITOR_TAG MONITOR_COMMIT=$MONITOR_COMMIT MONITOR_BUILT_AT=$MONITOR_BUILT_AT
RUN dotnet publish agent/src/Monitor.Agent -m:3 -c Release -r linux-musl-x64 \
ARG MOSHIRO_TAG=
ARG MOSHIRO_COMMIT=
ARG MOSHIRO_BUILT_AT=
ENV MOSHIRO_TAG=$MOSHIRO_TAG MOSHIRO_COMMIT=$MOSHIRO_COMMIT MOSHIRO_BUILT_AT=$MOSHIRO_BUILT_AT
RUN dotnet publish agent/src/MoShiro.Agent -m:3 -c Release -r linux-musl-x64 \
--self-contained true --no-restore -p:PublishAot=true -p:UseAotAnywhere=false \
-p:UseAppHost=true -p:StripSymbols=true \
-p:DebugType=none -p:DebugSymbols=false --artifacts-path /artifacts -o /out/agent \
@@ -21,23 +21,23 @@ RUN dotnet publish agent/src/Monitor.Agent -m:3 -c Release -r linux-musl-x64 \
-p:UseAppHost=true -p:StripSymbols=true \
-p:DebugType=none -p:DebugSymbols=false --artifacts-path /artifacts -o /out/enroll
# 原生程序有几 MB;几十 KB 的是只会去找 .dll 的启动器
RUN test -x /out/agent/monitor-agent && test -x /out/enroll/fleet-enroll \
&& test "$(stat -c%s /out/agent/monitor-agent)" -gt 2000000 && test "$(stat -c%s /out/enroll/fleet-enroll)" -gt 2000000
RUN test -x /out/agent/moshiro-agent && test -x /out/enroll/fleet-enroll \
&& test "$(stat -c%s /out/agent/moshiro-agent)" -gt 2000000 && test "$(stat -c%s /out/enroll/fleet-enroll)" -gt 2000000
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
ARG APP_VERSION=main
LABEL org.opencontainers.image.title="Monitor Agent" \
org.opencontainers.image.description="MyMonitor node agent for Linux" \
LABEL org.opencontainers.image.title="MoShiro Agent" \
org.opencontainers.image.description="MoShiro node agent for Linux" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.version="$APP_VERSION"
COPY --chown=1654:1654 --from=build /out/agent/monitor-agent /usr/local/bin/monitor-agent
COPY --chown=1654:1654 --from=build /out/agent/moshiro-agent /usr/local/bin/moshiro-agent
COPY --chown=1654:1654 --from=build /out/enroll/fleet-enroll /usr/local/bin/fleet-enroll
COPY --chown=1654:1654 config/ /etc/monitor/
COPY --chown=1654:1654 config/ /etc/moshiro/
USER 1654:1654
WORKDIR /etc/monitor
VOLUME ["/etc/monitor"]
ENTRYPOINT ["/usr/local/bin/monitor-agent"]
CMD ["--config", "/etc/monitor/agent.json"]
WORKDIR /etc/moshiro
VOLUME ["/etc/moshiro"]
ENTRYPOINT ["/usr/local/bin/moshiro-agent"]
CMD ["--config", "/etc/moshiro/agent.json"]
+4 -4
View File
@@ -1,20 +1,20 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
ARG APP_VERSION=unknown
LABEL org.opencontainers.image.title="Monitor Backend" \
LABEL org.opencontainers.image.title="MoShiro Backend" \
org.opencontainers.image.description="Self-hosted network path quality monitoring backend" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.version="$APP_VERSION"
WORKDIR /app
COPY --chown=1654:1654 app/monitor-backend /app/monitor-backend
COPY --chown=1654:1654 app/moshiro-backend /app/moshiro-backend
COPY --chown=1654:1654 data/.keep /data/.keep
ENV ASPNETCORE_HTTP_PORTS=8080 \
Monitor__DataDirectory=/data \
MoShiro__DataDirectory=/data \
DOTNET_EnableDiagnostics=0
USER 1654:1654
VOLUME ["/data"]
EXPOSE 8080
ENTRYPOINT ["/app/monitor-backend"]
ENTRYPOINT ["/app/moshiro-backend"]
+8 -8
View File
@@ -1,16 +1,16 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
ARG APP_VERSION=unknown
LABEL org.opencontainers.image.title="Monitor Probe" \
org.opencontainers.image.description="MyMonitor network measurement probe for Linux" \
LABEL org.opencontainers.image.title="MoShiro Probe" \
org.opencontainers.image.description="MoShiro network measurement probe for Linux" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.version="$APP_VERSION"
COPY --chown=1654:1654 app/monitor-probe /usr/local/bin/monitor-probe
COPY --chown=1654:1654 config/ /etc/monitor/
COPY --chown=1654:1654 app/moshiro-probe /usr/local/bin/moshiro-probe
COPY --chown=1654:1654 config/ /etc/moshiro/
USER 1654:1654
WORKDIR /etc/monitor
VOLUME ["/etc/monitor"]
ENTRYPOINT ["/usr/local/bin/monitor-probe"]
CMD ["--config", "/etc/monitor/probe.json"]
WORKDIR /etc/moshiro
VOLUME ["/etc/moshiro"]
ENTRYPOINT ["/usr/local/bin/moshiro-probe"]
CMD ["--config", "/etc/moshiro/probe.json"]
@@ -3,35 +3,35 @@ FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine-aot AS build
WORKDIR /src/backend
COPY restore/backend/ ./
# restore 也要带 PublishAot:不然不会还原 ILCompiler,之后 --no-restore 的发布就悄悄变成「裁剪过的框架依赖程序」
RUN dotnet restore probe/src/Monitor.Probe -r linux-musl-x64 -p:PublishAot=true --artifacts-path /artifacts
RUN dotnet restore probe/src/MoShiro.Probe -r linux-musl-x64 -p:PublishAot=true --artifacts-path /artifacts
COPY source/backend/ ./
# 构建信息:CI 通过 --build-arg 传入;不传就是空(放在 restore 之后,每次构建都变的时间不会让依赖还原的缓存失效)
ARG MONITOR_TAG=
ARG MONITOR_COMMIT=
ARG MONITOR_BUILT_AT=
ENV MONITOR_TAG=$MONITOR_TAG MONITOR_COMMIT=$MONITOR_COMMIT MONITOR_BUILT_AT=$MONITOR_BUILT_AT
RUN dotnet publish probe/src/Monitor.Probe -m:3 -c Release -r linux-musl-x64 \
ARG MOSHIRO_TAG=
ARG MOSHIRO_COMMIT=
ARG MOSHIRO_BUILT_AT=
ENV MOSHIRO_TAG=$MOSHIRO_TAG MOSHIRO_COMMIT=$MOSHIRO_COMMIT MOSHIRO_BUILT_AT=$MOSHIRO_BUILT_AT
RUN dotnet publish probe/src/MoShiro.Probe -m:3 -c Release -r linux-musl-x64 \
--self-contained true --no-restore -p:PublishAot=true -p:UseAotAnywhere=false \
-p:UseAppHost=true -p:StripSymbols=true \
-p:DebugType=none -p:DebugSymbols=false --artifacts-path /artifacts -o /out/probe
# 原生程序有几 MB;几十 KB 的是只会去找 .dll 的启动器
RUN test -x /out/probe/monitor-probe \
&& test "$(stat -c%s /out/probe/monitor-probe)" -gt 2000000
RUN test -x /out/probe/moshiro-probe \
&& test "$(stat -c%s /out/probe/moshiro-probe)" -gt 2000000
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
ARG APP_VERSION=main
LABEL org.opencontainers.image.title="Monitor Probe" \
org.opencontainers.image.description="MyMonitor network measurement probe for Linux" \
LABEL org.opencontainers.image.title="MoShiro Probe" \
org.opencontainers.image.description="MoShiro network measurement probe for Linux" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.version="$APP_VERSION"
COPY --chown=1654:1654 --from=build /out/probe/monitor-probe /usr/local/bin/monitor-probe
COPY --chown=1654:1654 config/ /etc/monitor/
COPY --chown=1654:1654 --from=build /out/probe/moshiro-probe /usr/local/bin/moshiro-probe
COPY --chown=1654:1654 config/ /etc/moshiro/
USER 1654:1654
WORKDIR /etc/monitor
VOLUME ["/etc/monitor"]
ENTRYPOINT ["/usr/local/bin/monitor-probe"]
CMD ["--config", "/etc/monitor/probe.json"]
WORKDIR /etc/moshiro
VOLUME ["/etc/moshiro"]
ENTRYPOINT ["/usr/local/bin/moshiro-probe"]
CMD ["--config", "/etc/moshiro/probe.json"]
+23 -23
View File
@@ -1,18 +1,18 @@
#!/bin/sh
# Installs monitor-agent or monitor-probe from an extracted release directory (the directory this script lives in).
# Installs moshiro-agent or moshiro-probe from an extracted release directory (the directory this script lives in).
# POSIX sh: runs on Debian/Ubuntu/Alpine/OpenWrt (busybox).
#
# ./install.sh agent --server https://panel.example.com --join <join-token> --name hk-1
# ./install.sh probe [--probe-json /path/to/probe.json]
# ./install.sh uninstall agent|probe [--purge]
#
# Binaries go to /usr/lib/monitor (root-owned: the collector cannot rewrite its own executable);
# config and identity go to /etc/monitor (owned by the unprivileged `monitor` user).
# Binaries go to /usr/lib/moshiro (root-owned: the collector cannot rewrite its own executable);
# config and identity go to /etc/moshiro (owned by the unprivileged `moshiro` user).
set -eu
PREFIX=/usr/lib/monitor
CONFIG=/etc/monitor
USER_NAME=monitor
PREFIX=/usr/lib/moshiro
CONFIG=/etc/moshiro
USER_NAME=moshiro
HERE="$(cd "$(dirname "$0")" && pwd)"
# busybox on OpenWrt has no `install`
@@ -95,22 +95,22 @@ install_role() {
if [ "$have_user" -eq 1 ]; then chown "$USER_NAME" "$CONFIG"; fi
chmod 0750 "$CONFIG"
install_binary "monitor-$role"
install_binary "moshiro-$role"
if [ "$role" = agent ]; then install_binary fleet-enroll; fi
say "installed binaries to $PREFIX"
init="$(init_system)"
case "$init" in
systemd)
put 0644 "$HERE/systemd/monitor-$role.service" "/etc/systemd/system/monitor-$role.service"
if [ "$have_user" -eq 0 ]; then sed -i '/^User=/d;/^Group=/d' "/etc/systemd/system/monitor-$role.service"; fi
put 0644 "$HERE/systemd/moshiro-$role.service" "/etc/systemd/system/moshiro-$role.service"
if [ "$have_user" -eq 0 ]; then sed -i '/^User=/d;/^Group=/d' "/etc/systemd/system/moshiro-$role.service"; fi
systemctl daemon-reload ;;
procd)
[ "$role" = probe ] || die "the agent is meant for servers; on OpenWrt only the probe is supported"
put 0755 "$HERE/openwrt/monitor-probe.init" /etc/init.d/monitor-probe
put 0755 "$HERE/openwrt/moshiro-probe.init" /etc/init.d/moshiro-probe
mkdir -p /lib/upgrade/keep.d
put 0644 "$HERE/openwrt/monitor.keep" /lib/upgrade/keep.d/monitor ;;
*) echo "warning: no systemd or procd found: start $PREFIX/monitor-$role --config $CONFIG/$role.json with your own supervisor" >&2 ;;
put 0644 "$HERE/openwrt/moshiro.keep" /lib/upgrade/keep.d/moshiro ;;
*) echo "warning: no systemd or procd found: start $PREFIX/moshiro-$role --config $CONFIG/$role.json with your own supervisor" >&2 ;;
esac
ready=0
@@ -136,18 +136,18 @@ install_role() {
if [ "$ready" -eq 1 ] && [ "$no_start" -eq 0 ]; then
case "$init" in
systemd) systemctl enable --now "monitor-$role" ;;
procd) /etc/init.d/monitor-probe enable; /etc/init.d/monitor-probe restart ;;
systemd) systemctl enable --now "moshiro-$role" ;;
procd) /etc/init.d/moshiro-probe enable; /etc/init.d/moshiro-probe restart ;;
esac
say "monitor-$role is installed"
say "moshiro-$role is installed"
else
say "installed, not started yet. Next:"
if [ "$role" = agent ]; then
echo " $PREFIX/fleet-enroll --server <panel-url> --join <token> --name <name> --identity-dir $CONFIG (as the '$USER_NAME' user)"
echo " write $CONFIG/agent.json (see README.md), then: systemctl enable --now monitor-agent"
echo " write $CONFIG/agent.json (see README.md), then: systemctl enable --now moshiro-agent"
else
echo " save the panel's probe identity (POST /api/admin/probe/identity) as $CONFIG/probe.json (mode 0600, owner $USER_NAME)"
echo " then: systemctl enable --now monitor-probe (OpenWrt: /etc/init.d/monitor-probe enable && /etc/init.d/monitor-probe start)"
echo " then: systemctl enable --now moshiro-probe (OpenWrt: /etc/init.d/moshiro-probe enable && /etc/init.d/moshiro-probe start)"
fi
fi
}
@@ -157,15 +157,15 @@ uninstall() {
if [ "${2:-}" = "--purge" ]; then purge=1; fi
case "$(init_system)" in
systemd)
systemctl disable --now "monitor-$role" 2>/dev/null || true
rm -f "/etc/systemd/system/monitor-$role.service"
systemctl disable --now "moshiro-$role" 2>/dev/null || true
rm -f "/etc/systemd/system/moshiro-$role.service"
systemctl daemon-reload ;;
procd)
/etc/init.d/monitor-probe stop 2>/dev/null || true
/etc/init.d/monitor-probe disable 2>/dev/null || true
rm -f /etc/init.d/monitor-probe /lib/upgrade/keep.d/monitor ;;
/etc/init.d/moshiro-probe stop 2>/dev/null || true
/etc/init.d/moshiro-probe disable 2>/dev/null || true
rm -f /etc/init.d/moshiro-probe /lib/upgrade/keep.d/moshiro ;;
esac
rm -f "$PREFIX/monitor-$role"
rm -f "$PREFIX/moshiro-$role"
if [ "$role" = agent ]; then rm -f "$PREFIX/fleet-enroll"; fi
rmdir "$PREFIX" 2>/dev/null || true
if [ "$purge" -eq 1 ]; then
-1
View File
@@ -1 +0,0 @@
/etc/monitor/
@@ -1,16 +1,16 @@
#!/bin/sh /etc/rc.common
# procd service for monitor-probe (OpenWrt). Installed as /etc/init.d/monitor-probe.
# procd service for moshiro-probe (OpenWrt). Installed as /etc/init.d/moshiro-probe.
START=95
STOP=10
USE_PROCD=1
PROG=/usr/lib/monitor/monitor-probe
CONF=/etc/monitor/probe.json
PROG=/usr/lib/moshiro/moshiro-probe
CONF=/etc/moshiro/probe.json
start_service() {
[ -f "$CONF" ] || {
logger -t monitor-probe "$CONF not found: download it from the panel (POST /api/admin/probe/identity)"
logger -t moshiro-probe "$CONF not found: download it from the panel (POST /api/admin/probe/identity)"
return 1
}
procd_open_instance
@@ -21,6 +21,6 @@ start_service() {
procd_set_param stderr 1
procd_set_param limits nofile=4096
# Run unprivileged when the installer could create the user (busybox adduser may be missing)
id monitor >/dev/null 2>&1 && procd_set_param user monitor
id moshiro >/dev/null 2>&1 && procd_set_param user moshiro
procd_close_instance
}
+1
View File
@@ -0,0 +1 @@
/etc/moshiro/
@@ -1,16 +0,0 @@
[Unit]
Description=Monitor Probe (Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/monitor-update/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f monitor-probe
ExecStart=/usr/bin/podman run --rm --name monitor-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v monitor-probe-config:/etc/monitor -v monitor-probe-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 monitor-probe
[Install]
WantedBy=multi-user.target
@@ -1,16 +0,0 @@
[Unit]
Description=Monitor Probe (Docker container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/monitor-update/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/docker rm -f monitor-probe
ExecStart=/usr/bin/docker run --rm --name monitor-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v monitor-probe-config:/etc/monitor -v monitor-probe-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/docker stop -t 20 monitor-probe
[Install]
WantedBy=multi-user.target
@@ -1,16 +0,0 @@
[Unit]
Description=Monitor Probe (rootless Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=%h/.config/monitor/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f monitor-probe
ExecStart=/usr/bin/podman run --rm --name monitor-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v monitor-probe-config:/etc/monitor -v monitor-probe-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 monitor-probe
[Install]
WantedBy=default.target
@@ -1,16 +1,16 @@
[Unit]
Description=Monitor Agent (Podman container)
Description=MoShiro Agent (Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/monitor-update/agent.image
EnvironmentFile=/etc/moshiro-update/agent.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f monitor-agent
ExecStart=/usr/bin/podman run --rm --name monitor-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v monitor-agent-config:/etc/monitor -v monitor-agent-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 monitor-agent
ExecStartPre=-/usr/bin/podman rm -f moshiro-agent
ExecStart=/usr/bin/podman run --rm --name moshiro-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v moshiro-agent-config:/etc/moshiro -v moshiro-agent-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 moshiro-agent
[Install]
WantedBy=multi-user.target
@@ -1,16 +1,16 @@
[Unit]
Description=Monitor Agent (Docker container)
Description=MoShiro Agent (Docker container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/monitor-update/agent.image
EnvironmentFile=/etc/moshiro-update/agent.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/docker rm -f monitor-agent
ExecStart=/usr/bin/docker run --rm --name monitor-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v monitor-agent-config:/etc/monitor -v monitor-agent-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/docker stop -t 20 monitor-agent
ExecStartPre=-/usr/bin/docker rm -f moshiro-agent
ExecStart=/usr/bin/docker run --rm --name moshiro-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v moshiro-agent-config:/etc/moshiro -v moshiro-agent-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/docker stop -t 20 moshiro-agent
[Install]
WantedBy=multi-user.target
@@ -1,16 +1,16 @@
[Unit]
Description=Monitor Agent (rootless Podman container)
Description=MoShiro Agent (rootless Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=%h/.config/monitor/agent.image
EnvironmentFile=%h/.config/moshiro/agent.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f monitor-agent
ExecStart=/usr/bin/podman run --rm --name monitor-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v monitor-agent-config:/etc/monitor -v monitor-agent-status:/etc/monitor/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 monitor-agent
ExecStartPre=-/usr/bin/podman rm -f moshiro-agent
ExecStart=/usr/bin/podman run --rm --name moshiro-agent --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v /proc:/host/proc:ro -v /sys:/host/sys:ro -v /:/host/root:ro -e HOST_PROC=/host/proc -e HOST_SYS=/host/sys -e HOST_ROOT=/host/root -v moshiro-agent-config:/etc/moshiro -v moshiro-agent-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 moshiro-agent
[Install]
WantedBy=default.target
@@ -1,18 +1,18 @@
[Unit]
Description=Monitor agent (network line quality collector)
Description=MoShiro agent (network line quality collector)
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=monitor
Group=monitor
ExecStart=/usr/lib/monitor/monitor-agent --config /etc/monitor/agent.json
User=moshiro
Group=moshiro
ExecStart=/usr/lib/moshiro/moshiro-agent --config /etc/moshiro/agent.json
Restart=always
RestartSec=5
# The agent is a pure collector: it reads its config and identity, never writes files, never starts processes.
ReadOnlyPaths=/etc/monitor
ReadOnlyPaths=/etc/moshiro
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
@@ -0,0 +1,16 @@
[Unit]
Description=MoShiro Probe (Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/moshiro-update/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f moshiro-probe
ExecStart=/usr/bin/podman run --rm --name moshiro-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v moshiro-probe-config:/etc/moshiro -v moshiro-probe-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 moshiro-probe
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,16 @@
[Unit]
Description=MoShiro Probe (Docker container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/moshiro-update/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/docker rm -f moshiro-probe
ExecStart=/usr/bin/docker run --rm --name moshiro-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v moshiro-probe-config:/etc/moshiro -v moshiro-probe-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/docker stop -t 20 moshiro-probe
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,16 @@
[Unit]
Description=MoShiro Probe (rootless Podman container)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=%h/.config/moshiro/probe.image
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f moshiro-probe
ExecStart=/usr/bin/podman run --rm --name moshiro-probe --network host --read-only --security-opt no-new-privileges --security-opt label=disable --cap-drop all --tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 -v /etc/os-release:/etc/os-release:ro -v moshiro-probe-config:/etc/moshiro -v moshiro-probe-status:/etc/moshiro/update-status:ro ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 moshiro-probe
[Install]
WantedBy=default.target
@@ -1,19 +1,19 @@
[Unit]
Description=Monitor probe (network line quality measurement origin)
Description=MoShiro probe (network line quality measurement origin)
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=monitor
Group=monitor
ExecStart=/usr/lib/monitor/monitor-probe --config /etc/monitor/probe.json
User=moshiro
Group=moshiro
ExecStart=/usr/lib/moshiro/moshiro-probe --config /etc/moshiro/probe.json
Restart=always
RestartSec=5
# The probe is a pure collector: it never starts processes and writes no measurement data.
# The only file the probe writes is agents.json (the latest agent list) next to probe.json.
ReadWritePaths=/etc/monitor
ReadWritePaths=/etc/moshiro
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
+24 -24
View File
@@ -30,8 +30,8 @@ case "$POLICY" in auto|manual) ;; *) echo "--policy must be auto or manual" >&2;
case "$ENGINE" in podman|docker) ;; *) echo "--engine must be podman or docker" >&2; exit 2 ;; esac
if [ -n "$DATA_VOLUME" ]; then
[ -z "$DATA_DIR" ] || { echo "use --volume or --data-dir, not both" >&2; exit 2; }
[ -n "$HELPER_IMAGE" ] || { echo "--volume needs --helper-image (an already pulled Monitor image)" >&2; exit 2; }
STATUS_VOLUME="${STATUS_VOLUME:-monitor-$COMPONENT-status}"
[ -n "$HELPER_IMAGE" ] || { echo "--volume needs --helper-image (an already pulled MoShiro image)" >&2; exit 2; }
STATUS_VOLUME="${STATUS_VOLUME:-moshiro-$COMPONENT-status}"
"$ENGINE" image inspect "$HELPER_IMAGE" >/dev/null
"$ENGINE" volume inspect "$DATA_VOLUME" >/dev/null 2>&1 || "$ENGINE" volume create "$DATA_VOLUME" >/dev/null
"$ENGINE" volume inspect "$STATUS_VOLUME" >/dev/null 2>&1 || "$ENGINE" volume create "$STATUS_VOLUME" >/dev/null
@@ -42,15 +42,15 @@ fi
if [ "$SERVICE_SCOPE" = user ]; then
[ "$(id -u)" -ne 0 ] || { echo "--user must run as the rootless Podman user, without sudo" >&2; exit 1; }
[ "$ENGINE" = podman ] || { echo "--user currently supports rootless Podman; Docker uses system services" >&2; exit 2; }
CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/monitor"
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/monitor-update"
CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/moshiro"
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/moshiro-update"
UNIT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
BIN_DIR="$HOME/.local/bin"
TARGET=default.target
else
[ "$(id -u)" -eq 0 ] || { echo "system installation needs root; use --user for rootless Podman" >&2; exit 1; }
CONF_DIR=/etc/monitor-update
STATE_DIR=/var/lib/monitor-update
CONF_DIR=/etc/moshiro-update
STATE_DIR=/var/lib/moshiro-update
UNIT_DIR=/etc/systemd/system
BIN_DIR=/usr/local/sbin
TARGET=multi-user.target
@@ -64,8 +64,8 @@ unit_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
HERE="$(cd "$(dirname "$0")" && pwd)"
install -d -m 755 "$CONF_DIR" "$STATE_DIR" "$UNIT_DIR" "$BIN_DIR"
BIN="$BIN_DIR/monitor-update"
install -m 755 "$HERE/monitor-update.sh" "$BIN"
BIN="$BIN_DIR/moshiro-update"
install -m 755 "$HERE/moshiro-update.sh" "$BIN"
install -m 644 "$HERE/release-key.pub.pem" "$CONF_DIR/release-key.pub.pem"
if [ -n "$DATA_VOLUME" ]; then
: # Named volumes are initialized by the image; no host directory or chown needed.
@@ -92,49 +92,49 @@ PUBKEY="$CONF_DIR/release-key.pub.pem"
chmod 600 "$CONF_DIR/$COMPONENT.conf"
if [ -n "$DATA_VOLUME" ]; then
cat > "$UNIT_DIR/monitor-update-$COMPONENT.service" <<UNITFILE
cat > "$UNIT_DIR/moshiro-update-$COMPONENT.service" <<UNITFILE
[Unit]
Description=Check/apply signed volume update for monitor-$COMPONENT
Description=Check/apply signed volume update for moshiro-$COMPONENT
[Service]
Type=oneshot
TimeoutStartSec=300
Environment="MONITOR_UPDATE_CONF_DIR=$(unit_escape "$CONF_DIR")"
Environment="MOSHIRO_UPDATE_CONF_DIR=$(unit_escape "$CONF_DIR")"
ExecStart="$(unit_escape "$BIN")" check $COMPONENT
UNITFILE
cat > "$UNIT_DIR/monitor-update-$COMPONENT.timer" <<UNITFILE
cat > "$UNIT_DIR/moshiro-update-$COMPONENT.timer" <<UNITFILE
[Unit]
Description=Poll the update volume for monitor-$COMPONENT
Description=Poll the update volume for moshiro-$COMPONENT
[Timer]
OnBootSec=10s
OnUnitInactiveSec=30s
Unit=monitor-update-$COMPONENT.service
Unit=moshiro-update-$COMPONENT.service
[Install]
WantedBy=$TARGET
UNITFILE
else
for action in check apply; do
cat > "$UNIT_DIR/monitor-update-$action-$COMPONENT.service" <<UNITFILE
cat > "$UNIT_DIR/moshiro-update-$action-$COMPONENT.service" <<UNITFILE
[Unit]
Description=$action the signed update for monitor-$COMPONENT
Description=$action the signed update for moshiro-$COMPONENT
[Service]
Type=oneshot
TimeoutStartSec=300
Environment="MONITOR_UPDATE_CONF_DIR=$(unit_escape "$CONF_DIR")"
Environment="MOSHIRO_UPDATE_CONF_DIR=$(unit_escape "$CONF_DIR")"
ExecStart="$(unit_escape "$BIN")" $action $COMPONENT
UNITFILE
watched=offer.sig
[ "$action" != apply ] || watched=apply.request
cat > "$UNIT_DIR/monitor-update-$action-$COMPONENT.path" <<UNITFILE
cat > "$UNIT_DIR/moshiro-update-$action-$COMPONENT.path" <<UNITFILE
[Unit]
Description=Watch $action events for monitor-$COMPONENT
Description=Watch $action events for moshiro-$COMPONENT
[Path]
PathChanged=$DATA_DIR/update/$watched
Unit=monitor-update-$action-$COMPONENT.service
Unit=moshiro-update-$action-$COMPONENT.service
[Install]
WantedBy=$TARGET
@@ -144,11 +144,11 @@ fi
if [ "$ENABLE" = true ]; then
service_ctl daemon-reload
if [ -n "$DATA_VOLUME" ]; then
service_ctl disable --now "monitor-update-check-$COMPONENT.path" "monitor-update-apply-$COMPONENT.path" >/dev/null 2>&1 || true
service_ctl enable --now "monitor-update-$COMPONENT.timer"
service_ctl disable --now "moshiro-update-check-$COMPONENT.path" "moshiro-update-apply-$COMPONENT.path" >/dev/null 2>&1 || true
service_ctl enable --now "moshiro-update-$COMPONENT.timer"
else
service_ctl disable --now "monitor-update-$COMPONENT.timer" >/dev/null 2>&1 || true
service_ctl enable --now "monitor-update-check-$COMPONENT.path" "monitor-update-apply-$COMPONENT.path"
service_ctl disable --now "moshiro-update-$COMPONENT.timer" >/dev/null 2>&1 || true
service_ctl enable --now "moshiro-update-check-$COMPONENT.path" "moshiro-update-apply-$COMPONENT.path"
fi
fi
echo "updater installed for $COMPONENT (engine: $ENGINE, scope: $SERVICE_SCOPE, policy: $POLICY)"
@@ -1,10 +1,10 @@
#!/bin/sh
# Monitor 容器节点(Agent、Probe)的宿主机更新器。用法:monitor-update <check|apply> <组件> 组件 = agent 或 probe
# MoShiro 容器节点(Agent、Probe)的宿主机更新器。用法:moshiro-update <check|apply> <组件> 组件 = agent 或 probe
#
# 信任模型(防篡改、防中间人):
# - 只接受用发布私钥签名的清单(ECDSA P-256 / SHA-256,对清单文件的原始字节签名);公钥放在本机,面板和 Registry 都改不了它。
# - 清单里写的是镜像的 digest:拉取时用 repo@sha256:…,内容寻址,Registry 或链路上的人换不出另一个镜像。
# - 镜像仓库、组件、服务名都来自本机的配置(/etc/monitor-update/<组件>.conf),清单里写什么都不会改变拉哪个仓库。
# - 镜像仓库、组件、服务名都来自本机的配置(/etc/moshiro-update/<组件>.conf),清单里写什么都不会改变拉哪个仓库。
# - 清单的 seq 必须比已安装的大(防止旧清单被重放回滚)。
# - 业务进程(Agent、Probe)只能往数据目录里写「清单」和「请求」文件,更新由这个宿主机脚本完成,业务进程不执行任何命令。
# Shell snippets below execute inside helper containers.
@@ -13,27 +13,27 @@ set -eu
CMD="${1:-}"
COMPONENT="${2:-}"
case "$CMD" in check|apply) ;; *) echo "usage: monitor-update <check|apply> <agent|probe>" >&2; exit 2 ;; esac
case "$CMD" in check|apply) ;; *) echo "usage: moshiro-update <check|apply> <agent|probe>" >&2; exit 2 ;; esac
case "$COMPONENT" in agent|probe) ;; *) echo "component must be agent or probe" >&2; exit 2 ;; esac
if [ "$(id -u)" -eq 0 ]; then
DEFAULT_CONF_DIR=/etc/monitor-update
DEFAULT_CONF_DIR=/etc/moshiro-update
else
DEFAULT_CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/monitor"
DEFAULT_CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/moshiro"
fi
CONF="${MONITOR_UPDATE_CONF_DIR:-$DEFAULT_CONF_DIR}/$COMPONENT.conf"
CONF="${MOSHIRO_UPDATE_CONF_DIR:-$DEFAULT_CONF_DIR}/$COMPONENT.conf"
[ -r "$CONF" ] || { echo "missing $CONF" >&2; exit 2; }
# 配置:DATA_DIR(容器里 /etc/monitor 对应的宿主机目录)、IMAGE_REPO、UNIT、PUBKEY、POLICY(auto|manual)、AUTHFILE(可选)、
# 配置:DATA_DIR(容器里 /etc/moshiro 对应的宿主机目录)、IMAGE_REPO、UNIT、PUBKEY、POLICY(auto|manual)、AUTHFILE(可选)、
# STATE_DIR(已安装版本的记录)、ENV_FILE(容器单元读取的 IMAGE=… 文件)
# shellcheck disable=SC1090
. "$CONF"
: "${IMAGE_REPO:?}" "${UNIT:?}" "${PUBKEY:?}" "${ENV_FILE:?}"
POLICY="${POLICY:-manual}"
STATE_DIR="${STATE_DIR:-/var/lib/monitor-update}"
STATE_DIR="${STATE_DIR:-/var/lib/moshiro-update}"
ENGINE="${ENGINE:-podman}"
SERVICE_SCOPE="${SERVICE_SCOPE:-system}"
DATA_VOLUME="${DATA_VOLUME:-}"
STATUS_VOLUME="${STATUS_VOLUME:-monitor-$COMPONENT-status}"
STATUS_VOLUME="${STATUS_VOLUME:-moshiro-$COMPONENT-status}"
case "$ENGINE" in podman|docker) ;; *) echo "unsupported engine: $ENGINE" >&2; exit 2 ;; esac
case "$SERVICE_SCOPE" in system|user) ;; *) echo "unsupported service scope: $SERVICE_SCOPE" >&2; exit 2 ;; esac
service_ctl() {
@@ -84,8 +84,8 @@ fetch_offer() {
for name in offer.manifest offer.sig; do
if [ -n "$DATA_VOLUME" ]; then
"$ENGINE" run --pull=never --rm --network none --read-only --cap-drop ALL --security-opt no-new-privileges \
-v "$DATA_VOLUME:/etc/monitor:ro" --entrypoint /bin/sh "$HELPER_IMAGE" \
-c 'f="/etc/monitor/update/$1"; if [ -f "$f" ] && [ ! -L "$f" ]; then head -c 8192 "$f"; fi' sh "$name" > "$WORK/$name"
-v "$DATA_VOLUME:/etc/moshiro:ro" --entrypoint /bin/sh "$HELPER_IMAGE" \
-c 'f="/etc/moshiro/update/$1"; if [ -f "$f" ] && [ ! -L "$f" ]; then head -c 8192 "$f"; fi' sh "$name" > "$WORK/$name"
continue
fi
f="$UPDATE_DIR/$name"
@@ -163,7 +163,7 @@ do_check() {
do_apply() {
if [ -n "$DATA_VOLUME" ]; then
"$ENGINE" run --pull=never --rm --network none --read-only --cap-drop ALL --security-opt no-new-privileges \
-v "$DATA_VOLUME:/etc/monitor" --entrypoint /bin/sh "$HELPER_IMAGE" -c 'rm -f /etc/monitor/update/apply.request'
-v "$DATA_VOLUME:/etc/moshiro" --entrypoint /bin/sh "$HELPER_IMAGE" -c 'rm -f /etc/moshiro/update/apply.request'
else
rm -f "$UPDATE_DIR/apply.request"
fi
@@ -200,8 +200,8 @@ case "$CMD" in
check)
if [ -n "$DATA_VOLUME" ] && [ "$POLICY" != auto ]; then
requested="$($ENGINE run --pull=never --rm --network none --read-only --cap-drop ALL --security-opt no-new-privileges \
-v "$DATA_VOLUME:/etc/monitor:ro" --entrypoint /bin/sh "$HELPER_IMAGE" \
-c '[ ! -f /etc/monitor/update/apply.request ] || printf yes')"
-v "$DATA_VOLUME:/etc/moshiro:ro" --entrypoint /bin/sh "$HELPER_IMAGE" \
-c '[ ! -f /etc/moshiro/update/apply.request ] || printf yes')"
if [ "$requested" = yes ]; then do_apply; else do_check; fi
else
do_check