@@ -91,7 +91,7 @@ type unpackHandler interface {
9191type copyActionStoreFunc func (log * logger.Logger , newHome string ) error
9292type copyRunDirectoryFunc func (log * logger.Logger , oldRunPath , newRunPath string ) error
9393type fileDirCopyFunc func (from , to string , opts ... filecopy.Options ) error
94- type markUpgradeFunc func (log * logger.Logger , dataDirPath string , updatedOn time.Time , agent , previousAgent agentInstall , action * fleetapi.ActionUpgrade , upgradeDetails * details.Details , rollbackWindow time. Duration ) error
94+ type markUpgradeFunc func (log * logger.Logger , dataDirPath string , updatedOn time.Time , agent , previousAgent agentInstall , action * fleetapi.ActionUpgrade , upgradeDetails * details.Details , availableRollbacks []v1. AgentInstallDesc ) error
9595type changeSymlinkFunc func (log * logger.Logger , topDirPath , symlinkPath , newTarget string ) error
9696type rollbackInstallFunc func (ctx context.Context , log * logger.Logger , topDirPath , versionedHome , oldVersionedHome string , ids installDescriptorSource ) error
9797
@@ -414,7 +414,6 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
414414 return nil , fmt .Errorf ("calculating home path relative to top, home: %q top: %q : %w" , paths .Home (), paths .Top (), err )
415415 }
416416
417- //FIXME make it nicer
418417 _ , err = u .installDescriptorSource .AddInstallDesc (
419418 v1.AgentInstallDesc {Version : version , VersionedHome : unpackRes .VersionedHome , Hash : unpackRes .Hash , Flavor : detectedFlavor , Active : false },
420419 )
@@ -465,13 +464,9 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
465464 rollbackWindow = u .upgradeSettings .Rollback .Window
466465 }
467466
468- var currentInstallTTL * time.Time = nil
469- if rollbackWindow > 0 {
470- currentInstallTTLVar := time .Now ().Add (rollbackWindow )
471- currentInstallTTL = & currentInstallTTLVar
472- }
473-
474- _ , err = u .installDescriptorSource .ModifyInstallDesc (
467+ // timestamp marking the moment the links have been rotated. It will be used for TTL calculations of pre-existing elastic-agent installs
468+ rotationTimestamp := time .Now ()
469+ modifiedInstallDescriptor , err := u .installDescriptorSource .ModifyInstallDesc (
475470 func (desc * v1.AgentInstallDesc ) error {
476471 if desc .VersionedHome == unpackRes .VersionedHome {
477472 desc .Active = true
@@ -480,16 +475,17 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
480475 desc .Active = false
481476 }
482477
478+ // set the TTL only for the current install
483479 if desc .VersionedHome == currentVersionedHome {
484- desc .TTL = currentInstallTTL
480+ desc .TTL = getCurrentInstallTTL ( rollbackWindow , rotationTimestamp )
485481 }
486482
487483 return nil
488484 },
489485 )
490486
491487 if err != nil {
492- err = fmt .Errorf ("error encountered when adding install description: %w" , err )
488+ err = fmt .Errorf ("error encountered when setting new install description as active : %w" , err )
493489
494490 rollbackErr := rollbackInstall (ctx , u .log , paths .Top (), unpackRes .VersionedHome , currentVersionedHome , u .installDescriptorSource )
495491 if rollbackErr != nil {
@@ -517,12 +513,14 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
517513 versionedHome : currentVersionedHome ,
518514 }
519515
516+ availableRollbacks := getAvailableRollbacks (rollbackWindow , rotationTimestamp , unpackRes .VersionedHome , modifiedInstallDescriptor )
517+
520518 if err := u .markUpgrade (u .log ,
521519 paths .Data (), // data dir to place the marker in
522520 time .Now (),
523521 current , // new agent version data
524522 previous , // old agent version data
525- action , det , rollbackWindow ); err != nil {
523+ action , det , availableRollbacks ); err != nil {
526524 u .log .Errorw ("Rolling back: marking upgrade failed" , "error.message" , err )
527525 rollbackErr := u .rollbackInstall (ctx , u .log , paths .Top (), hashedDir , currentVersionedHome , u .installDescriptorSource )
528526 return nil , goerrors .Join (err , rollbackErr )
@@ -556,6 +554,32 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
556554 return cb , nil
557555}
558556
557+ func getAvailableRollbacks (rollbackWindow time.Duration , now time.Time , newVersionedHome string , descriptor * v1.InstallDescriptor ) []v1.AgentInstallDesc {
558+ if rollbackWindow == 0 {
559+ // if there's no rollback window it means that no rollback should survive the watcher cleanup at the end of the grace period.
560+ return nil
561+ }
562+
563+ res := make ([]v1.AgentInstallDesc , 0 , len (descriptor .AgentInstalls ))
564+ for _ , installDesc := range descriptor .AgentInstalls {
565+ if installDesc .VersionedHome != newVersionedHome && (installDesc .TTL == nil || now .Before (* installDesc .TTL )) {
566+ // this is a valid possible rollback target, so we have to keep it available beyond the end of the grace period
567+ res = append (res , installDesc )
568+ }
569+ }
570+ return res
571+ }
572+
573+ func getCurrentInstallTTL (rollbackWindow time.Duration , now time.Time ) * time.Time {
574+ if rollbackWindow == 0 {
575+ // no rollback window, no TTL
576+ return nil
577+ }
578+
579+ currentInstallTTLVar := now .Add (rollbackWindow )
580+ return & currentInstallTTLVar
581+ }
582+
559583func (u * Upgrader ) rollbackToPreviousVersion (ctx context.Context , topDir string , now time.Time , version string , action * fleetapi.ActionUpgrade ) (reexec.ShutdownCallbackFn , error ) {
560584 if version == "" {
561585 return nil , ErrEmptyRollbackVersion
0 commit comments