Install narrates itself: stop/copy/start steps and the potentially long icacls tree grant

This commit is contained in:
mram
2026-09-21 21:36:45 +02:00
parent 299b6dc0bb
commit bdc844872d
+22 -7
View File
@@ -146,6 +146,7 @@ func Install(configPath string, copyBin bool, version string) error {
if st, qErr := s.Query(); qErr == nil && if st, qErr := s.Query(); qErr == nil &&
(st.State == svc.Running || st.State == svc.StartPending) { (st.State == svc.Running || st.State == svc.StartPending) {
wasRunning = true wasRunning = true
fmt.Println("stopping the running gpu-turnstile service")
if err := stopAndWait(s); err != nil { if err := stopAndWait(s); err != nil {
return err return err
} }
@@ -161,6 +162,7 @@ func Install(configPath string, copyBin bool, version string) error {
} }
installedExe := filepath.Join(installDir, "gpu-turnstile.exe") installedExe := filepath.Join(installDir, "gpu-turnstile.exe")
if same, _ := sameFileContent(exe, installedExe); !same { if same, _ := sameFileContent(exe, installedExe); !same {
fmt.Printf("installing %s\n", installedExe)
if err := copyFile(exe, installedExe); err != nil { if err := copyFile(exe, installedExe); err != nil {
return fmt.Errorf("copy binary to %s: %w", installedExe, err) return fmt.Errorf("copy binary to %s: %w", installedExe, err)
} }
@@ -208,6 +210,7 @@ func Install(configPath string, copyBin bool, version string) error {
// Best effort: start now instead of waiting for the next boot. A // Best effort: start now instead of waiting for the next boot. A
// missing config (no consumer URLs) fails the start; the service stays // missing config (no consumer URLs) fails the start; the service stays
// registered and can be started once the config exists. // registered and can be started once the config exists.
fmt.Println("starting the gpu-turnstile service")
s.Start() s.Start()
return nil return nil
} }
@@ -243,6 +246,7 @@ func Install(configPath string, copyBin bool, version string) error {
return err return err
} }
if wasRunning { if wasRunning {
fmt.Println("starting the gpu-turnstile service")
if err := s.Start(); err != nil { if err := s.Start(); err != nil {
return fmt.Errorf("start service: %w", err) return fmt.Errorf("start service: %w", err)
} }
@@ -477,21 +481,32 @@ func RelaunchElevated(args []string) (int, error) {
// grantAccess gives the virtual account the icacls permission set (e.g. // grantAccess gives the virtual account the icacls permission set (e.g.
// "(OI)(CI)(M)") on path. // "(OI)(CI)(M)") on path.
func grantAccess(path, perms string) error { func grantAccess(path, perms string) error {
out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms).CombinedOutput() return runIcacls(path, perms, false)
if err != nil {
return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out)))
}
return nil
} }
// grantAccessTree is grantAccess with /T: the ACE is applied to the // grantAccessTree is grantAccess with /T: the ACE is applied to the
// existing tree, not just inherited by children created later. Needed when // existing tree, not just inherited by children created later. Needed when
// the tree already exists, e.g. a ComfyUI install in a user profile. // the tree already exists, e.g. a ComfyUI install in a user profile. On a
// large tree (a venv has tens of thousands of files) this takes minutes,
// so it says what it is doing instead of looking hung.
func grantAccessTree(path, perms string) error { func grantAccessTree(path, perms string) error {
out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms, "/T").CombinedOutput() return runIcacls(path, perms, true)
}
func runIcacls(path, perms string, recursive bool) error {
args := []string{path, "/grant", virtualAccount + ":" + perms}
if recursive {
fmt.Printf("granting %s modify access to %s (large trees can take minutes)\n", virtualAccount, path)
args = append(args, "/T")
}
start := time.Now()
out, err := exec.Command("icacls", args...).CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out))) return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out)))
} }
if recursive {
fmt.Printf("access granted in %s\n", time.Since(start).Round(time.Second))
}
return nil return nil
} }