Skip to content

Commit 1c65022

Browse files
committed
WIP - add install descriptors
1 parent a25640c commit 1c65022

File tree

5 files changed

+83
-17
lines changed

5 files changed

+83
-17
lines changed

internal/pkg/agent/application/upgrade/upgrade.go

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ var (
6666
ErrNilUpdateMarker = errors.New("loaded a nil update marker")
6767
ErrEmptyRollbackVersion = errors.New("rollback version is empty")
6868
ErrNoRollbacksAvailable = errors.New("no rollbacks available")
69-
69+
ErrAgentInstallNotFound = errors.New("agent install descriptor not found")
7070
// Version_9_2_0_SNAPSHOT is the minimum version for manual rollback and rollback reason
7171
Version_9_2_0_SNAPSHOT = agtversion.NewParsedSemVer(9, 2, 0, "SNAPSHOT", "")
7272
)
@@ -368,8 +368,22 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
368368
return nil, err
369369
}
370370

371+
currentVersionedHome, err := filepath.Rel(paths.Top(), paths.Home())
372+
if err != nil {
373+
return nil, fmt.Errorf("calculating home path relative to top, home: %q top: %q : %w", paths.Home(), paths.Top(), err)
374+
}
375+
371376
//FIXME make it nicer
372-
err = addInstallDesc(version, unpackRes.VersionedHome, unpackRes.Hash, detectedFlavor)
377+
err = addInstallDesc(version, unpackRes.VersionedHome, unpackRes.Hash, detectedFlavor, false)
378+
if err != nil {
379+
err = fmt.Errorf("error encountered when adding install description: %w", err)
380+
381+
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), unpackRes.VersionedHome, currentVersionedHome)
382+
if rollbackErr != nil {
383+
return nil, goerrors.Join(err, rollbackErr)
384+
}
385+
return nil, err
386+
}
373387

374388
newHash := unpackRes.Hash
375389
if newHash == "" {
@@ -403,17 +417,33 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
403417
// paths.BinaryPath properly derives the binary directory depending on the platform. The path to the binary for macOS is inside of the app bundle.
404418
newPath := paths.BinaryPath(filepath.Join(paths.Top(), hashedDir), agentName)
405419

406-
currentVersionedHome, err := filepath.Rel(paths.Top(), paths.Home())
407-
if err != nil {
408-
return nil, fmt.Errorf("calculating home path relative to top, home: %q top: %q : %w", paths.Home(), paths.Top(), err)
409-
}
410-
411420
if err := u.changeSymlink(u.log, paths.Top(), symlinkPath, newPath); err != nil {
412421
u.log.Errorw("Rolling back: changing symlink failed", "error.message", err)
413422
rollbackErr := u.rollbackInstall(ctx, u.log, paths.Top(), hashedDir, currentVersionedHome)
414423
return nil, goerrors.Join(err, rollbackErr)
415424
}
416425

426+
//FIXME make it nicer
427+
err = modifyInstallDesc(func(desc *v1.AgentInstallDesc) error {
428+
if desc.VersionedHome == unpackRes.VersionedHome {
429+
desc.Active = true
430+
return nil
431+
}
432+
433+
desc.Active = false
434+
return nil
435+
})
436+
437+
if err != nil {
438+
err = fmt.Errorf("error encountered when adding install description: %w", err)
439+
440+
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), unpackRes.VersionedHome, currentVersionedHome)
441+
if rollbackErr != nil {
442+
return nil, goerrors.Join(err, rollbackErr)
443+
}
444+
return nil, err
445+
}
446+
417447
// We rotated the symlink successfully: prepare the current and previous agent installation details for the update marker
418448
// In update marker the `current` agent install is the one where the symlink is pointing (the new one we didn't start yet)
419449
// while the `previous` install is the currently executing elastic-agent that is no longer reachable via the symlink.
@@ -475,7 +505,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
475505
return cb, nil
476506
}
477507

