mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-10-10 20:23:04 +08:00
Detect stale systemd service templates in doctor
This commit is contained in:
@@ -3129,6 +3129,51 @@ logs_service() {
|
||||
esac
|
||||
}
|
||||
|
||||
systemd_unit_file_path() {
|
||||
printf '/etc/systemd/system/%s\n' "$(service_unit_name)"
|
||||
}
|
||||
|
||||
systemd_user_unit_file_path() {
|
||||
printf '%s/.config/systemd/user/%s\n' "$(user_home_dir)" "$(service_unit_name)"
|
||||
}
|
||||
|
||||
systemd_unit_has_stale_runtime_template() {
|
||||
local unit_file="$1"
|
||||
|
||||
[ -f "$unit_file" ] || return 1
|
||||
|
||||
grep -Eq '^[[:space:]]*Type=forking([[:space:]]|$)|^[[:space:]]*PIDFile=|clashctl[[:space:]]+start-direct' "$unit_file"
|
||||
}
|
||||
|
||||
systemd_unit_stale_runtime_template_warning() {
|
||||
local backend="$1"
|
||||
local unit_file label refresh_cmd restart_cmd
|
||||
|
||||
case "$backend" in
|
||||
systemd)
|
||||
unit_file="$(systemd_unit_file_path)"
|
||||
label="systemd"
|
||||
refresh_cmd="sudo bash install.sh system"
|
||||
restart_cmd="sudo systemctl restart $(service_unit_name)"
|
||||
;;
|
||||
systemd-user)
|
||||
unit_file="$(systemd_user_unit_file_path)"
|
||||
label="用户级 systemd"
|
||||
refresh_cmd="bash install.sh user"
|
||||
restart_cmd="systemctl --user restart $(service_unit_name)"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
systemd_unit_has_stale_runtime_template "$unit_file" || return 1
|
||||
|
||||
echo "${label} 服务文件仍是旧模板:$unit_file"
|
||||
echo "建议刷新服务文件:$refresh_cmd"
|
||||
echo "刷新后重启服务:$restart_cmd"
|
||||
}
|
||||
|
||||
cmd_logs() {
|
||||
prepare
|
||||
|
||||
@@ -3595,7 +3640,7 @@ doctor_build() {
|
||||
}
|
||||
|
||||
doctor_service() {
|
||||
local backend
|
||||
local backend stale_warning
|
||||
|
||||
doctor_print_title "服务检查"
|
||||
|
||||
@@ -3608,6 +3653,12 @@ doctor_service() {
|
||||
|
||||
case "$backend" in
|
||||
systemd)
|
||||
stale_warning="$(systemd_unit_stale_runtime_template_warning systemd 2>/dev/null || true)"
|
||||
if [ -n "${stale_warning:-}" ]; then
|
||||
doctor_warn "$stale_warning"
|
||||
else
|
||||
doctor_ok "systemd 服务模板:当前版本"
|
||||
fi
|
||||
if systemctl is-active --quiet "$(service_unit_name)"; then
|
||||
doctor_ok "systemd 服务运行中"
|
||||
systemctl show "$(service_unit_name)" --property MainPID --value 2>/dev/null | awk '{print " 进程号:" $1}'
|
||||
@@ -3616,6 +3667,12 @@ doctor_service() {
|
||||
fi
|
||||
;;
|
||||
systemd-user)
|
||||
stale_warning="$(systemd_unit_stale_runtime_template_warning systemd-user 2>/dev/null || true)"
|
||||
if [ -n "${stale_warning:-}" ]; then
|
||||
doctor_warn "$stale_warning"
|
||||
else
|
||||
doctor_ok "用户级 systemd 服务模板:当前版本"
|
||||
fi
|
||||
if systemctl --user is-active --quiet "$(service_unit_name)"; then
|
||||
doctor_ok "用户级 systemd 服务运行中"
|
||||
systemctl --user show "$(service_unit_name)" --property MainPID --value 2>/dev/null | awk '{print " 进程号:" $1}'
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
source_clashctl_for_tests() {
|
||||
set -- ""
|
||||
source "$PROJECT_DIR/scripts/core/clashctl.sh" >/dev/null
|
||||
}
|
||||
|
||||
source_clashctl_for_tests
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp_dir"' EXIT
|
||||
|
||||
test_unit_file="$tmp_dir/clash-for-linux.service"
|
||||
|
||||
service_unit_name() { printf 'clash-for-linux.service\n'; }
|
||||
|
||||
run_case() {
|
||||
local name="$1"
|
||||
local expected="$2"
|
||||
local content="$3"
|
||||
|
||||
printf '%s\n' "$content" > "$test_unit_file"
|
||||
|
||||
case "$expected" in
|
||||
stale)
|
||||
if ! systemd_unit_has_stale_runtime_template "$test_unit_file"; then
|
||||
echo "not ok - $name: stale unit was not detected" >&2
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
fresh)
|
||||
if systemd_unit_has_stale_runtime_template "$test_unit_file"; then
|
||||
echo "not ok - $name: fresh unit was marked stale" >&2
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "not ok - bad expected value: $expected" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "ok - $name"
|
||||
}
|
||||
|
||||
run_case "detects forking type" stale '[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/local/bin/clashctl run-direct'
|
||||
|
||||
run_case "detects pid file" stale '[Service]
|
||||
Type=simple
|
||||
PIDFile=/tmp/mihomo.pid
|
||||
ExecStart=/usr/local/bin/clashctl run-direct'
|
||||
|
||||
run_case "detects old start direct command" stale '[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/clashctl start-direct'
|
||||
|
||||
run_case "accepts current run direct template" fresh '[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/clashctl run-direct
|
||||
ExecStopPost=/bin/rm -f /tmp/mihomo.pid'
|
||||
|
||||
systemd_unit_file_path() { printf '%s\n' "$test_unit_file"; }
|
||||
systemd_user_unit_file_path() { printf '%s\n' "$test_unit_file"; }
|
||||
|
||||
printf '%s\n' '[Service]
|
||||
Type=forking
|
||||
PIDFile=/tmp/mihomo.pid
|
||||
ExecStart=/usr/local/bin/clashctl start-direct' > "$test_unit_file"
|
||||
|
||||
output="$(systemd_unit_stale_runtime_template_warning systemd)"
|
||||
if ! printf '%s\n' "$output" | grep -Fq "systemd 服务文件仍是旧模板"; then
|
||||
echo "not ok - systemd warning missing" >&2
|
||||
printf '%s\n' "$output" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
output="$(systemd_unit_stale_runtime_template_warning systemd-user)"
|
||||
if ! printf '%s\n' "$output" | grep -Fq "用户级 systemd 服务文件仍是旧模板"; then
|
||||
echo "not ok - systemd-user warning missing" >&2
|
||||
printf '%s\n' "$output" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "ok - stale unit warning text"
|
||||
Reference in New Issue
Block a user