fleet/orbit/pkg/execuser/execuser.go
Lucas Manuel Rodriguez 0823cc7e76
Fix orbit active GUI session detection to start Fleet Desktop and key escrowing on Linux (#39777)
Resolves #36024 and #34501.

Main change is about stop using the first user in the `users` command
output [*] and instead use `loginctl` commands to pick the correct
current active GUI user.

[*] `users` was returning empty on some new distributions, and in
multi-sessions we were always picking the first one (even if it wasn't
active).

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

## Testing

- [x] QA'd all new/changed functionality manually

## fleetd/orbit/Fleet Desktop

- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [x] Verified that fleetd runs on macOS, Linux and Windows
- [x] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Fixed Fleet Desktop startup to correctly detect and use the active GUI
session on Linux systems.
* Improved GUI user detection for dialog prompts, ensuring system
dialogs run in the proper user context.

* **Improvements**
* Enhanced error reporting and logging clarity for GUI session detection
failures.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-16 11:41:16 -03:00

71 lines
1.9 KiB
Go

// Package execuser is used to run applications from a high privilege user (root on Unix,
// SYSTEM service on Windows) as the current login user.
package execuser
import (
"time"
)
type eopts struct {
env [][2]string
args [][2]string
stderrPath string //nolint:structcheck,unused
timeout time.Duration
user string
}
// Option allows configuring the application.
type Option func(*eopts)
// WithEnv sets environment variables for the application.
func WithEnv(name, value string) Option {
return func(a *eopts) {
a.env = append(a.env, [2]string{name, value})
}
}
// WithArg sets command line arguments for the application.
func WithArg(name, value string) Option {
return func(a *eopts) {
a.args = append(a.args, [2]string{name, value})
}
}
// WithTimeout sets the timeout for the application. Currently only supported on Linux.
func WithTimeout(duration time.Duration) Option {
return func(a *eopts) {
a.timeout = duration
}
}
// WithUser sets the user to run the application as. Currently only supported on MacOS.
func WithUser(user string) Option {
return func(a *eopts) {
a.user = user
}
}
// Run runs an application as the current login user.
// It assumes the caller is running with high privileges (root on Unix, SYSTEM on Windows).
//
// It returns after starting the child process.
func Run(path string, opts ...Option) (lastLogs string, err error) {
var o eopts
for _, fn := range opts {
fn(&o)
}
return run(path, o)
}
// RunWithOutput runs an application as the current login user and returns its output.
// It assumes the caller is running with high privileges (root on UNIX).
//
// It blocks until the child process exits.
// Non ExitError errors return with a -1 exitCode.
func RunWithOutput(path string, opts ...Option) (output []byte, exitCode int, err error) {
var o eopts
for _, fn := range opts {
fn(&o)
}
return runWithOutput(path, o)
}