diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2adb06..9834b7d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Version 0.9.8 + +- hotfix: wait for lingering process to finish and retry usreland `systemctl --user +daemon-reload` if needed +- hotfix: the `install_docker.sh` script now runs if an optional flag is set for + bootstrap command + ## Version 0.9.7 - fix: audio for when pipewire is installed diff --git a/pyproject.toml b/pyproject.toml index 8afdf9e0..f54894e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ubo-app" -version = "0.9.7" +version = "0.9.8" description = "Ubo main app, running on device initialization. A platform for running other apps." authors = ["Sassan Haradji "] license = "Apache-2.0" diff --git a/ubo_app/__init__.py b/ubo_app/__init__.py index f7640f5d..c735a827 100644 --- a/ubo_app/__init__.py +++ b/ubo_app/__init__.py @@ -31,7 +31,9 @@ def main() -> None: if len(sys.argv) > 1 and sys.argv[1] == 'bootstrap': from ubo_app.system.bootstrap import bootstrap - bootstrap() + bootstrap( + with_docker=sys.argv[2] == '--with-docker' if len(sys.argv) > 2 else False, + ) sys.exit(0) from headless_kivy_pi import HeadlessWidget diff --git a/ubo_app/system/bootstrap.py b/ubo_app/system/bootstrap.py index fc3baeb4..212a2bc1 100644 --- a/ubo_app/system/bootstrap.py +++ b/ubo_app/system/bootstrap.py @@ -5,12 +5,15 @@ import os import pwd import subprocess +import time from pathlib import Path from typing import Literal, TypedDict from ubo_app.constants import INSTALLATION_PATH, USERNAME from ubo_app.logging import logger +RETRIES = 5 + class Service(TypedDict): """System service metadata.""" @@ -42,7 +45,7 @@ class Service(TypedDict): gid = grp.getgrnam(USERNAME).gr_gid -def bootstrap() -> None: +def bootstrap(*, with_docker: bool = False) -> None: """Create the service files and enable the services.""" for service in services: if service['scope'] == 'user': @@ -89,19 +92,38 @@ def bootstrap() -> None: os.chown(service_file_path, uid, gid) subprocess.run(['/usr/bin/env', 'loginctl', 'enable-linger', USERNAME], check=True) # noqa: S603 - subprocess.run( - [ # noqa: S603 - '/usr/bin/env', - 'sudo', - f'XDG_RUNTIME_DIR=/run/user/{uid}', - '-u', - USERNAME, - 'systemctl', - '--user', - 'daemon-reload', - ], - check=True, - ) + + logger.info('Waiting for the user services to come up...') + for i in range(RETRIES): + time.sleep(1) + print('.', end='', flush=True) # noqa: T201 + try: + subprocess.run( + [ # noqa: S603 + '/usr/bin/env', + 'sudo', + f'XDG_RUNTIME_DIR=/run/user/{uid}', + '-u', + USERNAME, + 'systemctl', + '--user', + 'daemon-reload', + ], + check=True, + ) + except subprocess.CalledProcessError as exception: + if i < RETRIES - 1: + logger.error( + 'Failed to reload user services, retrying...', + exc_info=exception, + ) + continue + else: + break + else: + logger.error(f'Failed to reload user services {RETRIES} times, giving up!') + return + print(flush=True) # noqa: T201 subprocess.run( ['/usr/bin/env', 'systemctl', 'daemon-reload'], # noqa: S603 check=True, @@ -144,6 +166,31 @@ def bootstrap() -> None: .replace('{{USERNAME}}', USERNAME), ) + if with_docker: + logger.info('Installing docker...') + for i in range(RETRIES): + time.sleep(1) + print('.', end='', flush=True) # noqa: T201 + try: + subprocess.run( + [Path(__file__).parent.joinpath('install_docker.sh').as_posix()], # noqa: S603 + env={'USERNAME': USERNAME}, + check=True, + ) + except subprocess.CalledProcessError as exception: + if i < RETRIES - 1: + logger.error( + 'Failed to install docker, retrying...', + exc_info=exception, + ) + continue + else: + break + else: + logger.error(f'Failed to installed docker {RETRIES} times, giving up!') + return + print(flush=True) # noqa: T201 + subprocess.run( [Path(__file__).parent.joinpath('install_wm8960.sh').as_posix()], # noqa: S603 check=True, diff --git a/ubo_app/system/install.sh b/ubo_app/system/install.sh index 070f7ff3..fe5c17bd 100755 --- a/ubo_app/system/install.sh +++ b/ubo_app/system/install.sh @@ -106,17 +106,12 @@ chown -R $USERNAME:$USERNAME "$INSTALLATION_PATH" chmod -R 700 "$INSTALLATION_PATH" # Bootstrap the application -"$INSTALLATION_PATH/env/bin/ubo" bootstrap +UBO_LOG_LEVEL=INFO "$INSTALLATION_PATH/env/bin/ubo" bootstrap${WITH_DOCKER:+ --with-docker} if [ "$UPDATE" = true ]; then # Remove the update directory rm -rf "$INSTALLATION_PATH/_update" fi -if [ "$WITH_DOCKER" = true ]; then - # Install Docker - ./install_docker.sh -fi - # The audio driver needs a reboot to work reboot diff --git a/ubo_app/system/install_wm8960.sh b/ubo_app/system/install_wm8960.sh index bdd33412..3681675d 100755 --- a/ubo_app/system/install_wm8960.sh +++ b/ubo_app/system/install_wm8960.sh @@ -27,6 +27,10 @@ grep -q "^snd-soc-wm8960$" /etc/modules || \ echo "snd-soc-wm8960" >> /etc/modules grep -q "^snd-soc-wm8960-soundcard$" /etc/modules || \ echo "snd-soc-wm8960-soundcard" >> /etc/modules + +# set modprobe blacklist +grep -q "^blacklist snd_bcm2835$" /etc/modprobe.d/raspi-blacklist.conf || \ + echo "blacklist snd_bcm2835" >> /etc/modprobe.d/raspi-blacklist.conf #set dtoverlays sed -i -e 's:#dtparam=i2s=on:dtparam=i2s=on:g' /boot/firmware/config.txt || true diff --git a/ubo_app/system/system_manager/__main__.py b/ubo_app/system/system_manager/__main__.py index 397ac62b..3264d7a9 100644 --- a/ubo_app/system/system_manager/__main__.py +++ b/ubo_app/system/system_manager/__main__.py @@ -94,6 +94,11 @@ def install_docker(command: str) -> None: ['/usr/bin/env', 'systemctl', 'start', 'docker'], # noqa: S603 check=False, ) + elif command == 'stop': + subprocess.run( + ['/usr/bin/env', 'systemctl', 'stop', 'docker'], # noqa: S603 + check=False, + ) finally: DOCKER_INSTALLATION_LOCK_FILE.unlink(missing_ok=True)