mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-10 20:32:21 +08:00
fix(linux): report an unrestored Service state regardless of readiness
Refs #8515
This commit is contained in:
@@ -92,17 +92,15 @@ pub(crate) async fn notify_incomplete_service_upgrade() {
|
||||
return;
|
||||
}
|
||||
let status = SERVICE_MANAGER.current().await;
|
||||
match service_upgrade_notice(&marker, matches!(status, ServiceStatus::Ready)) {
|
||||
Some(ServiceUpgradeNotice::Reinstall) => {
|
||||
logging!(warn, Type::Service, "安装包升级后服务未就绪: {status:?}");
|
||||
*PENDING_SERVICE_FALLBACK_NOTICE.lock() = Some(SERVICE_UPGRADE_INCOMPLETE.to_owned());
|
||||
Handle::notice(NoticeStatus::ServiceCoreSidecarFallback, "");
|
||||
}
|
||||
Some(ServiceUpgradeNotice::StateNotRestored(state)) => {
|
||||
logging!(warn, Type::Service, "安装包升级后未能恢复服务原状态: {state}");
|
||||
Handle::notice(NoticeStatus::ServiceCoreUpgradeStateNotRestored, state);
|
||||
}
|
||||
None => {}
|
||||
let notice = service_upgrade_notice(&marker, matches!(status, ServiceStatus::Ready));
|
||||
if notice.reinstall {
|
||||
logging!(warn, Type::Service, "安装包升级后服务未就绪: {status:?}");
|
||||
*PENDING_SERVICE_FALLBACK_NOTICE.lock() = Some(SERVICE_UPGRADE_INCOMPLETE.to_owned());
|
||||
Handle::notice(NoticeStatus::ServiceCoreSidecarFallback, "");
|
||||
}
|
||||
if let Some(state) = notice.unrestored_state {
|
||||
logging!(warn, Type::Service, "安装包升级后未能恢复服务原状态: {state}");
|
||||
Handle::notice(NoticeStatus::ServiceCoreUpgradeStateNotRestored, state);
|
||||
}
|
||||
if let Err(error) = std::fs::write(&ack, id) {
|
||||
logging!(warn, Type::Service, "无法记录服务升级确认: {error}");
|
||||
@@ -111,21 +109,18 @@ pub(crate) async fn notify_incomplete_service_upgrade() {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum ServiceUpgradeNotice<'a> {
|
||||
Reinstall,
|
||||
/// A reinstall would enable and start the Service again, so it cannot restore this state.
|
||||
StateNotRestored(&'a str),
|
||||
struct ServiceUpgradeNotice<'a> {
|
||||
reinstall: bool,
|
||||
/// Reported regardless of readiness: a reinstall enables and starts the Service, so it cannot restore this state.
|
||||
unrestored_state: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn service_upgrade_notice(marker: &str, ready: bool) -> Option<ServiceUpgradeNotice<'_>> {
|
||||
if !ready {
|
||||
return Some(ServiceUpgradeNotice::Reinstall);
|
||||
fn service_upgrade_notice(marker: &str, ready: bool) -> ServiceUpgradeNotice<'_> {
|
||||
ServiceUpgradeNotice {
|
||||
reinstall: !ready,
|
||||
unrestored_state: marker.lines().find_map(|line| line.strip_prefix("restore=")),
|
||||
}
|
||||
marker
|
||||
.lines()
|
||||
.find_map(|line| line.strip_prefix("restore="))
|
||||
.map(ServiceUpgradeNotice::StateNotRestored)
|
||||
}
|
||||
|
||||
pub(crate) fn take_service_fallback_notice() -> Option<ServiceFallbackNotice> {
|
||||
@@ -2855,21 +2850,22 @@ mod tests {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn upgrade_marker_reports_unrestored_state_only_for_a_ready_service() {
|
||||
fn upgrade_marker_reports_unrestored_state_regardless_of_readiness() {
|
||||
let restored = "gid=995\nid=1\n";
|
||||
let unrestored = "gid=995\nid=1\nrestore=disabled,inactive\n";
|
||||
let unrestored = "gid=995\nid=1\nrestore=disabled,active\n";
|
||||
let notice = |reinstall, unrestored_state| ServiceUpgradeNotice {
|
||||
reinstall,
|
||||
unrestored_state,
|
||||
};
|
||||
assert_eq!(service_upgrade_notice(restored, true), notice(false, None));
|
||||
assert_eq!(service_upgrade_notice(restored, false), notice(true, None));
|
||||
assert_eq!(
|
||||
service_upgrade_notice(restored, false),
|
||||
Some(ServiceUpgradeNotice::Reinstall)
|
||||
service_upgrade_notice(unrestored, true),
|
||||
notice(false, Some("disabled,active"))
|
||||
);
|
||||
assert_eq!(
|
||||
service_upgrade_notice(unrestored, false),
|
||||
Some(ServiceUpgradeNotice::Reinstall)
|
||||
);
|
||||
assert_eq!(service_upgrade_notice(restored, true), None);
|
||||
assert_eq!(
|
||||
service_upgrade_notice(unrestored, true),
|
||||
Some(ServiceUpgradeNotice::StateNotRestored("disabled,inactive"))
|
||||
notice(true, Some("disabled,active"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "تعذّر على الخدمة التأكد من أن ملفات النواة ومجلداتها آمنة للتشغيل بصلاحيات مرتفعة.",
|
||||
"permissionRepairGuide": "عرض خطوات الإصلاح",
|
||||
"sidecarFallback": "تعذّر على الخدمة تشغيل النواة. تم التبديل إلى وضع Sidecar؛ ولا تزال الخدمة غير متاحة.",
|
||||
"upgradeStateNotRestored": "أعادت الترقية تثبيت خدمة Clash Verge لكنها لم تتمكن من استعادة حالة بدء التشغيل والتشغيل السابقة ({{state}}). لن تؤدي إعادة تثبيت الخدمة إلى استعادتها؛ تحقق منها باستخدام systemctl status clash-verge-service واضبطها باستخدام systemctl.",
|
||||
"upgradeStateNotRestored": "بعد الترقية تعذّرت استعادة حالة بدء التشغيل والتشغيل السابقة لخدمة Clash Verge ({{state}}). لن تؤدي إعادة تثبيت الخدمة إلى استعادتها؛ تحقق منها باستخدام systemctl status clash-verge-service واضبطها باستخدام systemctl.",
|
||||
"uninstallSuccess": "تم إلغاء تثبيت الخدمة بنجاح"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "Der Dienst konnte nicht bestätigen, dass die Kerndateien und Ordner für die Ausführung mit erhöhten Rechten sicher sind.",
|
||||
"permissionRepairGuide": "Reparaturanleitung öffnen",
|
||||
"sidecarFallback": "Der Dienst konnte den Kern nicht starten. Die Anwendung läuft im Sidecar-Modus weiter; der Dienst bleibt nicht verfügbar.",
|
||||
"upgradeStateNotRestored": "Das Upgrade hat den Clash Verge-Dienst neu installiert, konnte aber seinen vorherigen Autostart- und Laufzustand ({{state}}) nicht wiederherstellen. Eine Neuinstallation des Dienstes stellt ihn nicht wieder her; prüfen Sie ihn mit systemctl status clash-verge-service und passen Sie ihn mit systemctl an.",
|
||||
"upgradeStateNotRestored": "Nach dem Upgrade konnte der vorherige Autostart- und Laufzustand des Clash Verge-Dienstes ({{state}}) nicht wiederhergestellt werden. Eine Neuinstallation des Dienstes stellt ihn nicht wieder her; prüfen Sie ihn mit systemctl status clash-verge-service und passen Sie ihn mit systemctl an.",
|
||||
"uninstallSuccess": "Service erfolgreich deinstalliert"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "The service could not confirm that the core files and folders are safe to run with elevated privileges.",
|
||||
"permissionRepairGuide": "View repair instructions",
|
||||
"sidecarFallback": "The service could not start the core. Switched to Sidecar mode; the service remains unavailable.",
|
||||
"upgradeStateNotRestored": "The upgrade reinstalled the Clash Verge service but could not restore its previous startup and running state ({{state}}). Reinstalling the service will not restore it; check it with systemctl status clash-verge-service and adjust it with systemctl.",
|
||||
"upgradeStateNotRestored": "After the upgrade, Clash Verge could not restore the service's previous startup and running state ({{state}}). Reinstalling the service will not restore it; check it with systemctl status clash-verge-service and adjust it with systemctl.",
|
||||
"uninstallSuccess": "Service Uninstalled Successfully"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "El servicio no pudo confirmar que los archivos y carpetas del núcleo sean seguros para ejecutarlos con privilegios elevados.",
|
||||
"permissionRepairGuide": "Ver instrucciones de reparación",
|
||||
"sidecarFallback": "El servicio no pudo iniciar el núcleo. Se ha cambiado al modo Sidecar; el servicio sigue sin estar disponible.",
|
||||
"upgradeStateNotRestored": "La actualización reinstaló el servicio de Clash Verge, pero no pudo restaurar su estado anterior de inicio y ejecución ({{state}}). Reinstalar el servicio no lo restaurará; compruébelo con systemctl status clash-verge-service y ajústelo con systemctl.",
|
||||
"upgradeStateNotRestored": "Tras la actualización no se pudo restaurar el estado anterior de inicio y ejecución del servicio de Clash Verge ({{state}}). Reinstalar el servicio no lo restaurará; compruébelo con systemctl status clash-verge-service y ajústelo con systemctl.",
|
||||
"uninstallSuccess": "Servicio desinstalado con éxito"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "سرویس نتوانست ایمن بودن فایلها و پوشههای هسته را برای اجرا با دسترسی بالا تأیید کند.",
|
||||
"permissionRepairGuide": "مشاهدهٔ راهنمای رفع مشکل",
|
||||
"sidecarFallback": "سرویس نتوانست هسته را اجرا کند. اجرا در حالت Sidecar ادامه مییابد؛ سرویس همچنان در دسترس نیست.",
|
||||
"upgradeStateNotRestored": "ارتقا سرویس Clash Verge را دوباره نصب کرد اما نتوانست وضعیت قبلی راهاندازی خودکار و اجرای آن ({{state}}) را بازگرداند. نصب دوباره سرویس آن را بازنمیگرداند؛ با systemctl status clash-verge-service آن را بررسی و با systemctl تنظیم کنید.",
|
||||
"upgradeStateNotRestored": "پس از ارتقا، وضعیت قبلی راهاندازی خودکار و اجرای سرویس Clash Verge ({{state}}) بازگردانده نشد. نصب دوباره سرویس آن را بازنمیگرداند؛ با systemctl status clash-verge-service آن را بررسی و با systemctl تنظیم کنید.",
|
||||
"uninstallSuccess": "سرویس با موفقیت حذف نصب شد"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "Layanan tidak dapat memastikan bahwa berkas dan folder inti aman dijalankan dengan hak istimewa.",
|
||||
"permissionRepairGuide": "Lihat panduan perbaikan",
|
||||
"sidecarFallback": "Layanan tidak dapat memulai inti. Beralih ke mode Sidecar; layanan masih tidak tersedia.",
|
||||
"upgradeStateNotRestored": "Pembaruan telah memasang ulang layanan Clash Verge tetapi tidak dapat memulihkan status mulai otomatis dan berjalan sebelumnya ({{state}}). Memasang ulang layanan tidak akan memulihkannya; periksa dengan systemctl status clash-verge-service dan sesuaikan dengan systemctl.",
|
||||
"upgradeStateNotRestored": "Setelah pembaruan, status mulai otomatis dan berjalan sebelumnya dari layanan Clash Verge ({{state}}) tidak dapat dipulihkan. Memasang ulang layanan tidak akan memulihkannya; periksa dengan systemctl status clash-verge-service dan sesuaikan dengan systemctl.",
|
||||
"uninstallSuccess": "Layanan Berhasil Dicopot"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "コアファイルとフォルダーを高い権限で安全に実行できるか確認できませんでした。",
|
||||
"permissionRepairGuide": "修復方法を見る",
|
||||
"sidecarFallback": "サービスでコアを起動できなかったため、Sidecar モードで動作を継続しています。サービスは引き続き利用できません。",
|
||||
"upgradeStateNotRestored": "アップグレードで Clash Verge サービスを再インストールしましたが、以前の自動起動と実行状態({{state}})を復元できませんでした。サービスを再インストールしても復元されません。systemctl status clash-verge-service で状態を確認し、systemctl で調整してください。",
|
||||
"upgradeStateNotRestored": "アップグレード後、Clash Verge サービスの以前の自動起動と実行状態({{state}})を復元できませんでした。サービスを再インストールしても復元されません。systemctl status clash-verge-service で状態を確認し、systemctl で調整してください。",
|
||||
"uninstallSuccess": "サービスのアンインストールに成功しました。"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "서비스가 코어 파일과 폴더를 높은 권한으로 안전하게 실행할 수 있는지 확인하지 못했습니다.",
|
||||
"permissionRepairGuide": "해결 방법 보기",
|
||||
"sidecarFallback": "서비스가 코어를 시작하지 못해 Sidecar 모드로 계속 실행합니다. 서비스는 여전히 사용할 수 없습니다.",
|
||||
"upgradeStateNotRestored": "업그레이드 중 Clash Verge 서비스를 다시 설치했지만 이전 부팅 시 시작 및 실행 상태({{state}})를 복원하지 못했습니다. 서비스를 다시 설치해도 복원되지 않습니다. systemctl status clash-verge-service로 상태를 확인하고 systemctl로 조정하세요.",
|
||||
"upgradeStateNotRestored": "업그레이드 후 Clash Verge 서비스의 이전 부팅 시 시작 및 실행 상태({{state}})를 복원하지 못했습니다. 서비스를 다시 설치해도 복원되지 않습니다. systemctl status clash-verge-service로 상태를 확인하고 systemctl로 조정하세요.",
|
||||
"uninstallSuccess": "서비스가 제거되었습니다"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "O serviço não conseguiu confirmar que os arquivos e pastas do núcleo são seguros para execução com privilégios elevados.",
|
||||
"permissionRepairGuide": "Ver instruções de reparo",
|
||||
"sidecarFallback": "O serviço não conseguiu iniciar o núcleo. Mudou para o modo Sidecar; o serviço continua indisponível.",
|
||||
"upgradeStateNotRestored": "A atualização reinstalou o serviço do Clash Verge, mas não conseguiu restaurar o estado anterior de inicialização e execução ({{state}}). Reinstalar o serviço não o restaurará; verifique-o com systemctl status clash-verge-service e ajuste-o com systemctl.",
|
||||
"upgradeStateNotRestored": "Após a atualização, não foi possível restaurar o estado anterior de inicialização e execução do serviço do Clash Verge ({{state}}). Reinstalar o serviço não o restaurará; verifique-o com systemctl status clash-verge-service e ajuste-o com systemctl.",
|
||||
"uninstallSuccess": "Serviço Desinstalado com Sucesso"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "Служба не смогла подтвердить безопасность файлов и папок ядра для запуска с повышенными правами.",
|
||||
"permissionRepairGuide": "Инструкция по исправлению",
|
||||
"sidecarFallback": "Служба не смогла запустить ядро. Работа продолжена в режиме Sidecar; служба по-прежнему недоступна.",
|
||||
"upgradeStateNotRestored": "Обновление переустановило службу Clash Verge, но не смогло восстановить её прежнее состояние автозапуска и работы ({{state}}). Переустановка службы его не восстановит; проверьте её командой systemctl status clash-verge-service и настройте через systemctl.",
|
||||
"upgradeStateNotRestored": "После обновления не удалось восстановить прежнее состояние автозапуска и работы службы Clash Verge ({{state}}). Переустановка службы его не восстановит; проверьте её командой systemctl status clash-verge-service и настройте через systemctl.",
|
||||
"uninstallSuccess": "Служба успешно удалена"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "Hizmet, çekirdek dosya ve klasörlerinin yükseltilmiş yetkilerle güvenle çalıştırılabileceğini doğrulayamadı.",
|
||||
"permissionRepairGuide": "Düzeltme adımlarını görüntüle",
|
||||
"sidecarFallback": "Hizmet çekirdeği başlatamadı. Sidecar moduna geçildi; hizmet hâlâ kullanılamıyor.",
|
||||
"upgradeStateNotRestored": "Yükseltme Clash Verge hizmetini yeniden kurdu ancak önceki açılışta başlatma ve çalışma durumunu ({{state}}) geri yükleyemedi. Hizmeti yeniden kurmak bunu geri yüklemez; systemctl status clash-verge-service ile kontrol edin ve systemctl ile ayarlayın.",
|
||||
"upgradeStateNotRestored": "Yükseltmeden sonra Clash Verge hizmetinin önceki açılışta başlatma ve çalışma durumu ({{state}}) geri yüklenemedi. Hizmeti yeniden kurmak bunu geri yüklemez; systemctl status clash-verge-service ile kontrol edin ve systemctl ile ayarlayın.",
|
||||
"uninstallSuccess": "Hizmet Başarıyla Kaldırıldı"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "Хезмәт төш файлларын һәм папкаларын югары хокуклар белән имин эшләтеп булачагын раслый алмады.",
|
||||
"permissionRepairGuide": "Төзәтү күрсәтмәләрен карау",
|
||||
"sidecarFallback": "Хезмәт төшне эшләтеп җибәрә алмады. Эш Sidecar режимында дәвам итә; хезмәт һаман да эшләми.",
|
||||
"upgradeStateNotRestored": "Яңарту Clash Verge хезмәтен яңадан урнаштырды, ләкин аның элекке автоҗибәрү һәм эшләү халәтен ({{state}}) кайтара алмады. Хезмәтне яңадан урнаштыру аны кайтармый; аны systemctl status clash-verge-service белән тикшерегез һәм systemctl белән көйләгез.",
|
||||
"upgradeStateNotRestored": "Яңартудан соң Clash Verge хезмәтенең элекке автоҗибәрү һәм эшләү халәтен ({{state}}) кайтарып булмады. Хезмәтне яңадан урнаштыру аны кайтармый; аны systemctl status clash-verge-service белән тикшерегез һәм systemctl белән көйләгез.",
|
||||
"uninstallSuccess": "Сервис уңышлы салдырылды"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "服务无法确认内核文件及所在目录是否安全,已拒绝高权限运行。",
|
||||
"permissionRepairGuide": "查看修复方法",
|
||||
"sidecarFallback": "服务无法启动内核,已降级为 Sidecar 模式运行,服务仍不可用。",
|
||||
"upgradeStateNotRestored": "升级已重装 Clash Verge 服务,但未能恢复其原有的开机启动和运行状态({{state}})。重新安装服务也无法恢复该状态;请用 systemctl status clash-verge-service 检查服务状态,并用 systemctl 调整。",
|
||||
"upgradeStateNotRestored": "升级后未能恢复 Clash Verge 服务原有的开机启动和运行状态({{state}})。重新安装服务也无法恢复该状态;请用 systemctl status clash-verge-service 检查服务状态,并用 systemctl 调整。",
|
||||
"uninstallSuccess": "已成功卸载服务"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
"permissionRejectedReason": "服務無法確認核心檔案及所在目錄是否安全,已拒絕以高權限執行。",
|
||||
"permissionRepairGuide": "查看修復方法",
|
||||
"sidecarFallback": "服務無法啟動核心,已降級為 Sidecar 模式執行,服務仍無法使用。",
|
||||
"upgradeStateNotRestored": "升級已重新安裝 Clash Verge 服務,但未能恢復其原有的開機啟動和執行狀態({{state}})。重新安裝服務也無法恢復該狀態;請用 systemctl status clash-verge-service 檢查服務狀態,並用 systemctl 調整。",
|
||||
"upgradeStateNotRestored": "升級後未能恢復 Clash Verge 服務原有的開機啟動和執行狀態({{state}})。重新安裝服務也無法恢復該狀態;請用 systemctl status clash-verge-service 檢查服務狀態,並用 systemctl 調整。",
|
||||
"uninstallSuccess": "已成功解除安裝服務"
|
||||
},
|
||||
"updater": {
|
||||
|
||||
Reference in New Issue
Block a user