Skip to content

Commit

Permalink
Re-enabled notifyFleetAuditUninstall on Windows (#6257) (#6289)
Browse files Browse the repository at this point in the history
* Write integration test.

* Skip notifyFleetAuditUninstall on Windows.

* Re-enable notifyFleetAuditUninstall on Windows.

* Update test to be in Fleet group.

* Adjust OGC supported.

* Add changelog.

* Update changelog.

* Add check for connected to Fleet.

* Remove TestRepeatedInstallUninstall.

(cherry picked from commit dcf5b7a)

Co-authored-by: Blake Rouse <blake.rouse@elastic.co>
  • Loading branch information
mergify[bot] and blakerouse authored Dec 12, 2024
1 parent 6030b6b commit 5253ed2
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -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: bug-fix

# Change summary; a 80ish characters long description of the change.
summary: Notify Fleet of uninstall on Windows

# 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:

# 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/6257

# 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/5952
4 changes: 1 addition & 3 deletions internal/pkg/agent/install/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,7 @@ func Uninstall(ctx context.Context, cfgFile, topPath, uninstallToken string, log
}
pt.Describe("Removed install directory")

// Skip on Windows because of https://github.com/elastic/elastic-agent/issues/5952
// Once the root-cause is identified then this can be re-enabled on Windows.
if notifyFleet && runtime.GOOS != "windows" {
if notifyFleet {
notifyFleetAuditUninstall(ctx, log, pt, cfg, ai) //nolint:errcheck // ignore the error as we can't act on it
}

Expand Down
14 changes: 8 additions & 6 deletions pkg/testing/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Fixture struct {

srcPackage string
workDir string
extractDir string

installed bool
installOpts *InstallOpts
Expand Down Expand Up @@ -198,7 +199,7 @@ func (f *Fixture) Prepare(ctx context.Context, components ...UsableComponent) er
if err != nil {
return err
}
if f.workDir != "" {
if f.extractDir != "" {
// already prepared
return fmt.Errorf("already been prepared")
}
Expand All @@ -212,16 +213,17 @@ func (f *Fixture) Prepare(ctx context.Context, components ...UsableComponent) er
if err != nil {
return err
}
workDir := createTempDir(f.t)
finalDir := filepath.Join(workDir, name)
err = ExtractArtifact(f.t, src, workDir)
extractDir := createTempDir(f.t)
finalDir := filepath.Join(extractDir, name)
err = ExtractArtifact(f.t, src, extractDir)
if err != nil {
return fmt.Errorf("extracting artifact %q in %q: %w", src, workDir, err)
return fmt.Errorf("extracting artifact %q in %q: %w", src, extractDir, err)
}
err = f.prepareComponents(finalDir, components...)
if err != nil {
return err
}
f.extractDir = finalDir
f.workDir = finalDir
return nil
}
Expand Down Expand Up @@ -823,7 +825,7 @@ func (f *Fixture) IsInstalled() bool {

// EnsurePrepared ensures that the fixture has been prepared.
func (f *Fixture) EnsurePrepared(ctx context.Context) error {
if f.workDir == "" {
if f.extractDir == "" {
return f.Prepare(ctx)
}
return nil
Expand Down
1 change: 1 addition & 0 deletions pkg/testing/fixture_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ func (f *Fixture) uninstallNoPkgManager(ctx context.Context, uninstallOpts *Unin
return out, fmt.Errorf("error running uninstall command: %w", err)
}
f.installed = false
f.workDir = f.extractDir

// Check that Elastic Agent files are actually removed
basePath := f.installOpts.BasePath
Expand Down
72 changes: 50 additions & 22 deletions testing/integration/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/elastic/elastic-agent/internal/pkg/agent/install"
atesting "github.com/elastic/elastic-agent/pkg/testing"
"github.com/elastic/elastic-agent/pkg/testing/define"
"github.com/elastic/elastic-agent/pkg/testing/tools/check"
"github.com/elastic/elastic-agent/pkg/testing/tools/fleettools"
"github.com/elastic/elastic-agent/pkg/testing/tools/testcontext"
"github.com/elastic/elastic-agent/testing/installtest"
Expand Down Expand Up @@ -420,13 +421,14 @@ func TestInstallUninstallAudit(t *testing.T) {
require.Equal(t, "uninstall", res.Source.AuditUnenrolledReason)
}

// TestRepeatedInstallUninstall will install then uninstall the agent
// repeatedly. This test exists because of a number of race
// conditions that have occurred in the uninstall process. Current
// testing shows each iteration takes around 16 seconds.
func TestRepeatedInstallUninstall(t *testing.T) {
define.Require(t, define.Requirements{
Group: Default,
// TestRepeatedInstallUninstallFleet will install then uninstall the agent
// repeatedly with it enrolled into Fleet. This test exists because of a number
// of race conditions that have occurred in the uninstall process when enrolled
// into Fleet. Current testing shows each iteration takes around 16 seconds.
func TestRepeatedInstallUninstallFleet(t *testing.T) {
info := define.Require(t, define.Requirements{
Group: Fleet,
Stack: &define.Stack{}, // needs a fleet-server.
// We require sudo for this test to run
// `elastic-agent install` (even though it will
// be installed as non-root).
Expand All @@ -437,37 +439,63 @@ func TestRepeatedInstallUninstall(t *testing.T) {
Local: false,
})

prepareCtx, prepareCancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(5*time.Minute))
defer prepareCancel()

policyResp, enrollmentTokenResp := createPolicyAndEnrollmentToken(prepareCtx, t, info.KibanaClient, createBasicPolicy())
t.Logf("Created policy %+v", policyResp.AgentPolicy)

t.Log("Getting default Fleet Server URL...")
fleetServerURL, err := fleettools.DefaultURL(prepareCtx, info.KibanaClient)
require.NoError(t, err, "failed getting Fleet Server URL")

// Get path to Elastic Agent executable
fixture, err := define.NewFixtureFromLocalBuild(t, define.Version())
require.NoError(t, err)

// Prepare the Elastic Agent so the binary is extracted and ready to use.
err = fixture.Prepare(prepareCtx)
require.NoError(t, err)

maxRunTime := 2 * time.Minute
iterations := 100
for i := 0; i < iterations; i++ {
t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {

// Get path to Elastic Agent executable
fixture, err := define.NewFixtureFromLocalBuild(t, define.Version())
require.NoError(t, err)

successful := t.Run(fmt.Sprintf("%s-%d", t.Name(), i), func(t *testing.T) {
ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(maxRunTime))
defer cancel()

// Prepare the Elastic Agent so the binary is extracted and ready to use.
err = fixture.Prepare(ctx)
require.NoError(t, err)

// Run `elastic-agent install`. We use `--force` to prevent interactive
// execution.
opts := &atesting.InstallOpts{Force: true}
opts := &atesting.InstallOpts{
Force: true,
EnrollOpts: atesting.EnrollOpts{
URL: fleetServerURL,
EnrollmentToken: enrollmentTokenResp.APIKey,
},
}
out, err := fixture.Install(ctx, opts)
if err != nil {
t.Logf("install output: %s", out)
require.NoError(t, err)
require.NoErrorf(t, err, "install failed: %s", err)
}

// Check that Agent was installed in default base path
// Check that Agent was installed in successfully
require.NoError(t, installtest.CheckSuccess(ctx, fixture, opts.BasePath, &installtest.CheckOpts{Privileged: opts.Privileged}))
t.Run("check agent package version", testAgentPackageVersion(ctx, fixture, true))

// Check connected to Fleet.
check.ConnectedToFleet(ctx, t, fixture, 5*time.Minute)

// Perform uninstall.
out, err = fixture.Uninstall(ctx, &atesting.UninstallOpts{Force: true})
require.NoErrorf(t, err, "uninstall failed: %s", err)
if err != nil {
t.Logf("uninstall output: %s", out)
require.NoErrorf(t, err, "uninstall failed: %s", err)
}
})
if !successful {
// quit now, another test run will continue to fail now
return
}
}
}

Expand Down

0 comments on commit 5253ed2

Please sign in to comment.