Skip to content

Run COSMOS updates through Moonraker's update_manager - #313

Open
kyleinoregon wants to merge 3 commits into
OpenCentauri:mainfrom
kyleinoregon:cosmos-update-manager
Open

Run COSMOS updates through Moonraker's update_manager#313
kyleinoregon wants to merge 3 commits into
OpenCentauri:mainfrom
kyleinoregon:cosmos-update-manager

Conversation

@kyleinoregon

@kyleinoregon kyleinoregon commented Sep 5, 2026

Copy link
Copy Markdown

Replaces #308, following the discussion there: consistency across UIs by using the update_manager API that Mainsail and Fluidd already implement. The screen side is pellcorp/grumpyscreen#289.

Reworked after the first review: everything about updates now lives in Moonraker. No shell helper, no Klipper macros, no startup check script, and the component no longer touches update_manager's table beyond adding its own entry.

What changes

  • cosmos_update.py, a Moonraker component placed into the Moonraker source tree by the recipe (subdir=), so the installed tree is the same as the source. It registers a cosmos entry with update_manager: installed version from /etc/issue, channel from config-manager, latest version from the GitHub releases list on the stable channel or commits behind main on nightly. The update step runs update-cosmos and streams its output line by line to the clients.
  • 0001-update_manager-skip-placeholder-applications.patch: update_manager always creates klipper and moonraker entries, and on this image neither is a git checkout, so they are bare placeholders with an empty status that Mainsail and Fluidd render as empty rows. The patch leaves entries without a status out of the status response and the refreshed notification (two hunks). Worth sending upstream as well.
  • moonraker-readonly.conf enables [update_manager] (system updates off, refresh once a day) and the [cosmos_update] section.
  • update-cosmos now prints what it is doing: download progress in 20 % steps, install, reboot, and a plain failure line if the download or the flash fails. The curl and swupdate chatter goes to /board-resource/update-cosmos.log instead of the user's screen. URLs, flash, cleanup, reboot and exit codes are unchanged.
  • grumpyscreen.cfg gains [update_manager] application: cosmos. With Run the update through Moonraker's update_manager when configured pellcorp/grumpyscreen#289 the screen's update button sends machine.update.client over its own Moonraker connection and shows the notify_update_response stream in a dialog. Until cosmos ships a grumpyscreen with that client the button keeps running update-cosmos directly, as today.
  • Removed: the check-update script and recipe, the CHECK_FOR_UPDATES / UPDATE_COSMOS shell commands, the _UPDATE_COSMOS macro, the startup check_for_updates_startup delayed gcode, the "Update Available" special case in _SHOW_PROMPT, and the check_for_updates option in cosmos.conf. update_manager's own refresh replaces the check, and the web UIs show the result in their update panel. A leftover check_for_updates line in a user's cosmos.conf is ignored by config-manager.

What the user sees

  • Mainsail and Fluidd: a "cosmos" row in the update panel with 26.08.0 > 26.09.0 and a working Update button when a release is out, a release-notes link, and the standard update dialog with the live log during the update. The dialog appears whichever UI or button started the update.
  • Screen: with Run the update through Moonraker's update_manager when configured pellcorp/grumpyscreen#289, the same messages in a dialog on the panel, ending on "COSMOS update installed, the printer is rebooting". The startup "Update Available" prompt is gone; if a screen-side notice is wanted, it can be added on the grumpyscreen side from notify_update_refreshed.

Tested

On a Centauri Carbon running 26.08.0:

  • Component loaded with Moonraker 0.10 as shipped; status reports 26.08.0 installed / 26.08.0 latest from GitHub; with the patch the placeholder klipper/moonraker rows are gone.
  • Dry-run update through machine.update.client: every line streamed to a websocket client and to Mainsail's update dialog, completion flag at the end.
  • update-cosmos run against the real release asset with flash and reboot stubbed: download progress lines at 20 % steps, install and reboot lines, chatter in the log file, swu file cleaned up.
  • A real update through the whole path, started from the screen's Update button with the Drop smooth time to 1.5 to cover all* hotends #289 client: 26.08.0 re-flashed to the other slot (boot slot flipped A -> B, swupdate's post-update steps in the log), progress shown on the screen and in Mainsail, automatic reboot, printer back in about a minute with printer.cfg byte-identical and all calibration loaded.
  • The final line carries update_manager's completion flag, so clients know when to close their dialog.

The recipe's grumpyscreen SRCREV is not bumped here; pellcorp merges #289 once this is in, and the bump can follow.

The docs page that mentions check_for_updates (troubleshooting/questions.md in OpenCentauri/OpenCentauri) needs a follow-up once this lands.

