Skip to content

Commit f6d02d3

Browse files
committed
WIP - add rollbacks available to upgrade marker
1 parent 3f2d8b4 commit f6d02d3

File tree

8 files changed

+56
-35
lines changed

8 files changed

+56
-35
lines changed

internal/pkg/agent/application/application.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func New(
120120

121121
// monitoring is not supported in bootstrap mode https://github.com/elastic/elastic-agent/issues/1761
122122
isMonitoringSupported := !disableMonitoring && cfg.Settings.V1MonitoringEnabled
123-
upgrader, err := upgrade.NewUpgrader(log, cfg.Settings.DownloadConfig, agentInfo)
123+
upgrader, err := upgrade.NewUpgrader(log, cfg.Settings.DownloadConfig, cfg.Settings.Upgrade, agentInfo)
124124
if err != nil {
125125
return nil, nil, nil, fmt.Errorf("failed to create upgrader: %w", err)
126126
}

internal/pkg/agent/application/coordinator/coordinator_unit_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,7 @@ func TestCoordinatorReportsInvalidPolicy(t *testing.T) {
459459
}
460460
}()
461461

462-
upgradeMgr, err := upgrade.NewUpgrader(
463-
log,
464-
&artifact.Config{},
465-
&info.AgentInfo{},
466-
)
462+
upgradeMgr, err := upgrade.NewUpgrader(log, &artifact.Config{}, nil, &info.AgentInfo{})
467463
require.NoError(t, err, "errored when creating a new upgrader")
468464

469465
// Channels have buffer length 1, so we don't have to run on multiple

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ type Metadata struct {
5959
// Reason is a string that may give out more information about transitioning to the current state. It has been
6060
// introduced initially to distinguish between manual and automatic rollbacks
6161
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
62+
63+
RollbacksAvailable []RollbackAvailable `json:"rollbacks_available,omitempty" yaml:"rollbacks_available,omitempty"`
64+
}
65+
66+
//rollback_available:
67+
//- version: 8.16.0-SNAPSHOT,
68+
//home: data/elastic-agent-8.16.0-SNAPSHOT-b65953
69+
//valid_until: "2024-11-21T14:42:21Z"
70+
71+
type RollbackAvailable struct {
72+
Version string `json:"version" yaml:"version"`
73+
Home string `json:"home" yaml:"home"`
74+
ValidUntil time.Time `json:"valid_until" yaml:"valid_until"`
6275
}
6376

