This commit is contained in:
firestar5683
2026-04-11 21:56:46 -05:00
parent d2e5f06395
commit d43b7d0d3f
187 changed files with 5499 additions and 6222 deletions
Regular → Executable
+18 -53
View File
@@ -7,21 +7,19 @@ from enum import IntEnum
import pyray as rl
from openpilot.system.hardware import PC
from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.button import Button, ButtonStyle
from openpilot.system.ui.widgets.label import gui_label, gui_text_box
NVME = "/dev/nvme0n1"
USERDATA = "/dev/disk/by-partlabel/userdata"
TIMEOUT = 3*60
PC = not (os.path.isfile("/TICI") or os.path.isfile("/EON"))
class ResetMode(IntEnum):
USER_RESET = 0 # user initiated a factory reset from openpilot
RECOVER = 1 # userdata is corrupt for some reason, give a chance to recover
FORMAT = 2 # finish up a factory reset from a tool that doesn't flash an empty partition to userdata
class ResetState(IntEnum):
@@ -37,35 +35,14 @@ class Reset(Widget):
self._mode = mode
self._previous_reset_state = None
self._reset_state = ResetState.NONE
self._cancel_button = Button("Cancel", self._cancel_callback)
self._cancel_button = Button("Cancel", gui_app.request_close)
self._confirm_button = Button("Confirm", self._confirm, button_style=ButtonStyle.PRIMARY)
self._reboot_button = Button("Reboot", lambda: os.system("sudo reboot"))
self._render_status = True
def _cancel_callback(self):
self._render_status = False
def _backup_ssh_params(self):
if PC:
return
backup_dir = "/cache/reset_backup"
os.system(f"sudo rm -rf {backup_dir}")
os.system(f"sudo mkdir -p {backup_dir}")
for key in ("GithubSshKeys", "SshEnabled"):
os.system(f"sudo cp /data/params/d/{key} {backup_dir}/{key} 2>/dev/null || true")
os.system(f"sudo chmod 600 {backup_dir}/* 2>/dev/null || true")
def _do_erase(self):
if PC:
return
self._backup_ssh_params()
# Best effort to wipe NVME
os.system(f"sudo umount {NVME}")
os.system(f"yes | sudo mkfs.ext4 {NVME}")
# Removing data and formatting
rm = os.system("sudo rm -rf /data/*")
os.system(f"sudo umount {USERDATA}")
@@ -76,7 +53,7 @@ class Reset(Widget):
else:
self._reset_state = ResetState.FAILED
def start_reset(self):
def _start_reset(self):
self._reset_state = ResetState.RESETTING
threading.Timer(0.1, self._do_erase).start()
@@ -87,34 +64,34 @@ class Reset(Widget):
elif self._reset_state != ResetState.RESETTING and (time.monotonic() - self._timeout_st) > TIMEOUT:
exit(0)
def _render(self, rect: rl.Rectangle):
label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, 100 * FONT_SCALE)
def _render(self, _):
content_rect = rl.Rectangle(45, 200, self._rect.width - 90, self._rect.height - 245)
label_rect = rl.Rectangle(content_rect.x + 140, content_rect.y, content_rect.width - 280, 100 * FONT_SCALE)
gui_label(label_rect, "System Reset", 100, font_weight=FontWeight.BOLD)
text_rect = rl.Rectangle(rect.x + 140, rect.y + 140, rect.width - 280, rect.height - 90 - 100 * FONT_SCALE)
text_rect = rl.Rectangle(content_rect.x + 140, content_rect.y + 140, content_rect.width - 280, content_rect.height - 90 - 100 * FONT_SCALE)
gui_text_box(text_rect, self._get_body_text(), 90)
button_height = 160
button_spacing = 50
button_top = rect.y + rect.height - button_height
button_width = (rect.width - button_spacing) / 2.0
button_top = content_rect.y + content_rect.height - button_height
button_width = (content_rect.width - button_spacing) / 2.0
if self._reset_state != ResetState.RESETTING:
if self._mode == ResetMode.RECOVER:
self._reboot_button.render(rl.Rectangle(rect.x, button_top, button_width, button_height))
self._reboot_button.render(rl.Rectangle(content_rect.x, button_top, button_width, button_height))
elif self._mode == ResetMode.USER_RESET:
self._cancel_button.render(rl.Rectangle(rect.x, button_top, button_width, button_height))
self._cancel_button.render(rl.Rectangle(content_rect.x, button_top, button_width, button_height))
if self._reset_state != ResetState.FAILED:
self._confirm_button.render(rl.Rectangle(rect.x + button_width + 50, button_top, button_width, button_height))
self._confirm_button.render(rl.Rectangle(content_rect.x + button_width + 50, button_top, button_width, button_height))
else:
self._reboot_button.render(rl.Rectangle(rect.x, button_top, rect.width, button_height))
return self._render_status
self._reboot_button.render(rl.Rectangle(content_rect.x, button_top, content_rect.width, button_height))
def _confirm(self):
if self._reset_state == ResetState.CONFIRM:
self.start_reset()
self._start_reset()
else:
self._reset_state = ResetState.CONFIRM
@@ -131,30 +108,18 @@ class Reset(Widget):
def main():
# Safety fallback: if this module is launched on a small-UI device,
# hand off to the mici reset implementation to avoid off-screen layout.
if not gui_app.big_ui():
import openpilot.system.ui.mici_reset as mici_reset
mici_reset.main()
return
mode = ResetMode.USER_RESET
if len(sys.argv) > 1:
if sys.argv[1] == '--recover':
mode = ResetMode.RECOVER
elif sys.argv[1] == "--format":
mode = ResetMode.FORMAT
gui_app.init_window("System Reset", 20)
reset = Reset(mode)
if mode == ResetMode.FORMAT:
reset.start_reset()
gui_app.push_widget(reset)
for should_render in gui_app.render():
if should_render:
if not reset.render(rl.Rectangle(45, 200, gui_app.width - 90, gui_app.height - 245)):
break
for _ in gui_app.render():
pass
if __name__ == "__main__":