Skip to content

Commit e2d7dcc

Browse files
authored
Fix current agent directory value when collecting diagnostics (#4378)
This PR fixes the calculation of elastic-agent installation directory when collecting diagnostics. The issue has been triggered by the change of the elastic-agent installation directory name introduced with #4193 where the agent install directory can be different from elastic-agent-<hash>.
1 parent f10892d commit e2d7dcc

File tree

2 files changed

+142
-1
lines changed

2 files changed

+142
-1
lines changed

internal/pkg/diagnostics/diagnostics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func redactKey(k string) bool {
381381
}
382382

383383
func zipLogs(zw *zip.Writer, ts time.Time) error {
384-
currentDir := fmt.Sprintf("%s-%s", agentName, release.ShortCommit())
384+
currentDir := filepath.Base(paths.Home())
385385
if !paths.IsVersionHome() {
386386
// running in a container with custom top path set
387387
// logs are directly under top path

testing/integration/endpoint_security_test.go

+141
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
package integration
88

99
import (
10+
"archive/zip"
1011
"bytes"
1112
"context"
1213
_ "embed"
1314
"encoding/json"
1415
"fmt"
16+
"io/fs"
1517
"os"
1618
"path/filepath"
1719
"runtime"
20+
"slices"
1821
"strings"
1922
"testing"
2023
"text/template"
@@ -646,6 +649,144 @@ func TestEndpointSecurityUnprivileged(t *testing.T) {
646649
}, 2*time.Minute, 10*time.Second, "Agent never became DEGRADED with root/Administrator install message")
647650
}
648651

652+
// TestEndpointLogsAreCollectedInDiagnostics tests that diagnostics archive contain endpoint logs
653+
func TestEndpointLogsAreCollectedInDiagnostics(t *testing.T) {
654+
info := define.Require(t, define.Requirements{
655+
Group: Fleet,
656+
Stack: &define.Stack{},
657+
Local: false, // requires Agent installation
658+
Sudo: true, // requires Agent installation
659+
OS: []define.OS{
660+
{Type: define.Linux},
661+
},
662+
})
663+
664+
ctx, cn := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute))
665+
defer cn()
666+
667+
// Get path to agent executable.
668+
fixture, err := define.NewFixture(t, define.Version())
669+
require.NoError(t, err)
670+
671+
t.Log("Enrolling the agent in Fleet")
672+
policyUUID := uuid.New().String()
673+
createPolicyReq := kibana.AgentPolicy{
674+
Name: "test-policy-" + policyUUID,
675+
Namespace: "default",
676+
Description: "Test policy " + policyUUID,
677+
MonitoringEnabled: []kibana.MonitoringEnabledOption{
678+
kibana.MonitoringEnabledLogs,
679+
kibana.MonitoringEnabledMetrics,
680+
},
681+
}
682+
installOpts := atesting.InstallOpts{
683+
NonInteractive: true,
684+
Force: true,
685+
Unprivileged: atesting.NewBool(false),
686+
}
687+
688+
policyResp, err := tools.InstallAgentWithPolicy(ctx, t, installOpts, fixture, info.KibanaClient, createPolicyReq)
689+
require.NoErrorf(t, err, "Policy Response was: %v", policyResp)
690+
691+
t.Cleanup(func() {
692+
t.Log("Un-enrolling Elastic Agent...")
693+
// Use a separate context as the one in the test body will have been cancelled at this point.
694+
cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), time.Minute)
695+
defer cleanupCancel()
696+
assert.NoError(t, fleettools.UnEnrollAgent(cleanupCtx, info.KibanaClient, policyResp.ID))
697+
})
698+
699+
t.Log("Installing Elastic Defend")
700+
pkgPolicyResp, err := installElasticDefendPackage(t, info, policyResp.ID)
701+
require.NoErrorf(t, err, "Policy Response was: %v", pkgPolicyResp)
702+
703+
// wait for endpoint to be healthy
704+
t.Log("Polling for endpoint-security to become Healthy")
705+
pollingCtx, pollingCancel := context.WithTimeout(ctx, endpointHealthPollingTimeout)
706+
defer pollingCancel()
707+
708+
require.Eventually(t,
709+
func() bool {
710+
agentClient := fixture.Client()
711+
err = agentClient.Connect(ctx)
712+
if err != nil {
713+
t.Logf("error connecting to agent: %v", err)
714+
return false
715+
}
716+
defer agentClient.Disconnect()
717+
return agentAndEndpointAreHealthy(t, pollingCtx, agentClient)
718+
},
719+
endpointHealthPollingTimeout,
720+
time.Second,
721+
"Endpoint component or units are not healthy.",
722+
)
723+
724+
outDir := t.TempDir()
725+
diagFile := t.Name() + ".zip"
726+
diagAbsPath := filepath.Join(outDir, diagFile)
727+
_, err = fixture.Exec(ctx, []string{"diagnostics", "-f", diagAbsPath})
728+
require.NoError(t, err, "diagnostics command failed")
729+
require.FileExists(t, diagAbsPath, "diagnostic archive should have been created")
730+
checkDiagnosticsForEndpointFiles(t, diagAbsPath)
731+
}
732+
733+
func checkDiagnosticsForEndpointFiles(t *testing.T, diagsPath string) {
734+
zipReader, err := zip.OpenReader(diagsPath)
735+
require.NoError(t, err, "error opening diagnostics archive")
736+
737+
defer func(zipReader *zip.ReadCloser) {
738+
err := zipReader.Close()
739+
assert.NoError(t, err, "error closing diagnostic archive")
740+
}(zipReader)
741+
742+
t.Logf("---- Contents of diagnostics archive")
743+
for _, file := range zipReader.File {
744+
t.Logf("%q - %+v", file.Name, file.FileHeader.FileInfo())
745+
}
746+
t.Logf("---- End contents of diagnostics archive")
747+
// check there are files under the components/ directory
748+
endpointComponentDirName := "components/endpoint-default"
749+
endpointComponentDir, err := zipReader.Open(endpointComponentDirName)
750+
if assert.NoErrorf(t, err, "error looking up directory %q in diagnostic archive: %v", endpointComponentDirName, err) {
751+
defer func(endpointComponentDir fs.File) {
752+
err := endpointComponentDir.Close()
753+
if err != nil {
754+
assert.NoError(t, err, "error closing endpoint component directory")
755+
}
756+
}(endpointComponentDir)
757+
if assert.Implementsf(t, (*fs.ReadDirFile)(nil), endpointComponentDir, "endpoint should have a directory in the diagnostic archive under %s", endpointComponentDirName) {
758+
dirFile := endpointComponentDir.(fs.ReadDirFile)
759+
endpointFiles, err := dirFile.ReadDir(-1)
760+
assert.NoError(t, err, "error reading endpoint component directory %q in diagnostic archive", endpointComponentDirName)
761+
assert.NotEmpty(t, endpointFiles, "endpoint component directory should not be empty")
762+
}
763+
}
764+
765+
// check endpoint logs
766+
servicesLogDirName := "logs/services"
767+
servicesLogDir, err := zipReader.Open(servicesLogDirName)
768+
if assert.NoErrorf(t, err, "error looking up directory %q in diagnostic archive: %v", servicesLogDirName, err) {
769+
defer func(servicesLogDir fs.File) {
770+
err := servicesLogDir.Close()
771+
if err != nil {
772+
assert.NoError(t, err, "error closing services logs directory")
773+
}
774+
}(servicesLogDir)
775+
if assert.Implementsf(t, (*fs.ReadDirFile)(nil), servicesLogDir, "service logs should be in a directory in the diagnostic archive under %s", servicesLogDir) {
776+
dirFile := servicesLogDir.(fs.ReadDirFile)
777+
servicesLogFiles, err := dirFile.ReadDir(-1)
778+
assert.NoError(t, err, "error reading services logs directory %q in diagnostic archive", servicesLogDirName)
779+
assert.True(t,
780+
slices.ContainsFunc(servicesLogFiles,
781+
func(entry fs.DirEntry) bool {
782+
return strings.HasPrefix(entry.Name(), "endpoint-") && strings.HasSuffix(entry.Name(), ".log")
783+
}),
784+
"service logs should contain endpoint-*.log files",
785+
)
786+
}
787+
}
788+
}
789+
649790
func agentAndEndpointAreHealthy(t *testing.T, ctx context.Context, agentClient client.Client) bool {
650791
t.Helper()
651792

0 commit comments

Comments
 (0)