Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix filemarker creation process, update error message on uninstall #4172

Merged
merged 40 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
fdf8b28
move install file marker create, rename methods, change error message
fearful-symmetry Jan 31, 2024
e6b77f1
change error message
fearful-symmetry Jan 31, 2024
1e52607
change error message
fearful-symmetry Jan 31, 2024
400bb0d
remove calls to InstallMarkerExists
fearful-symmetry Jan 31, 2024
43bf5f0
fix windows helper
fearful-symmetry Jan 31, 2024
75c93dc
fix windows, again
fearful-symmetry Jan 31, 2024
d7538fe
Revert "remove calls to InstallMarkerExists"
fearful-symmetry Feb 5, 2024
fdb90cc
change install file locaton, revert removal of filepath.Dir
fearful-symmetry Feb 5, 2024
97fdec6
fix wording
fearful-symmetry Feb 6, 2024
297bb1a
Merge remote-tracking branch 'upstream/main' into uninstall-filemarker
fearful-symmetry Feb 6, 2024
10d9218
move IsUpgradeable, remove duplication
fearful-symmetry Feb 7, 2024
a398e25
add tests
fearful-symmetry Feb 7, 2024
7960e16
add mostly useless test
fearful-symmetry Feb 7, 2024
5506e07
linter
fearful-symmetry Feb 7, 2024
bb3416d
tinkering with CI
fearful-symmetry Feb 7, 2024
13bd8f6
skip supervisor test on windows
fearful-symmetry Feb 7, 2024
ba39105
tinkering with the linter
fearful-symmetry Feb 7, 2024
ab8797f
remove experiment
fearful-symmetry Feb 7, 2024
d0048f9
refactor install to make adding tests easier
fearful-symmetry Feb 9, 2024
995a1f3
linter
fearful-symmetry Feb 9, 2024
140752e
add more tests...
fearful-symmetry Feb 9, 2024
088232d
still fixing tests
fearful-symmetry Feb 9, 2024
ee51e43
sonarQube
fearful-symmetry Feb 9, 2024
49b84f8
fix windows tests, fight sonarqube
fearful-symmetry Feb 10, 2024
6d3edba
tinker with file marker create
fearful-symmetry Feb 10, 2024
3f4a7f0
Merge remote-tracking branch 'upstream/main' into uninstall-filemarker
fearful-symmetry Feb 12, 2024
ef4b866
move install path
fearful-symmetry Feb 12, 2024
2911ad4
fix bad merge
fearful-symmetry Feb 12, 2024
59b9d29
still cleaning up merge
fearful-symmetry Feb 12, 2024
62f0c01
add tests
fearful-symmetry Feb 12, 2024
9c20838
add tests, docs
fearful-symmetry Feb 13, 2024
aa4e4c1
fix tests
fearful-symmetry Feb 13, 2024
791ba0e
don't check mode bits
fearful-symmetry Feb 13, 2024
b848e5b
move command, fix permissions
fearful-symmetry Feb 13, 2024
91ee83d
SonarQube...
fearful-symmetry Feb 14, 2024
4cff2f1
refactor dir setup to make Sonarqube happy
fearful-symmetry Feb 14, 2024
c0e82e9
add changelog
fearful-symmetry Feb 14, 2024
28ad7df
Update changelog/fragments/1707951532-change-install-marker-creation.…
fearful-symmetry Feb 15, 2024
d6d0fac
Merge branch 'main' into uninstall-filemarker
fearful-symmetry Feb 20, 2024
e2d5d89
Merge branch 'main' into uninstall-filemarker
cmacknz Feb 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/pkg/agent/application/info/agent_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (i *AgentInfo) ECSMetadata(l *logger.Logger) (*ECSMeta, error) {
BuildOriginal: release.Info().String(),
// only upgradeable if running from Agent installer and running under the
// control of the system supervisor (or built specifically with upgrading enabled)
Upgradeable: release.Upgradeable() || (paths.RunningInstalled() && RunningUnderSupervisor()),
Upgradeable: release.Upgradeable() || (paths.InstallMarkerExists() && RunningUnderSupervisor()),
LogLevel: i.LogLevel(),
},
},
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/agent/application/paths/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ func TopBinaryPath() string {
return filepath.Join(Top(), BinaryName)
}