6477
func NewDetails(targetVersion string, initialState State, actionID string) *Details {

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,10 +504,6 @@ func createUpdateMarker(t *testing.T, log *logger.Logger, topDir, newAgentVersio
504504
hash: oldAgentHash,
505505
versionedHome: oldAgentVersionedHome,
506506
}
507-
err := markUpgrade(log,
508-
paths.DataFrom(topDir),
509-
newAgentInstall,
510-
oldAgentInstall,
511-
nil, nil, OUTCOME_UPGRADE)
507+
err := markUpgrade(log, paths.DataFrom(topDir), newAgentInstall, oldAgentInstall, nil, nil, OUTCOME_UPGRADE, 0)
512508
require.NoError(t, err, "error writing fake update marker")
513509
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func TestDownloadWithRetries(t *testing.T) {
9191
return &mockDownloader{expectedDownloadPath, nil}, nil
9292
}
9393

94-
u, err := NewUpgrader(testLogger, &settings, &info.AgentInfo{})
94+
u, err := NewUpgrader(testLogger, &settings, nil, &info.AgentInfo{})
9595
require.NoError(t, err)
9696

9797
parsedVersion, err := agtversion.ParseVersion("8.9.0")
@@ -141,7 +141,7 @@ func TestDownloadWithRetries(t *testing.T) {
141141
return nil, nil
142142
}
143143

144-
u, err := NewUpgrader(testLogger, &settings, &info.AgentInfo{})
144+
u, err := NewUpgrader(testLogger, &settings, nil, &info.AgentInfo{})
145145
require.NoError(t, err)
146146

147147
parsedVersion, err := agtversion.ParseVersion("8.9.0")
@@ -196,7 +196,7 @@ func TestDownloadWithRetries(t *testing.T) {
196196
return nil, nil
197197
}
198198

199-
u, err := NewUpgrader(testLogger, &settings, &info.AgentInfo{})
199+
u, err := NewUpgrader(testLogger, &settings, nil, &info.AgentInfo{})
200200
require.NoError(t, err)
201201

202202
parsedVersion, err := agtversion.ParseVersion("8.9.0")
@@ -241,7 +241,7 @@ func TestDownloadWithRetries(t *testing.T) {
241241
return &mockDownloader{"", errors.New("download failed")}, nil
242242
}
243243

244-
u, err := NewUpgrader(testLogger, &settings, &info.AgentInfo{})
244+
u, err := NewUpgrader(testLogger, &settings, nil, &info.AgentInfo{})
245245
require.NoError(t, err)
246246

247247
parsedVersion, err := agtversion.ParseVersion("8.9.0")

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ type agentInstall struct {
197197
}
198198

199199
// markUpgrade marks update happened so we can handle grace period
200-
func markUpgrade(log *logger.Logger, dataDirPath string, agent, previousAgent agentInstall, action *fleetapi.ActionUpgrade, upgradeDetails *details.Details, desiredOutcome UpgradeOutcome) error {
200+
func markUpgrade(log *logger.Logger, dataDirPath string, agent, previousAgent agentInstall, action *fleetapi.ActionUpgrade, upgradeDetails *details.Details, desiredOutcome UpgradeOutcome, rollbackWindow time.Duration) error {
201201

202202
if len(previousAgent.hash) > hashLen {
203203
previousAgent.hash = previousAgent.hash[:hashLen]
@@ -216,13 +216,22 @@ func markUpgrade(log *logger.Logger, dataDirPath string, agent, previousAgent ag
216216
DesiredOutcome: desiredOutcome,
217217
}
218218

219+
if rollbackWindow > 0 {
220+
// if we have a not empty rollback window, write the prev version in the rollbacks_available field
221+
upgradeDetails.Metadata.RollbacksAvailable = []details.RollbackAvailable{details.RollbackAvailable{
222+
Version: previousAgent.version,
223+
Home: previousAgent.versionedHome,
224+
ValidUntil: time.Now().Add(rollbackWindow),
225+
}}
226+
}
227+
219228
markerBytes, err := yaml.Marshal(newMarkerSerializer(marker))
220229
if err != nil {
221230
return errors.New(err, errors.TypeConfig, "failed to parse marker file")
222231
}
223232

224233
markerPath := markerFilePath(dataDirPath)
225-
log.Infow("Writing upgrade marker file", "file.path", markerPath, "hash", marker.Hash, "prev_hash", marker.PrevHash)
234+
log.Infow("Writing upgrade marker file", "file.path", markerPath, "hash", marker.Hash, "prev_hash", marker.PrevHash, "content", string(markerBytes))
226235
if err := os.WriteFile(markerPath, markerBytes, 0600); err != nil {
227236
return errors.New(err, errors.TypeFilesystem, "failed to create update marker file", errors.M(errors.MetaKeyPath, markerPath))
228237
}

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

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@ func init() {
7373

7474
// Upgrader performs an upgrade
7575
type Upgrader struct {
76-
log *logger.Logger
77-
settings *artifact.Config
78-
agentInfo info.Agent
79-
upgradeable bool
80-
fleetServerURI string
81-
markerWatcher MarkerWatcher
76+
log *logger.Logger
77+
settings *artifact.Config
78+
upgradeSettings *configuration.UpgradeConfig
79+
agentInfo info.Agent
80+
upgradeable bool
81+
fleetServerURI string
82+
markerWatcher MarkerWatcher
8283
}
8384

8485
// IsUpgradeable when agent is installed and running as a service or flag was provided.
@@ -89,13 +90,14 @@ func IsUpgradeable() bool {
8990
}
9091

9192
// NewUpgrader creates an upgrader which is capable of performing upgrade operation
92-
func NewUpgrader(log *logger.Logger, settings *artifact.Config, agentInfo info.Agent) (*Upgrader, error) {
93+
func NewUpgrader(log *logger.Logger, settings *artifact.Config, upgradeConfig *configuration.UpgradeConfig, agentInfo info.Agent) (*Upgrader, error) {
9394
return &Upgrader{
94-
log: log,
95-
settings: settings,
96-
agentInfo: agentInfo,
97-
upgradeable: IsUpgradeable(),
98-
markerWatcher: newMarkerFileWatcher(markerFilePath(paths.Data()), log),
95+
log: log,
96+
settings: settings,
97+
upgradeSettings: upgradeConfig,
98+
agentInfo: agentInfo,
99+
upgradeable: IsUpgradeable(),
100+
markerWatcher: newMarkerFileWatcher(markerFilePath(paths.Data()), log),
99101
}, nil
100102
}
101103

@@ -147,6 +149,8 @@ func (u *Upgrader) Reload(rawConfig *config.Config) error {
147149
}
148150

149151
u.settings = cfg.Settings.DownloadConfig
152+
u.upgradeSettings = cfg.Settings.Upgrade
153+
150154
return nil
151155
}
152156

@@ -346,12 +350,11 @@ func (u *Upgrader) Upgrade(ctx context.Context, version string, rollback bool, s
346350
hash: release.Commit(),
347351
versionedHome: currentVersionedHome,
348352
}
349-
350-
if err := markUpgrade(u.log,
351-
paths.Data(), // data dir to place the marker in
352-
current, // new agent version data
353-
previous, // old agent version data
354-
action, det, OUTCOME_UPGRADE); err != nil {
353+
rollbackWindow := time.Duration(0)
354+
if u.upgradeSettings != nil && u.upgradeSettings.Rollback != nil { // TODO && target version supports manual rollback and deferred cleanup
355+
rollbackWindow = u.upgradeSettings.Rollback.Window
356+
}
357+
if err := markUpgrade(u.log, paths.Data(), current, previous, action, det, OUTCOME_UPGRADE, rollbackWindow); err != nil {
355358
u.log.Errorw("Rolling back: marking upgrade failed", "error.message", err)
356359
rollbackErr := rollbackInstall(ctx, u.log, paths.Top(), hashedDir, currentVersionedHome)
357360
return nil, goerrors.Join(err, rollbackErr)

internal/pkg/agent/cmd/watch.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,11 @@ func getConfig(streams *cli.IOStreams) *configuration.Configuration {
308308
}
309309

310310
func initUpgradeDetails(marker *upgrade.UpdateMarker, saveMarker func(*upgrade.UpdateMarker, bool) error, log *logp.Logger) *details.Details {
311+
// FIXME this should edit details not rewrite them
311312
upgradeDetails := details.NewDetails(version.GetAgentPackageVersion(), details.StateWatching, marker.GetActionID())
313+
if marker.Details != nil {
314+
upgradeDetails.Metadata.RollbacksAvailable = marker.Details.Metadata.RollbacksAvailable
315+
}
312316
upgradeDetails.RegisterObserver(func(details *details.Details) {
313317
marker.Details = details
314318
if err := saveMarker(marker, true); err != nil {

0 commit comments

Comments
 (0)