Skip to content

Commit 65e2c30

Browse files
Fix filemarker creation process, update error message on uninstall (#4172)
* move install file marker create, rename methods, change error message * change error message * change error message * remove calls to InstallMarkerExists * fix windows helper * fix windows, again * Revert "remove calls to InstallMarkerExists" This reverts commit 400bb0d. * change install file locaton, revert removal of filepath.Dir * fix wording * move IsUpgradeable, remove duplication * add tests * add mostly useless test * linter * tinkering with CI * skip supervisor test on windows * tinkering with the linter * remove experiment * refactor install to make adding tests easier * linter * add more tests... * still fixing tests * sonarQube * fix windows tests, fight sonarqube * tinker with file marker create * move install path * fix bad merge * still cleaning up merge * add tests * add tests, docs * fix tests * don't check mode bits * move command, fix permissions * SonarQube... * refactor dir setup to make Sonarqube happy * add changelog * Update changelog/fragments/1707951532-change-install-marker-creation.yaml Co-authored-by: Craig MacKenzie <craig.mackenzie@elastic.co> --------- Co-authored-by: Craig MacKenzie <craig.mackenzie@elastic.co>
1 parent ed1c28c commit 65e2c30

File tree

3 files changed

+69
-12
lines changed

3 files changed

+69
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: feature
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: change-install-marker-creation
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
description: Create the .installed marker earlier on in the install process, allowing the use of `elastic-agent uninstall` to cleanup if the install fails.
20+
21+
# Affected component; a word indicating the component this changeset affects.
22+
component: install
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: https://github.com/elastic/elastic-agent/pull/4172
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
issue: https://github.com/elastic/elastic-agent/issues/4051

internal/pkg/agent/install/install.go

+28-12
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,9 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
102102
}
103103
}
104104

105-
// ensure parent directory exists
106-
err = os.MkdirAll(filepath.Dir(topPath), 0755)
105+
err = setupInstallPath(topPath, ownership)
107106
if err != nil {
108-
return utils.FileOwner{}, errors.New(
109-
err,
110-
fmt.Sprintf("failed to create installation parent directory (%s)", filepath.Dir(topPath)),
111-
errors.M("directory", filepath.Dir(topPath)))
107+
return utils.FileOwner{}, fmt.Errorf("error setting up install path: %w", err)
112108
}
113109

114110
manifest, err := readPackageManifest(dir)
@@ -173,11 +169,6 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
173169
}
174170
}
175171

176-
// create the install marker
177-
if err := CreateInstallMarker(topPath, ownership); err != nil {
178-
return utils.FileOwner{}, fmt.Errorf("failed to create install marker: %w", err)
179-
}
180-
181172
// post install (per platform)
182173
err = postInstall(topPath)
183174
if err != nil {
@@ -216,6 +207,27 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
216207
return ownership, nil
217208
}
218209

210+
// setup the basic topPath, and the .installed file
211+
func setupInstallPath(topPath string, ownership utils.FileOwner) error {
212+
// ensure parent directory exists
213+
err := os.MkdirAll(filepath.Dir(topPath), 0755)
214+
if err != nil {
215+
return errors.New(err, fmt.Sprintf("failed to create installation parent directory (%s)", filepath.Dir(topPath)), errors.M("directory", filepath.Dir(topPath)))
216+
}
217+
218+
// create Agent/ directory with more locked-down permissions
219+
err = os.MkdirAll(topPath, 0750)
220+
if err != nil {
221+
return errors.New(err, fmt.Sprintf("failed to create top path (%s)", topPath), errors.M("directory", topPath))
222+
}
223+
224+
// create the install marker
225+
if err := CreateInstallMarker(topPath, ownership); err != nil {
226+
return fmt.Errorf("failed to create install marker: %w", err)
227+
}
228+
return nil
229+
}
230+
219231
func readPackageManifest(extractedPackageDir string) (*v1.PackageManifest, error) {
220232
manifestFilePath := filepath.Join(extractedPackageDir, v1.ManifestFileName)
221233
manifestFile, err := os.Open(manifestFilePath)
@@ -473,10 +485,14 @@ func hasAllSSDs(block ghw.BlockInfo) bool {
473485
return true
474486
}
475487

488+
// CreateInstallMarker creates a `.installed` file at the given install path,
489+
// and then calls fixInstallMarkerPermissions to set the ownership provided by `ownership`
476490
func CreateInstallMarker(topPath string, ownership utils.FileOwner) error {
477491
markerFilePath := filepath.Join(topPath, paths.MarkerFileName)
478-
if _, err := os.Create(markerFilePath); err != nil {
492+
handle, err := os.Create(markerFilePath)
493+
if err != nil {
479494
return err
480495
}
496+
_ = handle.Close()
481497
return fixInstallMarkerPermissions(markerFilePath, ownership)
482498
}

internal/pkg/agent/install/install_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import (
1414
"github.com/stretchr/testify/assert"
1515
"github.com/stretchr/testify/require"
1616

17+
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
1718
"github.com/elastic/elastic-agent/internal/pkg/cli"
1819
v1 "github.com/elastic/elastic-agent/pkg/api/v1"
20+
"github.com/elastic/elastic-agent/pkg/utils"
1921
)
2022

2123
func TestHasAllSSDs(t *testing.T) {
@@ -185,3 +187,10 @@ func TestCopyFiles(t *testing.T) {
185187
}
186188

187189
}
190+
191+
func TestSetupInstallPath(t *testing.T) {
192+
tmpdir := t.TempDir()
193+
err := setupInstallPath(tmpdir, utils.CurrentFileOwner())
194+
require.NoError(t, err)
195+
require.FileExists(t, filepath.Join(tmpdir, paths.MarkerFileName))
196+
}

0 commit comments

Comments
 (0)