refactor: simplify service installation process
This commit is contained in:
57
internal/cli/elevate.go
Normal file
57
internal/cli/elevate.go
Normal file
@ -0,0 +1,57 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"gitea.epss.net.cn/klesh/ss/internal/storage"
|
||||
)
|
||||
|
||||
// ensureRoot re-execs the current command under sudo if it isn't already
|
||||
// running as root. It resolves the config directory *before* elevating and
|
||||
// passes it through explicitly as SF_CONFIG_DIR, because sudo resets $HOME
|
||||
// to /root's — without this, the elevated process would silently resolve
|
||||
// the default config directory under /root instead of the invoking user's
|
||||
// home.
|
||||
//
|
||||
// Windows is handled separately: UAC elevation launches a new process that
|
||||
// can't transparently inherit the current console, so internal/service's
|
||||
// runAsAdmin instead prints manual elevation instructions rather than
|
||||
// auto-elevating.
|
||||
func ensureRoot() error {
|
||||
if runtime.GOOS == "windows" {
|
||||
return nil
|
||||
}
|
||||
if os.Geteuid() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
s, err := storage.New()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve config directory: %w", err)
|
||||
}
|
||||
|
||||
self, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to determine executable path: %w", err)
|
||||
}
|
||||
|
||||
sudoPath, err := exec.LookPath("sudo")
|
||||
if err != nil {
|
||||
return fmt.Errorf("this command requires root privileges, but sudo was not found on PATH: %w", err)
|
||||
}
|
||||
|
||||
args := append([]string{"env", "SF_CONFIG_DIR=" + s.ConfigDir, self}, os.Args[1:]...)
|
||||
cmd := exec.Command(sudoPath, args...)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
runErr := cmd.Run()
|
||||
if cmd.ProcessState != nil {
|
||||
os.Exit(cmd.ProcessState.ExitCode())
|
||||
}
|
||||
return fmt.Errorf("failed to re-exec under sudo: %w", runErr)
|
||||
}
|
||||
Reference in New Issue
Block a user