Namespaces, assemblies, projects and directories, the solution, binaries, images, systemd units, config paths, environment variables, protocol method names, the media type and the raw chunk magic all move to MoShiro/moshiro. Existing data and deployments are not compatible and must be recreated. Also fix the architecture tests after the solution layout change and make the update tests independent of their order.
190 lines
7.3 KiB
Bash
190 lines
7.3 KiB
Bash
#!/bin/sh
|
|
# 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/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/moshiro
|
|
CONFIG=/etc/moshiro
|
|
USER_NAME=moshiro
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
# busybox on OpenWrt has no `install`
|
|
put() { cp "$2" "$3" && chmod "$1" "$3"; }
|
|
die() { echo "install.sh: $*" >&2; exit 1; }
|
|
say() { echo "==> $*"; }
|
|
|
|
[ "$(id -u)" -eq 0 ] || die "run as root"
|
|
|
|
init_system() {
|
|
if [ -d /run/systemd/system ]; then echo systemd
|
|
elif [ -f /etc/openwrt_release ]; then echo procd
|
|
else echo none; fi
|
|
}
|
|
|
|
check_openssl() {
|
|
for dir in /lib /usr/lib /lib64 /usr/lib64 /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu /lib/x86_64-linux-gnu /lib/aarch64-linux-gnu; do
|
|
ls "$dir"/libssl.so.3* >/dev/null 2>&1 && return 0
|
|
done
|
|
die "OpenSSL 3 (libssl.so.3) is required. Debian/Ubuntu: apt install libssl3 | Alpine: apk add libssl3 | OpenWrt: opkg install libopenssl3 (newer snapshots: apk add libopenssl3)"
|
|
}
|
|
|
|
ensure_user() {
|
|
id "$USER_NAME" >/dev/null 2>&1 && return 0
|
|
if command -v useradd >/dev/null 2>&1; then
|
|
useradd --system --no-create-home --shell /usr/sbin/nologin "$USER_NAME"
|
|
elif command -v adduser >/dev/null 2>&1; then
|
|
adduser -S -D -H -s /sbin/nologin "$USER_NAME" 2>/dev/null || adduser -S -H -s /bin/false "$USER_NAME" 2>/dev/null || true
|
|
fi
|
|
if ! id "$USER_NAME" >/dev/null 2>&1 && [ -w /etc/passwd ] && [ -w /etc/group ]; then
|
|
# OpenWrt: no useradd/adduser in the default busybox; add a system user by hand
|
|
uid=900
|
|
while grep -q "^[^:]*:[^:]*:$uid:" /etc/passwd /etc/group 2>/dev/null; do uid=$((uid + 1)); done
|
|
echo "$USER_NAME:x:$uid:" >>/etc/group
|
|
echo "$USER_NAME:x:$uid:$uid:$USER_NAME:/var/run/$USER_NAME:/bin/false" >>/etc/passwd
|
|
fi
|
|
id "$USER_NAME" >/dev/null 2>&1 || {
|
|
echo "warning: could not create the '$USER_NAME' user; the service will run as root" >&2
|
|
return 1
|
|
}
|
|
}
|
|
|
|
install_binary() {
|
|
src="$1"
|
|
[ -f "$HERE/$src" ] || die "$HERE/$src not found (is this an extracted release?)"
|
|
mkdir -p "$PREFIX"
|
|
put 0755 "$HERE/$src" "$PREFIX/$src"
|
|
}
|
|
|
|
write_agent_config() {
|
|
cat >"$CONFIG/agent.json" <<JSON
|
|
{
|
|
"fleet": { "server": "$1", "identity_dir": "$CONFIG" },
|
|
"listen": { "control_port": 7443, "udp_ports": [7443], "tcp_ports": [7444] },
|
|
"limits": { "max_total_mbps": 200, "max_total_pps": 20000, "allowed_target_cidrs": [], "max_concurrent_tests": 1 }
|
|
}
|
|
JSON
|
|
chmod 0640 "$CONFIG/agent.json"
|
|
if [ "$have_user" -eq 1 ]; then chown "root:$(id -gn "$USER_NAME")" "$CONFIG/agent.json"; fi
|
|
}
|
|
|
|
install_role() {
|
|
role="$1"; shift
|
|
server=""; join=""; name=""; probe_json=""; no_start=0
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--server) server="$2"; shift 2 ;;
|
|
--join) join="$2"; shift 2 ;;
|
|
--name) name="$2"; shift 2 ;;
|
|
--probe-json) probe_json="$2"; shift 2 ;;
|
|
--no-start) no_start=1; shift ;;
|
|
*) die "unknown option: $1" ;;
|
|
esac
|
|
done
|
|
|
|
check_openssl
|
|
have_user=0
|
|
ensure_user && have_user=1
|
|
mkdir -p "$CONFIG"
|
|
if [ "$have_user" -eq 1 ]; then chown "$USER_NAME" "$CONFIG"; fi
|
|
chmod 0750 "$CONFIG"
|
|
|
|
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/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/moshiro-probe.init" /etc/init.d/moshiro-probe
|
|
mkdir -p /lib/upgrade/keep.d
|
|
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
|
|
if [ "$role" = agent ]; then
|
|
if [ -n "$server" ] && [ ! -f "$CONFIG/node.json" ]; then
|
|
[ -n "$join" ] && [ -n "$name" ] || die "--server needs --join and --name to enroll"
|
|
say "enrolling as $name"
|
|
if [ "$have_user" -eq 1 ]; then
|
|
su -s /bin/sh "$USER_NAME" -c "'$PREFIX/fleet-enroll' --server '$server' --join '$join' --name '$name' --identity-dir '$CONFIG'"
|
|
else
|
|
"$PREFIX/fleet-enroll" --server "$server" --join "$join" --name "$name" --identity-dir "$CONFIG"
|
|
fi
|
|
fi
|
|
if [ ! -f "$CONFIG/agent.json" ] && [ -n "$server" ]; then write_agent_config "$server"; fi
|
|
if [ -f "$CONFIG/agent.json" ] && [ -f "$CONFIG/node.json" ]; then ready=1; fi
|
|
else
|
|
if [ -n "$probe_json" ]; then
|
|
put 0600 "$probe_json" "$CONFIG/probe.json"
|
|
if [ "$have_user" -eq 1 ]; then chown "$USER_NAME" "$CONFIG/probe.json"; fi
|
|
fi
|
|
if [ -f "$CONFIG/probe.json" ]; then ready=1; fi
|
|
fi
|
|
|
|
if [ "$ready" -eq 1 ] && [ "$no_start" -eq 0 ]; then
|
|
case "$init" in
|
|
systemd) systemctl enable --now "moshiro-$role" ;;
|
|
procd) /etc/init.d/moshiro-probe enable; /etc/init.d/moshiro-probe restart ;;
|
|
esac
|
|
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 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 moshiro-probe (OpenWrt: /etc/init.d/moshiro-probe enable && /etc/init.d/moshiro-probe start)"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
uninstall() {
|
|
role="$1"; purge=0
|
|
if [ "${2:-}" = "--purge" ]; then purge=1; fi
|
|
case "$(init_system)" in
|
|
systemd)
|
|
systemctl disable --now "moshiro-$role" 2>/dev/null || true
|
|
rm -f "/etc/systemd/system/moshiro-$role.service"
|
|
systemctl daemon-reload ;;
|
|
procd)
|
|
/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/moshiro-$role"
|
|
if [ "$role" = agent ]; then rm -f "$PREFIX/fleet-enroll"; fi
|
|
rmdir "$PREFIX" 2>/dev/null || true
|
|
if [ "$purge" -eq 1 ]; then
|
|
rm -rf "$CONFIG"
|
|
say "removed $CONFIG (identity included: the node must enroll again)"
|
|
else
|
|
say "kept $CONFIG (use --purge to remove the identity as well)"
|
|
fi
|
|
}
|
|
|
|
cmd="${1:-}"
|
|
case "$cmd" in
|
|
agent|probe) shift; install_role "$cmd" "$@" ;;
|
|
uninstall)
|
|
shift
|
|
role="${1:-}"
|
|
[ "$role" = agent ] || [ "$role" = probe ] || die "usage: install.sh uninstall agent|probe [--purge]"
|
|
shift
|
|
uninstall "$role" "$@" ;;
|
|
*) die "usage: install.sh agent|probe [options] | uninstall agent|probe [--purge]" ;;
|
|
esac
|