UPDATE: Add admin relaunch functionality for macOS and Linux, enhance README with new features and usage examples
Build and Release / release (push) Successful in 18s
Build and Release / release (push) Successful in 18s
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func relaunchWithAdminIfNeeded() (bool, error) {
|
||||
if os.Geteuid() == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
exePath, err := os.Executable()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("get executable path: %w", err)
|
||||
}
|
||||
|
||||
workDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("get working directory: %w", err)
|
||||
}
|
||||
|
||||
args := make([]string, 0, len(os.Args))
|
||||
args = append(args, shellQuote(exePath))
|
||||
for _, arg := range os.Args[1:] {
|
||||
args = append(args, shellQuote(arg))
|
||||
}
|
||||
|
||||
logPath := filepath.Join(os.TempDir(), "firefly-go-proxy.log")
|
||||
command := fmt.Sprintf(
|
||||
"cd %s && nohup %s >> %s 2>&1 &",
|
||||
shellQuote(workDir),
|
||||
strings.Join(args, " "),
|
||||
shellQuote(logPath),
|
||||
)
|
||||
|
||||
if pkexecPath, err := exec.LookPath("pkexec"); err == nil {
|
||||
if out, err := exec.Command(pkexecPath, "sh", "-c", command).CombinedOutput(); err == nil {
|
||||
return true, nil
|
||||
} else if _, sudoErr := exec.LookPath("sudo"); sudoErr != nil {
|
||||
return false, formatCommandError("relaunch proxy as admin with pkexec", err, out)
|
||||
}
|
||||
}
|
||||
|
||||
sudoPath, err := exec.LookPath("sudo")
|
||||
if err != nil {
|
||||
return false, errors.New("pkexec or sudo is required to relaunch with admin privileges")
|
||||
}
|
||||
if out, err := exec.Command(sudoPath, "sh", "-c", command).CombinedOutput(); err != nil {
|
||||
return false, formatCommandError("relaunch proxy as admin with sudo", err, out)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func shellQuote(value string) string {
|
||||
return "'" + strings.ReplaceAll(value, "'", "'\\''") + "'"
|
||||
}
|
||||
|
||||
func formatCommandError(action string, err error, out []byte) error {
|
||||
msg := strings.TrimSpace(string(out))
|
||||
if msg == "" {
|
||||
return fmt.Errorf("%s: %w", action, err)
|
||||
}
|
||||
return fmt.Errorf("%s: %w: %s", action, err, msg)
|
||||
}
|
||||
Reference in New Issue
Block a user