Skip to content

Commit

Permalink
unstage tests, stash working version post refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zackattack01 committed May 17, 2024
1 parent 4ea038c commit afab399
Show file tree
Hide file tree
Showing 17 changed files with 439 additions and 333 deletions.
30 changes: 21 additions & 9 deletions cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import (
"github.com/kolide/kit/ulid"
"github.com/kolide/kit/version"
"github.com/kolide/launcher/cmd/launcher/internal"
"github.com/kolide/launcher/cmd/launcher/watchdog"
"github.com/kolide/launcher/ee/agent"
"github.com/kolide/launcher/ee/agent/flags"
"github.com/kolide/launcher/ee/agent/flags/keys"
"github.com/kolide/launcher/ee/agent/knapsack"
"github.com/kolide/launcher/ee/agent/startupsettings"
"github.com/kolide/launcher/ee/agent/storage"
agentbbolt "github.com/kolide/launcher/ee/agent/storage/bbolt"
agentsqlite "github.com/kolide/launcher/ee/agent/storage/sqlite"
"github.com/kolide/launcher/ee/agent/timemachine"
"github.com/kolide/launcher/ee/control/actionqueue"
"github.com/kolide/launcher/ee/control/consumers/acceleratecontrolconsumer"
Expand All @@ -49,7 +50,6 @@ import (
"github.com/kolide/launcher/pkg/launcher"
"github.com/kolide/launcher/pkg/log/logshipper"
"github.com/kolide/launcher/pkg/log/multislogger"
"github.com/kolide/launcher/pkg/log/sqlitelogger"
"github.com/kolide/launcher/pkg/log/teelogger"
"github.com/kolide/launcher/pkg/osquery"
"github.com/kolide/launcher/pkg/osquery/runsimple"
Expand Down Expand Up @@ -280,14 +280,26 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl
go checkpointer.Once(ctx)
runGroup.Add("logcheckpoint", checkpointer.Run, checkpointer.Interrupt)

if k.LauncherWatchdogEnabled() { // no need to publish watchdog logs if the service isn't enabled
sqliteLogWriter, err := agentsqlite.OpenRW(ctx, opts.RootDirectory, agentsqlite.RestartServiceLogStore)
if err != nil {
return fmt.Errorf("opening log db in %s: %w", opts.RootDirectory, err)
}
slogger.Log(ctx, slog.LevelDebug, // TODO REMOVEME
"checking LauncherKolideRestartSvc enabled",
"knapsack_enabled", k.LauncherWatchdogEnabled(),
"opts_enabled", opts.LauncherWatchdogEnabled,
)

if opts.LauncherWatchdogEnabled { // TODO REMOVEME
k.SetLauncherWatchdogEnabled(true)
}

sqliteLogPublisher := sqlitelogger.NewSqliteLogPublisher(slogger, sqliteLogWriter)
runGroup.Add("sqlite_log_publisher", sqliteLogPublisher.Run, sqliteLogPublisher.Interrupt)
watchdogController, err := watchdog.NewController(ctx, k)
if err != nil { // log any issues here but move on, watchdog is not critical path
slogger.Log(ctx, slog.LevelError,
"could not init watchdog controller",
"err", err,
)
} else if watchdogController != nil { // watchdogController will be nil on non-windows platforms for now
go watchdogController.ServiceEnabledChanged(k.LauncherWatchdogEnabled())
k.RegisterChangeObserver(watchdogController, keys.LauncherWatchdogEnabled)
runGroup.Add("watchdog_controller", watchdogController.Run, watchdogController.Interrupt)
}

// Create a channel for signals
Expand Down
6 changes: 3 additions & 3 deletions cmd/launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/kolide/kit/env"
"github.com/kolide/kit/logutil"
"github.com/kolide/kit/version"
"github.com/kolide/launcher/cmd/launcher/restartservice"
"github.com/kolide/launcher/cmd/launcher/watchdog"
"github.com/kolide/launcher/ee/tuf"
"github.com/kolide/launcher/pkg/autoupdate"
"github.com/kolide/launcher/pkg/contexts/ctxlog"
Expand Down Expand Up @@ -187,8 +187,8 @@ func runSubcommands(systemMultiSlogger *multislogger.MultiSlogger) error {
run = runUninstall
case "secure-enclave":
run = runSecureEnclave
case "restart-service": // note only implemented for windows
run = restartservice.RunRestartService
case "watchdog": // note: this is currently only implemented for windows
run = watchdog.RunWatchdogService
default:
return fmt.Errorf("unknown subcommand %s", os.Args[1])
}
Expand Down
23 changes: 0 additions & 23 deletions cmd/launcher/restartservice/windows_restart_service.md

This file was deleted.

163 changes: 0 additions & 163 deletions cmd/launcher/svc_config_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@ package main

import (
"context"
"fmt"
"log/slog"
"os"
"time"

"github.com/kolide/launcher/cmd/launcher/restartservice"
"github.com/kolide/launcher/pkg/launcher"

"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
)

Expand Down Expand Up @@ -81,7 +76,6 @@ func checkServiceConfiguration(slogger *slog.Logger, opts *launcher.Options) {
defer sman.Disconnect()

checkRestartActions(sman, slogger)
checkRestartService(sman, slogger, opts)
}

// checkDelayedAutostart checks the current value of `DelayedAutostart` (whether to wait ~2 minutes
Expand Down Expand Up @@ -192,160 +186,3 @@ func checkRestartActions(serviceManager *mgr.Mgr, slogger *slog.Logger) {
slogger.Log(logCtx, slog.LevelInfo, "successfully set RecoveryActionsOnNonCrashFailures flag")
}

// serviceExists utilizes the service manager to determine if there is already a registered
// service for serviceName. It handles closing the service handle (if present)
func serviceExists(serviceManager *mgr.Mgr, serviceName string) bool { // nolint:unused
existingService, err := serviceManager.OpenService(serviceName)
if err == nil {
existingService.Close()
return true
}

return false
}

// removeService utilizes the passed serviceManager to remove the existing service
// after looking up the handle from serviceName
func removeService(serviceManager *mgr.Mgr, serviceName string) error { // nolint:unused
existingService, err := serviceManager.OpenService(serviceName)
if err != nil {
return err
}

defer existingService.Close()

if err = existingService.Delete(); err != nil {
return err
}

return nil
}

func restartService(service *mgr.Service) error {
status, err := service.Control(svc.Stop)
if err != nil {
return fmt.Errorf("stopping %s service: %w", service.Name, err)
}

timeout := time.Now().Add(10 * time.Second)
for status.State != svc.Stopped {
if timeout.Before(time.Now()) {
return fmt.Errorf("timeout waiting for %s service to stop", service.Name)
}

time.Sleep(500 * time.Millisecond)
status, err = service.Query()
if err != nil {
return fmt.Errorf("could not retrieve service status: %w", err)
}
}

return service.Start()
}

func checkRestartService(serviceManager *mgr.Mgr, slogger *slog.Logger, opts *launcher.Options) {
logCtx := context.TODO()
slogger = slogger.With("target_service", restartservice.LauncherRestartServiceName)
// if we don't currently have the service enabled, remove it
if !opts.LauncherWatchdogEnabled {
if err := removeService(serviceManager, restartservice.LauncherRestartServiceName); err != nil {
// TODO can we check for service does not exist error and prevent spamming logs here
slogger.Log(logCtx, slog.LevelWarn,
"encountered error disabling restart service",
"err", err,
)
}

return
}
// first check if we've already installed the service
existingService, err := serviceManager.OpenService(restartservice.LauncherRestartServiceName)
if err == nil {
// if the service already exists, just restart it to ensure it's running from the latest launcher update.
// If this fails, log the error but move on, this service is not worth tying up the main launcher startup.
if err = restartService(existingService); err != nil {
slogger.Log(logCtx, slog.LevelError,
"failure attempting to restart service",
"err", err,
)
}

existingService.Close()
return
}

// if we need to make any changes to the initial configuration of this service,
// (e.g. all logic below here), we will likely need to rework this method to re-install,
// rather than restart the service. This may make more sense to do as part of the upgrade process
// instead of standard start up flow
currentExe, err := os.Executable()
if err != nil {
slogger.Log(logCtx, slog.LevelError,
"installing launcher restart service, unable to collect current executable path",
"err", err,
)
}

svcMgrConf := mgr.Config{
DisplayName: restartservice.LauncherRestartServiceName,
Description: "The Kolide Launcher Restart Service",
StartType: mgr.StartAutomatic,
ErrorControl: mgr.ErrorNormal,
// no reason to rush start for this service, we should wait until after
// launcher proper has attempted to start anyway
DelayedAutoStart: true,
}

serviceArgs := []string{"restart-service"}
// add any original service arguments from the launcher proper invocation (currently running)
serviceArgs = append(serviceArgs, os.Args[2:]...)

restartService, err := serviceManager.CreateService(
restartservice.LauncherRestartServiceName,
currentExe,
svcMgrConf,
serviceArgs...,
)

if err != nil {
slogger.Log(context.TODO(), slog.LevelWarn,
"unable to create launcher restart service",
"err", err,
)

return
}

defer restartService.Close()

recoveryActions := []mgr.RecoveryAction{
{
Type: mgr.ServiceRestart,
Delay: 5 * time.Second,
},
}

if err = restartService.SetRecoveryActions(recoveryActions, 10800); err != nil {
slogger.Log(context.TODO(), slog.LevelWarn,
"unable to set recovery actions for service installation, proceeding",
"service", restartservice.LauncherRestartServiceName,
"err", err,
)
}

if err = restartService.SetRecoveryActionsOnNonCrashFailures(true); err != nil {
slogger.Log(context.TODO(), slog.LevelWarn,
"unable to set RecoveryActionsOnNonCrashFailures flag, proceeding",
"service", restartservice.LauncherRestartServiceName,
"err", err,
)
}

if err = restartService.Start(); err != nil {
slogger.Log(context.TODO(), slog.LevelWarn,
"unable to start launcher restart service",
"service", restartservice.LauncherRestartServiceName,
"err", err,
)
}
}
31 changes: 31 additions & 0 deletions cmd/launcher/watchdog/controller_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build !windows
// +build !windows

package watchdog

import (
"context"

"github.com/kolide/launcher/ee/agent/flags/keys"
"github.com/kolide/launcher/ee/agent/types"
)

func NewController(_ context.Context, _ types.Knapsack) (*WatchdogController, error) {
return nil, nil
}

func (wc *WatchdogController) FlagsChanged(flagKeys ...keys.FlagKey) {
return
}

func (wc *WatchdogController) ServiceEnabledChanged(enabled bool) {
return
}

func (wc *WatchdogController) Run() error {
return nil
}

func (wc *WatchdogController) Interrupt(_ error) {
return
}
Loading

0 comments on commit afab399

Please sign in to comment.