// RunningInstalled returns true when executing Agent is the installed Agent.
func RunningInstalled() bool {
// InstallMarkerExists returns true if the .installed file marker exists relative to the top path
func InstallMarkerExists() bool {
// Check if install marker created by `elastic-agent install` exists
markerFilePath := filepath.Join(Top(), MarkerFileName)
if _, err := os.Stat(markerFilePath); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/pkg/agent/application/paths/paths_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func AgentVaultPath() string {

func initialControlSocketPath(topPath string) string {
// when installed the control address is fixed
if RunningInstalled() {
if InstallMarkerExists() {
return WindowsControlSocketInstalledPath
}
return ControlSocketFromPath(runtime.GOOS, topPath)
Expand All @@ -57,11 +57,11 @@ func initialControlSocketPath(topPath string) string {
// ResolveControlSocket updates the control socket path.
//
// Called during the upgrade process from pre-8.8 versions. In pre-8.8 versions the
// RunningInstalled will always be false, even when it is an installed version. Once
// InstallMarkerExists will always be false, even when it is an installed version. Once
// that is fixed from the upgrade process the control socket path needs to be updated.
func ResolveControlSocket() {
currentPath := ControlSocket()
if currentPath == ControlSocketFromPath(runtime.GOOS, topPath) && RunningInstalled() {
if currentPath == ControlSocketFromPath(runtime.GOOS, topPath) && InstallMarkerExists() {
// path is not correct being that it's installed
// reset the control socket path to be the installed path
SetControlSocket(WindowsControlSocketInstalledPath)
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/agent/application/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type Upgrader struct {
func IsUpgradeable() bool {
// only upgradeable if running from Agent installer and running under the
// control of the system supervisor (or built specifically with upgrading enabled)
return release.Upgradeable() || (paths.RunningInstalled() && info.RunningUnderSupervisor())
return release.Upgradeable() || (paths.InstallMarkerExists() && info.RunningUnderSupervisor())
}

// NewUpgrader creates an upgrader which is capable of performing upgrade operation
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/agent/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
return
}
oLogs := logp.ObserverLogs().TakeAll()
fmt.Fprintf(os.Stderr, "Error uninstalling. Printing logs\n")
fmt.Fprintf(os.Stderr, "Error installing. Printing logs\n")
for _, oLog := range oLogs {
fmt.Fprintf(os.Stderr, "%v\n", oLog.Entry)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/agent/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func runElasticAgent(ctx context.Context, cancel context.CancelFunc, override cf
// option during installation
//
// Windows `paths.ControlSocketRunSymlink` is `""` so this is always skipped on Windows.
if isRoot && paths.RunningInstalled() && paths.ControlSocketRunSymlink != "" {
if isRoot && paths.InstallMarkerExists() && paths.ControlSocketRunSymlink != "" {
socketPath := strings.TrimPrefix(paths.ControlSocket(), "unix://")
socketLog := controlLog.With("path", socketPath).With("link", paths.ControlSocketRunSymlink)
// ensure it doesn't exist before creating the symlink
Expand Down Expand Up @@ -660,7 +660,7 @@ func ensureInstallMarkerPresent() error {

// Only an installed Elastic Agent can be self-upgraded. So, if the
// installation marker file is already present, we're all set.
if paths.RunningInstalled() {
if paths.InstallMarkerExists() {
return nil
}

Expand Down
5 changes: 3 additions & 2 deletions internal/pkg/agent/cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
if status == install.NotInstalled {
return fmt.Errorf("not installed")
}
if status == install.Installed && !paths.RunningInstalled() {
return fmt.Errorf("can only be uninstalled by executing the installed Elastic Agent at: %s", install.ExecutablePath(paths.Top()))

if status == install.Installed && !paths.InstallMarkerExists() {
return fmt.Errorf("cannot find %s file relative to running elastic agent; agent uninstall should be run from %s, or the install may be corrupt", paths.MarkerFileName, install.ExecutablePath(paths.Top()))
}

force, _ := cmd.Flags().GetBool("force")
Expand Down
11 changes: 6 additions & 5 deletions internal/pkg/agent/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
Sync: true,
NumOfWorkers: int64(copyConcurrency),
})

if err != nil {
pt.Describe("Error copying files")
return utils.FileOwner{}, errors.New(
Expand All @@ -140,6 +141,11 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
}
pt.Describe("Successfully copied files")

// create the install marker
if err := CreateInstallMarker(topPath, ownership); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was expecting this call to be moved before the copy of other files, aren't we going to have the same issue if the copy of files above fails or gets interrupted for whatever reason ?

Copy link
Contributor Author

@fearful-symmetry fearful-symmetry Feb 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the install marker is just there so elastic-agent doesn't complain during an uninstall operation. However, if that initial copy doesn't complete, we might not even have an elastic-agent binary or any files, and anything that is copied can either be removed via rm or just overwritten on the next install. This is a less troublesome failure mode than creating the install marker at the end, where we'd have to remove service files, systemd config, etc, by hand. If the copy operation fails, you can also end up with a directory that is completely empty save for a .installed file, which seems a bit weird.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still happening after the copyFiles call, it should be immediately after the err = os.MkdirAll(filepath.Dir(topPath), 0755) earlier in this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I chose to not put it there, since putting the .installed file before anything has been installed seemed counter-intuitive, and if the copy fails we might not be able to run elastic-agent at all. Unless there's something I'm not factoring in?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't run elastic-agent uninstall unless the .installed marker exists, so if you put it after the copy you can't remove the copied files from disk with the elastic-agent uninstall command.

return utils.FileOwner{}, fmt.Errorf("failed to create install marker: %w", err)
}

// place shell wrapper, if present on platform
if paths.ShellWrapperPath != "" {
pathDir := filepath.Dir(paths.ShellWrapperPath)
Expand Down Expand Up @@ -186,11 +192,6 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
}
}

// create the install marker
if err := CreateInstallMarker(topPath, ownership); err != nil {
return utils.FileOwner{}, fmt.Errorf("failed to create install marker: %w", err)
}

// post install (per platform)
err = postInstall(topPath)
if err != nil {
Expand Down
Loading