From 8146ed44f22cba5cd804f0d5825af8e9610a4412 Mon Sep 17 00:00:00 2001 From: James Turton Date: Sat, 3 Oct 2026 00:00:00 +0200 Subject: [PATCH 1/2] Add SWU deploy as moonraker update_manager backend --- .github/workflows/push.yml | 3 + meta-opencentauri/images/cosmos-image-base.bb | 1 + .../0001-Add-support-for-SWUDeploy.patch | 53 +++ .../moonraker/files/moonraker-readonly.conf | 9 + .../moonraker/files/swu_deploy.py | 373 ++++++++++++++++++ ...oonraker_0.10.0.bb => moonraker_0.11.0.bb} | 8 +- .../files/build-klipper-var-config.sh | 13 + 7 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 meta-opencentauri/recipes-apps/moonraker/files/0001-Add-support-for-SWUDeploy.patch create mode 100644 meta-opencentauri/recipes-apps/moonraker/files/swu_deploy.py rename meta-opencentauri/recipes-apps/moonraker/{moonraker_0.10.0.bb => moonraker_0.11.0.bb} (89%) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7edf8e79..efda0eb1 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -49,3 +49,6 @@ jobs: "./firmware/cosmos-centauri-carbon-2.swu" \ --clobber \ --repo OpenCentauri/cosmos + + gh api -X PATCH repos/${GITHUB_REPOSITORY}/git/refs/tags/0.0.0 \ + -f sha=$GITHUB_SHA -F force=true diff --git a/meta-opencentauri/images/cosmos-image-base.bb b/meta-opencentauri/images/cosmos-image-base.bb index 478349a5..584017c5 100644 --- a/meta-opencentauri/images/cosmos-image-base.bb +++ b/meta-opencentauri/images/cosmos-image-base.bb @@ -14,6 +14,7 @@ inherit core-image IMAGE_FEATURES += "ssh-server-dropbear" CORE_IMAGE_EXTRA_INSTALL += "\ + os-release \ usbutils \ libgpiod \ libgpiod-tools \ diff --git a/meta-opencentauri/recipes-apps/moonraker/files/0001-Add-support-for-SWUDeploy.patch b/meta-opencentauri/recipes-apps/moonraker/files/0001-Add-support-for-SWUDeploy.patch new file mode 100644 index 00000000..cf3c1437 --- /dev/null +++ b/meta-opencentauri/recipes-apps/moonraker/files/0001-Add-support-for-SWUDeploy.patch @@ -0,0 +1,53 @@ +From 24908423635c63389f1da713cb723aa3a3af21c9 Mon Sep 17 00:00:00 2001 +From: James Turton +Date: Thu, 1 Oct 2026 22:04:33 +0200 +Subject: [PATCH] update_manager: Add support for SWUDeploy + +--- + moonraker/components/update_manager/common.py | 3 +++ + moonraker/components/update_manager/update_manager.py | 4 +++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/moonraker/components/update_manager/common.py b/moonraker/components/update_manager/common.py +index 32c1cf8..232eb3d 100644 +--- a/moonraker/components/update_manager/common.py ++++ b/moonraker/components/update_manager/common.py +@@ -51,6 +51,7 @@ class AppType(ExtendedEnum): + ZIP = 4 + PYTHON = 5 + EXECUTABLE = 6 ++ SWUPDATE = 7 + + @classmethod + def detect(cls, app_path: Union[str, pathlib.Path, None] = None): +@@ -76,6 +77,8 @@ class AppType(ExtendedEnum): + return [] + elif self in [AppType.WEB, AppType.ZIP, AppType.EXECUTABLE]: + return [Channel.STABLE, Channel.BETA] # type: ignore ++ elif self == AppType.SWUPDATE: ++ return [Channel.STABLE, Channel.DEV] # type: ignore + else: + return list(Channel) + +diff --git a/moonraker/components/update_manager/update_manager.py b/moonraker/components/update_manager/update_manager.py +index cd580c9..0973132 100644 +--- a/moonraker/components/update_manager/update_manager.py ++++ b/moonraker/components/update_manager/update_manager.py +@@ -17,6 +17,7 @@ from .app_deploy import AppDeploy + from .git_deploy import GitDeploy + from .net_deploy import NetDeploy + from .python_deploy import PythonDeploy ++from .swu_deploy import SwuDeploy + from .system_deploy import PackageDeploy + from ...common import RequestType + from ...utils.filelock import AsyncExclusiveFileLock, LockTimeout +@@ -61,7 +62,8 @@ def get_deploy_class( + AppType.GIT_REPO: GitDeploy, + AppType.ZIP: NetDeploy, + AppType.PYTHON: PythonDeploy, +- AppType.EXECUTABLE: NetDeploy ++ AppType.EXECUTABLE: NetDeploy, ++ AppType.SWUPDATE: SwuDeploy + } + return _deployers.get(key, default) + diff --git a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf index 2145090b..4eabeca1 100644 --- a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf +++ b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf @@ -42,3 +42,12 @@ subscriptions: service: mjpegstreamer stream_url: /webcam/?action=stream snapshot_url: /webcam/?action=snapshot + +[update_manager] +enable_system_updates: False + +[update_manager cosmos] +type: swupdate +repo: OpenCentauri/cosmos +asset_name: cosmos-@MACHINE@.swu +channel: stable diff --git a/meta-opencentauri/recipes-apps/moonraker/files/swu_deploy.py b/meta-opencentauri/recipes-apps/moonraker/files/swu_deploy.py new file mode 100644 index 00000000..4c9fb9c6 --- /dev/null +++ b/meta-opencentauri/recipes-apps/moonraker/files/swu_deploy.py @@ -0,0 +1,373 @@ +# SWUpdate Firmware Deployment implementation +# +# Copyright (C) 2026 James Turton +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +from __future__ import annotations +import pathlib +import shlex +import shutil +import logging +from datetime import datetime +import distro +from .app_deploy import AppDeploy +from .common import AppType, Channel +from .git_deploy import GIT_MAX_LOG_CNT + +# Annotation imports +from typing import ( + TYPE_CHECKING, + Any, + Tuple, + Optional, + Dict, + List, + cast +) +if TYPE_CHECKING: + from ...confighelper import ConfigHelper + from ..machine import Machine + +SHORT_HASH_LEN = 10 +DOWNLOAD_TIMEOUT = 3600. +DOWNLOAD_PROGRESS_INTERVAL = 1. +INSTALL_TIMEOUT = 1800. +REBOOT_DELAY = 2. + +class SwuDeploy(AppDeploy): + def __init__(self, config: ConfigHelper) -> None: + super().__init__(config, "SWUpdate") + self.repo = config.get("repo").strip().strip("/") + self.owner, self.project_name = self.repo.split("/", 1) + self.asset_name = config.get("asset_name") + self.install_cmd = config.get("install_command", "flash") + self.nightly_tag: str = config.get("nightly_release_tag", "0.0.0") + self.version: str = "?" + self.remote_version: str = "?" + self.remote_hash: str = "?" + self.rollback_version: str = "?" + self.branch: str = "?" + self.last_error: str = "" + self.dl_info: Tuple[str, str, int] = ("?", "?", 0) + self.commits_behind: List[Dict[str, Any]] = [] + self.commits_behind_count: int = 0 + self.warnings: List[str] = [] + self.reboot_pending: bool = False + + def _validate_install(self) -> None: + self.warnings.clear() + self._is_valid = True + self.version = distro.os_release_attr("version_id") or "?" + if self.version == "?": + self.warnings.append( + "Unable to detect installed version from VERSION_ID in os-release" + ) + self._is_valid = False + cmd = shlex.split(self.install_cmd) + if not cmd or shutil.which(cmd[0]) is None: + self.warnings.append( + f"Install command '{self.install_cmd}' not found" + ) + self._is_valid = False + + async def initialize(self) -> Dict[str, Any]: + storage = await super().initialize() + self._validate_install() + self.remote_version = storage.get("remote_version", "?") + self.remote_hash = storage.get("remote_hash", "?") + self.rollback_version = storage.get("rollback_version", "?") + self.branch = storage.get("branch", "?") + self.last_error = storage.get("last_error", "") + dl_info: List[Any] = storage.get("dl_info", ["?", "?", 0]) + self.dl_info = cast(Tuple[str, str, int], tuple(dl_info)) + self.commits_behind = storage.get("commits_behind", []) + self.commits_behind_count = storage.get("cbh_count", 0) + if storage.get("version", self.version) != self.version: + self.commits_behind = [] + self.commits_behind_count = 0 + self.last_refresh_time = 0. + if not self.needs_refresh(): + self._log_app_info() + return storage + + def get_persistent_data(self) -> Dict[str, Any]: + storage = super().get_persistent_data() + storage.update({ + "version": self.version, + "remote_version": self.remote_version, + "remote_hash": self.remote_hash, + "rollback_version": self.rollback_version, + "branch": self.branch, + "dl_info": list(self.dl_info), + "commits_behind": self.commits_behind, + "cbh_count": self.commits_behind_count, + "last_error": self.last_error + }) + return storage + + async def refresh(self) -> None: + try: + self._validate_install() + if self.channel == Channel.DEV: + await self._refresh_nightly() + else: + await self._refresh_stable() + except Exception: + logging.exception(f"{self.prefix}Error Refreshing") + self._log_app_info() + self._save_state() + + async def _github_request(self, resource: str) -> Any: + client = self.cmd_helper.get_http_client() + resp = await client.github_api_request( + resource, attempts=3, retry_pause_time=.5 + ) + if resp.status_code == 304: + return resp.json() if resp.content else None + if resp.has_error(): + self.log_info(f"Github Request Error - {resp.error}") + self.last_error = str(resp.error) + return None + self.last_error = "" + return resp.json() + + def _find_asset(self, release: Dict[str, Any]) -> Tuple[str, str, int]: + for asset in release.get("assets", []): + if asset.get("name", "") == self.asset_name: + return ( + asset.get("browser_download_url", "?"), + asset.get("content_type", "?"), + asset.get("size", 0) + ) + return ("?", "?", 0) + + async def _refresh_stable(self) -> None: + release = await self._github_request(f"repos/{self.repo}/releases/latest") + if not release: + return + self.remote_version = release.get("tag_name", "?") + self.remote_hash = "?" + self.branch = release.get("target_commitish", "?") + self.dl_info = self._find_asset(release) + self.commits_behind = [] + self.commits_behind_count = 0 + + async def _refresh_nightly(self) -> None: + release = await self._github_request( + f"repos/{self.repo}/releases/tags/{self.nightly_tag}" + ) + if not release: + return + self.branch = release.get("target_commitish", "?") + self.dl_info = self._find_asset(release) + commits = await self._github_request( + f"repos/{self.repo}/commits?sha={self.nightly_tag}&per_page=1" + ) + if not commits: + return + self.remote_hash = commits[0].get("sha", "?") + self.remote_version = self.remote_hash[:SHORT_HASH_LEN] + if self.version == "?": + return + comparison = await self._github_request( + f"repos/{self.repo}/compare/{self.version}...{self.remote_hash}" + ) + if comparison is None: + if self.last_error: + self.commits_behind = [] + self.commits_behind_count = 0 + return + self.commits_behind_count = comparison.get("ahead_by", 0) + new_commits: List[Dict[str, Any]] = comparison.get("commits", []) + self.commits_behind = [ + self._format_commit(commit) + for commit in reversed(new_commits[-GIT_MAX_LOG_CNT:]) + ] + + def _format_commit(self, commit: Dict[str, Any]) -> Dict[str, Any]: + info: Dict[str, Any] = commit.get("commit", {}) + author: Dict[str, Any] = info.get("author", {}) + subject, _, message = info.get("message", "").partition("\n") + date: str = author.get("date", "") + timestamp = 0 + if date: + timestamp = int( + datetime.fromisoformat(date.replace("Z", "+00:00")).timestamp() + ) + return { + "sha": commit.get("sha", ""), + "author": author.get("name", ""), + "date": str(timestamp), + "subject": subject.strip(), + "message": message.strip(), + "tag": None + } + + def _log_app_info(self) -> None: + warn_str = "" + if self.warnings: + warn_str = "\nWarnings:\n" + warn_str += "\n".join([f" {item}" for item in self.warnings]) + dl_url, content_type, size = self.dl_info + self.log_info( + f"Detected\n" + f"Repo: {self.repo}\n" + f"Channel: {self.channel}\n" + f"Local Version: {self.version}\n" + f"Remote Version: {self.remote_version}\n" + f"Remote Hash: {self.remote_hash}\n" + f"Commits Behind: {self.commits_behind_count}\n" + f"Valid: {self._is_valid}\n" + f"Download Url: {dl_url}\n" + f"Download Size: {size}\n" + f"Content Type: {content_type}\n" + f"Rollback Version: {self.rollback_version}" + f"{warn_str}" + ) + + def _update_available(self) -> bool: + if self.channel == Channel.DEV: + return self.commits_behind_count > 0 + return self.remote_version not in ("?", self.version) + + async def update( + self, rollback_info: Optional[Tuple[str, str, int]] = None + ) -> bool: + if self.reboot_pending: + raise self.server.error( + f"{self.prefix}Reboot pending, aborting update" + ) + if not self._is_valid: + raise self.server.error( + f"{self.prefix}Invalid install detected, aborting update" + ) + if rollback_info is not None: + dl_info = rollback_info + new_ver = self.rollback_version + start_msg = "Rolling Back..." + else: + if not self._update_available(): + return False + dl_info = self.dl_info + new_ver = self.remote_version + start_msg = "Updating..." + dl_url, _, size = dl_info + if dl_url == "?": + raise self.server.error( + f"{self.prefix}Release asset '{self.asset_name}' not found" + ) + current_version = self.version + event_loop = self.server.get_event_loop() + self.notify_status(start_msg) + self.notify_status("Downloading Release...") + td = await self.cmd_helper.create_tempdir(self.name, "app") + try: + swu_file = pathlib.Path(td.name).joinpath(self.asset_name) + await self._download(dl_url, swu_file, size) + self.notify_status("Download Complete, installing firmware...") + await self.cmd_helper.run_cmd( + f"{self.install_cmd} {shlex.quote(str(swu_file))}", + timeout=INSTALL_TIMEOUT, notify=True, log_stderr=True + ) + finally: + await event_loop.run_in_thread(td.cleanup) + if rollback_info is None: + self.rollback_version = current_version + self.reboot_pending = True + self._save_state() + self.notify_status(f"Installed version {new_ver}, rebooting...") + event_loop.delay_callback(REBOOT_DELAY, self._reboot) + msg = "Update Finished..." if rollback_info is None else "Rollback Complete" + self.notify_status(msg, is_complete=True) + return True + + async def _download(self, url: str, dest: pathlib.Path, size: int) -> None: + last_pct = -1 + + def report_progress(eventtime: float) -> float: + nonlocal last_pct + try: + downloaded = dest.stat().st_size + except OSError: + downloaded = 0 + pct = min(100, int(downloaded / size * 100)) if size > 0 else 0 + if pct != last_pct: + last_pct = pct + self.cmd_helper.on_download_progress(pct, size, downloaded) + return eventtime + DOWNLOAD_PROGRESS_INTERVAL + + timer = self.server.get_event_loop().register_timer(report_progress) + timer.start() + try: + await self.cmd_helper.run_cmd( + f"curl -fsSL --retry 3 -o {shlex.quote(str(dest))} " + f"{shlex.quote(url)}", + timeout=DOWNLOAD_TIMEOUT, log_stderr=True + ) + finally: + timer.stop() + report_progress(0.) + + async def _reboot(self) -> None: + if self.cmd_helper.is_update_busy(): + self.server.get_event_loop().delay_callback(REBOOT_DELAY, self._reboot) + return + self.log_info("Rebooting to complete firmware update") + machine: Machine = self.server.lookup_component("machine") + await machine.get_system_provider().reboot() + + async def rollback(self) -> bool: + if self.rollback_version in ("?", self.version): + return False + release = await self._github_request( + f"repos/{self.repo}/releases/tags/{self.rollback_version}" + ) + if not release: + raise self.server.error( + f"No release found for rollback version {self.rollback_version}" + ) + return await self.update(self._find_asset(release)) + + def get_update_status(self) -> Dict[str, Any]: + status = super().get_update_status() + warnings = list(self.warnings) + if self.remote_version != "?" and self.dl_info[0] == "?": + warnings.append( + f"Asset '{self.asset_name}' not found in remote release" + ) + status.update({ + "name": self.name, + "owner": self.owner, + "repo_name": self.project_name, + "version": self.version, + "remote_version": self.remote_version, + "rollback_version": self.rollback_version, + "last_error": self.last_error, + "warnings": warnings, + "anomalies": [] + }) + if self.channel != Channel.DEV: + status["configured_type"] = str(AppType.WEB) + return status + repo_url = f"https://github.com/{self.repo}" + status.update({ + "configured_type": str(AppType.GIT_REPO), + "detected_type": str(AppType.GIT_REPO), + "repo_detected": True, + "remote_alias": "origin", + "branch": self.branch, + "remote_url": repo_url, + "recovery_url": repo_url, + "current_hash": self.version, + "remote_hash": self.remote_hash, + "is_dirty": False, + "detached": False, + "commits_behind": self.commits_behind, + "commits_behind_count": self.commits_behind_count, + "git_messages": [], + "full_version_string": self.version, + "pristine": True, + "corrupt": False + }) + return status diff --git a/meta-opencentauri/recipes-apps/moonraker/moonraker_0.10.0.bb b/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb similarity index 89% rename from meta-opencentauri/recipes-apps/moonraker/moonraker_0.10.0.bb rename to meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb index b344ae37..9129d058 100644 --- a/meta-opencentauri/recipes-apps/moonraker/moonraker_0.10.0.bb +++ b/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb @@ -6,18 +6,22 @@ HOMEPAGE = "https://github.com/Arksine/moonraker" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://LICENSE;md5=db95b6e40dc7d26d8308b6b7375637b6" +PACKAGE_ARCH = "${MACHINE_ARCH}" + FILESEXTRAPATHS:prepend := "${THISDIR}/files:" SRC_URI = " \ git://github.com/Arksine/moonraker.git;protocol=https;branch=master \ + file://swu_deploy.py;subdir=${BP}/moonraker/components/update_manager/ \ file://moonraker-init-d \ file://moonraker.conf \ file://moonraker-readonly.conf \ file://0001-Serve-static-files.patch \ file://0001-Reduce-log-rotate-threshold.patch \ + file://0001-Add-support-for-SWUDeploy.patch \ " -SRCREV = "16e530eb663218faa6ccd97ffb0583f1880e2983" +SRCREV = "985c1d0bbeb90bc057d34a232c9dc3b05e0c6c8d" PR = "r1" @@ -51,6 +55,7 @@ RDEPENDS:${PN} = " \ python3-msgspec \ python3-uvloop \ python3-aiofiles \ + curl \ kalico \ " @@ -78,6 +83,7 @@ do_install() { # Copy readonly config file to readonly folder install -d ${D}${sysconfdir}/klipper/config/moonraker-readonly install -m 0644 ${UNPACKDIR}/moonraker-readonly.conf ${D}${sysconfdir}/klipper/config/moonraker-readonly/moonraker.conf + sed -i -e 's,@MACHINE@,${MACHINE},g' ${D}${sysconfdir}/klipper/config/moonraker-readonly/moonraker.conf # Symlink gcodes to /user-resource ln -sf /user-resource/gcodes ${D}${sysconfdir}/klipper/gcodes diff --git a/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh b/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh index 6f46b7f0..3d04c82d 100644 --- a/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh +++ b/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh @@ -6,6 +6,7 @@ CONFIG_MANAGER="/usr/bin/config-manager" OUTPUT_DIR="/etc/klipper/config/klipper-readonly" OUTPUT_FILE="${OUTPUT_DIR}/_vars.cfg" EXTRAS_OUTPUT_FILE="${OUTPUT_DIR}/zextras.cfg" +MOONRAKER_UPDATE_FILE="/etc/klipper/config/moonraker-readonly/zupdate.conf" get_config_value() { "${CONFIG_MANAGER}" klipper "$1" @@ -25,6 +26,7 @@ full_calibrate_bed_temperature=$(get_config_value full_calibrate_bed_temperature bypass_calibration=$(get_config_value bypass_calibration) toolhead_led=$(get_config_value toolhead_led) elegoo_canvas=$("${CONFIG_MANAGER}" extras elegoo_canvas) +release=$("${CONFIG_MANAGER}" update release) mkdir -p "${OUTPUT_DIR}" @@ -60,3 +62,14 @@ if [ "${elegoo_canvas}" = "True" ]; then echo "[include ../extras-readonly/canvas.cfg]" >> "${EXTRAS_OUTPUT_FILE}" fi +cat > "${MOONRAKER_UPDATE_FILE}" <> "${MOONRAKER_UPDATE_FILE}" + echo "channel: dev" >> "${MOONRAKER_UPDATE_FILE}" +fi + From 1e15effe245b26875e203935ee8a04fa284a10b0 Mon Sep 17 00:00:00 2001 From: James Turton Date: Sat, 3 Oct 2026 22:08:14 +0200 Subject: [PATCH 2/2] Make moonraker respect check_for_updates --- .../moonraker/files/moonraker-readonly.conf | 6 ------ .../recipes-apps/moonraker/moonraker_0.11.0.bb | 3 --- .../config-manager/config-manager_0.1.bb | 3 +++ .../config-manager/files/build-klipper-var-config.sh | 12 ++++++++++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf index 4eabeca1..8bcf705f 100644 --- a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf +++ b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-readonly.conf @@ -45,9 +45,3 @@ snapshot_url: /webcam/?action=snapshot [update_manager] enable_system_updates: False - -[update_manager cosmos] -type: swupdate -repo: OpenCentauri/cosmos -asset_name: cosmos-@MACHINE@.swu -channel: stable diff --git a/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb b/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb index 9129d058..9c9c3a2a 100644 --- a/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb +++ b/meta-opencentauri/recipes-apps/moonraker/moonraker_0.11.0.bb @@ -6,8 +6,6 @@ HOMEPAGE = "https://github.com/Arksine/moonraker" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://LICENSE;md5=db95b6e40dc7d26d8308b6b7375637b6" -PACKAGE_ARCH = "${MACHINE_ARCH}" - FILESEXTRAPATHS:prepend := "${THISDIR}/files:" SRC_URI = " \ @@ -83,7 +81,6 @@ do_install() { # Copy readonly config file to readonly folder install -d ${D}${sysconfdir}/klipper/config/moonraker-readonly install -m 0644 ${UNPACKDIR}/moonraker-readonly.conf ${D}${sysconfdir}/klipper/config/moonraker-readonly/moonraker.conf - sed -i -e 's,@MACHINE@,${MACHINE},g' ${D}${sysconfdir}/klipper/config/moonraker-readonly/moonraker.conf # Symlink gcodes to /user-resource ln -sf /user-resource/gcodes ${D}${sysconfdir}/klipper/gcodes diff --git a/meta-opencentauri/recipes-data/config-manager/config-manager_0.1.bb b/meta-opencentauri/recipes-data/config-manager/config-manager_0.1.bb index 1113dff3..08dcd19e 100644 --- a/meta-opencentauri/recipes-data/config-manager/config-manager_0.1.bb +++ b/meta-opencentauri/recipes-data/config-manager/config-manager_0.1.bb @@ -2,6 +2,8 @@ DESCRIPTION = "Config manager script and default configuration" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-3.0-only;md5=c79ff39f19dfec6d293b95dea7b07891" +PACKAGE_ARCH = "${MACHINE_ARCH}" + SRC_URI = " \ file://config_manager.py \ file://build-klipper-var-config.sh \ @@ -14,6 +16,7 @@ do_install() { install -d ${D}${bindir} install -m 0755 ${S}/config_manager.py ${D}${bindir}/config-manager install -m 0755 ${S}/build-klipper-var-config.sh ${D}${bindir}/build-klipper-var-config + sed -i -e 's,@MACHINE@,${MACHINE},g' ${D}${bindir}/build-klipper-var-config install -d ${D}${sysconfdir}/klipper/config install -m 0644 ${S}/default.conf ${D}${sysconfdir}/klipper/config/cosmos.conf diff --git a/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh b/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh index 3d04c82d..1a387074 100644 --- a/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh +++ b/meta-opencentauri/recipes-data/config-manager/files/build-klipper-var-config.sh @@ -26,6 +26,7 @@ full_calibrate_bed_temperature=$(get_config_value full_calibrate_bed_temperature bypass_calibration=$(get_config_value bypass_calibration) toolhead_led=$(get_config_value toolhead_led) elegoo_canvas=$("${CONFIG_MANAGER}" extras elegoo_canvas) +check_for_updates=$("${CONFIG_MANAGER}" update check_for_updates) release=$("${CONFIG_MANAGER}" update release) mkdir -p "${OUTPUT_DIR}" @@ -68,8 +69,15 @@ cat > "${MOONRAKER_UPDATE_FILE}" <> "${MOONRAKER_UPDATE_FILE}" - echo "channel: dev" >> "${MOONRAKER_UPDATE_FILE}" + echo "type: swupdate" >> "${MOONRAKER_UPDATE_FILE}" + echo "repo: OpenCentauri/cosmos" >> "${MOONRAKER_UPDATE_FILE}" + echo "asset_name: cosmos-@MACHINE@.swu" >> "${MOONRAKER_UPDATE_FILE}" + if [ "${release}" = "nightly" ]; then + echo "channel: dev" >> "${MOONRAKER_UPDATE_FILE}" + else + echo "channel: stable" >> "${MOONRAKER_UPDATE_FILE}" + fi fi