@@ -2293,6 +2293,7 @@ async fn apply_auto_update(
22932293 headers : HeaderMap ,
22942294) -> ApiResult < Json < AutoUpdateStatusSummary > > {
22952295 let admin = require_admin ( & state, & headers) ?;
2296+ let executable_path = std:: env:: current_exe ( ) . map_err ( LoreError :: Io ) ?;
22962297 let status = run_auto_update_apply ( & state) . await ?;
22972298 let applied = status. applied ;
22982299 append_audit_event (
@@ -2311,7 +2312,7 @@ async fn apply_auto_update(
23112312 ) ?;
23122313 let summary = auto_update_status_summary ( & status) ;
23132314 if applied {
2314- schedule_server_restart ( ) ;
2315+ schedule_server_restart ( executable_path ) ;
23152316 }
23162317 Ok ( Json ( summary) )
23172318}
@@ -3497,6 +3498,7 @@ async fn apply_auto_update_from_ui(
34973498) -> UiResult < Redirect > {
34983499 let session = require_ui_admin ( & state, & headers) ?;
34993500 verify_csrf ( & session, & form. csrf_token ) ?;
3501+ let executable_path = std:: env:: current_exe ( ) . map_err ( LoreError :: Io ) ?;
35003502 let status = run_auto_update_apply ( & state) . await ?;
35013503 let applied = status. applied ;
35023504 append_audit_event (
@@ -3514,7 +3516,7 @@ async fn apply_auto_update_from_ui(
35143516 Some ( status. detail . clone ( ) ) ,
35153517 ) ?;
35163518 let flash = if applied {
3517- schedule_server_restart ( ) ;
3519+ schedule_server_restart ( executable_path ) ;
35183520 "Update%20applied%20—%20server%20restarting"
35193521 } else {
35203522 "Already%20up%20to%20date"
@@ -3553,6 +3555,7 @@ async fn apply_auto_update_json(
35533555) -> ApiResult < Json < AutoUpdateStatusSummary > > {
35543556 let session = require_ui_admin ( & state, & headers) ?;
35553557 verify_csrf ( & session, & form. csrf_token ) ?;
3558+ let executable_path = std:: env:: current_exe ( ) . map_err ( LoreError :: Io ) ?;
35563559 let status = run_auto_update_apply ( & state) . await ?;
35573560 let applied = status. applied ;
35583561 append_audit_event (
@@ -3571,7 +3574,7 @@ async fn apply_auto_update_json(
35713574 ) ?;
35723575 let summary = auto_update_status_summary ( & status) ;
35733576 if applied {
3574- schedule_server_restart ( ) ;
3577+ schedule_server_restart ( executable_path ) ;
35753578 }
35763579 Ok ( Json ( summary) )
35773580}
@@ -4940,14 +4943,27 @@ async fn run_auto_update_apply(state: &AppState) -> Result<AutoUpdateStatus, Lor
49404943 }
49414944}
49424945
4943- fn schedule_server_restart ( ) {
4944- tokio:: spawn ( async {
4946+ fn schedule_server_restart ( executable_path : std:: path:: PathBuf ) {
4947+ let args = std:: env:: args_os ( ) . skip ( 1 ) . collect :: < Vec < _ > > ( ) ;
4948+ tokio:: spawn ( async move {
49454949 tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) . await ;
4946- let executable_path = match std:: env:: current_exe ( ) {
4947- Ok ( path) => path,
4948- Err ( _) => std:: process:: exit ( 1 ) ,
4949- } ;
4950- let args = std:: env:: args_os ( ) . skip ( 1 ) . collect :: < Vec < _ > > ( ) ;
4950+ // If running as a systemd service, restart through systemd so the
4951+ // service manager tracks the new process and dependent services
4952+ // (like Caddy) are not disrupted.
4953+ if std:: path:: Path :: new ( "/etc/systemd/system/lore-server.service" ) . exists ( ) {
4954+ let status = std:: process:: Command :: new ( "sudo" )
4955+ . args ( [ "systemctl" , "restart" , "lore-server" ] )
4956+ . status ( ) ;
4957+ match status {
4958+ Ok ( s) if s. success ( ) => std:: process:: exit ( 0 ) ,
4959+ Ok ( s) => {
4960+ eprintln ! ( "warning: systemctl restart failed (exit {}), falling back to exec" , s. code( ) . unwrap_or( -1 ) ) ;
4961+ }
4962+ Err ( err) => {
4963+ eprintln ! ( "warning: systemctl restart failed ({err}), falling back to exec" ) ;
4964+ }
4965+ }
4966+ }
49514967 let mut command = std:: process:: Command :: new ( & executable_path) ;
49524968 command. args ( args) ;
49534969 #[ cfg( unix) ]
0 commit comments