478-
func addInstallDesc(version string, home string, hash string, flavor string) error {
508+
func addInstallDesc(version string, home string, hash string, flavor string, active bool) error {
479509
installMarkerFilePath := filepath.Join(paths.Top(), paths.MarkerFileName)
480510
installDescriptor, err := readInstallMarker(installMarkerFilePath)
481511
if err != nil {
@@ -493,6 +523,7 @@ func addInstallDesc(version string, home string, hash string, flavor string) err
493523
Hash: hash,
494524
VersionedHome: home,
495525
Flavor: flavor,
526+
Active: active,
496527
}
497528
installDescriptor.AgentInstalls[0] = newInstall
498529
copied := copy(installDescriptor.AgentInstalls[1:], existingInstalls)
@@ -508,6 +539,36 @@ func addInstallDesc(version string, home string, hash string, flavor string) err
508539
return nil
509540
}
510541

542+
func modifyInstallDesc(modifierFunc func(desc *v1.AgentInstallDesc) error) error {
543+
installMarkerFilePath := filepath.Join(paths.Top(), paths.MarkerFileName)
544+
installDescriptor, err := readInstallMarker(installMarkerFilePath)
545+
if err != nil {
546+
return err
547+
}
548+
549+
if installDescriptor == nil {
550+
return fmt.Errorf("no install descriptor found at %q")
551+
}
552+
553+
for i := range installDescriptor.AgentInstalls {
554+
err = modifierFunc(&installDescriptor.AgentInstalls[i])
555+
if err != nil {
556+
return fmt.Errorf("modifying agent install %s: %w", installDescriptor.AgentInstalls[i].VersionedHome, err)
557+
}
558+
}
559+
560+
err = writeInstallMarker(installMarkerFilePath, installDescriptor)
561+
if err != nil {
562+
return fmt.Errorf("writing updated install marker: %w", err)
563+
}
564+
565+
return nil
566+
}
567+
568+
func removeAgentInstallDesc(versionedHome string) error {
569+
570+
}
571+
511572
func writeInstallMarker(markerFilePath string, descriptor *v1.InstallDescriptor) error {
512573
installMarkerFile, err := os.Create(markerFilePath)
513574
if err != nil {
@@ -740,6 +801,10 @@ func rollbackInstall(ctx context.Context, log *logger.Logger, topDirPath, versio
740801
if err != nil && !errors.Is(err, fs.ErrNotExist) {
741802
return fmt.Errorf("rolling back install: removing new agent install at %q failed: %w", newAgentInstallPath, err)
742803
}
804+
err = removeAgentInstallDesc(versionedHome)
805+
if err != nil && !errors.Is(err, ErrAgentInstallNotFound) {
806+
return fmt.Errorf("rolling back install: removing agent install descriptor at %q failed: %w", versionedHome, err)
807+
}
743808
return nil
744809
}
745810

internal/pkg/agent/cmd/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ func ensureInstallMarkerPresent() error {
723723
if err != nil {
724724
return fmt.Errorf("failed to get current file owner: %w", err)
725725
}
726-
if err := install.CreateInstallMarker(paths.Top(), ownership, paths.Home(), version.GetAgentPackageVersion()); err != nil {
726+
if err := install.CreateInstallMarker(paths.Top(), ownership, paths.Home(), version.GetAgentPackageVersion(), ""); err != nil {
727727
return fmt.Errorf("unable to create installation marker file during upgrade: %w", err)
728728
}
729729

internal/pkg/agent/install/install.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
7373

7474
targetVersionedHome := filepath.FromSlash(pathMapper.Map(manifest.Package.VersionedHome))
7575

76-
err = setupInstallPath(topPath, ownership, targetVersionedHome, manifest.Package.Version)
76+
err = setupInstallPath(topPath, ownership, targetVersionedHome, manifest.Package.Version, flavor)
7777
if err != nil {
7878
return utils.FileOwner{}, fmt.Errorf("error setting up install path: %w", err)
7979
}
@@ -189,7 +189,7 @@ func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *p
189189
}
190190

191191
// setup the basic topPath, and the .installed file
192-
func setupInstallPath(topPath string, ownership utils.FileOwner, versionedHome string, version string) error {
192+
func setupInstallPath(topPath string, ownership utils.FileOwner, versionedHome string, version string, flavor string) error {
193193
// ensure parent directory exists
194194
err := os.MkdirAll(filepath.Dir(topPath), 0755)
195195
if err != nil {
@@ -203,7 +203,7 @@ func setupInstallPath(topPath string, ownership utils.FileOwner, versionedHome s
203203
}
204204

205205
// create the install marker
206-
if err := CreateInstallMarker(topPath, ownership, versionedHome, version); err != nil {
206+
if err := CreateInstallMarker(topPath, ownership, versionedHome, version, flavor); err != nil {
207207
return fmt.Errorf("failed to create install marker: %w", err)
208208
}
209209
return nil
@@ -521,16 +521,16 @@ func hasAllSSDs(block ghw.BlockInfo) bool {
521521

522522
// CreateInstallMarker creates a `.installed` file at the given install path,
523523
// and then calls fixInstallMarkerPermissions to set the ownership provided by `ownership`
524-
func CreateInstallMarker(topPath string, ownership utils.FileOwner, home string, version string) error {
524+
func CreateInstallMarker(topPath string, ownership utils.FileOwner, home string, version string, flavor string) error {
525525
markerFilePath := filepath.Join(topPath, paths.MarkerFileName)
526-
err := createInstallMarkerFile(markerFilePath, version, home)
526+
err := createInstallMarkerFile(markerFilePath, version, home, flavor)
527527
if err != nil {
528528
return fmt.Errorf("creating install marker: %w", err)
529529
}
530530
return fixInstallMarkerPermissions(markerFilePath, ownership)
531531
}
532532

533-
func createInstallMarkerFile(markerFilePath string, version string, home string) error {
533+
func createInstallMarkerFile(markerFilePath string, version string, home string, flavor string) error {
534534
handle, err := os.Create(markerFilePath)
535535
if err != nil {
536536
return fmt.Errorf("creating destination file %q : %w", markerFilePath, err)
@@ -539,7 +539,7 @@ func createInstallMarkerFile(markerFilePath string, version string, home string)
539539
_ = handle.Close()
540540
}()
541541
installDescriptor := v1.NewInstallDescriptor()
542-
installDescriptor.AgentInstalls = []v1.AgentInstallDesc{{Version: version, VersionedHome: home}}
542+
installDescriptor.AgentInstalls = []v1.AgentInstallDesc{{Version: version, VersionedHome: home, Flavor: flavor, Active: true}}
543543
err = yaml.NewEncoder(handle).Encode(installDescriptor)
544544
if err != nil {
545545
return fmt.Errorf("writing install descriptor: %w", err)

internal/pkg/agent/install/install_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func TestSetupInstallPath(t *testing.T) {
224224
tmpdir := t.TempDir()
225225
ownership, err := utils.CurrentFileOwner()
226226
require.NoError(t, err)
227-
err = setupInstallPath(tmpdir, ownership, "data/elastic-agent-1.2.3-SNAPSHOT", "1.2.3-SNAPSHOT")
227+
err = setupInstallPath(tmpdir, ownership, "data/elastic-agent-1.2.3-SNAPSHOT", "1.2.3-SNAPSHOT", "")
228228
require.NoError(t, err)
229229
markerFilePath := filepath.Join(tmpdir, paths.MarkerFileName)
230230
require.FileExists(t, markerFilePath)

pkg/api/v1/install.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type AgentInstallDesc struct {
2525
Hash string `yaml:"hash,omitempty" json:"hash,omitempty"`
2626
VersionedHome string `yaml:"versionedHome,omitempty" json:"versionedHome,omitempty"`
2727
Flavor string `yaml:"flavor,omitempty" json:"flavor,omitempty"`
28+
Active bool `yaml:"active,omitempty" json:"active,omitempty"`
2829
}
2930

3031
type InstallDescriptor struct {

0 commit comments

Comments
 (0)