@@ -28,28 +28,61 @@ func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string,
2828 // check that the upgrade marker exists and is accessible
2929 updateMarkerPath := markerFilePath (paths .DataFrom (topDir ))
3030 _ , err := os .Stat (updateMarkerPath )
31- if err != nil {
31+ if err != nil && ! errors . Is ( err , os . ErrNotExist ) {
3232 return nil , fmt .Errorf ("stat() on upgrade marker %q failed: %w" , updateMarkerPath , err )
3333 }
3434
35+ var watcherExecutable string
36+ var versionedHomeToRollbackTo string
37+
38+ if errors .Is (err , os .ErrNotExist ) {
39+ // there is no upgrade marker, we need to extract available rollbacks from agent installs
40+ watcherExecutable , versionedHomeToRollbackTo , err = rollbackUsingAgentInstalls ()
41+ } else {
42+ watcherExecutable , versionedHomeToRollbackTo , err = rollbackUsingUpgradeMarker (ctx , u .log , u .watcherHelper , topDir , now , version )
43+ }
44+
45+ if err != nil {
46+ return nil , err
47+ }
48+
49+ // rollback
50+ watcherCmd , err := u .watcherHelper .InvokeWatcher (u .log , watcherExecutable , "watch" , "--rollback" , versionedHomeToRollbackTo )
51+ if err != nil {
52+ return nil , fmt .Errorf ("starting rollback command: %w" , err )
53+ }
54+
55+ u .log .Infof ("rollback command started successfully, PID: %d" , watcherCmd .Process .Pid )
56+ return nil , nil
57+ }
58+
59+ func rollbackUsingAgentInstalls () (string , string , error ) {
60+ //FIXME implement
61+ //panic("Not implemented")
62+ return "" , "" , errors .Join (errors .New ("not implemented" ), os .ErrNotExist )
63+ }
64+
65+ func rollbackUsingUpgradeMarker (ctx context.Context , log * logger.Logger , watcherHelper WatcherHelper , topDir string , now time.Time , version string ) (string , string , error ) {
3566 // read the upgrade marker
3667 updateMarker , err := LoadMarker (paths .DataFrom (topDir ))
3768 if err != nil {
38- return nil , fmt .Errorf ("loading marker: %w" , err )
69+ return "" , "" , fmt .Errorf ("loading marker: %w" , err )
3970 }
4071
4172 if updateMarker == nil {
42- return nil , ErrNilUpdateMarker
73+ return "" , "" , ErrNilUpdateMarker
4374 }
4475
4576 // extract the agent installs involved in the upgrade and select the most appropriate watcher executable
4677 previous , current , err := extractAgentInstallsFromMarker (updateMarker )
4778 if err != nil {
48- return nil , fmt .Errorf ("extracting current and previous install details: %w" , err )
79+ return "" , "" , fmt .Errorf ("extracting current and previous install details: %w" , err )
4980 }
50- watcherExecutable := u .watcherHelper .SelectWatcherExecutable (topDir , previous , current )
81+ watcherExecutable := watcherHelper .SelectWatcherExecutable (topDir , previous , current )
82+
83+ var selectedRollback * RollbackAvailable
5184
52- err = withTakeOverWatcher (ctx , u . log , topDir , u . watcherHelper , func () error {
85+ err = withTakeOverWatcher (ctx , log , topDir , watcherHelper , func () error {
5386 // read the upgrade marker
5487 updateMarker , err = LoadMarker (paths .DataFrom (topDir ))
5588 if err != nil {
@@ -63,7 +96,7 @@ func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string,
6396 if len (updateMarker .RollbacksAvailable ) == 0 {
6497 return ErrNoRollbacksAvailable
6598 }
66- var selectedRollback * RollbackAvailable
99+
67100 for _ , rollback := range updateMarker .RollbacksAvailable {
68101 if rollback .Version == version && now .Before (rollback .ValidUntil ) {
69102 selectedRollback = & rollback
@@ -73,27 +106,19 @@ func (u *Upgrader) rollbackToPreviousVersion(ctx context.Context, topDir string,
73106 if selectedRollback == nil {
74107 return fmt .Errorf ("version %q not listed among the available rollbacks: %w" , version , ErrNoRollbacksAvailable )
75108 }
76-
77- // rollback
78- _ , err = u .watcherHelper .InvokeWatcher (u .log , watcherExecutable , "watch" , "--rollback" , updateMarker .PrevVersionedHome )
79- if err != nil {
80- return fmt .Errorf ("starting rollback command: %w" , err )
81- }
82- u .log .Debug ("rollback command started successfully, PID" )
83109 return nil
84110 })
85111
86112 if err != nil {
87113 // Invoke watcher again (now that we released the watcher applocks)
88- _ , invokeWatcherErr := u . watcherHelper .InvokeWatcher (u . log , watcherExecutable )
114+ _ , invokeWatcherErr := watcherHelper .InvokeWatcher (log , watcherExecutable )
89115 if invokeWatcherErr != nil {
90- return nil , errors .Join (err , fmt .Errorf ("invoking watcher: %w" , invokeWatcherErr ))
116+ return "" , "" , errors .Join (err , fmt .Errorf ("invoking watcher: %w" , invokeWatcherErr ))
91117 }
92- return nil , err
118+ return "" , "" , err
93119 }
94120
95- return nil , nil
96-
121+ return watcherExecutable , selectedRollback .Home , nil
97122}
98123
99124func withTakeOverWatcher (ctx context.Context , log * logger.Logger , topDir string , watcherHelper WatcherHelper , f func () error ) error {
0 commit comments