From 5c44db38496fa6e1f8eeb7fec824e7ce9f182b83 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Mon, 2 Oct 2023 17:55:11 -0700 Subject: [PATCH 01/21] Adding FSM for upgrades --- go.mod | 1 + go.sum | 2 + internal/pkg/agent/application/upgrade/fsm.go | 108 ++++++++++++++++++ .../pkg/agent/application/upgrade/fsm_test.go | 42 +++++++ 4 files changed, 153 insertions(+) create mode 100644 internal/pkg/agent/application/upgrade/fsm.go create mode 100644 internal/pkg/agent/application/upgrade/fsm_test.go diff --git a/go.mod b/go.mod index 2016effc622..84c9aac7e9f 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7 + github.com/looplab/fsm v1.0.1 github.com/magefile/mage v1.15.0 github.com/mitchellh/gox v1.0.1 github.com/mitchellh/hashstructure v1.1.0 diff --git a/go.sum b/go.sum index 54eca1468e7..467728dbe0c 100644 --- a/go.sum +++ b/go.sum @@ -1269,6 +1269,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9 github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= +github.com/looplab/fsm v1.0.1 h1:OEW0ORrIx095N/6lgoGkFkotqH6s7vaFPsgjLAaF5QU= +github.com/looplab/fsm v1.0.1/go.mod h1:PmD3fFvQEIsjMEfvZdrCDZ6y8VwKTwWNjlpEr6IKPO4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= diff --git a/internal/pkg/agent/application/upgrade/fsm.go b/internal/pkg/agent/application/upgrade/fsm.go new file mode 100644 index 00000000000..4d8289baa70 --- /dev/null +++ b/internal/pkg/agent/application/upgrade/fsm.go @@ -0,0 +1,108 @@ +package upgrade + +import ( + "context" + "fmt" + + "github.com/elastic/elastic-agent/pkg/core/logger" + "github.com/looplab/fsm" +) + +const ( + StateRequested = "UPG_REQUESTED" + StateScheduled = "UPG_SCHEDULED" + StateDownloading = "UPG_DOWNLOADING" + StateExtracting = "UPG_EXTRACTING" + StateReplacing = "UPG_REPLACING" + StateRestarting = "UPG_RESTARTING" + StateWatching = "UPG_WATCHING" + StateRollback = "UPG_ROLLBACK" + StateCompleted = "UPG_COMPLETED" + StateFailed = "UPG_FAILED" + + ActionSucceeded = "succeeded" + ActionFailed = "failed" + ActionScheduling = "scheduling" + ActionRollingBack = "rolling_back" +) + +type FSM struct { + m *fsm.FSM +} + +type StateTransitionCallback func(oldState, newState, action string) + +// NewFSM models the following finite state machine for Elastic Agent upgrades: +// +// UPG_REQUESTED +// ├─ scheduling ─> UPG_SCHEDULED +// └─ succeeded ─> UPG_DOWNLOADING +// UPG_SCHEDULED +// ├─ succeeded ─> UPG_DOWNLOADING +// └─ failed ─> UPG_FAILED +// UPG_DOWNLOADING +// ├─ succeeded ─> UPG_EXTRACTING +// └─ failed ─> UPG_FAILED +// UPG_EXTRACTING +// ├─ succeeded ─> UPG_REPLACING +// └─ failed ─> UPG_FAILED +// UPG_REPLACING +// ├─ succeeded ─> UPG_RESTARTING +// └─ failed ─> UPG_FAILED +// UPG_RESTARTING +// ├─ succeeded ─> UPG_WATCHING +// └─ failed ─> UPG_FAILED +// UPG_WATCHING +// ├─ succeeded ─> UPG_COMPLETED +// ├─ rolling_back ─> UPG_ROLLBACK +// └─ failed ─> UPG_FAILED +// UPG_ROLLBACK +// ├─ succeeded ─> UPG_COMPLETED +// └─ failed ─> UPG_FAILED +// +// It accepts an onAction callback that will be called any time a transition from one +// state to the next is performed. +func NewFSM(log *logger.Logger, onTransition StateTransitionCallback) *FSM { + return &FSM{ + m: fsm.NewFSM( + StateRequested, + fsm.Events{ + {Name: ActionScheduling, Src: []string{StateRequested}, Dst: StateScheduled}, + {Name: ActionSucceeded, Src: []string{StateRequested, StateScheduled}, Dst: StateDownloading}, + {Name: ActionSucceeded, Src: []string{StateDownloading}, Dst: StateExtracting}, + {Name: ActionSucceeded, Src: []string{StateExtracting}, Dst: StateReplacing}, + {Name: ActionSucceeded, Src: []string{StateReplacing}, Dst: StateRestarting}, + {Name: ActionSucceeded, Src: []string{StateRestarting}, Dst: StateWatching}, + {Name: ActionSucceeded, Src: []string{StateWatching}, Dst: StateCompleted}, + {Name: ActionRollingBack, Src: []string{StateWatching}, Dst: StateRollback}, + {Name: ActionSucceeded, Src: []string{StateRollback}, Dst: StateCompleted}, + {Name: ActionFailed, Src: []string{StateScheduled, StateDownloading, StateExtracting, StateReplacing, StateRestarting, StateWatching, StateRollback}, Dst: StateFailed}, + }, + fsm.Callbacks{ + "enter_state": func(_ context.Context, e *fsm.Event) { + // Log state entry + log.Infow( + "transitioning upgrade state machine", + "from", e.Src, "to", e.Dst, "action", e.Event, + ) + + // Call onTransition + onTransition(e.Src, e.Dst, e.Event) + }, + }, + ), + } +} + +func (f *FSM) Transition(ctx context.Context, action string, args ...interface{}) error { + current := f.Current() + if err := f.m.Event(ctx, action, args...); err != nil { + return fmt.Errorf("unable to transition from [%s] with action [%s]: %w", current, action, err) + } + + return nil +} + +func (f *FSM) Current() string { + return f.m.Current() +} diff --git a/internal/pkg/agent/application/upgrade/fsm_test.go b/internal/pkg/agent/application/upgrade/fsm_test.go new file mode 100644 index 00000000000..08860faa502 --- /dev/null +++ b/internal/pkg/agent/application/upgrade/fsm_test.go @@ -0,0 +1,42 @@ +package upgrade + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/elastic/elastic-agent/pkg/core/logger" +) + +func TestFSM(t *testing.T) { + l, obs := logger.NewTesting("upgrade_fsm") + cb := func(oldState, newState, action string) { + // TODO + } + + fsm := NewFSM(l, cb) + + // Test that valid transition succeeds + err := fsm.Transition(context.Background(), ActionSucceeded) + require.NoError(t, err) + require.Equal(t, StateDownloading, fsm.Current()) + require.Equal(t, 1, obs.Len()) + + log := obs.TakeAll()[0] + require.Equal(t, "transitioning upgrade state machine", log.Message) + require.Equal(t, "from", log.Context[0].Key) + require.Equal(t, StateRequested, log.Context[0].String) + require.Equal(t, "to", log.Context[1].Key) + require.Equal(t, StateDownloading, log.Context[1].String) + + // Test that invalid transition returns error + err = fsm.Transition(context.Background(), ActionRollingBack) + require.Error(t, err) + require.EqualError(t, err, fmt.Sprintf( + "unable to transition from [%[1]s] with action [%[2]s]: event %[2]s inappropriate in current state %[1]s", + StateDownloading, ActionRollingBack, + )) + require.Equal(t, 0, obs.Len()) +} From ae6955d54639a4874aad984c27ce4efff0bcaef3 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Mon, 2 Oct 2023 18:49:34 -0700 Subject: [PATCH 02/21] Implementing TODO --- internal/pkg/agent/application/upgrade/fsm.go | 7 +- .../pkg/agent/application/upgrade/fsm_test.go | 69 ++++++++++++++----- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/internal/pkg/agent/application/upgrade/fsm.go b/internal/pkg/agent/application/upgrade/fsm.go index 4d8289baa70..a5469cc893d 100644 --- a/internal/pkg/agent/application/upgrade/fsm.go +++ b/internal/pkg/agent/application/upgrade/fsm.go @@ -1,11 +1,16 @@ +// 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 upgrade import ( "context" "fmt" - "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/looplab/fsm" + + "github.com/elastic/elastic-agent/pkg/core/logger" ) const ( diff --git a/internal/pkg/agent/application/upgrade/fsm_test.go b/internal/pkg/agent/application/upgrade/fsm_test.go index 08860faa502..b116b022fb6 100644 --- a/internal/pkg/agent/application/upgrade/fsm_test.go +++ b/internal/pkg/agent/application/upgrade/fsm_test.go @@ -1,42 +1,79 @@ +// 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 upgrade import ( "context" "fmt" + "sync/atomic" "testing" "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest/observer" "github.com/elastic/elastic-agent/pkg/core/logger" ) func TestFSM(t *testing.T) { l, obs := logger.NewTesting("upgrade_fsm") + + var cbCallCounter atomic.Int64 cb := func(oldState, newState, action string) { - // TODO + cbCallCounter.Add(1) } fsm := NewFSM(l, cb) + require.Equal(t, int64(0), cbCallCounter.Load()) + + // Test that valid transitions succeed + t.Run("valid_transition", func(t *testing.T) { + // UPG_REQUESTED ─── scheduling ───> UPG_SCHEDULED + err := fsm.Transition(context.Background(), ActionScheduling) + verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateRequested, StateScheduled, 1) + + // UPG_SCHEDULED ─── succeeded ───> UPG_DOWNLOADING + err = fsm.Transition(context.Background(), ActionSucceeded) + verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateScheduled, StateDownloading, 2) + + // UPG_DOWNLOADING ─── failed ───> UPG_FAILED + err = fsm.Transition(context.Background(), ActionFailed) + verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateDownloading, StateFailed, 3) + }) + + // Test that an invalid transition returns error + t.Run("invalid_transition", func(t *testing.T) { + // UPG_FAILED ─── rolling_back ───> error + err := fsm.Transition(context.Background(), ActionRollingBack) + require.Error(t, err) + require.EqualError(t, err, fmt.Sprintf( + "unable to transition from [%[1]s] with action [%[2]s]: event %[2]s inappropriate in current state %[1]s", + StateFailed, ActionRollingBack, + )) + require.Equal(t, int64(3), cbCallCounter.Load()) + require.Equal(t, 0, obs.Len()) + }) +} + +func verifyValidTransition( + t *testing.T, + upgradeFSM *FSM, obs *observer.ObservedLogs, + actualErr error, actualCBCallCounter int64, + expectedStartState, expectedEndState string, + expectedCBCallCounter int64, +) { + t.Helper() - // Test that valid transition succeeds - err := fsm.Transition(context.Background(), ActionSucceeded) - require.NoError(t, err) - require.Equal(t, StateDownloading, fsm.Current()) + require.NoError(t, actualErr) + require.Equal(t, expectedEndState, upgradeFSM.Current()) require.Equal(t, 1, obs.Len()) + require.Equal(t, expectedCBCallCounter, actualCBCallCounter) log := obs.TakeAll()[0] require.Equal(t, "transitioning upgrade state machine", log.Message) require.Equal(t, "from", log.Context[0].Key) - require.Equal(t, StateRequested, log.Context[0].String) + require.Equal(t, expectedStartState, log.Context[0].String) require.Equal(t, "to", log.Context[1].Key) - require.Equal(t, StateDownloading, log.Context[1].String) - - // Test that invalid transition returns error - err = fsm.Transition(context.Background(), ActionRollingBack) - require.Error(t, err) - require.EqualError(t, err, fmt.Sprintf( - "unable to transition from [%[1]s] with action [%[2]s]: event %[2]s inappropriate in current state %[1]s", - StateDownloading, ActionRollingBack, - )) - require.Equal(t, 0, obs.Len()) + require.Equal(t, expectedEndState, log.Context[1].String) } From 90919062d8a6808b4e250c06cbe647008f3b8d89 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 05:41:18 -0700 Subject: [PATCH 03/21] WIP --- .../gateway/fleet/fleet_gateway.go | 11 +- internal/pkg/agent/application/upgrade/fsm.go | 113 ------------------ .../pkg/agent/application/upgrade/fsm_test.go | 79 ------------ .../pkg/agent/application/upgrade/state.go | 24 ++++ .../pkg/agent/application/upgrade/upgrade.go | 6 + internal/pkg/fleetapi/checkin_cmd.go | 18 ++- 6 files changed, 49 insertions(+), 202 deletions(-) delete mode 100644 internal/pkg/agent/application/upgrade/fsm.go delete mode 100644 internal/pkg/agent/application/upgrade/fsm_test.go create mode 100644 internal/pkg/agent/application/upgrade/state.go diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go index 000ec534bf2..109ece58be9 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go @@ -332,11 +332,12 @@ func (f *FleetGateway) execute(ctx context.Context) (*fleetapi.CheckinResponse, // checkin cmd := fleetapi.NewCheckinCmd(f.agentInfo, f.client) req := &fleetapi.CheckinRequest{ - AckToken: ackToken, - Metadata: ecsMeta, - Status: agentStateToString(state.State), - Message: state.Message, - Components: components, + AckToken: ackToken, + Metadata: ecsMeta, + Status: agentStateToString(state.State), + Message: state.Message, + Components: components, + UpgradeDetails: state.UpgradeDetails, } resp, took, err := cmd.Execute(ctx, req) diff --git a/internal/pkg/agent/application/upgrade/fsm.go b/internal/pkg/agent/application/upgrade/fsm.go deleted file mode 100644 index a5469cc893d..00000000000 --- a/internal/pkg/agent/application/upgrade/fsm.go +++ /dev/null @@ -1,113 +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 upgrade - -import ( - "context" - "fmt" - - "github.com/looplab/fsm" - - "github.com/elastic/elastic-agent/pkg/core/logger" -) - -const ( - StateRequested = "UPG_REQUESTED" - StateScheduled = "UPG_SCHEDULED" - StateDownloading = "UPG_DOWNLOADING" - StateExtracting = "UPG_EXTRACTING" - StateReplacing = "UPG_REPLACING" - StateRestarting = "UPG_RESTARTING" - StateWatching = "UPG_WATCHING" - StateRollback = "UPG_ROLLBACK" - StateCompleted = "UPG_COMPLETED" - StateFailed = "UPG_FAILED" - - ActionSucceeded = "succeeded" - ActionFailed = "failed" - ActionScheduling = "scheduling" - ActionRollingBack = "rolling_back" -) - -type FSM struct { - m *fsm.FSM -} - -type StateTransitionCallback func(oldState, newState, action string) - -// NewFSM models the following finite state machine for Elastic Agent upgrades: -// -// UPG_REQUESTED -// ├─ scheduling ─> UPG_SCHEDULED -// └─ succeeded ─> UPG_DOWNLOADING -// UPG_SCHEDULED -// ├─ succeeded ─> UPG_DOWNLOADING -// └─ failed ─> UPG_FAILED -// UPG_DOWNLOADING -// ├─ succeeded ─> UPG_EXTRACTING -// └─ failed ─> UPG_FAILED -// UPG_EXTRACTING -// ├─ succeeded ─> UPG_REPLACING -// └─ failed ─> UPG_FAILED -// UPG_REPLACING -// ├─ succeeded ─> UPG_RESTARTING -// └─ failed ─> UPG_FAILED -// UPG_RESTARTING -// ├─ succeeded ─> UPG_WATCHING -// └─ failed ─> UPG_FAILED -// UPG_WATCHING -// ├─ succeeded ─> UPG_COMPLETED -// ├─ rolling_back ─> UPG_ROLLBACK -// └─ failed ─> UPG_FAILED -// UPG_ROLLBACK -// ├─ succeeded ─> UPG_COMPLETED -// └─ failed ─> UPG_FAILED -// -// It accepts an onAction callback that will be called any time a transition from one -// state to the next is performed. -func NewFSM(log *logger.Logger, onTransition StateTransitionCallback) *FSM { - return &FSM{ - m: fsm.NewFSM( - StateRequested, - fsm.Events{ - {Name: ActionScheduling, Src: []string{StateRequested}, Dst: StateScheduled}, - {Name: ActionSucceeded, Src: []string{StateRequested, StateScheduled}, Dst: StateDownloading}, - {Name: ActionSucceeded, Src: []string{StateDownloading}, Dst: StateExtracting}, - {Name: ActionSucceeded, Src: []string{StateExtracting}, Dst: StateReplacing}, - {Name: ActionSucceeded, Src: []string{StateReplacing}, Dst: StateRestarting}, - {Name: ActionSucceeded, Src: []string{StateRestarting}, Dst: StateWatching}, - {Name: ActionSucceeded, Src: []string{StateWatching}, Dst: StateCompleted}, - {Name: ActionRollingBack, Src: []string{StateWatching}, Dst: StateRollback}, - {Name: ActionSucceeded, Src: []string{StateRollback}, Dst: StateCompleted}, - {Name: ActionFailed, Src: []string{StateScheduled, StateDownloading, StateExtracting, StateReplacing, StateRestarting, StateWatching, StateRollback}, Dst: StateFailed}, - }, - fsm.Callbacks{ - "enter_state": func(_ context.Context, e *fsm.Event) { - // Log state entry - log.Infow( - "transitioning upgrade state machine", - "from", e.Src, "to", e.Dst, "action", e.Event, - ) - - // Call onTransition - onTransition(e.Src, e.Dst, e.Event) - }, - }, - ), - } -} - -func (f *FSM) Transition(ctx context.Context, action string, args ...interface{}) error { - current := f.Current() - if err := f.m.Event(ctx, action, args...); err != nil { - return fmt.Errorf("unable to transition from [%s] with action [%s]: %w", current, action, err) - } - - return nil -} - -func (f *FSM) Current() string { - return f.m.Current() -} diff --git a/internal/pkg/agent/application/upgrade/fsm_test.go b/internal/pkg/agent/application/upgrade/fsm_test.go deleted file mode 100644 index b116b022fb6..00000000000 --- a/internal/pkg/agent/application/upgrade/fsm_test.go +++ /dev/null @@ -1,79 +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 upgrade - -import ( - "context" - "fmt" - "sync/atomic" - "testing" - - "github.com/stretchr/testify/require" - "go.uber.org/zap/zaptest/observer" - - "github.com/elastic/elastic-agent/pkg/core/logger" -) - -func TestFSM(t *testing.T) { - l, obs := logger.NewTesting("upgrade_fsm") - - var cbCallCounter atomic.Int64 - cb := func(oldState, newState, action string) { - cbCallCounter.Add(1) - } - - fsm := NewFSM(l, cb) - require.Equal(t, int64(0), cbCallCounter.Load()) - - // Test that valid transitions succeed - t.Run("valid_transition", func(t *testing.T) { - // UPG_REQUESTED ─── scheduling ───> UPG_SCHEDULED - err := fsm.Transition(context.Background(), ActionScheduling) - verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateRequested, StateScheduled, 1) - - // UPG_SCHEDULED ─── succeeded ───> UPG_DOWNLOADING - err = fsm.Transition(context.Background(), ActionSucceeded) - verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateScheduled, StateDownloading, 2) - - // UPG_DOWNLOADING ─── failed ───> UPG_FAILED - err = fsm.Transition(context.Background(), ActionFailed) - verifyValidTransition(t, fsm, obs, err, cbCallCounter.Load(), StateDownloading, StateFailed, 3) - }) - - // Test that an invalid transition returns error - t.Run("invalid_transition", func(t *testing.T) { - // UPG_FAILED ─── rolling_back ───> error - err := fsm.Transition(context.Background(), ActionRollingBack) - require.Error(t, err) - require.EqualError(t, err, fmt.Sprintf( - "unable to transition from [%[1]s] with action [%[2]s]: event %[2]s inappropriate in current state %[1]s", - StateFailed, ActionRollingBack, - )) - require.Equal(t, int64(3), cbCallCounter.Load()) - require.Equal(t, 0, obs.Len()) - }) -} - -func verifyValidTransition( - t *testing.T, - upgradeFSM *FSM, obs *observer.ObservedLogs, - actualErr error, actualCBCallCounter int64, - expectedStartState, expectedEndState string, - expectedCBCallCounter int64, -) { - t.Helper() - - require.NoError(t, actualErr) - require.Equal(t, expectedEndState, upgradeFSM.Current()) - require.Equal(t, 1, obs.Len()) - require.Equal(t, expectedCBCallCounter, actualCBCallCounter) - - log := obs.TakeAll()[0] - require.Equal(t, "transitioning upgrade state machine", log.Message) - require.Equal(t, "from", log.Context[0].Key) - require.Equal(t, expectedStartState, log.Context[0].String) - require.Equal(t, "to", log.Context[1].Key) - require.Equal(t, expectedEndState, log.Context[1].String) -} diff --git a/internal/pkg/agent/application/upgrade/state.go b/internal/pkg/agent/application/upgrade/state.go new file mode 100644 index 00000000000..f21c4f799da --- /dev/null +++ b/internal/pkg/agent/application/upgrade/state.go @@ -0,0 +1,24 @@ +// 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 upgrade + +type State string + +const ( + StateRequested State = "UPG_REQUESTED" + StateScheduled State = "UPG_SCHEDULED" + StateDownloading State = "UPG_DOWNLOADING" + StateExtracting State = "UPG_EXTRACTING" + StateReplacing State = "UPG_REPLACING" + StateRestarting State = "UPG_RESTARTING" + StateWatching State = "UPG_WATCHING" + StateRollback State = "UPG_ROLLBACK" + StateCompleted State = "UPG_COMPLETED" + StateFailed State = "UPG_FAILED" +) + +func (s State) String() string { + return string(s) +} diff --git a/internal/pkg/agent/application/upgrade/upgrade.go b/internal/pkg/agent/application/upgrade/upgrade.go index da0ea3df6be..a79fa744417 100644 --- a/internal/pkg/agent/application/upgrade/upgrade.go +++ b/internal/pkg/agent/application/upgrade/upgrade.go @@ -153,6 +153,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string newHash, err := u.unpack(version, archivePath) if err != nil { + details.Fail(err) return nil, err } @@ -166,22 +167,26 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string } if err := copyActionStore(u.log, newHash); err != nil { + details.Fail(err) return nil, errors.New(err, "failed to copy action store") } if err := copyRunDirectory(u.log, newHash); err != nil { + details.Fail(err) return nil, errors.New(err, "failed to copy run directory") } det.SetState(details.StateReplacing) if err := ChangeSymlink(ctx, u.log, newHash); err != nil { + details.Fail(err) u.log.Errorw("Rolling back: changing symlink failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err } if err := u.markUpgrade(ctx, u.log, newHash, action); err != nil { + details.Fail(err) u.log.Errorw("Rolling back: marking upgrade failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err @@ -190,6 +195,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string det.SetState(details.StateWatching) if err := InvokeWatcher(u.log); err != nil { + details.Fail(err) u.log.Errorw("Rolling back: starting watcher failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err diff --git a/internal/pkg/fleetapi/checkin_cmd.go b/internal/pkg/fleetapi/checkin_cmd.go index b52eeb3903f..a5d7e0942e5 100644 --- a/internal/pkg/fleetapi/checkin_cmd.go +++ b/internal/pkg/fleetapi/checkin_cmd.go @@ -13,6 +13,8 @@ import ( "net/http" "time" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" "github.com/elastic/elastic-agent/internal/pkg/fleetapi/client" @@ -47,11 +49,17 @@ type CheckinComponent struct { // CheckinRequest consists of multiple events reported to fleet ui. type CheckinRequest struct { - Status string `json:"status"` - AckToken string `json:"ack_token,omitempty"` - Metadata *info.ECSMeta `json:"local_metadata,omitempty"` - Message string `json:"message"` // V2 Agent message - Components []CheckinComponent `json:"components"` // V2 Agent components + Status string `json:"status"` + AckToken string `json:"ack_token,omitempty"` + Metadata *info.ECSMeta `json:"local_metadata,omitempty"` + Message string `json:"message"` // V2 Agent message + Components []CheckinComponent `json:"components"` // V2 Agent components + UpgradeDetails *coordinator.UpgradeDetails `json:"upgrade_details,omitempty"` +} + +// UpgradeDetails consists of details regarding an ongoing upgrade. +type UpgradeDetails struct { + // TODO } // SerializableEvent is a representation of the event to be send to the Fleet Server API via the checkin From 0430e9af9b7480006419d2bf528bfc81d0b3f146 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 15:54:52 -0700 Subject: [PATCH 04/21] WIP --- .../handlers/handler_action_upgrade_test.go | 2 ++ .../application/coordinator/coordinator.go | 3 ++- .../pkg/agent/application/upgrade/state.go | 24 ------------------- .../pkg/agent/application/upgrade/upgrade.go | 12 +++++----- 4 files changed, 10 insertions(+), 31 deletions(-) delete mode 100644 internal/pkg/agent/application/upgrade/state.go diff --git a/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go b/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go index b917b00b900..2dfc74519a0 100644 --- a/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go +++ b/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go @@ -9,6 +9,8 @@ import ( "testing" "time" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" + "github.com/stretchr/testify/require" "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" diff --git a/internal/pkg/agent/application/coordinator/coordinator.go b/internal/pkg/agent/application/coordinator/coordinator.go index bce2188c0e7..734233c4a69 100644 --- a/internal/pkg/agent/application/coordinator/coordinator.go +++ b/internal/pkg/agent/application/coordinator/coordinator.go @@ -11,6 +11,8 @@ import ( "strings" "time" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" + "github.com/hashicorp/go-multierror" "go.elastic.co/apm" @@ -21,7 +23,6 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" "github.com/elastic/elastic-agent/internal/pkg/agent/configuration" "github.com/elastic/elastic-agent/internal/pkg/agent/transpiler" "github.com/elastic/elastic-agent/internal/pkg/capabilities" diff --git a/internal/pkg/agent/application/upgrade/state.go b/internal/pkg/agent/application/upgrade/state.go deleted file mode 100644 index f21c4f799da..00000000000 --- a/internal/pkg/agent/application/upgrade/state.go +++ /dev/null @@ -1,24 +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 upgrade - -type State string - -const ( - StateRequested State = "UPG_REQUESTED" - StateScheduled State = "UPG_SCHEDULED" - StateDownloading State = "UPG_DOWNLOADING" - StateExtracting State = "UPG_EXTRACTING" - StateReplacing State = "UPG_REPLACING" - StateRestarting State = "UPG_RESTARTING" - StateWatching State = "UPG_WATCHING" - StateRollback State = "UPG_ROLLBACK" - StateCompleted State = "UPG_COMPLETED" - StateFailed State = "UPG_FAILED" -) - -func (s State) String() string { - return string(s) -} diff --git a/internal/pkg/agent/application/upgrade/upgrade.go b/internal/pkg/agent/application/upgrade/upgrade.go index a79fa744417..281f6f3b336 100644 --- a/internal/pkg/agent/application/upgrade/upgrade.go +++ b/internal/pkg/agent/application/upgrade/upgrade.go @@ -153,7 +153,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string newHash, err := u.unpack(version, archivePath) if err != nil { - details.Fail(err) + det.Fail(err) return nil, err } @@ -167,26 +167,26 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string } if err := copyActionStore(u.log, newHash); err != nil { - details.Fail(err) + det.Fail(err) return nil, errors.New(err, "failed to copy action store") } if err := copyRunDirectory(u.log, newHash); err != nil { - details.Fail(err) + det.Fail(err) return nil, errors.New(err, "failed to copy run directory") } det.SetState(details.StateReplacing) if err := ChangeSymlink(ctx, u.log, newHash); err != nil { - details.Fail(err) + det.Fail(err) u.log.Errorw("Rolling back: changing symlink failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err } if err := u.markUpgrade(ctx, u.log, newHash, action); err != nil { - details.Fail(err) + det.Fail(err) u.log.Errorw("Rolling back: marking upgrade failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err @@ -195,7 +195,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string det.SetState(details.StateWatching) if err := InvokeWatcher(u.log); err != nil { - details.Fail(err) + det.Fail(err) u.log.Errorw("Rolling back: starting watcher failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err From f9b6594da7fab3924058a89a6ad79ebd4c7df45f Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 15:56:53 -0700 Subject: [PATCH 05/21] Reorganizing imports --- .../actions/handlers/handler_action_upgrade_test.go | 2 -- internal/pkg/agent/application/coordinator/coordinator.go | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go b/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go index 2dfc74519a0..b917b00b900 100644 --- a/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go +++ b/internal/pkg/agent/application/actions/handlers/handler_action_upgrade_test.go @@ -9,8 +9,6 @@ import ( "testing" "time" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" - "github.com/stretchr/testify/require" "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" diff --git a/internal/pkg/agent/application/coordinator/coordinator.go b/internal/pkg/agent/application/coordinator/coordinator.go index 734233c4a69..bce2188c0e7 100644 --- a/internal/pkg/agent/application/coordinator/coordinator.go +++ b/internal/pkg/agent/application/coordinator/coordinator.go @@ -11,8 +11,6 @@ import ( "strings" "time" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" - "github.com/hashicorp/go-multierror" "go.elastic.co/apm" @@ -23,6 +21,7 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" "github.com/elastic/elastic-agent/internal/pkg/agent/configuration" "github.com/elastic/elastic-agent/internal/pkg/agent/transpiler" "github.com/elastic/elastic-agent/internal/pkg/capabilities" From 2bcf7e45b6889a76b7d4363ce4d891322f56d974 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 15:59:48 -0700 Subject: [PATCH 06/21] Running go mod tidy --- go.mod | 1 - go.sum | 2 -- 2 files changed, 3 deletions(-) diff --git a/go.mod b/go.mod index 84c9aac7e9f..2016effc622 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,6 @@ require ( github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7 - github.com/looplab/fsm v1.0.1 github.com/magefile/mage v1.15.0 github.com/mitchellh/gox v1.0.1 github.com/mitchellh/hashstructure v1.1.0 diff --git a/go.sum b/go.sum index 467728dbe0c..54eca1468e7 100644 --- a/go.sum +++ b/go.sum @@ -1269,8 +1269,6 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9 github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/looplab/fsm v1.0.1 h1:OEW0ORrIx095N/6lgoGkFkotqH6s7vaFPsgjLAaF5QU= -github.com/looplab/fsm v1.0.1/go.mod h1:PmD3fFvQEIsjMEfvZdrCDZ6y8VwKTwWNjlpEr6IKPO4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= From eac4fe6b3eca7303a76d084c53f7b6889f40b406 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 16:54:52 -0700 Subject: [PATCH 07/21] Fix type --- internal/pkg/fleetapi/checkin_cmd.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/internal/pkg/fleetapi/checkin_cmd.go b/internal/pkg/fleetapi/checkin_cmd.go index a5d7e0942e5..8bff7a7f123 100644 --- a/internal/pkg/fleetapi/checkin_cmd.go +++ b/internal/pkg/fleetapi/checkin_cmd.go @@ -13,7 +13,7 @@ import ( "net/http" "time" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" @@ -49,17 +49,12 @@ type CheckinComponent struct { // CheckinRequest consists of multiple events reported to fleet ui. type CheckinRequest struct { - Status string `json:"status"` - AckToken string `json:"ack_token,omitempty"` - Metadata *info.ECSMeta `json:"local_metadata,omitempty"` - Message string `json:"message"` // V2 Agent message - Components []CheckinComponent `json:"components"` // V2 Agent components - UpgradeDetails *coordinator.UpgradeDetails `json:"upgrade_details,omitempty"` -} - -// UpgradeDetails consists of details regarding an ongoing upgrade. -type UpgradeDetails struct { - // TODO + Status string `json:"status"` + AckToken string `json:"ack_token,omitempty"` + Metadata *info.ECSMeta `json:"local_metadata,omitempty"` + Message string `json:"message"` // V2 Agent message + Components []CheckinComponent `json:"components"` // V2 Agent components + UpgradeDetails *details.Details `json:"upgrade_details,omitempty"` } // SerializableEvent is a representation of the event to be send to the Fleet Server API via the checkin From c0ee4ca6fea81c8034733e3865450bddd1d9ac45 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 17:05:26 -0700 Subject: [PATCH 08/21] Handle failures in one place --- internal/pkg/agent/application/upgrade/upgrade.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/pkg/agent/application/upgrade/upgrade.go b/internal/pkg/agent/application/upgrade/upgrade.go index 281f6f3b336..da0ea3df6be 100644 --- a/internal/pkg/agent/application/upgrade/upgrade.go +++ b/internal/pkg/agent/application/upgrade/upgrade.go @@ -153,7 +153,6 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string newHash, err := u.unpack(version, archivePath) if err != nil { - det.Fail(err) return nil, err } @@ -167,26 +166,22 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string } if err := copyActionStore(u.log, newHash); err != nil { - det.Fail(err) return nil, errors.New(err, "failed to copy action store") } if err := copyRunDirectory(u.log, newHash); err != nil { - det.Fail(err) return nil, errors.New(err, "failed to copy run directory") } det.SetState(details.StateReplacing) if err := ChangeSymlink(ctx, u.log, newHash); err != nil { - det.Fail(err) u.log.Errorw("Rolling back: changing symlink failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err } if err := u.markUpgrade(ctx, u.log, newHash, action); err != nil { - det.Fail(err) u.log.Errorw("Rolling back: marking upgrade failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err @@ -195,7 +190,6 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, sourceURI string det.SetState(details.StateWatching) if err := InvokeWatcher(u.log); err != nil { - det.Fail(err) u.log.Errorw("Rolling back: starting watcher failed", "error.message", err) rollbackInstall(ctx, u.log, newHash) return nil, err From e2b0e9748e69100b9279cca0abf5fc021abb1ba3 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 17:18:40 -0700 Subject: [PATCH 09/21] Remove Fleet changes --- .../application/gateway/fleet/fleet_gateway.go | 11 +++++------ internal/pkg/fleetapi/checkin_cmd.go | 13 +++++-------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go index 109ece58be9..000ec534bf2 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go @@ -332,12 +332,11 @@ func (f *FleetGateway) execute(ctx context.Context) (*fleetapi.CheckinResponse, // checkin cmd := fleetapi.NewCheckinCmd(f.agentInfo, f.client) req := &fleetapi.CheckinRequest{ - AckToken: ackToken, - Metadata: ecsMeta, - Status: agentStateToString(state.State), - Message: state.Message, - Components: components, - UpgradeDetails: state.UpgradeDetails, + AckToken: ackToken, + Metadata: ecsMeta, + Status: agentStateToString(state.State), + Message: state.Message, + Components: components, } resp, took, err := cmd.Execute(ctx, req) diff --git a/internal/pkg/fleetapi/checkin_cmd.go b/internal/pkg/fleetapi/checkin_cmd.go index 8bff7a7f123..b52eeb3903f 100644 --- a/internal/pkg/fleetapi/checkin_cmd.go +++ b/internal/pkg/fleetapi/checkin_cmd.go @@ -13,8 +13,6 @@ import ( "net/http" "time" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" - "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" "github.com/elastic/elastic-agent/internal/pkg/fleetapi/client" @@ -49,12 +47,11 @@ type CheckinComponent struct { // CheckinRequest consists of multiple events reported to fleet ui. type CheckinRequest struct { - Status string `json:"status"` - AckToken string `json:"ack_token,omitempty"` - Metadata *info.ECSMeta `json:"local_metadata,omitempty"` - Message string `json:"message"` // V2 Agent message - Components []CheckinComponent `json:"components"` // V2 Agent components - UpgradeDetails *details.Details `json:"upgrade_details,omitempty"` + Status string `json:"status"` + AckToken string `json:"ack_token,omitempty"` + Metadata *info.ECSMeta `json:"local_metadata,omitempty"` + Message string `json:"message"` // V2 Agent message + Components []CheckinComponent `json:"components"` // V2 Agent components } // SerializableEvent is a representation of the event to be send to the Fleet Server API via the checkin From e9c87010a3651e4ef349979315b7fb176eb4da11 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 4 Oct 2023 17:24:10 -0700 Subject: [PATCH 10/21] Send upgrade details in check-in requests to Fleet --- .../agent/application/gateway/fleet/fleet_gateway.go | 11 ++++++----- internal/pkg/fleetapi/checkin_cmd.go | 12 +++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go index 000ec534bf2..109ece58be9 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway.go @@ -332,11 +332,12 @@ func (f *FleetGateway) execute(ctx context.Context) (*fleetapi.CheckinResponse, // checkin cmd := fleetapi.NewCheckinCmd(f.agentInfo, f.client) req := &fleetapi.CheckinRequest{ - AckToken: ackToken, - Metadata: ecsMeta, - Status: agentStateToString(state.State), - Message: state.Message, - Components: components, + AckToken: ackToken, + Metadata: ecsMeta, + Status: agentStateToString(state.State), + Message: state.Message, + Components: components, + UpgradeDetails: state.UpgradeDetails, } resp, took, err := cmd.Execute(ctx, req) diff --git a/internal/pkg/fleetapi/checkin_cmd.go b/internal/pkg/fleetapi/checkin_cmd.go index b52eeb3903f..4c14454ce18 100644 --- a/internal/pkg/fleetapi/checkin_cmd.go +++ b/internal/pkg/fleetapi/checkin_cmd.go @@ -14,6 +14,7 @@ import ( "time" "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" "github.com/elastic/elastic-agent/internal/pkg/fleetapi/client" ) @@ -47,11 +48,12 @@ type CheckinComponent struct { // CheckinRequest consists of multiple events reported to fleet ui. type CheckinRequest struct { - Status string `json:"status"` - AckToken string `json:"ack_token,omitempty"` - Metadata *info.ECSMeta `json:"local_metadata,omitempty"` - Message string `json:"message"` // V2 Agent message - Components []CheckinComponent `json:"components"` // V2 Agent components + Status string `json:"status"` + AckToken string `json:"ack_token,omitempty"` + Metadata *info.ECSMeta `json:"local_metadata,omitempty"` + Message string `json:"message"` // V2 Agent message + Components []CheckinComponent `json:"components"` // V2 Agent components + UpgradeDetails *details.Details `json:"upgrade_details,omitempty"` } // SerializableEvent is a representation of the event to be send to the Fleet Server API via the checkin From 25aa28f46bdb38e1d46169ba6e9372365e285ac3 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 3 Nov 2023 18:31:18 +0530 Subject: [PATCH 11/21] Add unit test --- .../gateway/fleet/fleet_gateway_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go index 04572eab845..63e57654cb8 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go @@ -7,6 +7,7 @@ package fleet import ( "bytes" "context" + "encoding/json" "fmt" "io" @@ -23,9 +24,11 @@ import ( "gotest.tools/assert" "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" "github.com/elastic/elastic-agent/internal/pkg/agent/storage" "github.com/elastic/elastic-agent/internal/pkg/agent/storage/store" + "github.com/elastic/elastic-agent/internal/pkg/fleetapi" "github.com/elastic/elastic-agent/internal/pkg/fleetapi/acker/noop" "github.com/elastic/elastic-agent/internal/pkg/scheduler" agentclient "github.com/elastic/elastic-agent/pkg/control/v2/client" @@ -308,6 +311,72 @@ func TestFleetGateway(t *testing.T) { require.NoError(t, err) }) + t.Run("Sends upgrade details", func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + scheduler := scheduler.NewStepper() + client := newTestingClient() + + log, _ := logger.NewTesting("fleet_gateway") + + stateStore := newStateStore(t, log) + + upgradeDetails := details.Details{ + TargetVersion: "8.12.0", + State: "UPG_WATCHING", + ActionID: "foobarbaz", + } + stateFetcher := func() coordinator.State { + return coordinator.State{ + UpgradeDetails: &upgradeDetails, + } + } + + gateway, err := newFleetGatewayWithScheduler( + log, + settings, + agentInfo, + client, + scheduler, + noop.New(), + stateFetcher, + stateStore, + ) + + require.NoError(t, err) + + waitFn := ackSeq( + client.Answer(func(headers http.Header, body io.Reader) (*http.Response, error) { + data, err := io.ReadAll(body) + + var checkinRequest fleetapi.CheckinRequest + err = json.Unmarshal(data, &checkinRequest) + require.NoError(t, err) + + require.NotNil(t, checkinRequest.UpgradeDetails) + require.Equal(t, upgradeDetails, *checkinRequest.UpgradeDetails) + + resp := wrapStrToResp(http.StatusOK, `{ "actions": [] }`) + return resp, nil + }), + ) + + errCh := runFleetGateway(ctx, gateway) + + // Synchronize scheduler and acking of calls from the worker go routine. + scheduler.Next() + waitFn() + + cancel() + err = <-errCh + require.NoError(t, err) + select { + case actions := <-gateway.Actions(): + t.Errorf("Expected no actions, got %v", actions) + default: + } + }) } func TestRetriesOnFailures(t *testing.T) { From 98a4cd1c55c7c9bf8dbc7db1511a26a19cacf918 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 3 Nov 2023 18:34:41 +0530 Subject: [PATCH 12/21] Adding CHANGELOG entry --- ...9016628-send-upgrade-details-to-fleet.yaml | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 changelog/fragments/1699016628-send-upgrade-details-to-fleet.yaml diff --git a/changelog/fragments/1699016628-send-upgrade-details-to-fleet.yaml b/changelog/fragments/1699016628-send-upgrade-details-to-fleet.yaml new file mode 100644 index 00000000000..181cc9114f3 --- /dev/null +++ b/changelog/fragments/1699016628-send-upgrade-details-to-fleet.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: feature + +# Change summary; a 80ish characters long description of the change. +summary: Send upgrade details to Fleet + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +#description: + +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: elastic-agent + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +pr: https://github.com/elastic/elastic-agent/pull/3528 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +issue: https://github.com/elastic/elastic-agent/issues/3119 From a669b56d3469a63309070372b6ff0f787bfdac9c Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 3 Nov 2023 18:39:24 +0530 Subject: [PATCH 13/21] Compare pointer values so we're not copying locks --- .../agent/application/gateway/fleet/fleet_gateway_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go index 63e57654cb8..f672fac1a3a 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go @@ -322,14 +322,14 @@ func TestFleetGateway(t *testing.T) { stateStore := newStateStore(t, log) - upgradeDetails := details.Details{ + upgradeDetails := &details.Details{ TargetVersion: "8.12.0", State: "UPG_WATCHING", ActionID: "foobarbaz", } stateFetcher := func() coordinator.State { return coordinator.State{ - UpgradeDetails: &upgradeDetails, + UpgradeDetails: upgradeDetails, } } @@ -355,7 +355,7 @@ func TestFleetGateway(t *testing.T) { require.NoError(t, err) require.NotNil(t, checkinRequest.UpgradeDetails) - require.Equal(t, upgradeDetails, *checkinRequest.UpgradeDetails) + require.Equal(t, upgradeDetails, checkinRequest.UpgradeDetails) resp := wrapStrToResp(http.StatusOK, `{ "actions": [] }`) return resp, nil From 5fc5051b12903684235dc4aec2bb9bac60052f0e Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 3 Nov 2023 18:39:46 +0530 Subject: [PATCH 14/21] Add missing assertion --- .../pkg/agent/application/gateway/fleet/fleet_gateway_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go index f672fac1a3a..de40565c0b5 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go @@ -349,6 +349,7 @@ func TestFleetGateway(t *testing.T) { waitFn := ackSeq( client.Answer(func(headers http.Header, body io.Reader) (*http.Response, error) { data, err := io.ReadAll(body) + require.NoError(t, err) var checkinRequest fleetapi.CheckinRequest err = json.Unmarshal(data, &checkinRequest) From b24ff1261f94eae7599cf2e3663e268854a479b3 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 8 Nov 2023 15:10:24 +0530 Subject: [PATCH 15/21] Update Fleet-managed upgrade E2E test --- go.mod | 3 +++ go.sum | 4 ++-- testing/integration/upgrade_fleet_test.go | 10 ++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 2016effc622..4dd5838f129 100644 --- a/go.mod +++ b/go.mod @@ -180,5 +180,8 @@ replace ( github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c ) +// FIXME: remove once https://github.com/elastic/elastic-agent-libs/pull/158 has been merged +replace github.com/elastic/elastic-agent-libs => github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2 + // Exclude this version because the version has an invalid checksum. exclude github.com/docker/distribution v2.8.0+incompatible diff --git a/go.sum b/go.sum index 54eca1468e7..127dff2038b 100644 --- a/go.sum +++ b/go.sum @@ -781,8 +781,6 @@ github.com/elastic/elastic-agent-autodiscover v0.6.5 h1:5DeMpuNc8c/tN6HN0A4A2uOF github.com/elastic/elastic-agent-autodiscover v0.6.5/go.mod h1:chulyCAyZb/njMHgzkhC/yWnt8v/Y6eCRUhmFVnsA5o= github.com/elastic/elastic-agent-client/v7 v7.5.0 h1:niI3WQ+01Lnp2r5LxK8SyNhrPJe13vBiOkqrDRK2oTA= github.com/elastic/elastic-agent-client/v7 v7.5.0/go.mod h1:DYoX95xjC4BW/p2avyu724Qr2+hoUIz9eCU9CVS1d+0= -github.com/elastic/elastic-agent-libs v0.6.2 h1:tE5pFK4y7xm1FtXm+r+63G7STjJAaWh3+oKIQDzdPDo= -github.com/elastic/elastic-agent-libs v0.6.2/go.mod h1:o+EySawBZGeYu49shJxerg2wRCimS1dhrD4As0MS700= github.com/elastic/elastic-agent-system-metrics v0.8.0 h1:EsWbtd83JvnaqnL57bKS1E6GhOdemTRbxdFDcenR8zQ= github.com/elastic/elastic-agent-system-metrics v0.8.0/go.mod h1:9C1UEfj0P687HAzZepHszN6zXA+2tN2Lx3Osvq1zby8= github.com/elastic/elastic-integration-corpus-generator-tool v0.5.0/go.mod h1:uf9N86y+UACGybdEhZLpwZ93XHWVhsYZAA4c2T2v6YM= @@ -1739,6 +1737,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2 h1:rfSwTjGGvN+Fhs8h9d9GXzPjH6ZameepM77KLn0gylo= +github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2/go.mod h1:o+EySawBZGeYu49shJxerg2wRCimS1dhrD4As0MS700= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= diff --git a/testing/integration/upgrade_fleet_test.go b/testing/integration/upgrade_fleet_test.go index aca07472d58..132e0f25690 100644 --- a/testing/integration/upgrade_fleet_test.go +++ b/testing/integration/upgrade_fleet_test.go @@ -8,6 +8,7 @@ package integration import ( "context" + "os" "strings" "testing" "time" @@ -140,6 +141,15 @@ func testUpgradeFleetManagedElasticAgent(ctx context.Context, t *testing.T, info err = fleettools.UpgradeAgent(kibClient, policy.ID, endVersionInfo.Binary.String(), true) require.NoError(t, err) + // wait for upgrade details to show up in `.fleet-agents` indices. + hostname, err := os.Hostname() + require.NoError(t, err) + require.Eventually(t, func() bool { + agent, err := fleettools.GetAgentByPolicyIDAndHostnameFromList(kibClient, policy.ID, hostname) + return err != nil && agent.UpgradeDetails != nil + + }, 5*time.Minute, time.Second) + // wait for the watcher to show up t.Logf("Waiting for upgrade watcher to start...") err = upgradetest.WaitForWatcher(ctx, 5*time.Minute, 10*time.Second) From 1421d2bee1edbb571e99525bb2cc1fb982a12507 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 8 Nov 2023 15:15:56 +0530 Subject: [PATCH 16/21] Make scheduled_at optional so empty time is not serialized --- .../pkg/agent/application/coordinator/diagnostics_test.go | 2 +- internal/pkg/agent/application/upgrade/details/details.go | 2 +- pkg/control/v2/server/server.go | 7 ++++++- pkg/control/v2/server/server_test.go | 7 ++++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/internal/pkg/agent/application/coordinator/diagnostics_test.go b/internal/pkg/agent/application/coordinator/diagnostics_test.go index 9fec8e1844b..1e12dd38141 100644 --- a/internal/pkg/agent/application/coordinator/diagnostics_test.go +++ b/internal/pkg/agent/application/coordinator/diagnostics_test.go @@ -441,7 +441,7 @@ func TestDiagnosticState(t *testing.T) { ActionID: "foobar", Metadata: details.Metadata{ DownloadPercent: 0.17469, - ScheduledAt: now, + ScheduledAt: &now, DownloadRate: 123.56, }, }, diff --git a/internal/pkg/agent/application/upgrade/details/details.go b/internal/pkg/agent/application/upgrade/details/details.go index 5bc1e409cad..99ced3e0e1e 100644 --- a/internal/pkg/agent/application/upgrade/details/details.go +++ b/internal/pkg/agent/application/upgrade/details/details.go @@ -35,7 +35,7 @@ type Details struct { // Metadata consists of metadata relating to a specific upgrade state type Metadata struct { - ScheduledAt time.Time `json:"scheduled_at,omitempty" yaml:"scheduled_at,omitempty"` + ScheduledAt *time.Time `json:"scheduled_at,omitempty" yaml:"scheduled_at,omitempty"` // DownloadPercent is the percentage of the artifact that has been // downloaded. Minimum value is 0 and maximum value is 1. diff --git a/pkg/control/v2/server/server.go b/pkg/control/v2/server/server.go index 645068ea64d..149c426e2e4 100644 --- a/pkg/control/v2/server/server.go +++ b/pkg/control/v2/server/server.go @@ -370,12 +370,17 @@ func stateToProto(state *coordinator.State, agentInfo *info.AgentInfo) (*cproto. State: string(state.UpgradeDetails.State), ActionId: state.UpgradeDetails.ActionID, Metadata: &cproto.UpgradeDetailsMetadata{ - ScheduledAt: timestamppb.New(state.UpgradeDetails.Metadata.ScheduledAt), DownloadPercent: float32(state.UpgradeDetails.Metadata.DownloadPercent), FailedState: string(state.UpgradeDetails.Metadata.FailedState), ErrorMsg: state.UpgradeDetails.Metadata.ErrorMsg, }, } + + if state.UpgradeDetails.Metadata.ScheduledAt != nil && + !state.UpgradeDetails.Metadata.ScheduledAt.IsZero() { + upgradeDetails.Metadata.ScheduledAt = timestamppb.New(*state.UpgradeDetails.Metadata.ScheduledAt) + + } } return &cproto.StateResponse{ diff --git a/pkg/control/v2/server/server_test.go b/pkg/control/v2/server/server_test.go index cafab60450f..d7aee6d96c7 100644 --- a/pkg/control/v2/server/server_test.go +++ b/pkg/control/v2/server/server_test.go @@ -164,11 +164,16 @@ func TestStateMapping(t *testing.T) { if tc.upgradeDetails != nil { expectedMetadata := &cproto.UpgradeDetailsMetadata{ - ScheduledAt: timestamppb.New(tc.upgradeDetails.Metadata.ScheduledAt), DownloadPercent: float32(tc.upgradeDetails.Metadata.DownloadPercent), FailedState: string(tc.upgradeDetails.Metadata.FailedState), ErrorMsg: tc.upgradeDetails.Metadata.ErrorMsg, } + + if tc.upgradeDetails.Metadata.ScheduledAt != nil && + !tc.upgradeDetails.Metadata.ScheduledAt.IsZero() { + expectedMetadata.ScheduledAt = timestamppb.New(*tc.upgradeDetails.Metadata.ScheduledAt) + } + assert.Equal(t, string(tc.upgradeDetails.State), stateResponse.UpgradeDetails.State) assert.Equal(t, tc.upgradeDetails.TargetVersion, stateResponse.UpgradeDetails.TargetVersion) assert.Equal(t, tc.upgradeDetails.ActionID, stateResponse.UpgradeDetails.ActionId) From ea742d9478e4a83d9d26f48f9adf495cfb510f75 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Thu, 9 Nov 2023 18:19:14 +0530 Subject: [PATCH 17/21] Normalize comparison of hostnames --- pkg/testing/tools/fleettools/fleet.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/testing/tools/fleettools/fleet.go b/pkg/testing/tools/fleettools/fleet.go index baa1ca659c0..8d4a7f8f1ac 100644 --- a/pkg/testing/tools/fleettools/fleet.go +++ b/pkg/testing/tools/fleettools/fleet.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "os" + "strings" "github.com/elastic/elastic-agent-libs/kibana" ) @@ -25,7 +26,7 @@ func GetAgentByPolicyIDAndHostnameFromList(client *kibana.Client, policyID, host agentHostname := item.LocalMetadata.Host.Hostname agentPolicyID := item.PolicyID - if agentHostname == hostname && agentPolicyID == policyID { + if strings.ToLower(agentHostname) == strings.ToLower(hostname) && agentPolicyID == policyID { hostnameAgents = append(hostnameAgents, &listAgentsResp.Items[i]) } } From 5d1e9f76035f97595a40f9da03c18032b263ddfe Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Thu, 9 Nov 2023 18:19:25 +0530 Subject: [PATCH 18/21] Convert comment to log --- testing/integration/upgrade_fleet_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/integration/upgrade_fleet_test.go b/testing/integration/upgrade_fleet_test.go index 132e0f25690..fd281333ace 100644 --- a/testing/integration/upgrade_fleet_test.go +++ b/testing/integration/upgrade_fleet_test.go @@ -141,7 +141,7 @@ func testUpgradeFleetManagedElasticAgent(ctx context.Context, t *testing.T, info err = fleettools.UpgradeAgent(kibClient, policy.ID, endVersionInfo.Binary.String(), true) require.NoError(t, err) - // wait for upgrade details to show up in `.fleet-agents` indices. + t.Log("Waiting from upgrade details to show up in Fleet") hostname, err := os.Hostname() require.NoError(t, err) require.Eventually(t, func() bool { From b6090e6dfa87ea3df5130ee93b9a14381a88269a Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Thu, 9 Nov 2023 18:19:32 +0530 Subject: [PATCH 19/21] Fix assertion logic --- testing/integration/upgrade_fleet_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/integration/upgrade_fleet_test.go b/testing/integration/upgrade_fleet_test.go index fd281333ace..9c44386eb87 100644 --- a/testing/integration/upgrade_fleet_test.go +++ b/testing/integration/upgrade_fleet_test.go @@ -146,7 +146,7 @@ func testUpgradeFleetManagedElasticAgent(ctx context.Context, t *testing.T, info require.NoError(t, err) require.Eventually(t, func() bool { agent, err := fleettools.GetAgentByPolicyIDAndHostnameFromList(kibClient, policy.ID, hostname) - return err != nil && agent.UpgradeDetails != nil + return err == nil && agent.UpgradeDetails != nil }, 5*time.Minute, time.Second) From ceb5c1bf1e9c6c23fb8cd952af82fcd4b303d9fb Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 10 Nov 2023 18:01:00 +0530 Subject: [PATCH 20/21] Removing replace directive --- NOTICE.txt | 4 ++-- go.mod | 5 +---- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 11fa3452084..be3e1d39268 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1166,11 +1166,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.6.2 +Version: v0.7.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.7.0/LICENSE: Apache License Version 2.0, January 2004 diff --git a/go.mod b/go.mod index 4dd5838f129..d5b98bb4d67 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/elastic/e2e-testing v1.1.0 github.com/elastic/elastic-agent-autodiscover v0.6.5 github.com/elastic/elastic-agent-client/v7 v7.5.0 - github.com/elastic/elastic-agent-libs v0.6.2 + github.com/elastic/elastic-agent-libs v0.7.0 github.com/elastic/elastic-agent-system-metrics v0.8.0 github.com/elastic/elastic-transport-go/v8 v8.3.0 github.com/elastic/go-elasticsearch/v8 v8.10.1 @@ -180,8 +180,5 @@ replace ( github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c ) -// FIXME: remove once https://github.com/elastic/elastic-agent-libs/pull/158 has been merged -replace github.com/elastic/elastic-agent-libs => github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2 - // Exclude this version because the version has an invalid checksum. exclude github.com/docker/distribution v2.8.0+incompatible diff --git a/go.sum b/go.sum index 127dff2038b..ffcbb8e262a 100644 --- a/go.sum +++ b/go.sum @@ -781,6 +781,8 @@ github.com/elastic/elastic-agent-autodiscover v0.6.5 h1:5DeMpuNc8c/tN6HN0A4A2uOF github.com/elastic/elastic-agent-autodiscover v0.6.5/go.mod h1:chulyCAyZb/njMHgzkhC/yWnt8v/Y6eCRUhmFVnsA5o= github.com/elastic/elastic-agent-client/v7 v7.5.0 h1:niI3WQ+01Lnp2r5LxK8SyNhrPJe13vBiOkqrDRK2oTA= github.com/elastic/elastic-agent-client/v7 v7.5.0/go.mod h1:DYoX95xjC4BW/p2avyu724Qr2+hoUIz9eCU9CVS1d+0= +github.com/elastic/elastic-agent-libs v0.7.0 h1:g/+Gzpn4ayXPFbfZsn5lGjbPR1TGqlVpshJVVUNJGlQ= +github.com/elastic/elastic-agent-libs v0.7.0/go.mod h1:o+EySawBZGeYu49shJxerg2wRCimS1dhrD4As0MS700= github.com/elastic/elastic-agent-system-metrics v0.8.0 h1:EsWbtd83JvnaqnL57bKS1E6GhOdemTRbxdFDcenR8zQ= github.com/elastic/elastic-agent-system-metrics v0.8.0/go.mod h1:9C1UEfj0P687HAzZepHszN6zXA+2tN2Lx3Osvq1zby8= github.com/elastic/elastic-integration-corpus-generator-tool v0.5.0/go.mod h1:uf9N86y+UACGybdEhZLpwZ93XHWVhsYZAA4c2T2v6YM= @@ -1737,8 +1739,6 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2 h1:rfSwTjGGvN+Fhs8h9d9GXzPjH6ZameepM77KLn0gylo= -github.com/ycombinator/elastic-agent-libs v0.0.0-20231108093453-10b9f48ba4a2/go.mod h1:o+EySawBZGeYu49shJxerg2wRCimS1dhrD4As0MS700= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= From 9e3b7322a0ed7530a9de50b28acd258128d23b00 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 10 Nov 2023 18:05:22 +0530 Subject: [PATCH 21/21] Address linter error --- pkg/testing/tools/fleettools/fleet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/testing/tools/fleettools/fleet.go b/pkg/testing/tools/fleettools/fleet.go index 8d4a7f8f1ac..77c64069e41 100644 --- a/pkg/testing/tools/fleettools/fleet.go +++ b/pkg/testing/tools/fleettools/fleet.go @@ -26,7 +26,7 @@ func GetAgentByPolicyIDAndHostnameFromList(client *kibana.Client, policyID, host agentHostname := item.LocalMetadata.Host.Hostname agentPolicyID := item.PolicyID - if strings.ToLower(agentHostname) == strings.ToLower(hostname) && agentPolicyID == policyID { + if strings.EqualFold(agentHostname, hostname) && agentPolicyID == policyID { hostnameAgents = append(hostnameAgents, &listAgentsResp.Items[i]) } }