Skip to content

Commit

Permalink
dont show desktop until requested by runner
Browse files Browse the repository at this point in the history
  • Loading branch information
James-Pickett committed Sep 19, 2024
1 parent ecd9d3e commit d7efbab
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 37 deletions.
7 changes: 5 additions & 2 deletions cmd/launcher/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ func runDesktop(_ *multislogger.MultiSlogger, args []string) error {
}, func(error) {})

shutdownChan := make(chan struct{})
server, err := userserver.New(slogger, *flUserServerAuthToken, *flUserServerSocketPath, shutdownChan, notifier)
showDesktopChan := make(chan struct{})

server, err := userserver.New(slogger, *flUserServerAuthToken, *flUserServerSocketPath, shutdownChan, showDesktopChan, notifier)
if err != nil {
return err
}
Expand Down Expand Up @@ -182,9 +184,10 @@ func runDesktop(_ *multislogger.MultiSlogger, args []string) error {
}
}()

// block until a send on showDesktopChan
<-showDesktopChan
// blocks until shutdown called
m.Init()

return nil
}

Expand Down
81 changes: 54 additions & 27 deletions ee/desktop/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ type DesktopUsersProcessesRunner struct {
// usersFilesRoot is the launcher root dir with will be the parent dir
// for kolide desktop files on a per user basis
usersFilesRoot string
// processSpawningEnabled controls whether or not desktop user processes are automatically spawned
// This effectively represents whether or not the launcher desktop GUI is enabled or not
processSpawningEnabled bool
// knapsack is the almighty sack of knaps
knapsack types.Knapsack
// runnerServer is a local server that desktop processes call to monitor parent
Expand Down Expand Up @@ -155,17 +152,16 @@ func (pr processRecord) String() string {
// New creates and returns a new DesktopUsersProcessesRunner runner and initializes all required fields
func New(k types.Knapsack, messenger runnerserver.Messenger, opts ...desktopUsersProcessesRunnerOption) (*DesktopUsersProcessesRunner, error) {
runner := &DesktopUsersProcessesRunner{
interrupt: make(chan struct{}),
uidProcs: make(map[string]processRecord),
updateInterval: k.DesktopUpdateInterval(),
menuRefreshInterval: k.DesktopMenuRefreshInterval(),
procsWg: &sync.WaitGroup{},
interruptTimeout: time.Second * 5,
hostname: k.KolideServerURL(),
usersFilesRoot: agent.TempPath("kolide-desktop"),
processSpawningEnabled: k.DesktopEnabled(),
knapsack: k,
cachedMenuData: newMenuItemCache(),
interrupt: make(chan struct{}),
uidProcs: make(map[string]processRecord),
updateInterval: k.DesktopUpdateInterval(),
menuRefreshInterval: k.DesktopMenuRefreshInterval(),
procsWg: &sync.WaitGroup{},
interruptTimeout: time.Second * 5,
hostname: k.KolideServerURL(),
usersFilesRoot: agent.TempPath("kolide-desktop"),
knapsack: k,
cachedMenuData: newMenuItemCache(),
}

runner.slogger = k.Slogger().With("component", "desktop_runner")
Expand Down Expand Up @@ -452,12 +448,35 @@ func (r *DesktopUsersProcessesRunner) Update(data io.Reader) error {
}

func (r *DesktopUsersProcessesRunner) FlagsChanged(flagKeys ...keys.FlagKey) {
if slices.Contains(flagKeys, keys.DesktopEnabled) {
r.processSpawningEnabled = r.knapsack.DesktopEnabled()
r.slogger.Log(context.TODO(), slog.LevelDebug,
"runner processSpawningEnabled set by control server",
"process_spawning_enabled", r.processSpawningEnabled,
)
if !slices.Contains(flagKeys, keys.DesktopEnabled) {
return
}

r.slogger.Log(context.TODO(), slog.LevelDebug,
"desktop enabled set by control server",
"process_spawning_enabled", r.knapsack.DesktopEnabled(),
)

if !r.knapsack.DesktopEnabled() {
// there is no way to "hide" the menu, so we will just kill any existing processes
// they will respawn in "silent" mode
r.killDesktopProcesses(context.TODO())
return
}

// DesktopEnabled() == true
// Tell any running desktop user processes that they should show the menu
for uid, proc := range r.uidProcs {
client := client.New(r.userServerAuthToken, proc.socketPath)
if err := client.ShowDesktop(); err != nil {
r.slogger.Log(context.TODO(), slog.LevelError,
"sending refresh command to user desktop process",
"uid", uid,
"pid", proc.Process.Pid,
"path", proc.path,
"err", err,
)
}
}
}

Expand All @@ -483,6 +502,10 @@ func (r *DesktopUsersProcessesRunner) writeSharedFile(path string, data []byte)

// refreshMenu updates the menu file and tells desktop processes to refresh their menus
func (r *DesktopUsersProcessesRunner) refreshMenu() {
if !r.knapsack.DesktopEnabled() {
return
}

if err := r.generateMenuFile(); err != nil {
if r.knapsack.DebugServerData() {
r.slogger.Log(context.TODO(), slog.LevelError,
Expand All @@ -502,8 +525,18 @@ func (r *DesktopUsersProcessesRunner) refreshMenu() {
// Tell any running desktop user processes that they should refresh the latest menu data
for uid, proc := range r.uidProcs {
client := client.New(r.userServerAuthToken, proc.socketPath)
if err := client.Refresh(); err != nil {

if err := client.ShowDesktop(); err != nil {
r.slogger.Log(context.TODO(), slog.LevelError,
"sending refresh command to user desktop process",
"uid", uid,
"pid", proc.Process.Pid,
"path", proc.path,
"err", err,
)
}

if err := client.Refresh(); err != nil {
r.slogger.Log(context.TODO(), slog.LevelError,
"sending refresh command to user desktop process",
"uid", uid,
Expand Down Expand Up @@ -601,12 +634,6 @@ func (r *DesktopUsersProcessesRunner) runConsoleUserDesktop() error {
return nil
}

if !r.processSpawningEnabled {
// Desktop is disabled, kill any existing desktop user processes
r.killDesktopProcesses(context.Background())
return nil
}

executablePath, err := r.determineExecutablePath()
if err != nil {
return fmt.Errorf("determining executable path: %w", err)
Expand Down
4 changes: 4 additions & 0 deletions ee/desktop/user/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func (c *client) Refresh() error {
return c.get("refresh")
}

func (c *client) ShowDesktop() error {
return c.get("show")
}

func (c *client) Notify(n notify.Notification) error {
notificationToSend := notify.Notification{
Title: n.Title,
Expand Down
2 changes: 1 addition & 1 deletion ee/desktop/user/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestClient_GetAndShutdown(t *testing.T) {

socketPath := testSocketPath(t)
shutdownChan := make(chan struct{})
server, err := server.New(multislogger.NewNopLogger(), validAuthToken, socketPath, shutdownChan, nil)
server, err := server.New(multislogger.NewNopLogger(), validAuthToken, socketPath, shutdownChan, make(chan<- struct{}), nil)
require.NoError(t, err)

go func() {
Expand Down
30 changes: 24 additions & 6 deletions ee/desktop/user/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"os"
"runtime"
"strings"
"sync"
"time"

"github.com/kolide/launcher/ee/desktop/user/notify"
Expand All @@ -30,26 +31,34 @@ type UserServer struct {
server *http.Server
listener net.Listener
shutdownChan chan<- struct{}
showDesktopChan chan<- struct{}
authToken string
socketPath string
notifier notificationSender
refreshListeners []func()
}

func New(slogger *slog.Logger, authToken string, socketPath string, shutdownChan chan<- struct{}, notifier notificationSender) (*UserServer, error) {
func New(slogger *slog.Logger,
authToken string,
socketPath string,
shutdownChan chan<- struct{},
showDesktopChan chan<- struct{},
notifier notificationSender) (*UserServer, error) {
userServer := &UserServer{
shutdownChan: shutdownChan,
authToken: authToken,
slogger: slogger.With("component", "desktop_server"),
socketPath: socketPath,
notifier: notifier,
shutdownChan: shutdownChan,
showDesktopChan: showDesktopChan,
authToken: authToken,
slogger: slogger.With("component", "desktop_server"),
socketPath: socketPath,
notifier: notifier,
}

authedMux := http.NewServeMux()
authedMux.HandleFunc("/shutdown", userServer.shutdownHandler)
authedMux.HandleFunc("/ping", userServer.pingHandler)
authedMux.HandleFunc("/notification", userServer.notificationHandler)
authedMux.HandleFunc("/refresh", userServer.refreshHandler)
authedMux.HandleFunc("/show", userServer.showDesktop)

userServer.server = &http.Server{
Handler: userServer.authMiddleware(authedMux),
Expand Down Expand Up @@ -152,6 +161,15 @@ func (s *UserServer) notificationHandler(w http.ResponseWriter, req *http.Reques
w.WriteHeader(http.StatusOK)
}

func (s *UserServer) showDesktop(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

sync.OnceFunc(func() {
s.showDesktopChan <- struct{}{}
})()
}

func (s *UserServer) refreshHandler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
Expand Down
2 changes: 1 addition & 1 deletion ee/desktop/user/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func testServer(t *testing.T, authHeader, socketPath string, logBytes *bytes.Buf
Level: slog.LevelDebug,
}))

server, err := New(slogger, authHeader, socketPath, shutdownChan, nil)
server, err := New(slogger, authHeader, socketPath, shutdownChan, make(chan<- struct{}), nil)
require.NoError(t, err)
return server, shutdownChan
}
Expand Down

0 comments on commit d7efbab

Please sign in to comment.