2323import cmk .gui .watolib .changes as _changes
2424from cmk .ccc .archive import CheckmkTarArchive
2525from cmk .ccc .hostaddress import HostName
26- from cmk .ccc .site import SiteId
26+ from cmk .ccc .site import omd_site , SiteId
2727from cmk .ccc .version import Edition , edition , edition_has_enforced_licensing
2828from cmk .gui import forms
2929from cmk .gui .breadcrumb import Breadcrumb
4646 show_confirm_cancel_dialog ,
4747)
4848from cmk .gui .pages import AjaxPage , PageContext , PageEndpoint , PageRegistry , PageResult
49- from cmk .gui .site_config import is_distributed_setup_remote_site
5049from cmk .gui .sites import SiteStatus
5150from cmk .gui .table import Foldable , init_rowselect , table_element
5251from cmk .gui .type_defs import ActionResult , IconNames , PermissionName , ReadOnlySpec , StaticIcon
7675from cmk .gui .watolib .hosts_and_folders import folder_preserving_link , folder_tree , Host
7776from cmk .gui .watolib .mode import ModeRegistry , WatoMode
7877from cmk .gui .watolib .objref import ObjectRef , ObjectRefType
78+ from cmk .gui .watolib .sites import site_management_registry
7979from cmk .utils import paths , render
8080from cmk .utils .licensing .registry import get_licensing_user_effect
8181from cmk .utils .licensing .usage import get_license_usage_report_validity , LicenseUsageReportValidity
@@ -209,7 +209,9 @@ def _page_menu_entries_setup(self) -> Iterator[PageMenuEntry]:
209209 item = make_simple_link (folder_preserving_link ([("mode" , "auditlog" )])),
210210 )
211211
212- def _may_discard_changes (self , read_only_config : ReadOnlySpec , * , debug : bool ) -> bool :
212+ def _may_discard_changes (
213+ self , read_only_config : ReadOnlySpec , * , file_to_restore : str | None
214+ ) -> bool :
213215 if not user .may ("wato.activate" ):
214216 return False
215217
@@ -219,7 +221,7 @@ def _may_discard_changes(self, read_only_config: ReadOnlySpec, *, debug: bool) -
219221 if read_only .is_enabled (read_only_config ) and not read_only .may_override (read_only_config ):
220222 return False
221223
222- if not get_last_wato_snapshot_file ( debug = debug ) :
224+ if not file_to_restore :
223225 return False
224226
225227 return True
@@ -231,16 +233,18 @@ def action(self, config: Config) -> ActionResult:
231233 if not transactions .check_transaction ():
232234 return None
233235
234- if not self ._may_discard_changes (config .wato_read_only , debug = config .debug ):
236+ activation_site_ids = list (activation_sites (config .sites ))
237+
238+ file_to_restore = get_last_wato_snapshot_file (debug = config .debug )
239+
240+ if not self ._may_discard_changes (config .wato_read_only , file_to_restore = file_to_restore ):
235241 return None
236242
237243 if not self ._changes .has_changes ():
238244 return None
239245
240- # Now remove all currently pending changes by simply restoring the last automatically
241- # taken snapshot. Then activate the configuration. This should revert all pending changes.
242- file_to_restore = get_last_wato_snapshot_file (debug = config .debug )
243-
246+ # Revert all pending changes by restoring the last automatically taken snapshot, then
247+ # activate the restored configuration to make it effective again.
244248 if not file_to_restore :
245249 raise MKUserError (None , _ ("There is no Setup snapshot to be restored." ))
246250
@@ -257,17 +261,38 @@ def action(self, config: Config) -> ActionResult:
257261 )
258262
259263 _extract_snapshot (file_to_restore )
260- activate_changes .execute_activate_changes (
261- [d .get_domain_request ([]) for d in ABCConfigDomain .enabled_domains ()],
262- is_remote_site = is_distributed_setup_remote_site (config .sites ),
263- )
264+ request_index_rebuild ()
264265
265- for site_id in activation_sites (config .sites ):
266- self ._changes .confirm_site_changes (site_id )
266+ active_config .sites = site_management_registry ["site_management" ].load_sites ()
267+ reverted_site_ids = list (activation_sites (active_config .sites ))
268+ local_site = omd_site ()
267269
268- request_index_rebuild ()
270+ # Activate the local site since its files were just rewritten
271+ manager = activate_changes .ActivateChangesManager ()
272+ manager .changes .load (reverted_site_ids )
273+ manager .start (
274+ sites = [local_site ],
275+ source = "GUI" ,
276+ all_site_configs = active_config .sites ,
277+ user_permission_config = UserPermissionSerializableConfig .from_global_config (config ),
278+ max_snapshots = config .wato_max_snapshots ,
279+ use_git = config .wato_use_git ,
280+ debug = config .debug ,
281+ comment = msg ,
282+ activate_foreign = True ,
283+ )
269284
270- flash (_ ("Pending changes reverted." ))
285+ # No snapshot restored on the remote sites, just clear the obsolete change log entries
286+ for site_id in activation_site_ids :
287+ if site_id != local_site :
288+ self ._changes .confirm_site_changes (site_id )
289+
290+ # TODO: Show the live progress of the revert activation on the target page. Reverting OMD
291+ # settings restarts the site's apache (the change is added with force_restart=True), and
292+ # that restart truncates/races any progress monitor we render in this flow.
293+ # For now the activation runs in the background and the user has to reload the page to see
294+ # the result
295+ flash (_ ("Reverting pending changes. Reload this page to see the current status." ))
271296 return HTTPRedirect (makeuri_contextless (request , [("mode" , ModeActivateChanges .name ())]))
272297
273298 def page (self , config : Config ) -> None :
0 commit comments