From e3f9cd9d926bb924a000934bc1cd239b32a29049 Mon Sep 17 00:00:00 2001 From: Sassan Haradji Date: Sat, 10 Aug 2024 21:32:02 +0400 Subject: [PATCH] fix(core): update manager downloads the latest `install.sh` and runs it to do the update - closes #152 --- CHANGELOG.md | 1 + ubo_app/constants.py | 4 ++ ubo_app/store/update_manager/utils.py | 78 +++++++++++++++++--------- ubo_app/system/services/update.service | 4 +- 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bffb6a85..cbfa1350 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - fix(vscode): after login with vscode, the gui now goes back to login code page - closes #143 - fix(core): updating items of the pages after the first page, not being reflected on the screen - closes #149 - feat(rpi-connect): implement `rpi-connect` under `Remote` menu - closes #139 +- fix(core): update manager downloads the latest `install.sh` and runs it to do the update - closes #152 ## Version 0.15.5 diff --git a/ubo_app/constants.py b/ubo_app/constants.py index e94b7472..6ab2d7c4 100644 --- a/ubo_app/constants.py +++ b/ubo_app/constants.py @@ -8,6 +8,10 @@ from str_to_bool import str_to_bool USERNAME = os.environ.get('UBO_USERNAME', 'ubo') +INSTALLER_URL = os.environ.get( + 'UBO_INSTALLER_URL', + 'https://raw.githubusercontent.com/ubopod/ubo-app/main/ubo_app/system/install.sh', +) INSTALLATION_PATH = os.environ.get('UBO_INSTALLATION_PATH', '/opt/ubo') DEBUG_MODE = str_to_bool(os.environ.get('UBO_DEBUG', 'False')) == 1 LOG_LEVEL = os.environ.get('UBO_LOG_LEVEL', 'DEBUG' if DEBUG_MODE else None) diff --git a/ubo_app/store/update_manager/utils.py b/ubo_app/store/update_manager/utils.py index 785e9506..626f6127 100644 --- a/ubo_app/store/update_manager/utils.py +++ b/ubo_app/store/update_manager/utils.py @@ -13,8 +13,9 @@ from ubo_gui.constants import DANGER_COLOR, INFO_COLOR, SUCCESS_COLOR from ubo_gui.menu.types import ActionItem, Item -from ubo_app.constants import INSTALLATION_PATH +from ubo_app.constants import INSTALLATION_PATH, INSTALLER_URL from ubo_app.logging import logger +from ubo_app.store.core import RebootEvent from ubo_app.store.main import autorun, dispatch from ubo_app.store.services.notifications import ( Chime, @@ -71,32 +72,63 @@ async def check_version() -> None: async def update() -> None: """Update the Ubo app.""" logger.info('Updating Ubo app...') - dispatch( - NotificationsAddAction( - notification=Notification( - id='ubo:update_manager', - title='Updating...', - content='Fetching the latest version of Ubo app...', - display_type=NotificationDisplayType.BACKGROUND, - color=INFO_COLOR, - icon='󰇚', - blink=False, - progress=0, - ), - ), - ) async def download_files() -> None: + dispatch( + NotificationsAddAction( + notification=Notification( + id='ubo:update_manager', + title='Updating...', + content='Downloading the latest version of the install script...', + display_type=NotificationDisplayType.BACKGROUND, + color=INFO_COLOR, + icon='󰇚', + blink=False, + progress=0, + ), + ), + ) + target_path = Path(f'{INSTALLATION_PATH}/_update/') shutil.rmtree(target_path, ignore_errors=True) target_path.mkdir(parents=True, exist_ok=True) packages_count_path = f'{INSTALLATION_PATH}/.packages-count' - try: packages_count = int(Path(packages_count_path).read_text(encoding='utf-8')) except FileNotFoundError: packages_count = 55 + packages_count *= 2 + packages_count += 1 + counter = 0 + + process = await asyncio.create_subprocess_exec( + '/usr/bin/env', + 'curl', + '-Lk', + INSTALLER_URL, + '--output', + f'{target_path}/install.sh', + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + await process.wait() + Path(f'{target_path}/install.sh').chmod(0o755) + + dispatch( + NotificationsAddAction( + notification=Notification( + id='ubo:update_manager', + title='Updating...', + content='Fetching the latest version of Ubo app...', + display_type=NotificationDisplayType.BACKGROUND, + color=INFO_COLOR, + icon='󰇚', + blink=False, + progress=1 / packages_count, + ), + ), + ) process = await asyncio.create_subprocess_exec( '/usr/bin/env', @@ -127,7 +159,7 @@ async def download_files() -> None: UpdateManagerSetStatusAction(status=UpdateStatus.CHECKING), ) return - counter = 0 + while True: line = (await process.stdout.readline()).decode() if not line: @@ -144,7 +176,7 @@ async def download_files() -> None: color=INFO_COLOR, icon='󰇚', blink=False, - progress=min(counter / (packages_count * 2), 1), + progress=min((counter + 1) / packages_count, 1), ), ), ) @@ -177,15 +209,7 @@ async def download_files() -> None: await asyncio.sleep(2) - process = await asyncio.create_subprocess_exec( - '/usr/bin/env', - 'systemctl', - 'reboot', - '-i', - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - await process.wait() + dispatch(RebootEvent()) except Exception: logger.exception('Failed to update') dispatch( diff --git a/ubo_app/system/services/update.service b/ubo_app/system/services/update.service index 3bc00aac..665f0d0a 100644 --- a/ubo_app/system/services/update.service +++ b/ubo_app/system/services/update.service @@ -9,6 +9,6 @@ Type=oneshot User=root Environment=INSTALLATION_PATH={{INSTALLATION_PATH}} Environment=USERNAME={{USERNAME}} -ExecStartPre=/bin/bash -c '[[ $(ls {{INSTALLATION_PATH}}/_update/update_is_ready) ]]' -ExecStart={{INSTALLATION_PATH}}/env/lib/python3.11/site-packages/ubo_app/system/install.sh --update +ExecStartPre=/bin/bash -c '[[ -e /opt/ubo/_update/update_is_ready ]]' +ExecStart={{INSTALLATION_PATH}}/_update/install.sh --update RemainAfterExit=no