From 75f840796b55d0ff22a2d116e45f014c90e42893 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 23:19:13 +1000 Subject: [PATCH] Create installation marker on upgrade from versions < 8.8.0 (#2655) (#2668) * Create installation marker on upgrade from versions < 8.8.0 * Removing debugging lines * Mention re-exec for additional clarity * Adding changelog entry * Removing scratch statement * Re-ordering imports * Error check * Do not depend on parsing pre-upgrade version from upgrade marker file * Clarify comment about only installed Agent being eligible for self-upgrade (cherry picked from commit 9df651411ba2b54e8d05b465f31bda75ebd19e9a) Co-authored-by: Shaunak Kashyap --- .../1683748237-upgrade-install-marker.yaml | 32 ++++++++++++ internal/pkg/agent/application/info/state.go | 9 ++++ internal/pkg/agent/cmd/install.go | 11 +--- internal/pkg/agent/cmd/run.go | 51 ++++++++++++++++--- 4 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 changelog/fragments/1683748237-upgrade-install-marker.yaml diff --git a/changelog/fragments/1683748237-upgrade-install-marker.yaml b/changelog/fragments/1683748237-upgrade-install-marker.yaml new file mode 100644 index 00000000000..a8f6525d100 --- /dev/null +++ b/changelog/fragments/1683748237-upgrade-install-marker.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: bug-fix + +# Change summary; a 80ish characters long description of the change. +summary: Create install marker file during upgrade from versions < 8.8.0 + +# 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; a word indicating the component this changeset affects. +component: 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/2655 + +# 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/2645 diff --git a/internal/pkg/agent/application/info/state.go b/internal/pkg/agent/application/info/state.go index e60e6f19db8..4242be6cb54 100644 --- a/internal/pkg/agent/application/info/state.go +++ b/internal/pkg/agent/application/info/state.go @@ -27,3 +27,12 @@ func RunningInstalled() bool { return true } + +func CreateInstallMarker(topPath string) error { + markerFilePath := filepath.Join(topPath, MarkerFileName) + if _, err := os.Create(markerFilePath); err != nil { + return err + } + + return nil +} diff --git a/internal/pkg/agent/cmd/install.go b/internal/pkg/agent/cmd/install.go index b46c7130283..b75fd958f88 100644 --- a/internal/pkg/agent/cmd/install.go +++ b/internal/pkg/agent/cmd/install.go @@ -219,7 +219,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error { } } - if err := createInstallMarker(topPath); err != nil { + if err := info.CreateInstallMarker(topPath); err != nil { return fmt.Errorf("failed to create install marker: %w", err) } @@ -227,15 +227,6 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error { return nil } -func createInstallMarker(topPath string) error { - markerFilePath := filepath.Join(topPath, info.MarkerFileName) - if _, err := os.Create(markerFilePath); err != nil { - return err - } - - return nil -} - func installPath(basePath string) string { return filepath.Join(basePath, "Elastic", "Agent") } diff --git a/internal/pkg/agent/cmd/run.go b/internal/pkg/agent/cmd/run.go index a09dba66705..bd3f1d61ee7 100644 --- a/internal/pkg/agent/cmd/run.go +++ b/internal/pkg/agent/cmd/run.go @@ -14,19 +14,16 @@ import ( "path/filepath" "syscall" - "github.com/elastic/elastic-agent/pkg/control/v2/server" - - "github.com/elastic/elastic-agent-libs/logp" - "github.com/spf13/cobra" "go.elastic.co/apm" apmtransport "go.elastic.co/apm/transport" "gopkg.in/yaml.v2" - monitoringLib "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/elastic/elastic-agent-libs/api" + "github.com/elastic/elastic-agent-libs/logp" + monitoringLib "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/elastic-agent-libs/service" + "github.com/elastic/elastic-agent-system-metrics/report" "github.com/elastic/elastic-agent/internal/pkg/agent/application" "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" @@ -47,6 +44,7 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/diagnostics" "github.com/elastic/elastic-agent/internal/pkg/release" "github.com/elastic/elastic-agent/pkg/component" + "github.com/elastic/elastic-agent/pkg/control/v2/server" "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/elastic/elastic-agent/version" ) @@ -103,6 +101,10 @@ func run(override cfgOverrider, testingMode bool, modifiers ...component.Platfor service.WaitExecutionDone() }() + if err := handleUpgrade(); err != nil { + return fmt.Errorf("error checking for and handling upgrade: %w", err) + } + locker := filelock.NewAppLocker(paths.Data(), paths.AgentLockFileName) if err := locker.TryLock(); err != nil { return err @@ -557,3 +559,40 @@ func setupMetrics( func isProcessStatsEnabled(cfg *monitoringCfg.MonitoringConfig) bool { return cfg != nil && cfg.HTTP.Enabled } + +// handleUpgrade checks if agent is being run as part of an +// ongoing upgrade operation, i.e. being re-exec'd and performs +// any upgrade-specific work, if needed. +func handleUpgrade() error { + upgradeMarker, err := upgrade.LoadMarker() + if err != nil { + return fmt.Errorf("unable to load upgrade marker to check if Agent is being upgraded: %w", err) + } + + if upgradeMarker == nil { + // We're not being upgraded. Nothing more to do. + return nil + } + + // In v8.8.0, we introduced a new installation marker file to indicate that + // an Agent was running as installed. When an installed Agent that's older + // than v8.8.0 is upgraded, this installation marker file is not present. + // So, in such cases, we need to create it manually post-upgrade. + // Otherwise, the upgrade will be unsuccessful (see + // https://github.com/elastic/elastic-agent/issues/2645). + + // Only an installed Elastic Agent can be self-upgraded. So, if the + // installation marker file is already present, we're all set. + if info.RunningInstalled() { + return nil + } + + // Otherwise, we're being upgraded from a version of an installed Agent + // that didn't use an installation marker file (that is, before v8.8.0). + // So create the file now. + if err := info.CreateInstallMarker(paths.Top()); err != nil { + return fmt.Errorf("unable to create installation marker file during upgrade: %w", err) + } + + return nil +}