Skip to content

Add sysupdate backend - #247

Open
leolost2605 wants to merge 10 commits into
mainfrom
leolost/sysupdate
Open

leolost2605 wants to merge 10 commits into
mainfrom
leolost/sysupdate

Conversation

@leolost2605

@leolost2605 leolost2605 commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

This now introduces SysupdateTarget (and some utility classes use by it) which has a convenient (and stateless) API to communicate with sysupdate. It can be used by the system update and also for selecting features in the future. If we want to move it completely to the settings this class can be moved one to one there. It then uses that in the SystemDSystemUpdate which mirrors the exact interface that the packagekit system update has.

image

Testing

This is what I came up with since it's the first time i've really worked with an image based os. If anybody has a better way to do this or a great workflow you want to share I'd be happy. But what I did didn't take too long as well and should be pretty robust.

I used sysext which has a great introduction in this blog: https://blogs.gnome.org/alatiera/2023/08/04/developing-gnome-os-systemd-sysext/ together with distrobox because not all dependencies are yet in the sdk.

  1. Install ptyxis which IMO makes it a bit easier to work with containers as it has integrated support and you can see at glance whether you are in a container or not
  2. Create you container: distrobox create --image ubuntu:26.04 -n my-container
  3. enter the container either via distrobox enter my-container or via the ptyxis profiles and containers drop down
  4. install the dependencies for the settings daemon and your utilities like git and meson etc. You might also have to add the elementary os patches ppa because we need a newer gtk4 vapi that only ships there.
  5. clone the settings daemon in your projects directory (home is shared with the container so it doesn't matter whether you do this on the host or in the container)
  6. in the container run your normal meson setup build --prefix=/usr
  7. switch to your build dir
  8. then still in the container run sudo DESTDIR=~/sys-exts/settings-daemon meson install. This will create a file hierarchy under ~/sys-exts/settings-daemon that contains your normal /usr that only contains your settings daemon
  9. Now on your host you can copy that settings-daemon folder to /run/extensions
  10. On the host run sudo systemd-sysext refresh --force
  11. Now the settings daemon binary will be the one from the extensions so you can just do killall io.elementary.settings-daemon and then run io.elementary.settings-daemon and you are running this PR
  12. You can use systemd-sysext to manage the extension during your current boot and the extension will automatically be removed when you reboot so no need to worry about breaking your system.

Note that this will cause some problems if you have changes to the gschemas etc. because they have to be compiled via a custom script and custom scripts are skipped when running meson install with a custom DESTDIR so you would have to compile them manually. GNOMEs sysext-utils would take care of that but for now this should work.

@leolost2605 leolost2605 changed the title WIP Add sysupdate backend Oct 2, 2026
@danirabbit danirabbit added this to OS 9 Oct 2, 2026
@leolost2605

Copy link
Copy Markdown
Member Author

This PR now allows checking for new updates, updating, cancelling the update and also says that a restart is required. Progress report is left to a follow up. It's also missing any automatic updates stuff and last refresh time etc. since I wanted to focus on the actual functional parts. The rest is pretty independent from sysupdate and can always be added later without changing any architecture.

I think we should keep the system update in the settings daemon. A few reasons for that:

  • we get full control over automatic updates
  • it's a lot easier by having this standalone running process. While sysupdate allows to list running jobs there currently doesn't seem to be a way to match them to a target let alone an update. This would mean we would have to store the object path separately and then on start check if the object path exists and the job still exists and then reconnect to it which might get a bit complicated.
  • there doesn't seem to be too many drawbacks
  • though like I said the actual sysupdate classes can be copied one to one to the settings if we really would prefer that.

Now a few answers to things from the discussion in elementary/settings-system#422

With sysupdate we get actual versioned updates instead of a list of packages. So we'd need to handle an empty package list and then add a version field and handle that if it's empty. So right away we're getting into some messy stuff

Yeah we probably want to adjust the API at some point. But for now just sending the new version as a "package" works fine IMO.

We also will need a metainfo file I think to determine if an update contains security fixes. We could just parse that in settings daemon, but we'll need to parse it in both the daemon and in system setting anyways if we want to show release notes in system settings or include the link to the latest blog post or use other metainfo features: https://www.freedesktop.org/software/appstream/docs/sect-Metadata-OS.html

This ofc needs adjusted API but apart from that I don't think we need to parse it in both. I think we should just parse it in the system settings to get the release notes. The main reason why we would want to parse it in the daemon would be too handle security updates but I don't think it makes a lot of sense anymore to differentiate between security fixes and other updates. The main reason for this is that given that we only have one monolithic image chances are that every update contains at least one security fix in one package.

Like you said, sysupdate already runs as a separate service, so we don't need to worry about this

Like I said above unfortunately it turns out that this would be a bit more complex than expected but ofc still doable though I'm not sure it's worth the effort.

All in all IMO having it in the settings daemon is the better option but I'm not entirely against moving it to system settings as well. My main point was that I wanted to make sure we have some abstraction around the actual sysupdate logic and a rough plan for what we all need to support everything we want (e.g. I struggled a bit to find a proper way of handling jobs without races and still provide a good API while also making sure that it scales and is flexible because even the dbus interface API has been broken in the latest release (update will be two jobs: download + install instead of a single update job)) which is here now provided by SysupdateTarget that then can be used by the actual stateful update manager.

@leolost2605
leolost2605 force-pushed the leolost/sysupdate branch 4 times, most recently from 518fa52 to d1a8b43 Compare October 4, 2026 17:41
@leolost2605
leolost2605 marked this pull request as ready for review October 4, 2026 18:32
@leolost2605

Copy link
Copy Markdown
Member Author

Should be ready for an initial review :)

@leolost2605
leolost2605 requested a review from a team October 4, 2026 18:33

@danirabbit danirabbit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we add an interface that the backends implement so we can make sure to keep them in sync?

Comment thread src/Backends/SystemDSystemUpdate.vala Outdated
*/

[DBus (name="io.elementary.settings_daemon.SystemUpdate")]
public class SettingsDaemon.Backends.SystemDSystemUpdate : Object {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a reason to not just call this Sysupdate?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not really. I thought in the beginning it might be to similar to SystemUpdate but I think it's fine. However now the problem is that we also have the namespace Sysupdate which will clash if we try to use something from there in this class (notably Sysupdate.Target.HOST_PATH). We could change the namespace to DBus.Sysupdate but idk. Open to any suggestions :)

@leolost2605

leolost2605 commented Oct 7, 2026 •

Copy link
Copy Markdown
Member Author

Can we add an interface that the backends implement so we can make sure to keep them in sync?

Unfortunately this is a bigger refactor than I thought in the beginning. We then can't export the backend directly because the dbus generation doesn't recognize the interface async methods somehow. So we would need an intermediate class that just passes through the calls to the backend. I have a branch for that but I wasn't sure how much we want to make this exchangeable. I'll propose a separate PR for this :)

Edit: #251

@leolost2605

Copy link
Copy Markdown
Member Author

I also added progress report now since with the infrastructure in place that is only minimal changes :)

@leolost2605
leolost2605 requested a review from danirabbit October 9, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

2 participants