Skip to content

Commit 33afefd

Browse files
committed
WIP - add install descriptors
1 parent 70f1fb7 commit 33afefd

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
)
@@ -359,8 +359,22 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
359359
return nil, err
360360
}
361361

362+
currentVersionedHome, err := filepath.Rel(paths.Top(), paths.Home())
363+
if err != nil {
364+
return nil, fmt.Errorf("calculating home path relative to top, home: %q top: %q : %w", paths.Home(), paths.Top(), err)
365+
}
366+
362367
//FIXME make it nicer
363-
err = addInstallDesc(version, unpackRes.VersionedHome, unpackRes.Hash, detectedFlavor)
368+
err = addInstallDesc(version, unpackRes.VersionedHome, unpackRes.Hash, detectedFlavor, false)
369+
if err != nil {
370+
err = fmt.Errorf("error encountered when adding install description: %w", err)
371+
372+
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), unpackRes.VersionedHome, currentVersionedHome)
373+
if rollbackErr != nil {
374+
return nil, goerrors.Join(err, rollbackErr)
375+
}
376+
return nil, err
377+
}
364378

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

397-
currentVersionedHome, err := filepath.Rel(paths.Top(), paths.Home())
398-
if err != nil {
399-
return nil, fmt.Errorf("calculating home path relative to top, home: %q top: %q : %w", paths.Home(), paths.Top(), err)
400-
}
401-
402411
if err := changeSymlink(u.log, paths.Top(), symlinkPath, newPath); err != nil {
403412
u.log.Errorw("Rolling back: changing symlink failed", "error.message", err)
404413
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), hashedDir, currentVersionedHome)
405414
return nil, goerrors.Join(err, rollbackErr)
406415
}
407416

417+
//FIXME make it nicer
418+
err = modifyInstallDesc(func(desc *v1.AgentInstallDesc) error {
419+
if desc.VersionedHome == unpackRes.VersionedHome {
420+
desc.Active = true
421+
return nil
422+
}
423+
424+
desc.Active = false
425+
return nil
426+
})
427+
428+
if err != nil {
429+
err = fmt.Errorf("error encountered when adding install description: %w", err)
430+
431+
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), unpackRes.VersionedHome, currentVersionedHome)
432+
if rollbackErr != nil {
433+
return nil, goerrors.Join(err, rollbackErr)
434+
}
435+
return nil, err
436+
}
437+
408438
// We rotated the symlink successfully: prepare the current and previous agent installation details for the update marker
409439
// In update marker the `current` agent install is the one where the symlink is pointing (the new one we didn't start yet)
410440
// while the `previous` install is the currently executing elastic-agent that is no longer reachable via the symlink.
@@ -461,7 +491,7 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
461491
return cb, nil
462492
}
463493

464-
func addInstallDesc(version string, home string, hash string, flavor string) error {
494+
func addInstallDesc(version string, home string, hash string, flavor string, active bool) error {
465495
installMarkerFilePath := filepath.Join(paths.Top(), paths.MarkerFileName)
466496
installDescriptor, err := readInstallMarker(installMarkerFilePath)
467497
if err != nil {
@@ -479,6 +509,7 @@ func addInstallDesc(version string, home string, hash string, flavor string) err
479509
Hash: hash,
480510
VersionedHome: home,
481511
Flavor: flavor,
512+
Active: active,
482513
}
483514
installDescriptor.AgentInstalls[0] = newInstall
484515
copied := copy(installDescriptor.AgentInstalls[1:], existingInstalls)
@@ -494,6 +525,36 @@ func addInstallDesc(version string, home string, hash string, flavor string) err
494525
return nil
495526
}
496527

528+
func modifyInstallDesc(modifierFunc func(desc *v1.AgentInstallDesc) error) error {
529+
installMarkerFilePath := filepath.Join(paths.Top(), paths.MarkerFileName)
530+
installDescriptor, err := readInstallMarker(installMarkerFilePath)
531+
if err != nil {
532+
return err
533+
}
534+
535+
if installDescriptor == nil {
536+
return fmt.Errorf("no install descriptor found at %q")
537+
}
538+
539+
for i := range installDescriptor.AgentInstalls {
540+
err = modifierFunc(&installDescriptor.AgentInstalls[i])
541+
if err != nil {
542+
return fmt.Errorf("modifying agent install %s: %w", installDescriptor.AgentInstalls[i].VersionedHome, err)
543+
}
544+
}
545+
546+
err = writeInstallMarker(installMarkerFilePath, installDescriptor)
547+
if err != nil {
548+
return fmt.Errorf("writing updated install marker: %w", err)
549+
}
550+
551+
return nil
552+
}
553+
554+
func removeAgentInstallDesc(versionedHome string) error {
555+
556+
}
557+
497558
func writeInstallMarker(markerFilePath string, descriptor *v1.InstallDescriptor) error {
498559
installMarkerFile, err := os.Create(markerFilePath)
499560
if err != nil {
@@ -726,6 +787,10 @@ func rollbackInstall(ctx context.Context, log *logger.Logger, topDirPath, versio
726787
if err != nil && !errors.Is(err, fs.ErrNotExist) {
727788
return fmt.Errorf("rolling back install: removing new agent install at %q failed: %w", newAgentInstallPath, err)
728789
}
790+
err = removeAgentInstallDesc(versionedHome)
791+
if err != nil && !errors.Is(err, ErrAgentInstallNotFound) {
792+
return fmt.Errorf("rolling back install: removing agent install descriptor at %q failed: %w", versionedHome, err)
793+
}
729794
return nil
730795
}
731796

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)