Install narrates itself: stop/copy/start steps and the potentially long icacls tree grant
This commit is contained in:
@@ -146,6 +146,7 @@ func Install(configPath string, copyBin bool, version string) error {
|
||||
if st, qErr := s.Query(); qErr == nil &&
|
||||
(st.State == svc.Running || st.State == svc.StartPending) {
|
||||
wasRunning = true
|
||||
fmt.Println("stopping the running gpu-turnstile service")
|
||||
if err := stopAndWait(s); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -161,6 +162,7 @@ func Install(configPath string, copyBin bool, version string) error {
|
||||
}
|
||||
installedExe := filepath.Join(installDir, "gpu-turnstile.exe")
|
||||
if same, _ := sameFileContent(exe, installedExe); !same {
|
||||
fmt.Printf("installing %s\n", installedExe)
|
||||
if err := copyFile(exe, installedExe); err != nil {
|
||||
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
|
||||
// missing config (no consumer URLs) fails the start; the service stays
|
||||
// registered and can be started once the config exists.
|
||||
fmt.Println("starting the gpu-turnstile service")
|
||||
s.Start()
|
||||
return nil
|
||||
}
|
||||
@@ -243,6 +246,7 @@ func Install(configPath string, copyBin bool, version string) error {
|
||||
return err
|
||||
}
|
||||
if wasRunning {
|
||||
fmt.Println("starting the gpu-turnstile service")
|
||||
if err := s.Start(); err != nil {
|
||||
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.
|
||||
// "(OI)(CI)(M)") on path.
|
||||
func grantAccess(path, perms string) error {
|
||||
out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return nil
|
||||
return runIcacls(path, perms, false)
|
||||
}
|
||||
|
||||
// grantAccessTree is grantAccess with /T: the ACE is applied to the
|
||||
// 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 {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user