Install opens up COMFY_DIR for the sandboxed service: ACL grant on Windows, BindPaths on Linux
This commit is contained in:
@@ -24,8 +24,6 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
|
||||
"gpu-turnstile/internal/config"
|
||||
)
|
||||
|
||||
// Name is the Windows service name.
|
||||
@@ -106,10 +104,12 @@ func (h *handler) Execute(_ []string, requests <-chan svc.ChangeRequest, status
|
||||
// the service after 5s on failure — this is also what brings up a staged
|
||||
// update after the updater exits with a non-zero code. After registering,
|
||||
// the virtual account is granted modify access to the install and data
|
||||
// directories (self-updates rewrite the exe), and read access to the
|
||||
// config file if it lives elsewhere. The grants must come after
|
||||
// CreateService: the virtual account's SID only exists once the service is
|
||||
// registered.
|
||||
// directories (self-updates rewrite the exe), read access to the
|
||||
// config file if it lives elsewhere, and — when the config sets COMFY_DIR —
|
||||
// recursive modify access to the managed ComfyUI's install tree, which may
|
||||
// live inside a user profile the account otherwise cannot enter. The grants
|
||||
// must come after CreateService: the virtual account's SID only exists once
|
||||
// the service is registered.
|
||||
//
|
||||
// Re-running install on an existing service converges instead of failing:
|
||||
// the service is stopped first if running (so the binary can be replaced),
|
||||
@@ -354,7 +354,7 @@ func grantAll(exe, configPath string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if logFile := configuredLogFile(configPath); logFile != "" {
|
||||
if logFile := configuredValue(configPath, "LOG_FILE"); logFile != "" {
|
||||
dir := filepath.Dir(logFile)
|
||||
if err := os.MkdirAll(dir, 0o755); err == nil {
|
||||
if err := grantAccess(dir, "(OI)(CI)(M)"); err != nil {
|
||||
@@ -362,6 +362,17 @@ func grantAll(exe, configPath string) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
// A managed ComfyUI whose install lives somewhere the virtual account
|
||||
// may not go (a user profile) needs an explicit grant — recursively,
|
||||
// since ComfyUI also writes output/temp/user data next to its code. A
|
||||
// missing directory is skipped: the startup warning covers it.
|
||||
if comfyDir := configuredValue(configPath, "COMFY_DIR"); comfyDir != "" {
|
||||
if _, err := os.Stat(comfyDir); err == nil {
|
||||
if err := grantAccessTree(comfyDir, "(OI)(CI)(M)"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -473,19 +484,15 @@ func grantAccess(path, perms string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// configuredLogFile reads LOG_FILE from the config file so the installer
|
||||
// can pre-create and ACL the log directory. "" when unset or unreadable.
|
||||
func configuredLogFile(configPath string) string {
|
||||
f, err := os.Open(configPath)
|
||||
// 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.
|
||||
func grantAccessTree(path, perms string) error {
|
||||
out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms, "/T").CombinedOutput()
|
||||
if err != nil {
|
||||
return ""
|
||||
return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
defer f.Close()
|
||||
values, err := config.ParseEnvFile(f)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return values["LOG_FILE"]
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestartIfRunning restarts the service when it is installed and running
|
||||
|
||||
Reference in New Issue
Block a user