From 56814bfc389e1c0843230750324782b4c88de0ec Mon Sep 17 00:00:00 2001 From: Yellowcooln <12516003+yellowcooln@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:27:04 -0400 Subject: [PATCH 1/3] Support local embedded Buildroot installs --- buildroot-manage.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/buildroot-manage.sh b/buildroot-manage.sh index 2c4e69c..4acbbf0 100644 --- a/buildroot-manage.sh +++ b/buildroot-manage.sh @@ -24,6 +24,8 @@ R2_ENABLED=1 YQ_VERSION="${YQ_VERSION:-v4.44.3}" PYMC_CORE_REPO="${PYMC_CORE_REPO:-https://github.com/rightup/pyMC_core.git}" PYMC_CORE_REF="${PYMC_CORE_REF:-}" +PYMC_CORE_LOCAL_DIR="${PYMC_CORE_LOCAL_DIR:-}" +PYMC_SKIP_BUILDROOT_DEP_INSTALL="${PYMC_SKIP_BUILDROOT_DEP_INSTALL:-0}" RADIO_SETTINGS_JSON="$SCRIPT_DIR/radio-settings.json" RADIO_PRESETS_JSON="$SCRIPT_DIR/radio-presets.json" BUILDROOT_RADIO_SETTINGS_JSON="$SCRIPT_DIR/radio-settings-buildroot.json" @@ -533,6 +535,15 @@ install_buildroot_dependencies() { local wheel_base local deps + if [ "${PYMC_SKIP_BUILDROOT_DEP_INSTALL}" = "1" ]; then + stage "Checking embedded Python dependency baseline" + if check_buildroot_dependencies_installed >/dev/null 2>&1; then + info "Image-provided Python dependency wheels already satisfy Buildroot requirements" + return 0 + fi + fail "Embedded/offline install requested, but the required Python dependency wheels are not already present in the image." + fi + wheel_base=$(get_r2_wheel_base 2>/dev/null || true) deps=$(set_wheel_dependencies) stage "Installing Python dependency wheels" @@ -614,6 +625,14 @@ PY install_core_into_venv() { local core_repo core_ref core_spec + if [ -n "$PYMC_CORE_LOCAL_DIR" ]; then + [ -d "$PYMC_CORE_LOCAL_DIR" ] || fail "Missing local pyMC_core checkout: $PYMC_CORE_LOCAL_DIR" + stage "Installing pyMC_core" + info "Local dir: ${PYMC_CORE_LOCAL_DIR}" + "$VENV_PIP" install --upgrade --no-cache-dir --no-deps --no-build-isolation "$PYMC_CORE_LOCAL_DIR" + return 0 + fi + core_repo="$PYMC_CORE_REPO" case "$core_repo" in *.git) ;; From fe0d3d30af4104f4b3a998b81ac55abc9021a4d8 Mon Sep 17 00:00:00 2001 From: Yellowcooln <12516003+yellowcooln@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:43:13 -0400 Subject: [PATCH 2/3] Fix Buildroot OTA upgrade path --- buildroot-manage.sh | 17 +++++++++++++++++ repeater/web/update_endpoints.py | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/buildroot-manage.sh b/buildroot-manage.sh index 4acbbf0..26b4cea 100644 --- a/buildroot-manage.sh +++ b/buildroot-manage.sh @@ -622,6 +622,21 @@ PY info "Linked image-provided Python runtime into the venv" } +remove_shadowing_buildroot_native_packages() { + local removed=0 + + if "$VENV_PIP" show python-periphery >/dev/null 2>&1; then + stage "Restoring Buildroot GPIO runtime" + info "Removing venv-installed python-periphery so the image-provided package is used" + "$VENV_PIP" uninstall -y python-periphery >/dev/null 2>&1 || true + removed=1 + fi + + if [ "$removed" -eq 0 ]; then + info "No shadowing Buildroot native GPIO wheels found in the venv" + fi +} + install_core_into_venv() { local core_repo core_ref core_spec @@ -1361,6 +1376,7 @@ install_repeater() { install_buildroot_dependencies install_core_into_venv install_repeater_package + remove_shadowing_buildroot_native_packages link_system_site_packages stage "Validating installed runtime" @@ -1426,6 +1442,7 @@ upgrade_repeater() { ensure_yq >/dev/null 2>&1 || true install_repeater_package fi + remove_shadowing_buildroot_native_packages link_system_site_packages stage "Validating installed runtime" if check_venv_runtime; then diff --git a/repeater/web/update_endpoints.py b/repeater/web/update_endpoints.py index b45c977..7ff7ab1 100644 --- a/repeater/web/update_endpoints.py +++ b/repeater/web/update_endpoints.py @@ -29,6 +29,7 @@ from datetime import datetime from typing import List, Optional import cherrypy +from repeater.service_utils import is_buildroot logger = logging.getLogger("HTTPServer") @@ -808,9 +809,18 @@ def _do_install() -> None: _state.append_line(f"[pyMC updater] Installing from channel '{channel}'…") _UPGRADE_WRAPPER = "/usr/local/bin/pymc-do-upgrade" + _BUILDROOT_UPGRADE_HELPER = "/root/scripts/buildroot-manage.sh" is_root = (_os.geteuid() == 0) - if is_root: + if is_root and is_buildroot(): + env["PYMC_REPEATER_REF"] = channel + env["PYMC_CORE_REF"] = channel + _state.append_line(f"[pyMC updater] Buildroot image detected – using {_BUILDROOT_UPGRADE_HELPER}") + if not os.path.isfile(_BUILDROOT_UPGRADE_HELPER): + _state.finish_install(False, f"Buildroot upgrade helper not found at {_BUILDROOT_UPGRADE_HELPER}") + return + cmd = ["/bin/sh", _BUILDROOT_UPGRADE_HELPER, "upgrade"] + elif is_root: _migrate_service_unit() # Ensure venv exists (migration from system-pip era) From acb796199d6ca864a734ba016eab9ea0db410b05 Mon Sep 17 00:00:00 2001 From: Yellowcooln <12516003+yellowcooln@users.noreply.github.com> Date: Wed, 29 Apr 2026 14:14:34 -0400 Subject: [PATCH 3/3] Prefer repo Buildroot updater on embedded images --- repeater/web/update_endpoints.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/repeater/web/update_endpoints.py b/repeater/web/update_endpoints.py index 7ff7ab1..e167fc8 100644 --- a/repeater/web/update_endpoints.py +++ b/repeater/web/update_endpoints.py @@ -59,6 +59,18 @@ def _get_github_ssl_context() -> ssl.SSLContext: return _github_ssl_ctx +def _find_buildroot_upgrade_helper() -> Optional[str]: + candidates = [ + "/root/pyMC_Repeater/buildroot-manage.sh", + "/opt/pymc_repeater/pyMC_Repeater/buildroot-manage.sh", + "/root/scripts/buildroot-manage.sh", + ] + for path in candidates: + if os.path.isfile(path): + return path + return None + + class _RateLimitError(Exception): """Raised when GitHub returns HTTP 403 due to rate limiting.""" def __init__(self, msg: str, reset_at: Optional[datetime] = None): @@ -809,16 +821,16 @@ def _do_install() -> None: _state.append_line(f"[pyMC updater] Installing from channel '{channel}'…") _UPGRADE_WRAPPER = "/usr/local/bin/pymc-do-upgrade" - _BUILDROOT_UPGRADE_HELPER = "/root/scripts/buildroot-manage.sh" + _BUILDROOT_UPGRADE_HELPER = _find_buildroot_upgrade_helper() is_root = (_os.geteuid() == 0) if is_root and is_buildroot(): env["PYMC_REPEATER_REF"] = channel env["PYMC_CORE_REF"] = channel - _state.append_line(f"[pyMC updater] Buildroot image detected – using {_BUILDROOT_UPGRADE_HELPER}") - if not os.path.isfile(_BUILDROOT_UPGRADE_HELPER): - _state.finish_install(False, f"Buildroot upgrade helper not found at {_BUILDROOT_UPGRADE_HELPER}") + if not _BUILDROOT_UPGRADE_HELPER: + _state.finish_install(False, "Buildroot upgrade helper not found in repo checkout or image bootstrap paths") return + _state.append_line(f"[pyMC updater] Buildroot image detected – using {_BUILDROOT_UPGRADE_HELPER}") cmd = ["/bin/sh", _BUILDROOT_UPGRADE_HELPER, "upgrade"] elif is_root: _migrate_service_unit()