diff --git a/internal/pkg/agent/cmd/enroll.go b/internal/pkg/agent/cmd/enroll.go index 534f89503f6..d26e6d418d3 100644 --- a/internal/pkg/agent/cmd/enroll.go +++ b/internal/pkg/agent/cmd/enroll.go @@ -15,6 +15,8 @@ import ( "strings" "syscall" + "github.com/elastic/elastic-agent/internal/pkg/agent/install/pkgmgr" + "github.com/spf13/cobra" "github.com/elastic/elastic-agent/internal/pkg/agent/application" @@ -478,6 +480,12 @@ func enroll(streams *cli.IOStreams, cmd *cobra.Command) error { fixPermissions = nil } + // If agent was installed via a deb or rpm package, we want to avoid restarting because it may not be running yet. + // In this case, the user is expected to (re)start agent via systemd instead. + if pkgmgr.InstalledViaExternalPkgMgr() { + skipDaemonReload = true + } + options := enrollCmdOption{ EnrollAPIKey: enrollmentToken, URL: url, diff --git a/pkg/testing/fixture_install.go b/pkg/testing/fixture_install.go index d983e6fb62f..1d4ce977fc0 100644 --- a/pkg/testing/fixture_install.go +++ b/pkg/testing/fixture_install.go @@ -469,12 +469,6 @@ func (f *Fixture) installDeb(ctx context.Context, installOpts *InstallOpts, shou } }) - // start elastic-agent - out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() - if err != nil { - return out, fmt.Errorf("systemctl start elastic-agent failed: %w", err) - } - if !shouldEnroll { return nil, nil } @@ -504,6 +498,12 @@ func (f *Fixture) installDeb(ctx context.Context, installOpts *InstallOpts, shou return out, fmt.Errorf("elastic-agent enroll failed: %w, output: %s args: %v", err, string(out), enrollArgs) } + // start elastic-agent + out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() + if err != nil { + return out, fmt.Errorf("systemctl start elastic-agent failed: %w", err) + } + return nil, nil } @@ -556,12 +556,6 @@ func (f *Fixture) installRpm(ctx context.Context, installOpts *InstallOpts, shou } }) - // start elastic-agent - out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() - if err != nil { - return out, fmt.Errorf("systemctl start elastic-agent failed: %w", err) - } - if !shouldEnroll { return nil, nil } @@ -592,6 +586,12 @@ func (f *Fixture) installRpm(ctx context.Context, installOpts *InstallOpts, shou return out, fmt.Errorf("elastic-agent enroll failed: %w, output: %s args: %v", err, string(out), enrollArgs) } + // start elastic-agent + out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() + if err != nil { + return out, fmt.Errorf("systemctl start elastic-agent failed: %w", err) + } + return nil, nil } diff --git a/testing/integration/linux_deb_test.go b/testing/integration/linux_deb_test.go index a7de3170ff0..3e328af4dc7 100644 --- a/testing/integration/linux_deb_test.go +++ b/testing/integration/linux_deb_test.go @@ -97,6 +97,75 @@ func TestDebLogIngestFleetManaged(t *testing.T) { }) } +func TestDebEnroll(t *testing.T) { + info := define.Require(t, define.Requirements{ + Group: Deb, + Stack: &define.Stack{}, + OS: []define.OS{ + { + Type: define.Linux, + Distro: "ubuntu", + }, + }, + Local: false, + Sudo: true, + }) + + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + agentFixture, err := define.NewFixtureFromLocalBuild(t, define.Version(), atesting.WithPackageFormat("deb")) + require.NoError(t, err) + + // 1. Create a policy in Fleet without any + // To ensure there are no conflicts with previous test runs against + // the same ESS stack, we add the current time at the end of the policy + // name. This policy does not contain any integration. + t.Log("Creating a test policy") + createPolicyReq := kibana.AgentPolicy{ + Name: fmt.Sprintf("test-policy-enroll-%s", uuid.Must(uuid.NewV4()).String()), + Namespace: info.Namespace, + Description: "test policy for agent enrollment", + AgentFeatures: []map[string]interface{}{ + { + "name": "test_enroll", + "enabled": true, + }, + }, + } + + policy, err := info.KibanaClient.CreatePolicy(ctx, createPolicyReq) + require.NoError(t, err) + + enrollmentToken, err := tools.CreateEnrollmentToken(t, ctx, info.KibanaClient, policy.ID) + require.NoError(t, err) + + fleetServerURL, err := fleettools.DefaultURL(ctx, info.KibanaClient) + require.NoError(t, err) + + installOpts := atesting.InstallOpts{ + NonInteractive: true, + Force: true, + } + + // 2. Install agent without enrolling + t.Log("Installing agent from deb package") + out, err := agentFixture.InstallWithoutEnroll(ctx, &installOpts) + require.NoError(t, err, "failed to install agent, got error: %s", string(out)) + + // 3. Enroll the agent, should succeed without the agent having been started + t.Log("Enrolling agent") + enrollArgs := []string{"elastic-agent", "enroll", "--url", fleetServerURL, "--enrollment-token", enrollmentToken.APIKey, "--force"} + out, err = exec.CommandContext(ctx, "sudo", enrollArgs...).CombinedOutput() + require.NoError(t, err, "failed to enroll agent, got error: %s", string(out)) + + // 4. Start the agent, it should connect to fleet correctly + t.Log("Starting agent") + out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() + require.NoError(t, err, "failed to start elastic-agent, got error: %s", string(out)) + check.ConnectedToFleet(ctx, t, agentFixture, 5*time.Minute) +} + func TestDebFleetUpgrade(t *testing.T) { info := define.Require(t, define.Requirements{ Group: Deb, @@ -154,7 +223,6 @@ func TestDebFleetUpgrade(t *testing.T) { NonInteractive: true, Force: true, } - // 2. Install the Elastic-Agent with the policy that // was just created. policy, err := tools.InstallAgentWithPolicy( diff --git a/testing/integration/linux_rpm_test.go b/testing/integration/linux_rpm_test.go index b76313cd33b..d1424311ed6 100644 --- a/testing/integration/linux_rpm_test.go +++ b/testing/integration/linux_rpm_test.go @@ -98,6 +98,75 @@ func TestRpmLogIngestFleetManaged(t *testing.T) { }) } +func TestRpmEnroll(t *testing.T) { + info := define.Require(t, define.Requirements{ + Group: RPM, + Stack: &define.Stack{}, + OS: []define.OS{ + { + Type: define.Linux, + Distro: "rhel", + }, + }, + Local: false, + Sudo: true, + }) + + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + agentFixture, err := define.NewFixtureFromLocalBuild(t, define.Version(), atesting.WithPackageFormat("rpm")) + require.NoError(t, err) + + // 1. Create a policy in Fleet without any + // To ensure there are no conflicts with previous test runs against + // the same ESS stack, we add the current time at the end of the policy + // name. This policy does not contain any integration. + t.Log("Creating a test policy") + createPolicyReq := kibana.AgentPolicy{ + Name: fmt.Sprintf("test-policy-enroll-%s", uuid.Must(uuid.NewV4()).String()), + Namespace: info.Namespace, + Description: "test policy for agent enrollment", + AgentFeatures: []map[string]interface{}{ + { + "name": "test_enroll", + "enabled": true, + }, + }, + } + + policy, err := info.KibanaClient.CreatePolicy(ctx, createPolicyReq) + require.NoError(t, err) + + enrollmentToken, err := tools.CreateEnrollmentToken(t, ctx, info.KibanaClient, policy.ID) + require.NoError(t, err) + + fleetServerURL, err := fleettools.DefaultURL(ctx, info.KibanaClient) + require.NoError(t, err) + + installOpts := atesting.InstallOpts{ + NonInteractive: true, + Force: true, + } + + // 2. Install agent without enrolling + t.Log("Installing agent from rpm package") + out, err := agentFixture.InstallWithoutEnroll(ctx, &installOpts) + require.NoError(t, err, "failed to install agent, got error: %s", string(out)) + + // 3. Enroll the agent, should succeed without the agent having been started + t.Log("Enrolling agent") + enrollArgs := []string{"elastic-agent", "enroll", "--url", fleetServerURL, "--enrollment-token", enrollmentToken.APIKey, "--force"} + out, err = exec.CommandContext(ctx, "sudo", enrollArgs...).CombinedOutput() + require.NoError(t, err, "failed to enroll agent, got error: %s", string(out)) + + // 4. Start the agent, it should connect to fleet correctly + t.Log("Starting agent") + out, err = exec.CommandContext(ctx, "sudo", "systemctl", "start", "elastic-agent").CombinedOutput() + require.NoError(t, err, "failed to start elastic-agent, got error: %s", string(out)) + check.ConnectedToFleet(ctx, t, agentFixture, 5*time.Minute) +} + func TestRpmFleetUpgrade(t *testing.T) { info := define.Require(t, define.Requirements{ Group: RPM,