cleanup rosettax87 services

This commit is contained in:
aomizu
2025-05-29 18:29:49 +09:00
parent 3fe7cfd090
commit 48e950c399
2 changed files with 123 additions and 31 deletions

View File

@@ -3,4 +3,4 @@
Name = "TurtleSilicon" Name = "TurtleSilicon"
ID = "com.tairasu.turtlesilicon" ID = "com.tairasu.turtlesilicon"
Version = "1.1.0" Version = "1.1.0"
Build = 17 Build = 19

View File

@@ -25,6 +25,56 @@ var (
servicePID int servicePID int
) )
// CleanupExistingServices kills any existing rosettax87 processes
func CleanupExistingServices() error {
log.Println("Cleaning up any existing rosettax87 processes...")
// Find all rosettax87 processes
cmd := exec.Command("pgrep", "-f", "rosettax87")
output, err := cmd.Output()
if err != nil {
// No processes found, that's fine
return nil
}
pids := strings.Fields(strings.TrimSpace(string(output)))
if len(pids) == 0 {
return nil
}
// Kill all found processes without sudo (try regular kill first)
for _, pid := range pids {
// First try regular kill
killCmd := exec.Command("kill", "-9", pid)
err := killCmd.Run()
if err != nil {
// If regular kill fails, try with sudo (but this might fail too)
log.Printf("Regular kill failed for process %s, trying sudo: %v", pid, err)
sudoKillCmd := exec.Command("sudo", "kill", "-9", pid)
err2 := sudoKillCmd.Run()
if err2 != nil {
log.Printf("Failed to kill process %s with sudo: %v", pid, err2)
} else {
log.Printf("Killed existing rosettax87 process with sudo: %s", pid)
}
} else {
log.Printf("Killed existing rosettax87 process: %s", pid)
}
}
// Wait a moment for processes to die
time.Sleep(1 * time.Second)
return nil
}
// isRosettaSocketActive checks if the rosetta helper socket is active
func isRosettaSocketActive() bool {
// Check if the socket file exists and is accessible
cmd := exec.Command("ls", "-la", "/var/run/rosetta_helper.sock")
err := cmd.Run()
return err == nil
}
// StartRosettaX87Service starts the RosettaX87 service with sudo privileges // StartRosettaX87Service starts the RosettaX87 service with sudo privileges
func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) {
log.Println("Starting RosettaX87 service...") log.Println("Starting RosettaX87 service...")
@@ -47,6 +97,9 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) {
return return
} }
// Clean up any existing rosettax87 processes first
CleanupExistingServices()
// Show password dialog // Show password dialog
passwordEntry := widget.NewPasswordEntry() passwordEntry := widget.NewPasswordEntry()
passwordEntry.SetPlaceHolder("Enter your sudo password") passwordEntry.SetPlaceHolder("Enter your sudo password")
@@ -123,15 +176,20 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) {
// startServiceWithPassword starts the service using sudo with the provided password // startServiceWithPassword starts the service using sudo with the provided password
func startServiceWithPassword(workingDir, executable, password string) error { func startServiceWithPassword(workingDir, executable, password string) error {
// First test if the password is correct with a simple sudo command // First clear any existing sudo credentials to ensure fresh authentication
testCmd := exec.Command("sudo", "-S", "-v") clearCmd := exec.Command("sudo", "-k")
clearCmd.Run() // Ignore errors
// Test the password with a simple command that requires sudo
testCmd := exec.Command("sudo", "-S", "echo", "test")
testStdin, err := testCmd.StdinPipe() testStdin, err := testCmd.StdinPipe()
if err != nil { if err != nil {
return fmt.Errorf("failed to create test stdin pipe: %v", err) return fmt.Errorf("failed to create test stdin pipe: %v", err)
} }
// Capture stderr to check for authentication errors // Capture both stdout and stderr
var stderr bytes.Buffer var stdout, stderr bytes.Buffer
testCmd.Stdout = &stdout
testCmd.Stderr = &stderr testCmd.Stderr = &stderr
err = testCmd.Start() err = testCmd.Start()
@@ -149,18 +207,40 @@ func startServiceWithPassword(workingDir, executable, password string) error {
// Wait for the test command to complete // Wait for the test command to complete
err = testCmd.Wait() err = testCmd.Wait()
stderrOutput := stderr.String()
stdoutOutput := stdout.String()
log.Printf("Password test - Exit code: %v, Stderr: %q, Stdout: %q", err, stderrOutput, stdoutOutput)
// Check for authentication failure indicators
if strings.Contains(stderrOutput, "Sorry, try again") ||
strings.Contains(stderrOutput, "incorrect password") ||
strings.Contains(stderrOutput, "authentication failure") ||
strings.Contains(stderrOutput, "1 incorrect password attempt") {
return fmt.Errorf("incorrect password")
}
if err != nil { if err != nil {
stderrOutput := stderr.String() return fmt.Errorf("sudo authentication failed: %v, stderr: %s", err, stderrOutput)
if strings.Contains(stderrOutput, "Sorry, try again") || strings.Contains(stderrOutput, "incorrect password") { }
return fmt.Errorf("incorrect password")
} // Additional check: the stdout should contain "test" if the command succeeded
return fmt.Errorf("sudo authentication failed: %v", err) if !strings.Contains(stdoutOutput, "test") {
return fmt.Errorf("password authentication failed - no expected output")
} }
// If we get here, the password is correct, now start the actual service // If we get here, the password is correct, now start the actual service
log.Println("Password validated successfully, starting rosettax87 service...")
cmd := exec.Command("sudo", "-S", executable) cmd := exec.Command("sudo", "-S", executable)
cmd.Dir = workingDir cmd.Dir = workingDir
// Capture both stdout and stderr for debugging (reuse existing variables)
stdout.Reset()
stderr.Reset()
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// Create a pipe to send the password // Create a pipe to send the password
stdin, err := cmd.StdinPipe() stdin, err := cmd.StdinPipe()
if err != nil { if err != nil {
@@ -186,14 +266,25 @@ func startServiceWithPassword(workingDir, executable, password string) error {
servicePID = cmd.Process.Pid servicePID = cmd.Process.Pid
// Wait a moment to see if the process starts successfully // Wait a moment to see if the process starts successfully
time.Sleep(2 * time.Second) time.Sleep(3 * time.Second)
// Check if the process is still running // Check if the process is still running
if cmd.ProcessState != nil && cmd.ProcessState.Exited() { if cmd.ProcessState != nil && cmd.ProcessState.Exited() {
return fmt.Errorf("process exited prematurely with code: %d", cmd.ProcessState.ExitCode()) stderrOutput := stderr.String()
stdoutOutput := stdout.String()
log.Printf("Process exited - Stdout: %q, Stderr: %q", stdoutOutput, stderrOutput)
return fmt.Errorf("process exited prematurely with code: %d. Stderr: %s", cmd.ProcessState.ExitCode(), stderrOutput)
} }
log.Printf("RosettaX87 service started with PID: %d", servicePID) // Verify the service is actually listening
time.Sleep(1 * time.Second)
if !isRosettaSocketActive() {
log.Printf("Service started but socket not active - Stdout: %q, Stderr: %q", stdout.String(), stderr.String())
cmd.Process.Kill()
return fmt.Errorf("service started but is not listening on socket")
}
log.Printf("RosettaX87 service started successfully with PID: %d", servicePID)
return nil return nil
} }
@@ -240,31 +331,32 @@ func StopRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) {
// IsServiceRunning checks if the RosettaX87 service is currently running // IsServiceRunning checks if the RosettaX87 service is currently running
func IsServiceRunning() bool { func IsServiceRunning() bool {
if !ServiceRunning { // Check for any rosettax87 process running system-wide
cmd := exec.Command("pgrep", "-f", "rosettax87")
output, err := cmd.Output()
if err != nil {
// No rosettax87 process found
ServiceRunning = false
serviceCmd = nil
servicePID = 0
return false return false
} }
// Double-check by verifying the process is still alive // If there are rosettax87 processes running, the service is considered running
if serviceCmd != nil && serviceCmd.Process != nil { if len(strings.TrimSpace(string(output))) > 0 {
// Check if process is still running ServiceRunning = true
err := serviceCmd.Process.Signal(syscall.Signal(0)) return true
if err != nil {
// Process is not running
ServiceRunning = false
serviceCmd = nil
servicePID = 0
return false
}
} }
return ServiceRunning ServiceRunning = false
return false
} }
// CleanupService ensures the service is stopped when the application exits // CleanupService ensures the service is stopped when the application exits
func CleanupService() { func CleanupService() {
if ServiceRunning && serviceCmd != nil && serviceCmd.Process != nil { log.Println("Cleaning up RosettaX87 service on application exit...")
log.Println("Cleaning up RosettaX87 service on application exit...") CleanupExistingServices()
serviceCmd.Process.Kill() ServiceRunning = false
ServiceRunning = false serviceCmd = nil
} servicePID = 0
} }