Skip to content

Commit 8a2d8cf

Browse files
authored
Merge pull request #226 from wnlen/dev
fix(tun): rollback tun state on config sync failure and stage runtime…
2 parents f258692 + 45a2628 commit 8a2d8cf

2 files changed

Lines changed: 246 additions & 63 deletions

File tree

scripts/core/clashctl.sh

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,22 @@ status_tun_last_verify_time() {
554554
read_tun_last_verify_time 2>/dev/null || true
555555
}
556556

557+
status_tun_last_action() {
558+
read_tun_last_action 2>/dev/null || true
559+
}
560+
561+
status_tun_last_action_result() {
562+
read_tun_last_action_result 2>/dev/null || true
563+
}
564+
565+
status_tun_last_action_reason() {
566+
read_tun_last_action_reason 2>/dev/null || true
567+
}
568+
569+
status_tun_last_action_time() {
570+
read_tun_last_action_time 2>/dev/null || true
571+
}
572+
557573
status_tun_effective_status() {
558574
local enabled result
559575

@@ -1730,6 +1746,7 @@ status_risk_reason_lines() {
17301746
local build_block_reason build_block_time
17311747
local fallback_used fallback_time fallback_reason
17321748
local tun_enabled tun_effective tun_container_mode tun_kernel_support tun_verify_reason
1749+
local tun_action_result tun_action_reason tun_action_time
17331750
local bind_failure_text mixed_port
17341751

17351752
build_status="$(status_build_last_status 2>/dev/null || true)"
@@ -1749,6 +1766,9 @@ status_risk_reason_lines() {
17491766
tun_container_mode="$(status_tun_container_mode 2>/dev/null || echo unknown)"
17501767
tun_kernel_support="$(status_tun_kernel_support_level 2>/dev/null || echo unknown)"
17511768
tun_verify_reason="$(status_tun_last_verify_reason 2>/dev/null || true)"
1769+
tun_action_result="$(status_tun_last_action_result 2>/dev/null || true)"
1770+
tun_action_reason="$(status_tun_last_action_reason 2>/dev/null || true)"
1771+
tun_action_time="$(status_tun_last_action_time 2>/dev/null || true)"
17521772

17531773
if ! status_is_running; then
17541774
if [ -n "${bind_failure_text:-}" ]; then
@@ -1797,6 +1817,14 @@ status_risk_reason_lines() {
17971817
echo "• 订阅 ${last_risk_name} 连续失败 ${last_risk_fail_count:-?} 次(阈值 ${last_risk_threshold:-?}"
17981818
fi
17991819

1820+
if [ "${tun_action_result:-}" = "failed" ]; then
1821+
if [ -n "${tun_action_time:-}" ]; then
1822+
echo "• 最近一次 Tun 配置同步失败:${tun_action_reason:-unknown} @ ${tun_action_time}"
1823+
else
1824+
echo "• 最近一次 Tun 配置同步失败:${tun_action_reason:-unknown}"
1825+
fi
1826+
fi
1827+
18001828
if [ "$tun_enabled" = "true" ] && [ "$tun_effective" != "effective" ]; then
18011829
echo "• Tun 未生效"
18021830
fi
@@ -4698,8 +4726,9 @@ cmd_tun_on() {
46984726
;;
46994727
esac
47004728

4701-
set_tun_enabled "true"
4702-
regenerate_config
4729+
if ! sync_tun_target_state "on" "true"; then
4730+
return 1
4731+
fi
47034732

47044733
if status_is_running; then
47054734
service_restart
@@ -4732,8 +4761,9 @@ cmd_tun_off() {
47324761

47334762
prepare
47344763

4735-
set_tun_enabled "false"
4736-
regenerate_config
4764+
if ! sync_tun_target_state "off" "false"; then
4765+
return 1
4766+
fi
47374767

47384768
if status_is_running; then
47394769
service_restart
@@ -5607,10 +5637,14 @@ tun_problem_lines() {
56075637
local enabled env_type config_tun_enabled auto_route
56085638
local effective_result disable_result route_dev
56095639
local container_mode risk_reason
5640+
local last_action_result last_action_reason last_action_time
56105641
local kernel_support
56115642
kernel_support="$(tun_kernel_support_level 2>/dev/null || echo unknown)"
56125643
container_mode="$(tun_container_mode 2>/dev/null || echo unknown)"
56135644
risk_reason="$(tun_container_risk_reason 2>/dev/null || true)"
5645+
last_action_result="$(status_tun_last_action_result 2>/dev/null || true)"
5646+
last_action_reason="$(status_tun_last_action_reason 2>/dev/null || true)"
5647+
last_action_time="$(status_tun_last_action_time 2>/dev/null || true)"
56145648

56155649
enabled="$(tun_enabled 2>/dev/null || echo false)"
56165650
env_type="$(container_env_type 2>/dev/null || echo unknown)"
@@ -5657,6 +5691,14 @@ tun_problem_lines() {
56575691
;;
56585692
esac
56595693

5694+
if [ "${last_action_result:-}" = "failed" ]; then
5695+
if [ -n "${last_action_time:-}" ]; then
5696+
echo "• 最近一次 Tun 配置同步失败:${last_action_reason:-unknown} @ ${last_action_time}"
5697+
else
5698+
echo "• 最近一次 Tun 配置同步失败:${last_action_reason:-unknown}"
5699+
fi
5700+
fi
5701+
56605702
if ! runtime_config_exists 2>/dev/null; then
56615703
echo "• 运行时配置不存在"
56625704
return 0
@@ -5693,6 +5735,37 @@ tun_problem_lines() {
56935735
fi
56945736
}
56955737

5738+
sync_tun_target_state() {
5739+
local action="$1"
5740+
local target="$2"
5741+
local previous sync_output rc error_summary
5742+
5743+
previous="$(tun_enabled 2>/dev/null || echo false)"
5744+
set_tun_enabled "$target"
5745+
5746+
if sync_output="$(regenerate_config 2>&1)"; then
5747+
return 0
5748+
fi
5749+
5750+
rc=$?
5751+
set_tun_enabled "$previous"
5752+
5753+
error_summary="$(build_last_error_summary 2>/dev/null || true)"
5754+
if [ -z "${error_summary:-}" ]; then
5755+
error_summary="$(printf '%s\n' "$sync_output" | sed '/^[[:space:]]*$/d' | tail -n 1)"
5756+
fi
5757+
error_summary="$(single_line_text "${error_summary:-配置重建失败}")"
5758+
[ -n "${error_summary:-}" ] || error_summary="配置重建失败"
5759+
5760+
mark_tun_last_action "$action" "failed" "$error_summary"
5761+
mark_tun_last_verification "failed" "config-sync-failed"
5762+
5763+
ui_error "Tun 配置同步失败,已回滚状态文件"
5764+
ui_error "$error_summary"
5765+
ui_next "clashctl tun doctor"
5766+
return "$rc"
5767+
}
5768+
56965769
cmd_tun() {
56975770
case "${1:-}" in
56985771
""|status)

0 commit comments

Comments
 (0)