Register a "cosmos" entry with Moonraker's update_manager, so every client
that speaks that API (Mainsail and Fluidd today) shows the installed and
latest COSMOS version, offers the Update button, and follows the update
in the standard update dialog. The update itself runs under Moonraker,
outside Klipper's command queue, so it can no longer be cut off by the
shell command timeout.

- cosmos_update.py (Moonraker component): looks up the installed version
  and channel, checks GitHub for the latest stable release (or commits
  behind main on the nightly channel), and runs update-cosmos with its
  output streamed to the clients. No change to update_manager itself.
- update-cosmos prints what it is doing (download progress in 20% steps,
  install, reboot, failures) and sends the curl/swupdate chatter to
  /board-resource/update-cosmos.log.
- cosmos-update-start asks Moonraker to run the update and returns at
  once; the "Update Now" prompt button and the screen's Update button both
  use it, so all entry points share the same path and the same progress.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@jamesturton jamesturton left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just done a first pass at reviewing this, but there a quite a few major issues so I haven't gone into too much detail.

file://moonraker-init-d \
file://moonraker.conf \
file://moonraker-readonly.conf \
file://cosmos_update.py \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use subdir, we want the source to be coherent

install -d ${D}${datadir}/moonraker
cp -r ${S}/moonraker ${D}${datadir}/moonraker/
# COSMOS updater for update_manager
install -m 0644 ${WORKDIR}/cosmos_update.py ${D}${datadir}/moonraker/moonraker/components/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this, see comment above

factory_reset_cmd: /usr/bin/factory-reset
gui_restart_cmd: /etc/init.d/gui-switcher restart
cosmos_update_cmd: /usr/bin/update-cosmos
cosmos_update_cmd: /usr/bin/cosmos-update-start

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you splitting it out over grumpyscreen logic and shell scripts?
The whole point of this was for grumpyscreen to use the existing moonraker API rather than including lots of hacks for cosmos

@@ -93,8 +93,8 @@ timeout: 5
verbose: False

[gcode_shell_command UPDATE_COSMOS]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like all these update macros to be removed and for everything regarding updates to be handled in moonraker, not klipper

# Start a COSMOS update through Moonraker's update_manager and return at once.
# Every UI that speaks the update_manager API then shows the progress; the
# update itself runs under Moonraker, outside Klipper's command queue.
curl -s -X POST "http://localhost/machine/update/client?name=cosmos" >/dev/null 2>&1 &

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like this at all. Grumpyscreen should use the existing moonraker connection. Splitting it out into a shell script makes no sense here

phiplant and others added 2 commits September 5, 2026 00:33
Review follow-up. The cosmos_update.py component is now placed into the
Moonraker source tree with the subdir fetcher option instead of being
copied in do_install. The cosmos-update-start helper, the UPDATE_COSMOS
and CHECK_FOR_UPDATES shell commands, the _UPDATE_COSMOS macro, the
startup update check, the check-update script and the check_for_updates
option are removed: update_manager refreshes on its own schedule and the
web UIs show what it finds, and grumpyscreen starts the update over its
own Moonraker connection (pellcorp/grumpyscreen#289) using the
[update_manager] application key in grumpyscreen.cfg. The screen's
cosmos_update_cmd and the recipe wording are back to what main ships.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rom the component

update_manager always creates klipper and moonraker entries; on this
image neither is a git checkout, so they are bare BaseDeploy placeholders
whose status is an empty dict and the UIs show them as empty rows. The
component used to pop them from update_manager's table and re-pop them on
timers after every Klippy connect. Replace that with a two-hunk patch to
update_manager that leaves entries without a status out of the status
response and the refreshed notification. The component now only registers
the cosmos updater.

Also use calendar.timegm for the commit dates and drop the duplicate
refresh_interval from the cosmos_update section.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kyleinoregon

Copy link
Copy Markdown
Author

Sorry for the extra review load, the first version had more moving parts than it needed. Reworked: the component goes into the Moonraker source tree via subdir= and the extra install line is gone. The cosmos-update-start helper, the UPDATE_COSMOS / CHECK_FOR_UPDATES shell commands, the _UPDATE_COSMOS macro, the startup check, the check-update script and the check_for_updates option are all removed. The component no longer touches update_manager's table beyond adding its own entry; the empty klipper/moonraker rows are handled by a two-hunk patch to update_manager (skip entries with no status), which could go upstream too. The only thing left outside Moonraker is [update_manager] application: cosmos in grumpyscreen.cfg, the key pellcorp/grumpyscreen#289 reads to send machine.update.client over grumpyscreen's own Moonraker connection. pellcorp will merge #289 once this is in, so the grumpyscreen SRCREV bump would follow. One question: with the startup check gone, new versions show in Mainsail's and Fluidd's update panel through update_manager's refresh. Is that enough, or do you want a screen-side notice too? That would be a small addition on the grumpyscreen side from notify_update_refreshed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants