From 303f67718b1d9689ffac2a24904eed5c164fefa2 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Mon, 9 Dec 2024 10:33:25 -0800 Subject: [PATCH] ConfigureInitService: retry kickstart on macos --- src/action/common/configure_init_service.rs | 13 ++---- .../macos/kickstart_launchctl_service.rs | 33 ++------------- src/action/macos/mod.rs | 40 +++++++++++++++++++ 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/action/common/configure_init_service.rs b/src/action/common/configure_init_service.rs index 3fa847190..f7ad31b0d 100644 --- a/src/action/common/configure_init_service.rs +++ b/src/action/common/configure_init_service.rs @@ -279,16 +279,9 @@ impl Action for ConfigureInitService { } if *start_daemon { - execute_command( - Command::new("launchctl") - .process_group(0) - .arg("kickstart") - .arg("-k") - .arg(format!("{domain}/{service}")) - .stdin(std::process::Stdio::null()), - ) - .await - .map_err(Self::error)?; + crate::action::macos::retry_kickstart(domain, service) + .await + .map_err(Self::error)?; } }, InitSystem::Systemd => { diff --git a/src/action/macos/kickstart_launchctl_service.rs b/src/action/macos/kickstart_launchctl_service.rs index 40f4f29b7..6cd46bb45 100644 --- a/src/action/macos/kickstart_launchctl_service.rs +++ b/src/action/macos/kickstart_launchctl_service.rs @@ -1,5 +1,4 @@ use std::process::Output; -use std::time::Duration; use tokio::process::Command; use tracing::{span, Span}; @@ -95,35 +94,9 @@ impl Action for KickstartLaunchctlService { #[tracing::instrument(level = "debug", skip_all)] async fn execute(&mut self) -> Result<(), ActionError> { - let mut retry_tokens: usize = 10; - loop { - let mut command = Command::new("launchctl"); - command.process_group(0); - command.args(["kickstart", "-k"]); - command.arg(format!("{}/{}", self.domain, self.service)); - command.stdin(std::process::Stdio::null()); - command.stderr(std::process::Stdio::null()); - command.stdout(std::process::Stdio::null()); - tracing::debug!(%retry_tokens, command = ?command.as_std(), "Waiting for kickstart to succeed"); - - let output = command - .output() - .await - .map_err(|e| ActionErrorKind::command(&command, e)) - .map_err(Self::error)?; - - if output.status.success() { - break; - } else if retry_tokens == 0 { - return Err(Self::error(ActionErrorKind::command_output( - &command, output, - )))?; - } else { - retry_tokens = retry_tokens.saturating_sub(1); - } - - tokio::time::sleep(Duration::from_millis(500)).await; - } + super::retry_kickstart(&self.domain, &self.service) + .await + .map_err(Self::error)?; Ok(()) } diff --git a/src/action/macos/mod.rs b/src/action/macos/mod.rs index 29a1fd8b8..065dd6474 100644 --- a/src/action/macos/mod.rs +++ b/src/action/macos/mod.rs @@ -257,3 +257,43 @@ pub(crate) async fn retry_bootout(domain: &str, service_name: &str) -> Result<() Ok(()) } + +/// Wait for `launchctl kickstart {domain}/{service_name}` to succeed up to `retry_tokens * 500ms` amount +/// of time. +#[tracing::instrument] +pub(crate) async fn retry_kickstart( + domain: &str, + service_name: &str, +) -> Result<(), ActionErrorKind> { + let service_identifier = [domain, service_name].join("/"); + + let mut retry_tokens: usize = 10; + loop { + let mut command = Command::new("launchctl"); + command.process_group(0); + command.arg("kickstart"); + command.arg("-k"); + command.arg(&service_identifier); + command.stdin(std::process::Stdio::null()); + command.stderr(std::process::Stdio::null()); + command.stdout(std::process::Stdio::null()); + tracing::debug!(%retry_tokens, command = ?command.as_std(), "Waiting for kickstart to succeed"); + + let output = command + .output() + .await + .map_err(|e| ActionErrorKind::command(&command, e))?; + + if output.status.success() { + break; + } else if retry_tokens == 0 { + return Err(ActionErrorKind::command_output(&command, output))?; + } else { + retry_tokens = retry_tokens.saturating_sub(1); + } + + tokio::time::sleep(Duration::from_millis(500)).await; + } + + Ok(()) +}