Skip to content

Commit fcd8d05

Browse files
samuelclayclaude
andcommitted
Fix cold shutdown not clearing last_snapshot_timestamp, causing next boot to try loading a deleted snapshot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e12f172 commit fcd8d05

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

server/utils/emulator_shutdown_manager.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def shutdown_emulator( # noqa: C901 (complexity is acceptable for entry‑point
102102
server = AutomationServer.get_instance()
103103
automator = server.automators.get(email)
104104
if automator is None:
105-
return self._handle_orphaned_emulator(email, summary)
105+
return self._handle_orphaned_emulator(email, summary, cold=cold)
106106

107107
# ------------------------------------------------------------------
108108
# 3. UI navigation (navigate to library if needed) ──────
@@ -229,8 +229,14 @@ def _mark_for_restart(email: str, mark_for_restart: Optional[bool]):
229229

230230
# ----------------------- orphan‑handling ------------------------ #
231231

232-
def _handle_orphaned_emulator(self, email: str, summary: Dict[str, bool]): # noqa: C901
232+
def _handle_orphaned_emulator(
233+
self, email: str, summary: Dict[str, bool], cold: bool = False
234+
): # noqa: C901
233235
"""Stop an emulator that is still running but has no live automator."""
236+
# Handle cold boot cleanup even if there's no running emulator
237+
if cold:
238+
self._clear_snapshot_timestamp(email)
239+
234240
vnc_manager = VNCInstanceManager.get_instance()
235241
vnc_instance = vnc_manager.get_instance_for_profile(email)
236242
if not vnc_instance or not vnc_instance.get("emulator_id"):
@@ -485,6 +491,9 @@ def _delete_existing_snapshot(self, automator, email: str, summary: Dict[str, bo
485491
logger.debug(f"No default_boot snapshot found to delete for {email}")
486492
summary["snapshot_deleted"] = False
487493

494+
# Clear the snapshot timestamp so the next boot uses -no-snapshot-load
495+
self._clear_snapshot_timestamp(email)
496+
488497
except Exception as e:
489498
logger.error(f"Error deleting snapshot for {email}: {e}", exc_info=True)
490499
summary["snapshot_deleted"] = False
@@ -525,6 +534,17 @@ def _take_snapshot(self, automator, email: str, summary: Dict[str, bool]):
525534
snapshot_attempted=True,
526535
)
527536

537+
@staticmethod
538+
def _clear_snapshot_timestamp(email: str):
539+
"""Clear the snapshot timestamp so the next boot uses cold boot (-no-snapshot-load)."""
540+
with contextlib.suppress(Exception):
541+
from views.core.avd_profile_manager import AVDProfileManager
542+
543+
avd_mgr = AVDProfileManager.get_instance()
544+
avd_mgr.set_user_field(email, "last_snapshot_timestamp", None)
545+
avd_mgr.set_user_field(email, "last_snapshot", None)
546+
logger.info(f"Cleared snapshot timestamp for {email} - next boot will cold boot")
547+
528548
@staticmethod
529549
def _update_snapshot_timestamp(email: str):
530550
"""Persist the default_boot snapshot timestamp to the user's AVD profile."""

0 commit comments

Comments
 (0)