-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Work on privileged/unprivileged command. * Add integration tests for switching between unprivileged and privileged mode. * Fix upstream rename. * Add changelog. * Switch to new install privileged/unprivileged checks. * Adjust FixPermissions to take ownership back to Administrators. * Code review feedback. * Fix service component check. Support switching on macOS. * Fix lint. * Update to constant. * Add tests for unprivileged switch failure with endpoint installed. * Fix runtime check to keep runtime spec. * Fix test contains. * Only run test on linux. * Linux only, more.
- Loading branch information
1 parent
c45842a
commit 4f0d26b
Showing
26 changed files
with
1,179 additions
and
225 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
changelog/fragments/1715266075-Add-unprivileged-and-privileged-switch-commands.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# 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: Add unprivileged and privileged switch commands | ||
|
||
# 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: | | ||
Adds ability to switch between privileged and unprivileged mode using the privileged and unprivileged | ||
subcommands respectively. | ||
# 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/4621 | ||
|
||
# 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/ingest-dev/issues/2790 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// 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 cmd | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" | ||
"github.com/elastic/elastic-agent/internal/pkg/agent/install" | ||
"github.com/elastic/elastic-agent/internal/pkg/cli" | ||
"github.com/elastic/elastic-agent/pkg/control/v2/client/wait" | ||
"github.com/elastic/elastic-agent/pkg/utils" | ||
) | ||
|
||
func newPrivilegedCommandWithArgs(s []string, streams *cli.IOStreams) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "privileged", | ||
Short: "Switch installed Elastic Agent to run as privileged", | ||
Long: `This command converts the installed Elastic Agent from running unprivileged to running as privileged. | ||
By default this command will ask or a confirmation before making this change. You can bypass the confirmation request | ||
using the -f flag. This is not a zero downtime operation and will always stop the running Elastic Agent (if running). | ||
It is possible that loss of metrics, logs, or data could occur during this window of time. The Elastic Agent | ||
daemon will always be started (even if it was off to start). In the case that the Elastic Agent is already running | ||
privileged it will still perform all the same work, including stopping and starting the Elastic Agent. | ||
`, | ||
Args: cobra.ExactArgs(0), | ||
Run: func(c *cobra.Command, args []string) { | ||
if err := privilegedCmd(streams, c); err != nil { | ||
fmt.Fprintf(streams.Err, "Error: %v\n%s\n", err, troubleshootMessage()) | ||
os.Exit(1) | ||
} | ||
}, | ||
} | ||
|
||
cmd.Flags().BoolP("force", "f", false, "Do not prompt for confirmation") | ||
cmd.Flags().DurationP("daemon-timeout", "", 0, "Timeout waiting for Elastic Agent daemon restart after the change is applied (-1 = no wait)") | ||
|
||
return cmd | ||
} | ||
|
||
func privilegedCmd(streams *cli.IOStreams, cmd *cobra.Command) (err error) { | ||
isAdmin, err := utils.HasRoot() | ||
if err != nil { | ||
return fmt.Errorf("unable to perform privileged command while checking for root/Administrator rights: %w", err) | ||
} | ||
if !isAdmin { | ||
return fmt.Errorf("unable to perform privileged command, not executed with %s permissions", utils.PermissionUser) | ||
} | ||
|
||
topPath := paths.Top() | ||
daemonTimeout, _ := cmd.Flags().GetDuration("daemon-timeout") | ||
force, _ := cmd.Flags().GetBool("force") | ||
if !force { | ||
confirm, err := cli.Confirm("This will restart the running Elastic Agent and convert it to run in privileged mode. Do you want to continue?", true) | ||
if err != nil { | ||
return fmt.Errorf("problem reading prompt response") | ||
} | ||
if !confirm { | ||
return fmt.Errorf("unprivileged switch was cancelled by the user") | ||
} | ||
} | ||
|
||
pt := install.CreateAndStartNewSpinner(streams.Out, "Converting Elastic Agent to privileged...") | ||
err = install.SwitchExecutingMode(topPath, pt, "", "") | ||
if err != nil { | ||
// error already adds context | ||
return err | ||
} | ||
|
||
// wait for the service | ||
if daemonTimeout >= 0 { | ||
pt.Describe("Waiting for running service") | ||
ctx := handleSignal(context.Background()) // allowed to be cancelled | ||
err = wait.ForAgent(ctx, daemonTimeout) | ||
if err != nil { | ||
if errors.Is(err, context.Canceled) { | ||
pt.Describe("Cancelled waiting for running service") | ||
return nil | ||
} | ||
pt.Describe("Failed waiting for running service") | ||
return err | ||
} | ||
pt.Describe("Service is up and running") | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.