From 485e746bbc8faa12158b54490ebe9fb51c4fcff9 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Thu, 22 Sep 2022 16:43:35 -0400 Subject: [PATCH 01/13] Add stop timeout to the endpoint spec --- internal/pkg/agent/operation/monitoring.go | 2 +- .../pkg/agent/operation/monitoring_test.go | 2 +- internal/pkg/agent/program/spec.go | 9 ++++++++- internal/pkg/agent/program/supported.go | 2 +- internal/pkg/core/plugin/service/app.go | 18 +++++++++++++----- internal/spec/endpoint.yml | 2 ++ 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/internal/pkg/agent/operation/monitoring.go b/internal/pkg/agent/operation/monitoring.go index f28c681e42a..ebb0c095ab9 100644 --- a/internal/pkg/agent/operation/monitoring.go +++ b/internal/pkg/agent/operation/monitoring.go @@ -668,7 +668,7 @@ func normalizeHTTPCopyRules(name string) []map[string]interface{} { return fromToMap } - for _, exportedMetric := range spec.ExprtedMetrics { + for _, exportedMetric := range spec.ExportedMetrics { fromToMap = append(fromToMap, map[string]interface{}{ "from": fmt.Sprintf("http.agent.%s", exportedMetric), "to": exportedMetric, diff --git a/internal/pkg/agent/operation/monitoring_test.go b/internal/pkg/agent/operation/monitoring_test.go index 06a9cfbe23b..55b18741dad 100644 --- a/internal/pkg/agent/operation/monitoring_test.go +++ b/internal/pkg/agent/operation/monitoring_test.go @@ -37,7 +37,7 @@ import ( func TestExportedMetrics(t *testing.T) { programName := "testing" expectedMetricsName := "metric_name" - program.SupportedMap[programName] = program.Spec{ExprtedMetrics: []string{expectedMetricsName}} + program.SupportedMap[programName] = program.Spec{ExportedMetrics: []string{expectedMetricsName}} exportedMetrics := normalizeHTTPCopyRules(programName) diff --git a/internal/pkg/agent/program/spec.go b/internal/pkg/agent/program/spec.go index 12f860a1e9a..9cc91582378 100644 --- a/internal/pkg/agent/program/spec.go +++ b/internal/pkg/agent/program/spec.go @@ -40,7 +40,14 @@ type Spec struct { When string `yaml:"when"` Constraints string `yaml:"constraints"` RestartOnOutputChange bool `yaml:"restart_on_output_change,omitempty"` - ExprtedMetrics []string `yaml:"exported_metrics,omitempty"` + ExportedMetrics []string `yaml:"exported_metrics,omitempty"` + Process *ProcessSettings `yaml:"process,omitempty"` +} + +// ProcessSettings process specific settings +type ProcessSettings struct { + // Allows to override the agent stop timeout settings and specify a different stop timeout for Endpoint service + StopTimeoutSecs int `yaml:"stop_timeout"` } // ReadSpecs reads all the specs that match the provided globbing path. diff --git a/internal/pkg/agent/program/supported.go b/internal/pkg/agent/program/supported.go index 52685137b97..deb23d32f86 100644 --- a/internal/pkg/agent/program/supported.go +++ b/internal/pkg/agent/program/supported.go @@ -27,7 +27,7 @@ func init() { // internal/spec/metricbeat.yml // internal/spec/osquerybeat.yml // internal/spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("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") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index 312ac8b592e..6f7ee21a82e 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -247,6 +247,14 @@ func (a *Application) Configure(ctx context.Context, config map[string]interface return err } +func (a *Application) getStopTimeout() time.Duration { + if a.desc.Spec().Process != nil && a.desc.Spec().Process.StopTimeoutSecs > 0 { + to := time.Duration(a.desc.Spec().Process.StopTimeoutSecs) * time.Second + return to + } + return a.processConfig.StopTimeout +} + // Stop stops the current application. func (a *Application) Stop() { a.appLock.Lock() @@ -256,15 +264,15 @@ func (a *Application) Stop() { if srvState == nil { return } - - if err := srvState.Stop(a.processConfig.StopTimeout); err != nil { - a.appLock.Lock() + to := a.getStopTimeout() + a.logger.Infof("Stop %v service, with %v timeout", a.desc.Spec().Name, to) + a.appLock.Lock() + if err := srvState.Stop(to); err != nil { a.setState( state.Failed, - fmt.Errorf("failed to stop after %s: %w", a.processConfig.StopTimeout, err).Error(), + fmt.Errorf("failed to stop after %s: %w", to, err).Error(), nil) } else { - a.appLock.Lock() a.setState(state.Stopped, "Stopped", nil) } a.srvState = nil diff --git a/internal/spec/endpoint.yml b/internal/spec/endpoint.yml index 5f452ba1943..1f54121be4f 100644 --- a/internal/spec/endpoint.yml +++ b/internal/spec/endpoint.yml @@ -2,6 +2,8 @@ name: Endpoint Security cmd: endpoint-security artifact: endpoint-dev service: 6788 +process: + stop_timeout: 180 action_input_types: - endpoint log_paths: From 4868a3124d58eb19afc2c07dd7b492f2252bf1dd Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 09:33:02 -0400 Subject: [PATCH 02/13] Service watcher --- internal/pkg/agent/program/spec.go | 7 ++ .../pkg/core/plugin/service/status_watcher.go | 86 +++++++++++++++++++ .../plugin/service/status_watcher_test.go | 49 +++++++++++ internal/spec/endpoint.yml | 3 + 4 files changed, 145 insertions(+) create mode 100644 internal/pkg/core/plugin/service/status_watcher.go create mode 100644 internal/pkg/core/plugin/service/status_watcher_test.go diff --git a/internal/pkg/agent/program/spec.go b/internal/pkg/agent/program/spec.go index 9cc91582378..76be58d9ddc 100644 --- a/internal/pkg/agent/program/spec.go +++ b/internal/pkg/agent/program/spec.go @@ -42,6 +42,7 @@ type Spec struct { RestartOnOutputChange bool `yaml:"restart_on_output_change,omitempty"` ExportedMetrics []string `yaml:"exported_metrics,omitempty"` Process *ProcessSettings `yaml:"process,omitempty"` + ServiceInfo *ServiceInfo `yaml:"service_info,omitempty"` } // ProcessSettings process specific settings @@ -50,6 +51,12 @@ type ProcessSettings struct { StopTimeoutSecs int `yaml:"stop_timeout"` } +// Service info +type ServiceInfo struct { + Name string `yaml:"name"` + Label string `yaml:"label"` +} + // ReadSpecs reads all the specs that match the provided globbing path. func ReadSpecs(path string) ([]Spec, error) { var specs []Spec diff --git a/internal/pkg/core/plugin/service/status_watcher.go b/internal/pkg/core/plugin/service/status_watcher.go new file mode 100644 index 00000000000..554bb5c8ec5 --- /dev/null +++ b/internal/pkg/core/plugin/service/status_watcher.go @@ -0,0 +1,86 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package service + +import ( + "context" + "time" + + "github.com/kardianos/service" +) + +const ( + defaultCheckInterval = 10 * time.Second + defaultCheckDuration = 3 * time.Minute +) + +type statusCheckResult struct { + status service.Status + err error +} + +type serviceWatcher struct { + svc service.Service + statusCh chan statusCheckResult + checkInterval time.Duration + checkDuration time.Duration + stopOnError bool +} + +func newServiceWatcher(name string) (*serviceWatcher, error) { + svcConfig := &service.Config{ + Name: name, + } + + svc, err := service.New(nil, svcConfig) + if err != nil { + return nil, err + } + + return &serviceWatcher{ + svc: svc, + statusCh: make(chan statusCheckResult), + checkInterval: defaultCheckInterval, + checkDuration: defaultCheckDuration, + stopOnError: false, + }, nil +} + +func (s *serviceWatcher) run(ctx context.Context) { + start := time.Now() + t := time.NewTimer(s.checkInterval) + defer t.Stop() + defer close(s.statusCh) + + for { + select { + case <-ctx.Done(): + return + case <-t.C: + if time.Since(start) > s.checkDuration { + return + } + status, err := s.svc.Status() + + select { + case s.statusCh <- statusCheckResult{ + status: status, + err: err, + }: + case <-ctx.Done(): + return + } + + if s.stopOnError { + return + } + t.Reset(s.checkInterval) + } + } +} + +func (s *serviceWatcher) status() <-chan statusCheckResult { + return s.statusCh +} diff --git a/internal/pkg/core/plugin/service/status_watcher_test.go b/internal/pkg/core/plugin/service/status_watcher_test.go new file mode 100644 index 00000000000..b6ed01889ee --- /dev/null +++ b/internal/pkg/core/plugin/service/status_watcher_test.go @@ -0,0 +1,49 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package service + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/kardianos/service" +) + +func TestStatusWatcher(t *testing.T) { + ctx, cn := context.WithCancel(context.Background()) + defer cn() + + sw, err := newServiceWatcher("co.elastic.endpoint") + if err != nil { + t.Fatal(err) + } + + sw.checkDuration = time.Minute + sw.checkInterval = 2 * time.Second + + go func() { + sw.run(ctx) + }() + + for r := range sw.status() { + if r.err != nil { + fmt.Println("watch err:") + } else { + var s string + switch r.status { + case service.StatusUnknown: + s = "Unknown" + case service.StatusRunning: + s = "Running" + case service.StatusStopped: + s = "Stopped" + } + fmt.Println("status:", s) + } + } + fmt.Println("watch done") +} diff --git a/internal/spec/endpoint.yml b/internal/spec/endpoint.yml index 1f54121be4f..255513509ab 100644 --- a/internal/spec/endpoint.yml +++ b/internal/spec/endpoint.yml @@ -4,6 +4,9 @@ artifact: endpoint-dev service: 6788 process: stop_timeout: 180 +service_info: + name: ElasticEndpoint + label: co.elastic.endpoint action_input_types: - endpoint log_paths: From b9fc9d66afdfcf0099c2ff4ed207e2cc586d0bd9 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 12:10:37 -0400 Subject: [PATCH 03/13] Wire in the service watcher --- internal/pkg/core/plugin/service/app.go | 79 +++++++++++++++++++ .../pkg/core/plugin/service/status_watcher.go | 54 +++++++++---- .../plugin/service/status_watcher_test.go | 19 +++-- 3 files changed, 132 insertions(+), 20 deletions(-) diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index 6f7ee21a82e..b83b225c7c1 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -10,10 +10,12 @@ import ( "io" "net" "reflect" + "runtime" "sync" "time" "github.com/elastic/elastic-agent/internal/pkg/agent/program" + "github.com/kardianos/service" "gopkg.in/yaml.v2" @@ -272,6 +274,11 @@ func (a *Application) Stop() { state.Failed, fmt.Errorf("failed to stop after %s: %w", to, err).Error(), nil) + + // Start service status watcher if service haven't responded over RPC within the allowed duration. + // This monitors the service status over the platform specific service interfaces + // Set the state into stopped if the service has stopped + a.stopAndWatch() } else { a.setState(state.Stopped, "Stopped", nil) } @@ -282,6 +289,78 @@ func (a *Application) Stop() { a.appLock.Unlock() } +func (a *Application) stopAndWatch() { + var err error + + name := a.desc.Spec().ServiceInfo.Name + if runtime.GOOS == "darwin" { + name = a.desc.Spec().ServiceInfo.Label + } + + svc, err := getService(name) + if err != nil { + a.logger.Errorf("failed to get %s service: %v", name, err) + a.setState(state.Stopped, "Stopped", nil) + } + + // Attempt to stop the service, log any errors and continue to watch the service status anyways + err = svc.Stop() + if err != nil { + a.logger.Errorf("failed to stop %s service, err: %v, ", name, err) + } + + // Attempt to stop the service, log any errors and set the service to stopped to allow the agent health to recover + sw, err := newServiceWatcher(name) + if err != nil { + a.logger.Errorf("failed to create the %s service watcher, setting service status to stopped", name) + a.setState(state.Stopped, "Stopped", nil) + return + } + + // Run service watcher + ctx, cn := context.WithCancel(a.bgContext) + defer cn() + go func() { + sw.run(ctx) + }() + + var lastStatus service.Status +LOOP: + for r := range sw.status() { + if r.Err != nil { + err = r.Err + // If service watcher returned the error, log the error and exit the loop + a.logger.Errorf("%s service watcher returned err: %v", name, r.Err) + break LOOP + } else { + lastStatus = r.Status + switch lastStatus { + case service.StatusUnknown: + a.logger.Debugf("%s service watcher status: Unknown", name) + case service.StatusRunning: + a.logger.Debugf("%s service watcher status: Running", name) + case service.StatusStopped: + a.logger.Debugf("%s service watcher status: Stopped", name) + break LOOP + } + } + } + + if lastStatus != service.StatusStopped && err == nil { + var s string + switch lastStatus { + case service.StatusUnknown: + s = "Unknown" + case service.StatusRunning: + s = "Running" + } + a.logger.Errorf("%s service failed to stop within %v, last reported service status: %s", name, sw.checkDuration, s) + } + + a.logger.Infof("setting %s service status to Stopped", name) + a.setState(state.Stopped, "Stopped", nil) +} + // Shutdown disconnects the service, but doesn't signal it to stop. func (a *Application) Shutdown() { a.appLock.Lock() diff --git a/internal/pkg/core/plugin/service/status_watcher.go b/internal/pkg/core/plugin/service/status_watcher.go index 554bb5c8ec5..f3762e24b27 100644 --- a/internal/pkg/core/plugin/service/status_watcher.go +++ b/internal/pkg/core/plugin/service/status_watcher.go @@ -6,6 +6,7 @@ package service import ( "context" + "errors" "time" "github.com/kardianos/service" @@ -17,8 +18,8 @@ const ( ) type statusCheckResult struct { - status service.Status - err error + Status service.Status + Err error } type serviceWatcher struct { @@ -27,14 +28,25 @@ type serviceWatcher struct { checkInterval time.Duration checkDuration time.Duration stopOnError bool + + lastStatusCheckResult statusCheckResult + + // The github.com/kardianos/service library sometimes returns service.ErrNotInstalled error + // while the service transitioning from running to stopped, found during testing on linux + // Capture the last error separately in order to perform another watch loop pass if this happens + lastStatusCheckError error } -func newServiceWatcher(name string) (*serviceWatcher, error) { +func getService(name string) (service.Service, error) { svcConfig := &service.Config{ Name: name, } - svc, err := service.New(nil, svcConfig) + return service.New(nil, svcConfig) +} + +func newServiceWatcher(name string) (*serviceWatcher, error) { + svc, err := getService(name) if err != nil { return nil, err } @@ -44,13 +56,13 @@ func newServiceWatcher(name string) (*serviceWatcher, error) { statusCh: make(chan statusCheckResult), checkInterval: defaultCheckInterval, checkDuration: defaultCheckDuration, - stopOnError: false, + stopOnError: true, }, nil } func (s *serviceWatcher) run(ctx context.Context) { start := time.Now() - t := time.NewTimer(s.checkInterval) + t := time.NewTicker(s.checkInterval) defer t.Stop() defer close(s.statusCh) @@ -62,21 +74,33 @@ func (s *serviceWatcher) run(ctx context.Context) { if time.Since(start) > s.checkDuration { return } + status, err := s.svc.Status() - select { - case s.statusCh <- statusCheckResult{ - status: status, - err: err, - }: - case <-ctx.Done(): - return + if err != nil { + if s.lastStatusCheckError == nil && errors.Is(err, service.ErrNotInstalled) { + s.lastStatusCheckError = err + break + } } + s.lastStatusCheckError = err - if s.stopOnError { + // Send status check result if it changed + if s.lastStatusCheckResult.Status != status || !errors.Is(err, s.lastStatusCheckResult.Err) { + res := statusCheckResult{ + Status: status, + Err: err, + } + select { + case s.statusCh <- res: + case <-ctx.Done(): + return + } + s.lastStatusCheckResult = res + } + if err != nil && s.stopOnError { return } - t.Reset(s.checkInterval) } } } diff --git a/internal/pkg/core/plugin/service/status_watcher_test.go b/internal/pkg/core/plugin/service/status_watcher_test.go index b6ed01889ee..a6c55818006 100644 --- a/internal/pkg/core/plugin/service/status_watcher_test.go +++ b/internal/pkg/core/plugin/service/status_watcher_test.go @@ -7,34 +7,43 @@ package service import ( "context" "fmt" + "runtime" "testing" "time" "github.com/kardianos/service" ) +// Useful test to keep the code around. +// Marked as skipped, because can't really use as unit test with CI since it relies on actual endpoint service to be present func TestStatusWatcher(t *testing.T) { + t.Skip() ctx, cn := context.WithCancel(context.Background()) defer cn() - sw, err := newServiceWatcher("co.elastic.endpoint") + name := "ElasticEndpoint" + if runtime.GOOS == "darwin" { + name = "co.elastic.endpoint" + } + sw, err := newServiceWatcher(name) if err != nil { t.Fatal(err) } - sw.checkDuration = time.Minute + sw.checkDuration = 2 * time.Minute sw.checkInterval = 2 * time.Second + sw.stopOnError = false go func() { sw.run(ctx) }() for r := range sw.status() { - if r.err != nil { - fmt.Println("watch err:") + if r.Err != nil { + fmt.Println("watch err:", r.Err) } else { var s string - switch r.status { + switch r.Status { case service.StatusUnknown: s = "Unknown" case service.StatusRunning: From d28c280c58f2a273685b62d581a64160ea57f79c Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 13:36:09 -0400 Subject: [PATCH 04/13] Regenerate spec --- internal/pkg/agent/program/supported.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/agent/program/supported.go b/internal/pkg/agent/program/supported.go index deb23d32f86..5ee73b9ae21 100644 --- a/internal/pkg/agent/program/supported.go +++ b/internal/pkg/agent/program/supported.go @@ -27,7 +27,7 @@ func init() { // internal/spec/metricbeat.yml // internal/spec/osquerybeat.yml // internal/spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("eJzce1mXqzh39v33M/r2S/IylKsPWeu9MFQx2UW18TEC3SHJBdgCu8tgG2flv2dJDAZMjd3pdHJRa50jg4atPTz72Zv/+CXJ8vVrFtJ/HPZr/I9wn/7rYf16XL/+W5nSX/79F5TqOfy5ixae6sw9h+IMUhztNwgs7i1DP6GleIG+LUHfmgW+LYQAxoE8+luGL7sInHaRpVm5u7QOlmbnAZjEUPJyCCbCPPWKANgHCBYKMW0RLq2DlkwjKxF1KzlFVko2vqxSnDoUZQvFNnN19Sj+dD0buJ794gqKubjszk8PqmJFe6Kl3h02lJIY3taXREpMex/IT/eWfphZ2jQJfDWf+/WZEuugUWGGM+8A/ad7tu58qW6QrE582T360nmP5QUft7RpZBlUgEC4twx4gMAT2nHTPT4n6h5lqkjMpxkf06YRkiYvgaQUMD3vK/lMjkiest9zyxBj/LBrn8WGLoQPuwimZwr9xXW8s7dmbL5USwjEI0m9l1DyJs/Rrv2t+lNfob9l97EJJO+CRSXGBuXPfmse06aVTGkBT91nhAinXo5kSH0pp+uf1/M0f3zeRGX3XZDpjr8DU3rny46AUy9GP3fRWhZqmcA9Ml2KqSIF4Cz2zm06FBnehhhKOSbreh1h7av0+g6MkelRfOntK+d6umj3ciCGV17Prl4gONNAdo84u5H7zbrVfIpITFWszneVTecuc8ugRZh6G6IrOwj0LfTty3Oi/vqy2Muh4RXPiXqAYJIRI9rZZl6v4yiz5fT/Ww/TKACTrWXEMRZyul5G27VUr2kKB0sjFBn6hRh0gyUvxqmzs8tTZMs2hQa92OWJ7SELJT0Npcdsrk0zZCgZlt0YS1E2W+z++cu/DL1CQZIcrcN86BR8bxv6bgKBLmipk8OHXRT0xvQSdgxuDp6SOTe86zPz1DsEviOE4CkPAGGGXayBeLCSU/XOasXfwZInEH9ahOCcdx0FTPUDllbJfNpzLBfouyLWJgIE4gkZugCXE4pSPUGGt/0NMGVw6HANBPSC7wF4BdE6z/tuScDNGgckkSwEk2yenilJvcNvwKVB5mXDeaHkvGDDKwOm+A/Cdi3onvtIV4utp3q6Yv4UyMPz5vH0ZArDNWIC3D0xbBr4i6JyIDSbp+IRmtwZFBBM4oAp14OYBuB8gUtr5i/2Mc7cPUz1DWF3knoxMZ+OvbvJbMovPXNfmHNCsidg0xN8ydkFYJKx++VOeLHrOMVxg9WSp2gBzgfrURehQQW+nlYbiFYZIi7VBAKyR4kqh767szRSnU37kc2j3YjBOy9EokKoKyUEhK7NaW2AjSNyJ9hYVcZn2vQ5mWZ+Wq0/L+9e7do5Yck7QOAISLbumeGxM+LTbmaVqgoN92JpZI9Sl64fdhE3hFL8FRq6EHjKhZg2DYBQ8P/7DiWmkK8lNyaG/oJlt4RAz+fpJEbAu2BD30BfyFgAsAwvDqQoCsHkRPxFweQWgsnvbB++RAtoeHeNkyEmPTFZ87W7+zJdGZVqDA33BaaUIj6mlkhyKJYd5pCYEzqidBXBVCktw5OqIMr3d4H+onYUSgGXaopki829DXw3bu9vOeH/Z7Y1125+4/c219QYpYtoKBPuA3znFACHVvfXOrX6GfEFm/aRBx1JaZ3qbSCkBZa8kuhKDDOX4rfl8oCkiQR9W2juEYhC0dwDFnPCxonxo5a7e2G/c531YwEzW9CVQ+jzO2B+4dLsqQm4zXu1nu2J4eXPidqcpxkX0KXzLD97J4CbakyMqKtrY8F7Yz1Wv1d67F0sAx5xoqode2d2m4XgLuJ2oE2zyn4XR7u8i1wfUpxRIWSBmOkJk12iCqGhM/lc2nVMLh8BgkUU+E8RMWJqGbX/WKpFAER2f01QY3IqsHSOieG9YX99kMLvadEJdje2GBWzcpt13+XzPuwi++Fx1gEPfC894GHAEklC39a16x0goGwJONOOTFPLeIxae9XUPS7VCza8TQjgnstAUgqSeiXzS7WsuM7YUmM3LgvGyOYATyR2edfuEQH9FXpKjDM77gOcVldae+qd1/hxbxnX+evfciYrBBQJegr3ad13ahAznO8z77Rx66vrtLa/2H0MCg0O8rg82T2HQCnae9Btin1vj9NVFLC4YDhHlMI9LFUBleoGSSK1THeHU0WEUlTp5KOeMf9laXGBSvWAJCdGmpqG4ExxuS2+cJYqruhKyXTDl+AeGV5tp2+Byg7Q29z4gRpA1zZTy4ak+oEA79KRCQOTXOfhtDvG138JAcMipAx9twO8hQjL9MJ0R4t2G+tR30LzKSImOVqGvoW6kobAO7Cxri/FJQeajV+PGtwUglGf3wJCX6pkPE/pdq6NjGdOEfjqJTQUYfx35nOcPZLuBjGt+p3HtvTHvWXmSiVv54jN5o7UFKdKfgPYq4Spi3NmbO6hP4CZfWR4o48d+z62srMWG81qvNID9Vc8YLd3N1/212/tvcZEre4xnff5u7S6rzrmaWoL5Bt/UvnZGphrTOcnaQiIiFOd28ogZg4Sgd2MSDFFGxb/vALK7m6mub/2z96c8w8lBjwZwCmb94knA19KDDDdFWQsMZDORwIGiUFvbJAY/K1A/p58HhwPgHb3jNGeO6A64+SOYN2CI6EykqTOJNM9cz7MSWyhH3UyXR747i3jfIQyU+j+8w348eUOMNzs3mEdxsGWVYN0lnkiiTBnyYEoMk69u2xAzRW02BRKtLBMsidGFNmSc0Cyt60SAFzU+2VOXIC+/dI4TV9mz8cvOPUy6MenTsZ9C+6Z0aare0sj665858ku+4gRGMqrcpRczikDEFXy0t2jNcoy3LIGfcdz4zCivySTj2wpj2Gax9W/mY44DPjs7HI7uzHWdUb2uyQb2qoLJltsKHuULaKV5G2Ib++JuZ0FkritwIR7QhItiCZeIHBEnFJhPdB7eJ0jh4YnaRln1faBtLq3HgL5+SGatQGskaXJHKn6QgyaQ6CIbJ6nn9Hp+q7X3FP1vMESrdW99dgQBo7e7q0OuMjQEwhO9yzwdIiForO/WQAc7oBZsOI2LVe6/MwdsldAUz2yYK2l5yMUlVPgu7tqzwwk2XII7u4tzTr+NGiCU71cLxW9uae5cH1/zu/CpXN2L6XSkaPw+5zNXVpszkMIJiJLPq1EOWJzcXTBOcayuw9K5Xo+TbkQ7t+UA5LwsSvvWTJhYwnTW8KTS0XGl11kbZ/uff28wKmS4VTPrccKCPn6ud0v/3ezhn7GzOcRw8M+8zfiGY+ukzo7CJxXLj/ZjZFxuq+TLBqICgdsw8TKSjty8R0ayB4HQlb9XM0Ot4HXYkAjpel6aV3HEiFnAclqg/Y0wbLLgmbZjPV06TKdYUO5EJ3t3xEYEK3v+A4ChyXVB/hzkLRp9ri+N/swqrjVAgLNbufu7mu+FNs7qZ+7EMOlOLM6Y1Y+970TlO0YGqvBuE2xpIg4dSguOzJ4Q4795yf3oT9NmmQ1BCJlfuk5mUpPD1Nmh9SXvSIEE6ZTB/Swm82XKl0b3qYCy6sGsHHdf06mSVcP8NVHNGvEOCV9IKzZIkpb/Ui6gHd4j+PyGdn3hyTUFez58oDtfY8xrhOZbiI7BPdMPh1fMxuLabcA07ohAcYTNHXIcOcsaSdgxc+EgH4a2lOvMmDaIjJ6e/0waeMYIPXKXlK0uZVV1yb71QhhkCTdMt98Hz7cY4keUTQOaKs53UE8PFOUEiHUWDys5ScLe+vhLnqqyajQ0C9LyZuwOZqY+7JkMbCNDRcI9DKQohEgu2dgnOGwmNkR85UoVQSLrSfbIsrcPQKrIvDtTWgK0W8/hciW9BL9DAS7rNa3zbwkYMJ1dJ7CGAF6WPv1szw+xwz/VOfR3F9x5hXcNy0neQD2R5zVz15wNltOb2P1S0LXI7jaZT4LVElKHZ+5v+V4a7qv7DBRUa9qljmUmN5pntID+gQ+bjA4S0qxcY6JsRojmQeVOTFGKUsCRZ6Idp4XcObdYnBDyRhuhOXkAH1I0YO4hcAWYflhxc9Yrs76J4jzq1y0SZ184aIhjHA5IgdeMdRLYtCUYYTnROU4E5dKV8Yl9FlctwVfYhii1nld2YSGXkCGd2rb/chfvY37b7D4X0Gu2jVZ3/i1PUpxhFKPckLC+MFs7oQNr+CYP1VKuFRjlG0jJLs76FsN2c3yohhlTopkOw98d89sbc6SZd2hcKnuiOme8GV3nEs8BxCDhN2PcIRX3NPi3jmoiQeJXrDsUVz+EJ42uPhv9vUxkZ/yOteQA9/dhNP+b/jy1PrBwN+LOF3lXI8zd0fANV7Xc6RIZnHbnlx9pXNEmcv8T3sn86W6RZLzCv3r+9WciyPHKldSjpLUqzGhu0fRzbgQVJXl3hwEuKfr+hUWrHPR67OSc5r7qhhkjhhc5+V35ksdbNzOEwvEVH/HknIl6Iz9kfh2EYDztkOc8Dzl+v/zsakez5dqhWkNZRNKXtl7plRKCNw9FpULMhSZ6evg98vad9j7V9KG+Za+vA4EiAn07d8D4Lxe3xfPxOyQPaknwPR8JNd9HZ8ugViT7l2iehv61/tnGDQEd7Muodfbp+lu8FV/RGhe74aAyX59/U0OAcfYb8b9ATHZ5RdqfVNOa0+JkXF+IYbyggx6IQ+7G+K8LZp081eD+TNO1B7Cyv8VSFJOXYIV+vEG+ir7DVlZ7c/8qqjb+nyN+98TTpUN9J0Lku2LRYXhHgUkVsWYPj6puyr6ha7v7p9hc4oz9yVIvbQm7SoCuYqns16RwRgjExv80Z519p2C0nC/oe9SFgeG4701Txxn5oE/HeDxIYF6g/86RZzV54o2hhhjU6Vd7qgaPx9hnRN0bfaqDx3/VMeT7nqWNvBVm93AXpp16uKl7G4w25/hnN6Yh9nPvWV6Wzzt74WtPZfcYyDl7BzRwJ8083BfU9mw84KZf2b5OdOpnl13zn/1MfeW6UzYOx3f9SHWJr5DW5ww/fx7g4Jr1/+80WXTFCreKVB/obDzZhH8L85//sQiQwfHdc9g3RaBss5eqlhZcbpv5zqv0KcXhjngYtfHdoYXQ8NjuVSVp2ZkB8HdfT/Pua7RFjX+YM7Tkvp8j+Q1APA1WOKDpRGOK4mhX0IN77Xon7fE/gtdr/PxTkC3ygOjVZND1vx+nR/mbW555fiT+VKsur40MUeSS1k86HcLVl10bTfeZ7jzqN+1dYMDP9DFt7jmkcJeN//NO7nzn7O+0dY5PtxD05DzbiG0tt8rF13ts9kLsx8WZ97guSNQqikyPEq0SdO9WTRzXTnVVtciv40jbXw6Et9luUDDrTd2xYugaFQ+vPCFWj3Imq7MyQlJLJfZ8uLmyFqNnRdPWvvslfev4z80vDTwvQMxx7sIb/n9m33skOwIgw7AGznxzsjxzr+i0Rtm30xfUKoffFk94mzx0doXLJ1uukMbbDHfTIuhTnaxY0dW1X7b/Q3xY8ffdfmgzt9Y8bT/JzTF6Jt363zhiOVWLzrY5u3GmTf3+U4jwEfx9+NYOu3Gq9HmiD80x3LCi9tYVuNAWn3rXO/E5+/s79rkFH2rG3agW9MxjrB5dugfvhoruX28LLfRb8n0ZBl6AbU/u842Uj+L1+HrWBfs0vBinPWL3WFvrBMIP1vo/gYh95W2+k91sd4EaZsGzOFIMWXj3yfE6oKrH7cgte56GA+oosI7Rn3ZplDy7rqt8uOt3jZ9TtQ1lpmjjSm/2PJHMTuNKPKg2+c9YPt+l1DHMJu7uTra2xb2JlHLPPqZIvVbjvlth/yx8fUdc6ezZdTo/gagNF3nrwkescCfwBNwSje1RtYfp9QffEg1XT7+AUrTQrJHhvAxzd1Q6ZlLka8eeHn34zaVL37kwlJuskcpLhBPi08KNLyEADycNwtE5QR9e8Pm/W3p/vpz5a1WW/rwCXo8h75bhsCpU46mP2/C4DmnE8bOpb3pEfqyxqnHbrIkunJEVKk1zn0JpDhGKWHWWWl+1lIXb7THfKJvur77mi75XGvMe1QRgEJLwbbtN+3HQ+/2pg3ouV6fcIfq+YDWcYb9xn8rmi8Ei/9ddJ/h3RHTjplOcDnpCu/VvZYLBrCzQ/X19zgYH3zoNVqSeCtyjZQheIuTflfMSqWxzYs9ff8bhv/pMvRHdHRdCuJ+8u2Wr84d3PZ5l8zG/ST6x+rhzKP8b8nd62x5K6NqHt6Gdm9pbhcR3FK+Wo8q6qOHYR/plTLLA5BTX9JLnOqTUT1u/cQAhle60u75iz3gnfcWX6ABh7TC16nDb/ePd74r+QNzjKRInziD6V2gp3RSjD+VQuzFzffLCb2YWIzFhrYcffoKHdmPtY1c3u1V7skgpgFwKZuzOv9oq+IAH/wNeo13h9+L9Ws5Bv9k50yAV677nRFHLOsi9O3JsDviC50RX4d+X+k0/lRHhP39buT6sz80lM+7HZDKBfsexdl29r1Ov+Z9WnUMf7bDz3T3CHhH4i/urYfHU7d7+o1ksdsV0XzCN4BtTdd0R/0b9+IpHcjSmhyDq7xbBBmUyzAEnN1jriNlof3tDo0/8GlJ71PGIYvMTLu+v0FlYbyb+dOfPAy+X/7Lu5c/+A75tkur33XFkspYsbRHxdLw5fkhyEaTxn2It+sx2mZl6JtQ8oRe0miyYJPT5kOQNmksce5WaeoHCSN75ubZd79P4FIpRb3q4X6/j6r/7JuJYvbWB8C4f+bvUzd/kCLp15/fpEdOAXBe4QhP+H+sj/+jL/Jnv/zn//uvAAAA////CdBT") SupportedMap = make(map[string]Spec) for f, v := range unpacked { From b9ef2a96cf15fcb8883251d69bc50a6ad21dda20 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 21:54:24 -0400 Subject: [PATCH 05/13] Refinements and more comments --- internal/pkg/core/plugin/service/app.go | 34 +++++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index b83b225c7c1..d6703ef2cb0 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -277,7 +277,7 @@ func (a *Application) Stop() { // Start service status watcher if service haven't responded over RPC within the allowed duration. // This monitors the service status over the platform specific service interfaces - // Set the state into stopped if the service has stopped + // and sets the state into stopped if the service has stopped or the grace period ended. a.stopAndWatch() } else { a.setState(state.Stopped, "Stopped", nil) @@ -295,21 +295,24 @@ func (a *Application) stopAndWatch() { name := a.desc.Spec().ServiceInfo.Name if runtime.GOOS == "darwin" { name = a.desc.Spec().ServiceInfo.Label - } - - svc, err := getService(name) - if err != nil { - a.logger.Errorf("failed to get %s service: %v", name, err) - a.setState(state.Stopped, "Stopped", nil) - } + } else { + // Attempt to stop the service on non-windows platforms + svc, err := getService(name) + if err != nil { + a.logger.Errorf("failed to get %s service: %v", name, err) + a.setState(state.Stopped, "Stopped", nil) + } - // Attempt to stop the service, log any errors and continue to watch the service status anyways - err = svc.Stop() - if err != nil { - a.logger.Errorf("failed to stop %s service, err: %v, ", name, err) + // Attempt to stop the service, log any errors and continue to watch the service status anyways. + // The Endpoint service implements a protection from being stopped on windows + // and this call can result in "Access denied" error at the moment. + err = svc.Stop() + if err != nil { + a.logger.Debugf("failed to stop %s service, err: %v, ", name, err) + } } - // Attempt to stop the service, log any errors and set the service to stopped to allow the agent health to recover + // Watch the service status, log errors and set the state to stopped in order to allow the agent health to recover. sw, err := newServiceWatcher(name) if err != nil { a.logger.Errorf("failed to create the %s service watcher, setting service status to stopped", name) @@ -317,7 +320,7 @@ func (a *Application) stopAndWatch() { return } - // Run service watcher + // Run service watcher. ctx, cn := context.WithCancel(a.bgContext) defer cn() go func() { @@ -326,6 +329,7 @@ func (a *Application) stopAndWatch() { var lastStatus service.Status LOOP: + // The service watcher stops by closing the status update channel for r := range sw.status() { if r.Err != nil { err = r.Err @@ -346,6 +350,7 @@ LOOP: } } + // The service watcher exited at this point. Log the error if the status of the service is still not stopped. if lastStatus != service.StatusStopped && err == nil { var s string switch lastStatus { @@ -357,6 +362,7 @@ LOOP: a.logger.Errorf("%s service failed to stop within %v, last reported service status: %s", name, sw.checkDuration, s) } + // Set the service state to "stopped" a.logger.Infof("setting %s service status to Stopped", name) a.setState(state.Stopped, "Stopped", nil) } From 0de6cf050a28f42b77773f4307e9f9252c007e52 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 22:08:33 -0400 Subject: [PATCH 06/13] Delint --- internal/pkg/agent/program/spec.go | 1 + internal/pkg/core/plugin/service/app.go | 18 ++++++++++++------ .../core/plugin/service/status_watcher_test.go | 9 ++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/internal/pkg/agent/program/spec.go b/internal/pkg/agent/program/spec.go index 76be58d9ddc..9031a5694f1 100644 --- a/internal/pkg/agent/program/spec.go +++ b/internal/pkg/agent/program/spec.go @@ -59,6 +59,7 @@ type ServiceInfo struct { // ReadSpecs reads all the specs that match the provided globbing path. func ReadSpecs(path string) ([]Spec, error) { + //nolint:prealloc // do not lint var specs []Spec files, err := filepath.Glob(path) if err != nil { diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index d6703ef2cb0..a0c2ae6e371 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -34,6 +34,12 @@ import ( "github.com/elastic/elastic-agent/pkg/core/server" ) +const ( + darwin = "darwin" + unknown = "Unknown" + running = "Running" +) + var ( // ErrAppNotInstalled is returned when configuration is performed on not installed application. ErrAppNotInstalled = errors.New("application is not installed", errors.TypeApplication) @@ -167,8 +173,8 @@ func (a *Application) Start(ctx context.Context, _ app.Taggable, cfg map[string] // already started if a.srvState != nil { a.setState(state.Starting, "Starting", nil) - a.srvState.SetStatus(proto.StateObserved_STARTING, a.state.Message, a.state.Payload) - a.srvState.UpdateConfig(a.srvState.Config()) + _ = a.srvState.SetStatus(proto.StateObserved_STARTING, a.state.Message, a.state.Payload) + _ = a.srvState.UpdateConfig(a.srvState.Config()) } else { a.setState(state.Starting, "Starting", nil) a.srvState, err = a.srv.Register(a, string(cfgStr)) @@ -293,7 +299,7 @@ func (a *Application) stopAndWatch() { var err error name := a.desc.Spec().ServiceInfo.Name - if runtime.GOOS == "darwin" { + if runtime.GOOS == darwin { name = a.desc.Spec().ServiceInfo.Label } else { // Attempt to stop the service on non-windows platforms @@ -355,9 +361,9 @@ LOOP: var s string switch lastStatus { case service.StatusUnknown: - s = "Unknown" + s = unknown case service.StatusRunning: - s = "Running" + s = running } a.logger.Errorf("%s service failed to stop within %v, last reported service status: %s", name, sw.checkDuration, s) } @@ -420,7 +426,7 @@ func (a *Application) setState(s state.Status, msg string, payload map[string]in } func (a *Application) cleanUp() { - a.monitor.Cleanup(a.desc.Spec(), a.pipelineID) + _ = a.monitor.Cleanup(a.desc.Spec(), a.pipelineID) } func (a *Application) startCredsListener() error { diff --git a/internal/pkg/core/plugin/service/status_watcher_test.go b/internal/pkg/core/plugin/service/status_watcher_test.go index a6c55818006..07c24c73eea 100644 --- a/internal/pkg/core/plugin/service/status_watcher_test.go +++ b/internal/pkg/core/plugin/service/status_watcher_test.go @@ -22,7 +22,7 @@ func TestStatusWatcher(t *testing.T) { defer cn() name := "ElasticEndpoint" - if runtime.GOOS == "darwin" { + if runtime.GOOS == darwin { name = "co.elastic.endpoint" } sw, err := newServiceWatcher(name) @@ -40,19 +40,22 @@ func TestStatusWatcher(t *testing.T) { for r := range sw.status() { if r.Err != nil { + //nolint:forbidigo // ok for interractive test code fmt.Println("watch err:", r.Err) } else { var s string switch r.Status { case service.StatusUnknown: - s = "Unknown" + s = unknown case service.StatusRunning: - s = "Running" + s = running case service.StatusStopped: s = "Stopped" } + //nolint:forbidigo // ok for interractive test code fmt.Println("status:", s) } } + //nolint:forbidigo // ok for interractive test code fmt.Println("watch done") } From 876bd6c105d26e47ea9ff356e6f6a9e742cbdaa0 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Fri, 23 Sep 2022 22:13:46 -0400 Subject: [PATCH 07/13] Improve comment --- internal/pkg/core/plugin/service/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index a0c2ae6e371..4811e3b4138 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -335,7 +335,7 @@ func (a *Application) stopAndWatch() { var lastStatus service.Status LOOP: - // The service watcher stops by closing the status update channel + // The status update channel is closed when the service watcher stops for r := range sw.status() { if r.Err != nil { err = r.Err From 55cbe2ed4fcc293a69fb5d6435db6301ab72b052 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Mon, 26 Sep 2022 09:43:50 -0400 Subject: [PATCH 08/13] Delint --- internal/pkg/agent/operation/monitoring.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/pkg/agent/operation/monitoring.go b/internal/pkg/agent/operation/monitoring.go index ebb0c095ab9..d3f120da677 100644 --- a/internal/pkg/agent/operation/monitoring.go +++ b/internal/pkg/agent/operation/monitoring.go @@ -373,6 +373,7 @@ func (o *Operator) getMonitoringMetricbeatConfig(outputType string, output inter if len(hosts) == 0 { return nil, false } + //nolint:prealloc // false positive var modules []interface{} fixedAgentName := strings.ReplaceAll(agentName, "-", "_") From 6a677f2da88dae40e8164569666321d40c940573 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Wed, 5 Oct 2022 14:43:11 -0400 Subject: [PATCH 09/13] Address code review feedback --- internal/pkg/core/plugin/service/app.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index 4811e3b4138..bf0441901be 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -36,6 +36,7 @@ import ( const ( darwin = "darwin" + windows = "windows" unknown = "Unknown" running = "Running" ) @@ -278,7 +279,7 @@ func (a *Application) Stop() { if err := srvState.Stop(to); err != nil { a.setState( state.Failed, - fmt.Errorf("failed to stop after %s: %w", to, err).Error(), + fmt.Sprintf("failed to stop after %s: %v", to, err), nil) // Start service status watcher if service haven't responded over RPC within the allowed duration. @@ -301,7 +302,9 @@ func (a *Application) stopAndWatch() { name := a.desc.Spec().ServiceInfo.Name if runtime.GOOS == darwin { name = a.desc.Spec().ServiceInfo.Label - } else { + } + + if runtime.GOOS != windows { // Attempt to stop the service on non-windows platforms svc, err := getService(name) if err != nil { From 55eb9f997e23c9c2e99e385392beeb25644dac40 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Thu, 20 Oct 2022 08:29:01 -0400 Subject: [PATCH 10/13] Remove waiting on the service stop since Endpoint should not be stopped --- internal/pkg/agent/program/spec.go | 1 - internal/pkg/agent/program/supported.go | 2 +- internal/pkg/core/plugin/service/app.go | 108 +++--------------------- internal/spec/endpoint.yml | 3 - 4 files changed, 15 insertions(+), 99 deletions(-) diff --git a/internal/pkg/agent/program/spec.go b/internal/pkg/agent/program/spec.go index 9031a5694f1..a77851c28cb 100644 --- a/internal/pkg/agent/program/spec.go +++ b/internal/pkg/agent/program/spec.go @@ -42,7 +42,6 @@ type Spec struct { RestartOnOutputChange bool `yaml:"restart_on_output_change,omitempty"` ExportedMetrics []string `yaml:"exported_metrics,omitempty"` Process *ProcessSettings `yaml:"process,omitempty"` - ServiceInfo *ServiceInfo `yaml:"service_info,omitempty"` } // ProcessSettings process specific settings diff --git a/internal/pkg/agent/program/supported.go b/internal/pkg/agent/program/supported.go index 5ee73b9ae21..5bac02ad8f5 100644 --- a/internal/pkg/agent/program/supported.go +++ b/internal/pkg/agent/program/supported.go @@ -27,7 +27,7 @@ func init() { // internal/spec/metricbeat.yml // internal/spec/osquerybeat.yml // internal/spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("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") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index bf0441901be..259205166ea 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -10,12 +10,10 @@ import ( "io" "net" "reflect" - "runtime" "sync" "time" "github.com/elastic/elastic-agent/internal/pkg/agent/program" - "github.com/kardianos/service" "gopkg.in/yaml.v2" @@ -273,105 +271,27 @@ func (a *Application) Stop() { if srvState == nil { return } - to := a.getStopTimeout() - a.logger.Infof("Stop %v service, with %v timeout", a.desc.Spec().Name, to) - a.appLock.Lock() - if err := srvState.Stop(to); err != nil { - a.setState( - state.Failed, - fmt.Sprintf("failed to stop after %s: %v", to, err), - nil) - - // Start service status watcher if service haven't responded over RPC within the allowed duration. - // This monitors the service status over the platform specific service interfaces - // and sets the state into stopped if the service has stopped or the grace period ended. - a.stopAndWatch() - } else { - a.setState(state.Stopped, "Stopped", nil) - } - a.srvState = nil - - a.cleanUp() - a.stopCredsListener() - a.appLock.Unlock() -} - -func (a *Application) stopAndWatch() { - var err error - - name := a.desc.Spec().ServiceInfo.Name - if runtime.GOOS == darwin { - name = a.desc.Spec().ServiceInfo.Label - } - if runtime.GOOS != windows { - // Attempt to stop the service on non-windows platforms - svc, err := getService(name) - if err != nil { - a.logger.Errorf("failed to get %s service: %v", name, err) - a.setState(state.Stopped, "Stopped", nil) - } + name := a.desc.Spec().Name + to := a.getStopTimeout() - // Attempt to stop the service, log any errors and continue to watch the service status anyways. - // The Endpoint service implements a protection from being stopped on windows - // and this call can result in "Access denied" error at the moment. - err = svc.Stop() - if err != nil { - a.logger.Debugf("failed to stop %s service, err: %v, ", name, err) - } - } + a.logger.Infof("Stop %v service, with %v timeout", name, to) - // Watch the service status, log errors and set the state to stopped in order to allow the agent health to recover. - sw, err := newServiceWatcher(name) - if err != nil { - a.logger.Errorf("failed to create the %s service watcher, setting service status to stopped", name) - a.setState(state.Stopped, "Stopped", nil) - return + // Try to stop the service with 3 minutes (default) timeout + if err := srvState.Stop(to); err != nil { + // Log the error + a.logger.Errorf("Failed to stop %v service after %v timeout", name, to) } - // Run service watcher. - ctx, cn := context.WithCancel(a.bgContext) - defer cn() - go func() { - sw.run(ctx) - }() - - var lastStatus service.Status -LOOP: - // The status update channel is closed when the service watcher stops - for r := range sw.status() { - if r.Err != nil { - err = r.Err - // If service watcher returned the error, log the error and exit the loop - a.logger.Errorf("%s service watcher returned err: %v", name, r.Err) - break LOOP - } else { - lastStatus = r.Status - switch lastStatus { - case service.StatusUnknown: - a.logger.Debugf("%s service watcher status: Unknown", name) - case service.StatusRunning: - a.logger.Debugf("%s service watcher status: Running", name) - case service.StatusStopped: - a.logger.Debugf("%s service watcher status: Stopped", name) - break LOOP - } - } - } + // Cleanup + a.appLock.Lock() + defer a.appLock.Unlock() - // The service watcher exited at this point. Log the error if the status of the service is still not stopped. - if lastStatus != service.StatusStopped && err == nil { - var s string - switch lastStatus { - case service.StatusUnknown: - s = unknown - case service.StatusRunning: - s = running - } - a.logger.Errorf("%s service failed to stop within %v, last reported service status: %s", name, sw.checkDuration, s) - } + a.srvState = nil + a.cleanUp() + a.stopCredsListener() - // Set the service state to "stopped" + // Set the service state to "stopped", otherwise the agent is stuck in the failed stop state until restarted a.logger.Infof("setting %s service status to Stopped", name) a.setState(state.Stopped, "Stopped", nil) } diff --git a/internal/spec/endpoint.yml b/internal/spec/endpoint.yml index 255513509ab..1f54121be4f 100644 --- a/internal/spec/endpoint.yml +++ b/internal/spec/endpoint.yml @@ -4,9 +4,6 @@ artifact: endpoint-dev service: 6788 process: stop_timeout: 180 -service_info: - name: ElasticEndpoint - label: co.elastic.endpoint action_input_types: - endpoint log_paths: From 8cfb474e2c4e2833c81fd2f4bc910e057b494006 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Thu, 20 Oct 2022 22:18:48 -0400 Subject: [PATCH 11/13] Address code review comments --- internal/pkg/agent/program/spec.go | 4 +- internal/pkg/agent/program/spec_test.go | 44 +++++++ internal/pkg/agent/program/supported.go | 2 +- internal/pkg/core/plugin/service/app.go | 19 ++- .../pkg/core/plugin/service/status_watcher.go | 110 ------------------ .../plugin/service/status_watcher_test.go | 61 ---------- internal/spec/endpoint.yml | 5 +- 7 files changed, 64 insertions(+), 181 deletions(-) delete mode 100644 internal/pkg/core/plugin/service/status_watcher.go delete mode 100644 internal/pkg/core/plugin/service/status_watcher_test.go diff --git a/internal/pkg/agent/program/spec.go b/internal/pkg/agent/program/spec.go index a77851c28cb..41cf966aaed 100644 --- a/internal/pkg/agent/program/spec.go +++ b/internal/pkg/agent/program/spec.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "path/filepath" + "time" "gopkg.in/yaml.v2" @@ -47,7 +48,7 @@ type Spec struct { // ProcessSettings process specific settings type ProcessSettings struct { // Allows to override the agent stop timeout settings and specify a different stop timeout for Endpoint service - StopTimeoutSecs int `yaml:"stop_timeout"` + StopTimeout time.Duration `yaml:"stop_timeout"` } // Service info @@ -58,7 +59,6 @@ type ServiceInfo struct { // ReadSpecs reads all the specs that match the provided globbing path. func ReadSpecs(path string) ([]Spec, error) { - //nolint:prealloc // do not lint var specs []Spec files, err := filepath.Glob(path) if err != nil { diff --git a/internal/pkg/agent/program/spec_test.go b/internal/pkg/agent/program/spec_test.go index 110dd92eb36..31985d3d6d7 100644 --- a/internal/pkg/agent/program/spec_test.go +++ b/internal/pkg/agent/program/spec_test.go @@ -5,13 +5,16 @@ package program import ( + "fmt" "io/ioutil" "os" "path/filepath" "regexp" "strings" "testing" + "time" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" @@ -147,3 +150,44 @@ func TestExport(t *testing.T) { require.NoError(t, err) } } + +func TestSerializationProcessSettings(t *testing.T) { + ymlTmpl := `name: "Foobar" +process: + stop_timeout: %v` + + tests := []struct { + name string + tonum int + to time.Duration + }{ + {"zero", 0, 0}, + {"180ns", 180, 0}, + {"180s", 0, 120 * time.Second}, + {"3m", 0, 3 * time.Minute}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var ( + yml string + wantTimeout time.Duration + ) + if tc.to == 0 { + yml = fmt.Sprintf(ymlTmpl, tc.tonum) + wantTimeout = time.Duration(tc.tonum) + } else { + yml = fmt.Sprintf(ymlTmpl, tc.to) + wantTimeout = tc.to + } + var spec Spec + err := yaml.Unmarshal([]byte(yml), &spec) + if err != nil { + t.Fatal(err) + } + diff := cmp.Diff(wantTimeout, spec.Process.StopTimeout) + if diff != "" { + t.Fatal(diff) + } + }) + } +} diff --git a/internal/pkg/agent/program/supported.go b/internal/pkg/agent/program/supported.go index 5bac02ad8f5..0938fbff351 100644 --- a/internal/pkg/agent/program/supported.go +++ b/internal/pkg/agent/program/supported.go @@ -27,7 +27,7 @@ func init() { // internal/spec/metricbeat.yml // internal/spec/osquerybeat.yml // internal/spec/packetbeat.yml - unpacked := packer.MustUnpack("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") + unpacked := packer.MustUnpack("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") SupportedMap = make(map[string]Spec) for f, v := range unpacked { diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index 259205166ea..79c9f618350 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -255,9 +255,8 @@ func (a *Application) Configure(ctx context.Context, config map[string]interface } func (a *Application) getStopTimeout() time.Duration { - if a.desc.Spec().Process != nil && a.desc.Spec().Process.StopTimeoutSecs > 0 { - to := time.Duration(a.desc.Spec().Process.StopTimeoutSecs) * time.Second - return to + if a.desc.Spec().Process != nil && a.desc.Spec().Process.StopTimeout > 0 { + return a.desc.Spec().Process.StopTimeout } return a.processConfig.StopTimeout } @@ -276,8 +275,16 @@ func (a *Application) Stop() { to := a.getStopTimeout() a.logger.Infof("Stop %v service, with %v timeout", name, to) - - // Try to stop the service with 3 minutes (default) timeout + start := time.Now() + + // Try to stop the service with timeout + // If timed out and the service is still not stopped the runtime is set to STOPPED state anyways. + // This avoids leaving the runtime indefinitely in the failed state. + // + // The Agent is not managing the Endpoint service state by design. + // The service runtime should send STOPPING state to the Endpoint service only before the Endpoint is expected to be uninstalled. + // So if the Agent never receives the STOPPING check-in from the Endpoint after this, it's ok to set the state + // to STOPPED following with the Endpoint service uninstall. if err := srvState.Stop(to); err != nil { // Log the error a.logger.Errorf("Failed to stop %v service after %v timeout", name, to) @@ -292,7 +299,7 @@ func (a *Application) Stop() { a.stopCredsListener() // Set the service state to "stopped", otherwise the agent is stuck in the failed stop state until restarted - a.logger.Infof("setting %s service status to Stopped", name) + a.logger.Infof("setting %s service status to Stopped, took: %v", name, time.Since(start)) a.setState(state.Stopped, "Stopped", nil) } diff --git a/internal/pkg/core/plugin/service/status_watcher.go b/internal/pkg/core/plugin/service/status_watcher.go deleted file mode 100644 index f3762e24b27..00000000000 --- a/internal/pkg/core/plugin/service/status_watcher.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package service - -import ( - "context" - "errors" - "time" - - "github.com/kardianos/service" -) - -const ( - defaultCheckInterval = 10 * time.Second - defaultCheckDuration = 3 * time.Minute -) - -type statusCheckResult struct { - Status service.Status - Err error -} - -type serviceWatcher struct { - svc service.Service - statusCh chan statusCheckResult - checkInterval time.Duration - checkDuration time.Duration - stopOnError bool - - lastStatusCheckResult statusCheckResult - - // The github.com/kardianos/service library sometimes returns service.ErrNotInstalled error - // while the service transitioning from running to stopped, found during testing on linux - // Capture the last error separately in order to perform another watch loop pass if this happens - lastStatusCheckError error -} - -func getService(name string) (service.Service, error) { - svcConfig := &service.Config{ - Name: name, - } - - return service.New(nil, svcConfig) -} - -func newServiceWatcher(name string) (*serviceWatcher, error) { - svc, err := getService(name) - if err != nil { - return nil, err - } - - return &serviceWatcher{ - svc: svc, - statusCh: make(chan statusCheckResult), - checkInterval: defaultCheckInterval, - checkDuration: defaultCheckDuration, - stopOnError: true, - }, nil -} - -func (s *serviceWatcher) run(ctx context.Context) { - start := time.Now() - t := time.NewTicker(s.checkInterval) - defer t.Stop() - defer close(s.statusCh) - - for { - select { - case <-ctx.Done(): - return - case <-t.C: - if time.Since(start) > s.checkDuration { - return - } - - status, err := s.svc.Status() - - if err != nil { - if s.lastStatusCheckError == nil && errors.Is(err, service.ErrNotInstalled) { - s.lastStatusCheckError = err - break - } - } - s.lastStatusCheckError = err - - // Send status check result if it changed - if s.lastStatusCheckResult.Status != status || !errors.Is(err, s.lastStatusCheckResult.Err) { - res := statusCheckResult{ - Status: status, - Err: err, - } - select { - case s.statusCh <- res: - case <-ctx.Done(): - return - } - s.lastStatusCheckResult = res - } - if err != nil && s.stopOnError { - return - } - } - } -} - -func (s *serviceWatcher) status() <-chan statusCheckResult { - return s.statusCh -} diff --git a/internal/pkg/core/plugin/service/status_watcher_test.go b/internal/pkg/core/plugin/service/status_watcher_test.go deleted file mode 100644 index 07c24c73eea..00000000000 --- a/internal/pkg/core/plugin/service/status_watcher_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package service - -import ( - "context" - "fmt" - "runtime" - "testing" - "time" - - "github.com/kardianos/service" -) - -// Useful test to keep the code around. -// Marked as skipped, because can't really use as unit test with CI since it relies on actual endpoint service to be present -func TestStatusWatcher(t *testing.T) { - t.Skip() - ctx, cn := context.WithCancel(context.Background()) - defer cn() - - name := "ElasticEndpoint" - if runtime.GOOS == darwin { - name = "co.elastic.endpoint" - } - sw, err := newServiceWatcher(name) - if err != nil { - t.Fatal(err) - } - - sw.checkDuration = 2 * time.Minute - sw.checkInterval = 2 * time.Second - sw.stopOnError = false - - go func() { - sw.run(ctx) - }() - - for r := range sw.status() { - if r.Err != nil { - //nolint:forbidigo // ok for interractive test code - fmt.Println("watch err:", r.Err) - } else { - var s string - switch r.Status { - case service.StatusUnknown: - s = unknown - case service.StatusRunning: - s = running - case service.StatusStopped: - s = "Stopped" - } - //nolint:forbidigo // ok for interractive test code - fmt.Println("status:", s) - } - } - //nolint:forbidigo // ok for interractive test code - fmt.Println("watch done") -} diff --git a/internal/spec/endpoint.yml b/internal/spec/endpoint.yml index 1f54121be4f..e3e8c4fbe3e 100644 --- a/internal/spec/endpoint.yml +++ b/internal/spec/endpoint.yml @@ -3,7 +3,10 @@ cmd: endpoint-security artifact: endpoint-dev service: 6788 process: - stop_timeout: 180 + # After discussion with Endpoint team the stop timeout is set to 3m, + # in order to give enough time for the Endpoint to stop gracefully. + # https://github.com/elastic/elastic-agent/issues/1262 + stop_timeout: 3m action_input_types: - endpoint log_paths: From 80d5cd63d1fcb5fbc768123afdae80526938e932 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Mon, 24 Oct 2022 07:39:10 -0400 Subject: [PATCH 12/13] Fix linter --- internal/pkg/core/plugin/service/app.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/internal/pkg/core/plugin/service/app.go b/internal/pkg/core/plugin/service/app.go index 79c9f618350..af553ac5ac8 100644 --- a/internal/pkg/core/plugin/service/app.go +++ b/internal/pkg/core/plugin/service/app.go @@ -32,13 +32,6 @@ import ( "github.com/elastic/elastic-agent/pkg/core/server" ) -const ( - darwin = "darwin" - windows = "windows" - unknown = "Unknown" - running = "Running" -) - var ( // ErrAppNotInstalled is returned when configuration is performed on not installed application. ErrAppNotInstalled = errors.New("application is not installed", errors.TypeApplication) From 198f2e66924bf192b026e9c1ec7ae7c40bb27a67 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Mon, 24 Oct 2022 07:44:14 -0400 Subject: [PATCH 13/13] Add changelog --- changelog/fragments/1666611696-fix_service_stop_timeout.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog/fragments/1666611696-fix_service_stop_timeout.yaml diff --git a/changelog/fragments/1666611696-fix_service_stop_timeout.yaml b/changelog/fragments/1666611696-fix_service_stop_timeout.yaml new file mode 100644 index 00000000000..5125282618f --- /dev/null +++ b/changelog/fragments/1666611696-fix_service_stop_timeout.yaml @@ -0,0 +1,4 @@ +kind: bug-fix +summary: "Fix: Windows Agent Left Unhealthy After Removing Endpoint Integration" +pr: 1286 +issue: 1262