probe: add native OpenWrt deployment and signed automatic updates [CI]
This commit is contained in:
1 parent
24ba05fbb6
commit
cd193378a6
26 files changed
+987
-9
No files matched your search
@@ -0,0 +1,361 @@
|
||||
#!/bin/sh
|
||||
# Native OpenWrt Probe installer/updater. No container engine or .NET runtime.
|
||||
# Bootstrap: verify this script's published hash before running `sh install.sh install`.
|
||||
# Trust/configuration live outside the collector's writable identity directory.
|
||||
set -eu
|
||||
umask 077
|
||||
|
||||
ROOT=${MOSHIRO_NATIVE_ROOT:-/usr/lib/moshiro-native}
|
||||
CONF=${MOSHIRO_NATIVE_CONF:-/etc/moshiro-native.conf}
|
||||
STATE=${MOSHIRO_NATIVE_STATE:-/etc/moshiro-native-state}
|
||||
STATUS=${MOSHIRO_NATIVE_STATUS:-/var/run/moshiro-update}
|
||||
RUNTIME=${MOSHIRO_NATIVE_RUNTIME:-/var/run/moshiro-probe}
|
||||
ACTION=${1:-install}
|
||||
FEED=https://git.oeo.one/api/packages/justme/generic/moshiro-openwrt
|
||||
CHANNEL=${MOSHIRO_CHANNEL:-release}
|
||||
POLICY=auto
|
||||
INTERVAL=30
|
||||
HEALTH_TIMEOUT=90
|
||||
HEALTH_OBSERVE=20
|
||||
MAX_BYTES=67108864
|
||||
WORK=
|
||||
LOCK=
|
||||
STAGED=
|
||||
|
||||
die() { echo "moshiro-openwrt: $*" >&2; exit 1; }
|
||||
log() { echo "moshiro-openwrt: $*"; }
|
||||
ctl() {
|
||||
if [ "${MOSHIRO_NATIVE_TEST:-}" = 1 ]; then "$MOSHIRO_NATIVE_SERVICE" "$@"
|
||||
else /etc/init.d/moshiro-probe "$@"; fi
|
||||
}
|
||||
field() { jsonfilter -i "$WORK/manifest.json" -e "@.$1"; }
|
||||
download() {
|
||||
# curl never follows redirects; all downloads stay under the locally pinned feed.
|
||||
curl --fail --silent --show-error --connect-timeout 10 --max-time 120 \
|
||||
--proto '=https' --max-filesize "$2" "$1" -o "$3"
|
||||
[ "$(wc -c < "$3")" -le "$2" ] || die "download exceeds size limit"
|
||||
}
|
||||
cleanup() {
|
||||
[ -z "$WORK" ] || rm -rf "$WORK"
|
||||
[ -z "$LOCK" ] || rm -rf "$LOCK"
|
||||
[ -z "$STAGED" ] || rm -rf "$STAGED"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM HUP
|
||||
|
||||
status() {
|
||||
# Values are validated below; do not interpolate network-provided error messages.
|
||||
mkdir -p "$STATUS"
|
||||
chmod 755 "$STATUS"
|
||||
available=null
|
||||
case "$1" in available|applying|rolled_back)
|
||||
if [ -n "${VERSION:-}" ]; then
|
||||
available=$(printf '{"version":"%s","tag":"v%s","digest":"sha256:%s","seq":%s}' "$VERSION" "$VERSION" "$HASH" "$SEQ")
|
||||
fi ;;
|
||||
esac
|
||||
printf '{"state":"%s","current":"%s","available":%s,"error":"%s","at":%s}\n' \
|
||||
"$1" "$(readlink "$ROOT/current" 2>/dev/null | sed 's|.*/||')" "$available" "${2:-}" "$(date +%s)" > "$STATUS/status.new"
|
||||
chmod 644 "$STATUS/status.new"
|
||||
mv -f "$STATUS/status.new" "$STATUS/status.json"
|
||||
}
|
||||
|
||||
dependencies() {
|
||||
[ "$(id -u)" = 0 ] || [ "${MOSHIRO_NATIVE_TEST:-}" = 1 ] || die "run as root"
|
||||
[ -f /etc/openwrt_release ] || [ "${MOSHIRO_NATIVE_TEST:-}" = 1 ] || die "OpenWrt is required"
|
||||
missing=false
|
||||
for tool in curl openssl jsonfilter; do command -v "$tool" >/dev/null 2>&1 || missing=true; done
|
||||
if [ "$ACTION" = install ] && [ "$missing" = true ]; then
|
||||
if command -v opkg >/dev/null 2>&1; then
|
||||
opkg update
|
||||
opkg install curl ca-bundle openssl-util jsonfilter libopenssl3
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
apk add curl ca-bundle openssl-util jsonfilter libopenssl3
|
||||
fi
|
||||
fi
|
||||
for tool in curl openssl jsonfilter sha256sum tar readlink ubus; do
|
||||
command -v "$tool" >/dev/null 2>&1 || die "missing $tool; install curl ca-bundle openssl-util jsonfilter with opkg/apk"
|
||||
done
|
||||
}
|
||||
|
||||
load_config() {
|
||||
[ -f "$CONF" ] && [ ! -L "$CONF" ] || die "missing local updater configuration"
|
||||
# Root-owned configuration is intentionally shell data, never sourced from the feed.
|
||||
. "$CONF"
|
||||
case "$CHANNEL" in release|dev) ;; *) die "invalid channel" ;; esac
|
||||
case "$POLICY" in auto|manual) ;; *) die "invalid policy" ;; esac
|
||||
case "$RID" in linux-musl-arm64|linux-musl-x64) ;; *) die "unsupported architecture" ;; esac
|
||||
case "$FEED" in https://*) ;; *) die "feed must use HTTPS" ;; esac
|
||||
case "$FEED" in *[!A-Za-z0-9:/._-]*) die "invalid feed URL" ;; esac
|
||||
case "$INTERVAL" in ''|*[!0-9]*) die "invalid interval" ;; esac
|
||||
[ "$INTERVAL" -ge 5 ] || die "interval must be at least 5 seconds"
|
||||
}
|
||||
|
||||
acquire() {
|
||||
mkdir -p "$STATE" "$ROOT/versions"
|
||||
chmod 700 "$STATE"
|
||||
# /var/run is cleared on reboot. A crashed process leaves a recoverable PID lock.
|
||||
lockpath="$STATUS.lock"
|
||||
if ! mkdir "$lockpath" 2>/dev/null; then
|
||||
if [ -f "$lockpath/pid" ]; then
|
||||
owner=$(cat "$lockpath/pid")
|
||||
case "$owner" in ''|*[!0-9]*) return 1 ;; esac
|
||||
kill -0 "$owner" 2>/dev/null && return 1
|
||||
rm -f "$lockpath/pid"
|
||||
rmdir "$lockpath" 2>/dev/null || return 1
|
||||
mkdir "$lockpath" 2>/dev/null || return 1
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
LOCK=$lockpath
|
||||
echo $$ > "$LOCK/pid"
|
||||
for unfinished in "$ROOT"/versions/.stage.*; do
|
||||
[ ! -d "$unfinished" ] || rm -rf "$unfinished"
|
||||
done
|
||||
WORK=$(mktemp -d /tmp/moshiro-native.XXXXXX)
|
||||
}
|
||||
|
||||
verify() {
|
||||
download "$FEED/$CHANNEL/manifest-$RID.json" 8192 "$WORK/manifest.json" || return 1
|
||||
download "$FEED/$CHANNEL/manifest-$RID.sig" 1024 "$WORK/manifest.sig" || return 1
|
||||
base64 -d "$WORK/manifest.sig" > "$WORK/signature" 2>/dev/null || return 1
|
||||
openssl dgst -sha256 -verify "$STATE/release-key.pem" -signature "$WORK/signature" "$WORK/manifest.json" >/dev/null 2>&1 || return 1
|
||||
[ "$(field schema)" = 1 ] && [ "$(field component)" = probe ] \
|
||||
&& [ "$(field channel)" = "$CHANNEL" ] && [ "$(field rid)" = "$RID" ] || return 1
|
||||
HASH=$(field sha256); SIZE=$(field size); SEQ=$(field seq); VERSION=$(field version); PACKAGE=$(field package)
|
||||
case "$HASH" in ''|*[!0-9a-f]*) return 1 ;; esac
|
||||
[ "${#HASH}" = 64 ] || return 1
|
||||
case "$SEQ:$SIZE" in *[!0-9:]*) return 1 ;; esac
|
||||
[ -n "$SEQ" ] && [ "${#SEQ}" -le 15 ] && [ -n "$SIZE" ] && [ "${#SIZE}" -le 9 ] && [ "$SIZE" -gt 0 ] && [ "$SIZE" -le "$MAX_BYTES" ] || return 1
|
||||
case "$VERSION" in ''|*[!A-Za-z0-9.+_-]*) return 1 ;; esac
|
||||
[ "${#VERSION}" -le 100 ] && printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.-]+)?(\+[A-Za-z0-9.-]+)?$' || return 1
|
||||
[ "$PACKAGE" = "probe-$RID-$HASH.tar.gz" ] || return 1
|
||||
}
|
||||
|
||||
switch_to() {
|
||||
rm -f "$ROOT/current.new"
|
||||
ln -s "$1" "$ROOT/current.new"
|
||||
mv -fT "$ROOT/current.new" "$ROOT/current"
|
||||
}
|
||||
|
||||
recover() {
|
||||
if [ -f "$STATE/pending" ]; then
|
||||
previous=$(sed -n 1p "$STATE/pending")
|
||||
previous_hash=${previous#versions/}
|
||||
case "$previous_hash" in ''|*[!0-9a-f]*) die "invalid pending recovery record" ;; esac
|
||||
[ "$previous" = "versions/$previous_hash" ] && [ "${#previous_hash}" = 64 ] || die "invalid pending recovery record"
|
||||
[ -d "$ROOT/$previous" ] || die "previous version missing during recovery"
|
||||
switch_to "$previous"
|
||||
ctl restart
|
||||
rm -f "$STATE/pending"
|
||||
status rolled_back 'interrupted update recovered'
|
||||
fi
|
||||
}
|
||||
|
||||
stage() {
|
||||
# RAM must hold compressed archive and extraction must not fill the overlay.
|
||||
free_kb=$(df -Pk /tmp | awk 'END {print $4}')
|
||||
overlay_kb=$(df -Pk "$ROOT" | awk 'END {print $4}')
|
||||
[ "$free_kb" -gt $((SIZE / 1024 + 4096)) ] || die "not enough /tmp space"
|
||||
[ "$overlay_kb" -gt $((SIZE * 6 / 1024 + 8192)) ] || die "not enough installation space (allow archive expansion and rollback)"
|
||||
download "$FEED/$VERSION/$PACKAGE" "$SIZE" "$WORK/package.tar.gz" || return 1
|
||||
[ "$(wc -c < "$WORK/package.tar.gz")" -eq "$SIZE" ] || return 1
|
||||
echo "$HASH $WORK/package.tar.gz" | sha256sum -c - >/dev/null || return 1
|
||||
# Only a flat set of regular files is accepted, never symlinks, hardlinks or paths.
|
||||
tar -tzf "$WORK/package.tar.gz" > "$WORK/members" || return 1
|
||||
[ "$(wc -l < "$WORK/members")" -le 32 ] || return 1
|
||||
[ "$(sort -u "$WORK/members" | wc -l)" -eq "$(wc -l < "$WORK/members")" ] || return 1
|
||||
while IFS= read -r member; do
|
||||
case "$member" in
|
||||
moshiro-probe|fleet-enroll|openwrt.sh|probe.init|updater.init) ;;
|
||||
lib*.so.*) case "$member" in *[!A-Za-z0-9._+-]*) return 1 ;; esac ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
done < "$WORK/members"
|
||||
tar -tvzf "$WORK/package.tar.gz" > "$WORK/types" || return 1
|
||||
grep -q '^[^-]' "$WORK/types" && return 1
|
||||
# Signed manifests are the trust boundary. Bound expansion as a second safety limit.
|
||||
expanded=$(awk '{sum += $3} END {print sum+0}' "$WORK/types")
|
||||
[ "$expanded" -le 134217728 ] || return 1
|
||||
[ "$overlay_kb" -gt $((expanded / 1024 + 4096)) ] || return 1
|
||||
destination="$ROOT/versions/$HASH"
|
||||
[ ! -e "$destination" ] || return 0
|
||||
STAGED=$(mktemp -d "$ROOT/versions/.stage.XXXXXX")
|
||||
if ! tar -xzf "$WORK/package.tar.gz" -C "$STAGED"; then
|
||||
return 1
|
||||
fi
|
||||
for required in moshiro-probe fleet-enroll openwrt.sh probe.init updater.init; do
|
||||
[ -s "$STAGED/$required" ] || return 1
|
||||
chmod 755 "$STAGED/$required" || return 1
|
||||
done
|
||||
chmod 755 "$ROOT" "$ROOT/versions" "$STAGED" || return 1
|
||||
for library in "$STAGED"/lib*.so.*; do [ ! -f "$library" ] || chmod 644 "$library" || return 1; done
|
||||
mv "$STAGED" "$destination" || return 1
|
||||
STAGED=
|
||||
}
|
||||
|
||||
healthy() {
|
||||
# A PID alone is insufficient: require this version to complete a Backend heartbeat.
|
||||
elapsed=0
|
||||
stable_since=0
|
||||
stable_pid=
|
||||
while [ "$elapsed" -lt "$HEALTH_TIMEOUT" ]; do
|
||||
health="$RUNTIME/health.json"
|
||||
if [ -f "$health" ] && [ ! -L "$health" ]; then
|
||||
version=$(jsonfilter -i "$health" -e '@.version' 2>/dev/null || true)
|
||||
pid=$(jsonfilter -i "$health" -e '@.pid' 2>/dev/null || true)
|
||||
at=$(jsonfilter -i "$health" -e '@.at' 2>/dev/null || echo 0)
|
||||
active=$(ubus call service list '{"name":"moshiro-probe"}' 2>/dev/null | jsonfilter -e '@["moshiro-probe"].instances.*.pid' 2>/dev/null || true)
|
||||
case "$pid:$at" in ''|*[!0-9:]*) ;; *)
|
||||
now=$(date +%s)
|
||||
if [ "$version" = "$VERSION" ] && [ -n "$pid" ] && [ "$pid" = "$active" ] && [ "$at" -ge "$started" ] && [ $((now - at)) -le 30 ]; then
|
||||
if [ "$stable_pid" != "$pid" ]; then stable_pid=$pid; stable_since=$now; fi
|
||||
[ $((now - stable_since)) -lt "$HEALTH_OBSERVE" ] || return 0
|
||||
else
|
||||
stable_pid=
|
||||
fi ;;
|
||||
esac
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
check() {
|
||||
acquire || return 0
|
||||
recover
|
||||
requested=false
|
||||
if [ -f "$RUNTIME/apply.request" ] && [ ! -L "$RUNTIME/apply.request" ]; then requested=true; fi
|
||||
rm -f "$RUNTIME/apply.request"
|
||||
if ! verify; then status invalid 'feed unavailable or signature/metadata invalid'; return 1; fi
|
||||
current=$(readlink "$ROOT/current" 2>/dev/null || true)
|
||||
if [ "$current" = "versions/$HASH" ]; then status up_to_date; return 0; fi
|
||||
high=$(cat "$STATE/$CHANNEL.seq" 2>/dev/null || echo 0)
|
||||
[ "$SEQ" -gt "$high" ] || return 0
|
||||
status available
|
||||
if [ "$POLICY" != auto ] && [ "$requested" = false ]; then return 0; fi
|
||||
if ! stage; then status failed 'download, archive validation or extraction failed'; return 1; fi
|
||||
# High-water mark survives failed installs and rollbacks. Never retry a bad release.
|
||||
printf '%s\n' "$SEQ" > "$STATE/$CHANNEL.seq.new"
|
||||
mv -f "$STATE/$CHANNEL.seq.new" "$STATE/$CHANNEL.seq"
|
||||
printf '%s\n' "$current" > "$STATE/pending.new"
|
||||
mv -f "$STATE/pending.new" "$STATE/pending"
|
||||
sync
|
||||
status applying
|
||||
started=$(date +%s)
|
||||
switch_to "versions/$HASH"
|
||||
sync
|
||||
if ctl restart && healthy; then
|
||||
rm -f "$STATE/pending"
|
||||
status up_to_date
|
||||
# Keep current and exactly one previous version; no identity/config deletion.
|
||||
for directory in "$ROOT"/versions/*; do
|
||||
[ "$directory" = "$ROOT/versions/$HASH" ] || [ "$directory" = "$ROOT/$current" ] || rm -rf "$directory"
|
||||
done
|
||||
log "updated to $VERSION"
|
||||
else
|
||||
switch_to "$current"
|
||||
ctl restart
|
||||
rm -f "$STATE/pending"
|
||||
status rolled_back 'new version did not complete a Backend heartbeat'
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
restoring=false
|
||||
if [ -e "$CONF" ]; then
|
||||
load_config
|
||||
restoring=true
|
||||
fi
|
||||
case "$(uname -m)" in aarch64|arm64) detected_rid=linux-musl-arm64 ;; x86_64) detected_rid=linux-musl-x64 ;; *) die "only ARM64 and x86_64 are supported" ;; esac
|
||||
if [ "$restoring" = true ]; then
|
||||
[ "$RID" = "$detected_rid" ] || die "saved updater configuration belongs to a different architecture"
|
||||
fi
|
||||
RID=$detected_rid
|
||||
case "$CHANNEL" in release|dev) ;; *) die "MOSHIRO_CHANNEL must be release or dev" ;; esac
|
||||
if [ "$restoring" = false ]; then
|
||||
: "${MOSHIRO_SERVER:?panel URL required}" "${MOSHIRO_CODE:?join token required}" "${MOSHIRO_GENESIS:?trust root required}" "${MOSHIRO_CONTROLLERS:?owner required}"
|
||||
case "$MOSHIRO_SERVER" in https://*) ;; *) die "panel must use HTTPS" ;; esac
|
||||
case "$MOSHIRO_SERVER" in *[!A-Za-z0-9:/._-]*) die "unsupported panel URL characters" ;; esac
|
||||
[ ! -e /etc/moshiro/node.json ] && [ ! -e /etc/moshiro/probe.json ] || die "existing native identity/config found; migrate explicitly instead of overwriting it"
|
||||
else
|
||||
[ -f /etc/moshiro/node.json ] && [ -f /etc/moshiro/trust.json ] && [ -f /etc/moshiro/probe.json ] || die "saved identity/config incomplete; restore a backup before reinstalling"
|
||||
fi
|
||||
acquire || die "another installation is running"
|
||||
if [ ! -f "$STATE/release-key.pem" ]; then
|
||||
cat > "$STATE/release-key.pem" <<'KEY'
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfw7EkNcl0FZqOETK+Vt55RMZ9K0q
|
||||
YOrtO3Vso/QNdSMmepQlx1Q3v+KkN7ro3AY3I6DT2Q2txJu5pS7qzutSQA==
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
fi
|
||||
verify || die "no valid signed OpenWrt release for $CHANNEL/$RID"
|
||||
high=$(cat "$STATE/$CHANNEL.seq" 2>/dev/null || echo 0)
|
||||
[ "$SEQ" -ge "$high" ] || die "refusing to reinstall an older release"
|
||||
stage || die "could not validate and unpack release"
|
||||
id moshiro >/dev/null 2>&1 || {
|
||||
uid=900
|
||||
while awk -F: -v uid="$uid" '$3 == uid {found=1} END {exit !found}' /etc/passwd /etc/group; do uid=$((uid + 1)); done
|
||||
echo "moshiro:x:$uid:" >> /etc/group
|
||||
echo "moshiro:x:$uid:$uid:MoShiro:/var/run/moshiro-probe:/bin/false" >> /etc/passwd
|
||||
}
|
||||
mkdir -p /etc/moshiro "$RUNTIME"
|
||||
chmod 750 /etc/moshiro "$RUNTIME"
|
||||
# Enrollment tool is a one-shot trusted installer action. No dependency on BusyBox su.
|
||||
if [ "$restoring" = false ]; then
|
||||
LD_LIBRARY_PATH="$ROOT/versions/$HASH" "$ROOT/versions/$HASH/fleet-enroll" \
|
||||
--server "$MOSHIRO_SERVER" --join "$MOSHIRO_CODE" --name "${MOSHIRO_NAME:-$(uname -n)}" \
|
||||
--identity-dir /etc/moshiro --genesis "$MOSHIRO_GENESIS" --controllers "$MOSHIRO_CONTROLLERS"
|
||||
printf '{"fleet":{"server":"%s","identity_dir":"/etc/moshiro"},"limits":{"max_test_mbps":20,"max_total_pps":2000}}\n' "$MOSHIRO_SERVER" > /etc/moshiro/probe.json
|
||||
fi
|
||||
chown -R moshiro:moshiro /etc/moshiro "$RUNTIME"
|
||||
chmod 600 /etc/moshiro/node.key /etc/moshiro/tls.pfx
|
||||
if [ "$restoring" = false ]; then
|
||||
printf "FEED='%s'\nRID='%s'\nCHANNEL='%s'\nPOLICY='auto'\nINTERVAL=30\n" "$FEED" "$RID" "$CHANNEL" > "$CONF"
|
||||
fi
|
||||
chmod 600 "$CONF"
|
||||
switch_to "versions/$HASH"
|
||||
mkdir -p /usr/libexec
|
||||
ln -sf "$ROOT/current/openwrt.sh" /usr/libexec/moshiro-openwrt
|
||||
cp "$ROOT/current/probe.init" /etc/init.d/moshiro-probe
|
||||
cp "$ROOT/current/updater.init" /etc/init.d/moshiro-probe-update
|
||||
chmod 755 /etc/init.d/moshiro-probe /etc/init.d/moshiro-probe-update
|
||||
mkdir -p /lib/upgrade/keep.d
|
||||
printf '/etc/moshiro/\n%s\n%s/\n' "$CONF" "$STATE" > /lib/upgrade/keep.d/moshiro
|
||||
printf '%s\n' "$SEQ" > "$STATE/$CHANNEL.seq"
|
||||
status applying
|
||||
ctl enable
|
||||
started=$(date +%s)
|
||||
ctl restart
|
||||
if ! healthy; then
|
||||
status failed 'initial installation did not complete a Backend heartbeat; inspect logread'
|
||||
die "installed but not healthy; inspect logread -e moshiro, then rerun install (identity is preserved)"
|
||||
fi
|
||||
status up_to_date
|
||||
/etc/init.d/moshiro-probe-update enable
|
||||
/etc/init.d/moshiro-probe-update restart
|
||||
log "installed $VERSION ($CHANNEL/$RID); automatic signed updates enabled"
|
||||
}
|
||||
|
||||
dependencies
|
||||
case "$ACTION" in
|
||||
install) install ;;
|
||||
check) load_config; check ;;
|
||||
daemon)
|
||||
load_config
|
||||
ticks=$INTERVAL
|
||||
while :; do
|
||||
if [ "$ticks" -ge "$INTERVAL" ] || [ -f "$RUNTIME/check.request" ] || [ -f "$RUNTIME/apply.request" ]; then
|
||||
rm -f "$RUNTIME/check.request"
|
||||
/usr/libexec/moshiro-openwrt check || true
|
||||
ticks=0
|
||||
fi
|
||||
sleep 1
|
||||
ticks=$((ticks + 1))
|
||||
done ;;
|
||||
*) die "usage: $0 install|check|daemon" ;;
|
||||
esac
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=95
|
||||
STOP=10
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
[ -f /etc/moshiro/probe.json ] || return 1
|
||||
mkdir -p /var/run/moshiro-probe
|
||||
chown moshiro:moshiro /var/run/moshiro-probe
|
||||
chmod 750 /var/run/moshiro-probe
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/lib/moshiro-native/current/moshiro-probe --config /etc/moshiro/probe.json
|
||||
procd_set_param env LD_LIBRARY_PATH=/usr/lib/moshiro-native/current MOSHIRO_UPDATE=openwrt
|
||||
procd_set_param user moshiro
|
||||
procd_set_param group moshiro
|
||||
procd_set_param respawn 3600 5 0
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param limits nofile=4096
|
||||
procd_close_instance
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=96
|
||||
STOP=9
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
[ -f /etc/moshiro-native.conf ] || return 1
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/libexec/moshiro-openwrt daemon
|
||||
procd_set_param respawn 3600 5 0
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
Reference in new issue
Block a user