Skip to content

Commit b3adaa7

Browse files
committed
Implement manual rollback from list of agent installs
1 parent 7c4b247 commit b3adaa7

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

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

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ import (
99
"errors"
1010
"fmt"
1111
"os"
12+
"path/filepath"
1213
"time"
1314

1415
"github.com/elastic/elastic-agent/internal/pkg/agent/application/filelock"
1516
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
1617
"github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec"
18+
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details"
1719
"github.com/elastic/elastic-agent/internal/pkg/fleetapi"
20+
"github.com/elastic/elastic-agent/internal/pkg/release"
1821
v1 "github.com/elastic/elastic-agent/pkg/api/v1"
1922
"github.com/elastic/elastic-agent/pkg/core/logger"
2023
"github.com/elastic/elastic-agent/pkg/version"
24+
agtversion "github.com/elastic/elastic-agent/version"
2125
)
2226

2327
func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string, now time.Time, version string, action *fleetapi.ActionUpgrade) (reexec.ShutdownCallbackFn, error) {
@@ -37,7 +41,7 @@ func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string,
3741

3842
if errors.Is(err, os.ErrNotExist) {
3943
// there is no upgrade marker, we need to extract available rollbacks from agent installs
40-
watcherExecutable, versionedHomeToRollbackTo, err = rollbackUsingAgentInstalls()
44+
watcherExecutable, versionedHomeToRollbackTo, err = rollbackUsingAgentInstalls(ctx, u.log, u.watcherHelper, u.installDescriptorSource, topDir, now, version, u.markUpgrade)
4145
} else {
4246
watcherExecutable, versionedHomeToRollbackTo, err = rollbackUsingUpgradeMarker(ctx, u.log, u.watcherHelper, topDir, now, version)
4347
}
@@ -56,10 +60,69 @@ func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string,
5660
return nil, nil
5761
}
5862

59-
func rollbackUsingAgentInstalls() (string, string, error) {
63+
func rollbackUsingAgentInstalls(ctx context.Context, log *logger.Logger, watcherHelper WatcherHelper, source installDescriptorSource, topDir string, now time.Time, rollbackVersion string, markUpgrade markUpgradeFunc) (string, string, error) {
6064
//FIXME implement
6165
//panic("Not implemented")
62-
return "", "", errors.Join(errors.New("not implemented"), os.ErrNotExist)
66+
//return "", "", errors.Join(errors.New("not implemented"), os.ErrNotExist)
67+
68+
// read the available installs
69+
installDescriptor, err := source.GetInstallDesc()
70+
if err != nil {
71+
return "", "", fmt.Errorf("retrieving agent installs: %w", err)
72+
}
73+
// check for the version we want to rollback to
74+
found := false
75+
var targetInstall v1.AgentInstallDesc
76+
for _, i := range installDescriptor.AgentInstalls {
77+
if i.TTL == nil {
78+
// valid rollbacks should have a TTL associated
79+
continue
80+
}
81+
if i.Version == rollbackVersion && now.Before(*i.TTL) {
82+
// found a valid target
83+
found = true
84+
targetInstall = i
85+
break
86+
}
87+
}
88+
89+
if !found {
90+
return "", "", fmt.Errorf("version %q not listed among the available rollbacks: %w", rollbackVersion, ErrNoRollbacksAvailable)
91+
}
92+
93+
prevAgentParsedVersion, err := version.ParseVersion(targetInstall.Version)
94+
if err != nil {
95+
return "", "", fmt.Errorf("parsing version of target install %+v: %w", targetInstall, err)
96+
}
97+
98+
// write out a fake upgrade marker to make the upgrade details state happy
99+
relCurVersionedHome, err := filepath.Rel(paths.Top(), paths.Home())
100+
if err != nil {
101+
return "", "", fmt.Errorf("getting current install home path %q relative to top %q: %w", paths.Home(), paths.Top(), err)
102+
}
103+
curAgentInstall := agentInstall{
104+
parsedVersion: agtversion.GetParsedAgentPackageVersion(),
105+
version: release.VersionWithSnapshot(),
106+
hash: release.Commit(),
107+
versionedHome: relCurVersionedHome,
108+
}
109+
110+
prevAgentInstall := agentInstall{
111+
parsedVersion: prevAgentParsedVersion,
112+
version: targetInstall.Version,
113+
hash: targetInstall.Hash,
114+
versionedHome: targetInstall.VersionedHome,
115+
}
116+
117+
upgradeDetails := details.NewDetails(release.VersionWithSnapshot(), details.StateRequested, "" /*action.ID*/)
118+
err = markUpgrade(log, paths.DataFrom(topDir), now, curAgentInstall, prevAgentInstall, nil /*action*/, upgradeDetails, nil)
119+
if err != nil {
120+
return "", "", fmt.Errorf("creating upgrade marker: %w", err)
121+
}
122+
123+
// return watcher executable and versionedHome to rollback to
124+
watcherExecutable := watcherHelper.SelectWatcherExecutable(topDir, prevAgentInstall, curAgentInstall)
125+
return watcherExecutable, targetInstall.VersionedHome, nil
63126
}
64127

65128
func rollbackUsingUpgradeMarker(ctx context.Context, log *logger.Logger, watcherHelper WatcherHelper, topDir string, now time.Time, version string) (string, string, error) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ type installDescriptorSource interface {
121121
AddInstallDesc(desc v1.AgentInstallDesc) (*v1.InstallDescriptor, error)
122122
ModifyInstallDesc(modifierFunc func(desc *v1.AgentInstallDesc) error) (*v1.InstallDescriptor, error)
123123
RemoveAgentInstallDesc(versionedHome string) (*v1.InstallDescriptor, error)
124+
GetInstallDesc() (*v1.InstallDescriptor, error)
124125
}
125126

126127
// Upgrader performs an upgrade

pkg/utils/install/file_source.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ func NewFileDescriptorSource(descriptorFile string) *FileDescriptorSource {
2222
return &FileDescriptorSource{descriptorFile: descriptorFile}
2323
}
2424

25+
func (dp *FileDescriptorSource) GetInstallDesc() (*v1.InstallDescriptor, error) {
26+
return readInstallMarkerFile(dp.descriptorFile)
27+
}
28+
2529
func (dp *FileDescriptorSource) AddInstallDesc(desc v1.AgentInstallDesc) (*v1.InstallDescriptor, error) {
2630
installDescriptor, err := readInstallMarkerFile(dp.descriptorFile)
2731
// not existing or empty files are tolerated, since we would be writing a new descriptor, return any other error

0 commit comments

Comments
 (0)