diff --git a/cmd/gpu-turnstile/main.go b/cmd/gpu-turnstile/main.go index 047b30f..ec40f0a 100644 --- a/cmd/gpu-turnstile/main.go +++ b/cmd/gpu-turnstile/main.go @@ -58,7 +58,7 @@ func stdoutIsTerminal() bool { // --install-service / --remove-service switches, --no-copy, -h/--help, // -v/--version, --force-update and the hidden --elevated-child marker from // args. -func parseFlags(args []string) (configPath string, install, remove, noCopy, help, showVersion, forceUpdate, elevatedChild bool, rest []string) { +func parseFlags(args []string) (configPath string, install, remove, noCopy, help, showVersion, forceUpdate, updateNow, elevatedChild bool, rest []string) { rest = args[:0] for i := 0; i < len(args); i++ { switch { @@ -79,13 +79,15 @@ func parseFlags(args []string) (configPath string, install, remove, noCopy, help showVersion = true case args[i] == "--force-update" || args[i] == "-force-update": forceUpdate = true + case args[i] == "--update-now" || args[i] == "-update-now": + updateNow = true case args[i] == "--elevated-child": elevatedChild = true default: rest = append(rest, args[i]) } } - return configPath, install, remove, noCopy, help, showVersion, forceUpdate, elevatedChild, rest + return configPath, install, remove, noCopy, help, showVersion, forceUpdate, updateNow, elevatedChild, rest } // versionLine is printed at the top of every help and error screen. @@ -101,6 +103,8 @@ Usage: gpu-turnstile --force-update check for a signed update now, apply it and restart the service (no admin needed when the service runs) + gpu-turnstile --update-now like --force-update, but only + through the running service gpu-turnstile -h | --help this help Options: @@ -131,12 +135,12 @@ func fatalUsage(format string, args ...any) { } func main() { - configPath, install, remove, noCopy, help, showVersion, forceUpdate, elevatedChild, args := parseFlags(os.Args[1:]) + configPath, install, remove, noCopy, help, showVersion, forceUpdate, updateNow, elevatedChild, args := parseFlags(os.Args[1:]) if showVersion { fmt.Println(version) return } - bare := configPath == "" && !install && !remove && !forceUpdate && !elevatedChild && len(args) == 0 + bare := configPath == "" && !install && !remove && !forceUpdate && !updateNow && !elevatedChild && len(args) == 0 if help || (bare && stdoutIsTerminal()) { // Bare invocation in a terminal (e.g. double-clicked on Windows) // shows the help instead of starting a proxy window with no visible @@ -159,12 +163,16 @@ func main() { fatalUsage("error: --install-service and --remove-service are mutually exclusive") case forceUpdate && (install || remove): fatalUsage("error: --force-update cannot be combined with --install-service/--remove-service") + case updateNow && (install || remove || forceUpdate): + fatalUsage("error: --update-now cannot be combined with other commands") case install: os.Exit(serviceCommand(configPath, true, noCopy, elevatedChild)) case remove: os.Exit(serviceCommand(configPath, false, noCopy, elevatedChild)) case forceUpdate: os.Exit(forceUpdateCommand(configPath, elevatedChild)) + case updateNow: + os.Exit(updateNowCommand()) } if len(args) > 0 { fatalUsage("error: unknown arguments: %s", strings.Join(args, " ")) @@ -418,6 +426,17 @@ func printControlReply(reply string) int { return 0 } +// updateNowCommand only goes through the running service's control channel +// (no direct check, no elevation): the unprivileged update trigger. +func updateNowCommand() int { + reply, err := control.Ask(control.CmdUpdateNow) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n\ngpu-turnstile: no running service to ask — use --force-update for a direct check\n", versionLine()) + return 1 + } + return printControlReply(reply) +} + // reportElevatedUpdate prints the parent's summary of an elevated // --force-update child: exitCodeStaged means the child staged a new binary, // 0 means it found nothing to do. to is the tag the parent's own check