Files
small-packages/honk/files/honk.init
T
2026-11-01 17:09:57 +08:00

86 lines
3.9 KiB
Bash
Executable File

#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=10
. /lib/functions.sh
HONK_CONTROL=/usr/share/honk/control.sh
HONK_CONFIG=/etc/honk/config.dae
boot() {
# 开机自启内置:只要服务是"已启用 + 已初始化"就起来,
# 用户主动停掉(enabled=0)后重启也不会被强行拉起。
start
}
start_service() {
local enabled initialized config_file config_mode ready_token ready_hash ready_runtime ready_api_enabled ready_api_listen ready_clash_api_listen ready_clash_api_secret_set old_ready_token
config_load honk
config_get_bool enabled main enabled 0
config_get_bool initialized main initialized 0
[ "$enabled" -eq 1 ] && [ "$initialized" -eq 1 ] || {
logger -t honk "refusing to start before explicit initialization and enablement"
return 1
}
config_get config_file main config_file "$HONK_CONFIG"
config_get config_mode main config_mode managed
[ "$config_file" = "$HONK_CONFIG" ] || {
logger -t honk "refusing non-default config path"
return 1
}
"$HONK_CONTROL" preflight || return 1
"$HONK_CONTROL" local-direct || logger -t honk "local-direct sync skipped"
unset HONK_MAINT_CAP
if [ "$config_mode" = manual ]; then
ready_token=$(cat /proc/sys/kernel/random/uuid 2>/dev/null) || return 1
case "$ready_token" in *[!0-9a-f-]*|'') return 1 ;; esac
ready_hash=$(sha256sum "$HONK_CONFIG" 2>/dev/null | awk '{print $1}') || return 1
case "$ready_hash" in *[!0-9a-f]*|'') return 1 ;; esac
ready_runtime=$(/usr/bin/honk-core config validate --config "$HONK_CONFIG" 2>/dev/null) || return 1
ready_api_enabled=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.native_api_enabled' 2>/dev/null)
ready_api_listen=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.native_api_listen' 2>/dev/null)
ready_clash_api_listen=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.clash_api_listen' 2>/dev/null)
ready_clash_api_secret_set=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.clash_api_secret_set' 2>/dev/null)
case "$ready_api_enabled" in true|false) ;; *) return 1 ;; esac
case "$ready_api_listen" in *[!A-Za-z0-9:._-]*) return 1 ;; esac
case "$ready_clash_api_listen" in *[!A-Za-z0-9:._-]*) return 1 ;; esac
case "$ready_clash_api_secret_set" in true|false) ;; *) return 1 ;; esac
mkdir -p /var/run/honk || return 1
chmod 0700 /var/run/honk || return 1
if [ -f /var/run/honk/readiness ] && [ ! -L /var/run/honk/readiness ]; then
read -r old_ready_token _ < /var/run/honk/readiness
case "$old_ready_token" in ''|*[!0-9a-f-]*) ;; *) rm -f "/var/run/honk/core-ready-$old_ready_token" ;; esac
fi
printf '%s %s\n' "$ready_token" "$ready_hash" > /var/run/honk/readiness || return 1
chmod 0600 /var/run/honk/readiness || return 1
fi
procd_open_instance main
procd_set_param command /usr/bin/honk-core --config "$HONK_CONFIG" --disable-timestamp
# One env call, no empty values: procd drops the whole list when a KEY has an
# empty value, which silently stripped the readiness hash the core requires.
ready_env="DAE_LOCATION_ASSET=/usr/share/v2ray"
if [ "$config_mode" = manual ]; then
ready_env="$ready_env HONK_READY_TOKEN=$ready_token HONK_READY_CONFIG_HASH=$ready_hash HONK_READY_API_ENABLED=$ready_api_enabled HONK_READY_CLASH_API_SECRET_SET=$ready_clash_api_secret_set"
[ -n "$ready_api_listen" ] && ready_env="$ready_env HONK_READY_API_LISTEN=$ready_api_listen"
[ -n "$ready_clash_api_listen" ] && ready_env="$ready_env HONK_READY_CLASH_API_LISTEN=$ready_clash_api_listen"
fi
# shellcheck disable=SC2086
procd_set_param env $ready_env
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn 3600 5 5
procd_set_param term_timeout 20
procd_close_instance
}
reload_service() {
# honk-core has no hot-reload API wired here; a reload is an explicit
# restart so existing connections are cycled. The UI only exposes
# restart, this exists so manual `/etc/init.d/honk reload` is defined.
logger -t honk "reload requested, restarting (no hot-reload)"
restart
}