ORG.FREED...SYSUPDATE1(5)

πŸ’– NAME πŸ’–

org.freedesktop.sysupdate1 β€” literally the D-Bus interface of systemd-sysupdated, bestie. That's it, that's the name.


✨ EXPERIMENTAL ✨

Okay so real talk: this component is experimental and it can change without advance notice. Like, no heads up, no warning text, just vibes shifting under your feet 😭. It will get stabilized and given a backward-compatibility guarantee in a future release β€” pinky promise β€” but it may also possibly be removed entirely. So don't build your whole personality on it just yet. 🫢


🌸 INTRODUCTION 🌸

systemd-sysupdated.service(8) is a system service that lets unprivileged clients update the system. Iconic behavior honestly. And this page right here? It describes the D-Bus interface. πŸ’…

WARNING! This API is currently unstable and is thus subject to breaking changes between versions of systemd. Not "might", is. Protect your peace and your codebase accordingly. πŸ’€

πŸ‘‘ THE MANAGER OBJECT πŸ‘‘

The service exposes the following interfaces on the Manager object on the bus:

node /org/freedesktop/sysupdate1 {
  interface org.freedesktop.sysupdate1.Manager {
    methods:
      ListTargets(out a(sso) targets);
      ListJobs(out a(tsuo) jobs);
      ListAppStream(out as urls);
    signals:
      JobRemoved(t id,
                 o path,
                 i status);
  };
  interface org.freedesktop.DBus.Peer { ... };
  interface org.freedesktop.DBus.Introspectable { ... };
  interface org.freedesktop.DBus.Properties { ... };
};

πŸ”₯ Methods πŸ”₯

  • ListTargets() β€” returns a list of all the known update targets, no cap. It hands you back an array of structures, and each structure has: a string for the target's class (peep the Target's Class property below for what the possible values even are), a string with the target's name, and the target's object path. Three little pieces, one cute lil struct. πŸŽ€
  • ListJobs() β€” returns a list of all the ongoing jobs. Same deal, array of structures, and each one is: a numeric job ID, a string for the job type (see Job's Type property below for the possible values), the job's progress, and the job's object path.
  • ListAppStream() β€” returns an array of every appstream catalog URL this service knows about. Want the tea on what that even means? Check Target's GetAppStream() method below. β˜•

πŸ’Œ Signals πŸ’Œ

The JobRemoved() signal gets sent every single time a job finishes, gets canceled, or fails. Like a little group-chat notification that the job is done.

It carries the job ID and the object path, followed by a numeric status code. And here's the important part, so listen up:

  • If the status is zero, the job has succeeded. Slay. βœ…
  • A positive status should be treated as an exit code (i.e. "EXIT_FAILURE").
  • A negative status should be treated as a negative errno-style error code (i.e. "-EINVAL").

So like, read the sign. It matters. πŸ’…


πŸ¦‹ THE TARGET OBJECT πŸ¦‹

A target is a component of the system (i.e. the host itself, a sysext, a confext, etc.) that can be updated by systemd-sysupdate(8). Basically a thing that gets updated. Very main character.

The service exposes the following interfaces on Target objects on the bus:

node /org/freedesktop/sysupdate1/target/host {
  interface org.freedesktop.sysupdate1.Target {
    methods:
      List(in  t flags,
           out as versions);
      Describe(in  s version,
               in  t flags,
               out s json);
      CheckNew(out s new_version);
      Acquire(in  s new_version,
              in  t flags,
              out s new_version,
              out t job_id,
              out o job_path);
      Install(in  s new_version,
              in  t flags,
              out s new_version,
              out t job_id,
              out o job_path);
      Vacuum(out u instances,
             out u disabled_transfers);
      GetAppStream(out as appstream);
      GetVersion(out s version);
      ListFeatures(in  t flags,
                   out as features);
      DescribeFeature(in  s feature,
                      in  t flags,
                      out s json);
      SetFeatureEnabled(in  s feature,
                        in  i enabled,
                        in  t flags);
    properties:
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Class = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Name = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Path = '...';
  };
  interface org.freedesktop.DBus.Peer { ... };
  interface org.freedesktop.DBus.Introspectable { ... };
  interface org.freedesktop.DBus.Properties { ... };
};

🌈 Methods 🌈

✨ List()

List() returns a list of versions available for this target. Extra options can be passed through the flags argument. The valid flags are defined like this:

#define SD_SYSUPDATE_OFFLINE    (UINT64_C(1) << 0)

When SD_SYSUPDATE_OFFLINE is set, this method returns only the versions installed locally. Otherwise, it pulls metadata from the network and returns all versions available for this target. And to get more deets on any version it hands back, use Describe(). 🫢

πŸ’… Describe()

Describe() returns all the known information about a given version, as a JSON object. The version argument is how you pass in the version you want described. Extra options can go through the flags argument, and this method supports the same flags as List().

The returned JSON object contains several known keys β€” more keys may be added in the future, so stay flexible bestie β€” and the currently known keys are:

  • "version" β€” a string containing the version number.
  • "newest" β€” a boolean, says whether this version is the latest available for the target.
  • "available" β€” a boolean, says whether this version is available for download.
  • "installed" β€” a boolean, says whether this version is installed locally.
  • "obsolete" β€” a boolean, says whether this version is considered obsolete by the service, and is therefore disallowed from being installed. So like, blocked, respectfully. 🚫
  • "protected" β€” a boolean, says whether this version is exempt from deletion by a Vacuum() operation.
  • "incomplete" β€” a boolean, says whether this version is incomplete, which means it is missing some file. Heads up: only installed incomplete versions will be offered by the service β€” versions that are incomplete on the server-side are completely ignored. And the good news is incomplete versions can be repaired in-place by calling Acquire() and Install() on that version. ✨
  • "changelogUrls" β€” a list of strings containing user-presentable URLs to change logs associated with this version. The lore. πŸ“œ

πŸ” CheckNew()

CheckNew() checks if a newer version is available for this target. It pulls metadata from the network. If a newer version is found, it returns the version number. If no newer version is found, it returns an empty string (sad, but honest 😭). Use Describe() to query more information about the version it returns.

πŸ’Ύ Acquire()

Acquire() downloads an update for this target, if one is available. If a new_version is specified, that's the version that gets downloaded. Otherwise, the latest version gets downloaded. Call Install() to install the acquired update. The flags argument is there for future extensibility β€” no flags are currently defined, and the argument is required to be set to "0". This method pulls both metadata and payload data from the network. Heavy lifting energy. πŸ’ͺ

πŸŽ€ Install()

Install() installs an already-acquired update for this target. If a new_version is specified, that's the version that gets installed β€” assuming it's already been acquired. Otherwise, the latest acquired version gets installed. The flags argument is there for future extensibility, no flags are currently defined, and the argument is required to be set to "0".

Not me about to tell you the wild part: unlike all the other methods in this interface, Acquire() and Install() do not wait for their jobs to complete. Instead, they return the job's numeric ID and object path as soon as the job begins, so the caller can listen for progress updates or cancel the operation. They also return the version the target will be updated to, for those cases where no version was specified by the caller. Listen for the Manager's JobRemoved() signal to detect when the job is complete. That's the whole workflow, periodt. πŸ‘‘

🧹 Vacuum()

Vacuum() deletes old installed versions of this target to free up space. It returns the number of instances that have been deleted. Spring cleaning but make it systemd. 🧚

πŸ“ GetAppStream()

GetAppStream() returns a list of HTTP/HTTPS URLs to this target's appstream catalog[1] XML files. If this target has no appstream catalogs, the method returns an empty list. These catalog files can be used by software centers (such as GNOME Software or KDE Discover) to present rich metadata about the target, including a display name, changelog, icon, and more. And the returned catalogs will include special metadata[2] so the software center can correctly associate the catalogs with this target. It's giving ✨ organized ✨.

⭐ GetVersion()

GetVersion() returns the current version of this target, if any. The current version is the newest version that is installed. Important note though β€” that is not necessarily the same thing as the booted or currently-in-use version of the target. For example, on the host system the booted version is the current version most of the time, but if an update is installed and pending a reboot, it will become the current version instead. You can query the booted version of the host system via IMAGE_VERSION in /etc/os-release. If the target has no current version, the function returns an empty string.

🌟 ListFeatures()

ListFeatures() returns a list of this target's optional features, by ID. The flags argument is there for future extensibility and must be set to 0. If the target has no optional features, the method returns an empty array.

πŸ’œ DescribeFeature()

DescribeFeature() returns all the known information about a given optional feature. The feature argument is how you pass the ID of the feature to be described. The flags argument is there for future extensibility and must be set to 0.

The returned JSON object contains several known keys β€” more keys may be added in the future β€” and the currently known keys are:

  • "id" β€” a string containing the feature's ID.
  • "description" β€” an optional string containing a user-presentable description that identifies this feature.
  • "enabled" β€” a boolean, says whether this feature is enabled.
  • "suggested" β€” an optional boolean, says whether this feature is suggested for enablement. If it's omitted, it could not be determined whether the feature is suggested. 🀷
  • "documentation" β€” an optional array of strings containing user-presentable HTTP/HTTPS URLs to documentation about this feature.
  • "appStream" β€” an optional string containing an HTTP/HTTPS URL to an appstream catalog[1] XML file containing metadata about this feature.
  • "transfers" β€” an optional array of strings that list which transfer definitions belong to this feature.

(to be continued, bestie β€” there's more where this came from πŸ’–)

Okay so SetFeatureEnabled() writes an appropriate drop-in file to enable or disable the specified optional feature β€” it's giving "I flip the switch, you do the rest". If enable is zero, the feature gets disabled. If it's greater than zero, the feature is enabled. And if it's less than zero? The feature is reset to the distribution's default 🌸. The flags argument was added purely for future extensibility, and it must be set to 0 β€” no cap. Here's the cute part: the feature doesn't even have to exist! That's on purpose, so masked features get handled gracefully, and so preemptive decisions can be made about features that are planned to appear in future releases of the OS πŸ¦‹. The drop-in will have a filename of "50-systemd-sysupdate-enabled.conf".

Heads up bestie: this method only changes configuration files. To actually apply the changes, clients need to call Acquire() and Install(). Depending on the exact needs of the client, it can choose to update the system to the latest available version, or it can extend the newest existing installation in-place (by passing in the version returned by GetVersion()). For now, this method only works with the "host" target. πŸ’…

✨ Properties ✨

  • Class β€” exposes the class of this target, which describes where it was enumerated πŸ‘‘. Possible values include: "machine" for containers and virtual machines managed by systemd-machined.service(8), "portable" for portable services[3], "sysext" for system extensions managed by systemd-sysext(8), "confext" for configuration extensions managed by systemd-confext(8), "component" for components accepted by the --component= option of systemd-sysupdate(8), and "host" for the host system itself. At most one target will have a class of "host".
  • Path β€” exposes more detail about where this target was found πŸ”. For "machine", "portable", "extension", and "confext" targets, this is the file path to the image. For "component" and "host" targets, this is the name of a sysupdate.d(5) directory.
  • Name β€” exposes the name of this target. Note that the name is unique within a class but is not necessarily unique between classes. For instance, it is possible to have both a "portable" target named "foobar" and an "extension" target named "foobar", but it is not possible to have two "portable" targets named "foobar" 😌.

πŸ” Security πŸ”

Method calls on this service are authenticated via polkit[4] ✨.

  • List(), Describe(), and CheckNew() use the polkit action org.freedesktop.sysupdate1.check. By default, this action is permitted without administrator authentication 🫢. Cancellation of these methods uses the polkit action org.freedesktop.sysupdate1.cancel-check. By default, this cancellation action is permitted without administrator authentication.
  • Acquire() and Install() use the polkit action org.freedesktop.sysupdate1.update when no version is specified. By default, this action is permitted without administrator authentication. When a version is specified, org.freedesktop.sysupdate1.update-to-version is used instead β€” and by default, this alternate action requires administrator authentication πŸ”₯. Cancellation of these methods uses the polkit actions org.freedesktop.sysupdate1.cancel-update and org.freedesktop.sysupdate1.cancel-update-to-version. By default, these cancellation actions are permitted without administrator authentication.
  • Vacuum() uses the polkit action org.freedesktop.sysupdate1.vacuum. By default, this action requires administrator authentication. Cancellation of this method uses the polkit action org.freedesktop.sysupdate1.cancel-vacuum. By default, this cancellation action is permitted without administrator authentication.
  • SetFeatureEnabled() uses the polkit action org.freedesktop.sysupdate1.manage-features. By default, this action requires administrator authentication. Cancellation is not supported for this method 🚫.
  • GetAppStream(), GetVersion(), ListFeatures(), and DescribeFeature() are unauthenticated and may be called by anybody πŸŽ€. Cancellation is not supported for these methods, or is always allowed without administrator authentication.

All methods called on this interface expose additional variables to the polkit rules πŸ’œ. "class" contains the class of the Target being acted upon, and "name" contains the name of the same Target. Additionally, each method exposes its arguments to the rule. Flags are mapped as follows:

  • SD_SYSUPDATE_OFFLINE β†’ "update"

πŸ‘‘ THE JOB OBJECT πŸ‘‘

A job is an ongoing operation, started by one of the methods on a Target object. It's the main character of "something is happening right now" energy ⏳.

The service exposes the following interfaces on Job objects on the bus:

node /org/freedesktop/sysupdate1/job/_1 {
  interface org.freedesktop.sysupdate1.Job {
    methods:
      Cancel();
    properties:
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t Id = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Type = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Offline = ...;
      readonly u Progress = ...;
  };
  interface org.freedesktop.DBus.Peer { ... };
  interface org.freedesktop.DBus.Introspectable { ... };
  interface org.freedesktop.DBus.Properties { ... };
};

Methods

  • Cancel() β€” may be used to cancel the job πŸ›‘. It takes no parameters. That's it, that's the whole method, she's simple and she serves.

Properties

  • Id β€” exposes the numeric job ID of the job object πŸ”’.
  • Type β€” exposes the type of operation (one of: "list", "describe", "check-new", "acquire", "install", "vacuum", or "describe-feature") πŸ’«.
  • Offline β€” exposes whether the job is permitted to access the network or not 🌐.
  • Progress β€” exposes the current progress of the job as a value between 0 and 100. It is only available for "acquire" and "install" jobs; for all other jobs it is always 0 😭.

Security

Cancel() uses the polkit action that corresponds to the method that started this job πŸ”. For instance, trying to cancel a "list" job will require polkit to permit the org.freedesktop.sysupdate1.check action.


🌈 EXAMPLES 🌈

Example 1. Introspect org.freedesktop.sysupdate1.Manager on the bus

$ gdbus introspect --system \
  --dest org.freedesktop.sysupdate1 \
  --object-path /org/freedesktop/sysupdate1

Example 2. Introspect org.freedesktop.sysupdate1.Target on the bus

$ gdbus introspect --system \
  --dest org.freedesktop.sysupdate1 \
  --object-path /org/freedesktop/sysupdate1/target/host

Example 3. Introspect org.freedesktop.sysupdate1.Job on the bus

$ gdbus introspect --system \
  --dest org.freedesktop.sysupdate1 \
  --object-path /org/freedesktop/sysupdate1/job/_1

πŸŽ€ VERSIONING πŸŽ€

These D-Bus interfaces follow the usual interface versioning guidelines[5] πŸ“š.


πŸ“œ HISTORY πŸ“œ

The Manager Object

ListTargets(), ListJobs(), ListAppStream(), and JobRemoved() were added in version 257 ✨.

The Target Object

List(), Describe(), CheckNew(), Acquire(), Install(), Vacuum(), GetAppStream(), GetVersion(), ListFeatures(), DescribeFeature(), SetFeatureEnabled(), Class, Name, and Path were added in version 257 ✨.

The Job Object

Cancel(), Id, Type, Offline, and Progress were added in version 257 ✨.


πŸ‘€ SEE ALSO πŸ‘€

systemd(1), systemd-sysupdated.service(8), updatectl(1)


πŸ“ NOTES πŸ“

  1. appstream catalog β€” https://wwww.freedesktop.org/software/appstream/docs/chap-CatalogData.html
  2. special metadata β€” https://systemd.io/APPSTREAM_BUNDLE
  3. portable services β€” https://systemd.io/PORTABLE_SERVICES
  4. polkit β€” https://www.freedesktop.org/software/polkit/docs/latest/
  5. the usual interface versioning guidelines β€” https://0pointer.de/blog/projects/versioning-dbus.html

And that's the whole page bestie, you made it to the end 🫢 This lil beauty lives in systemd version 262.1, and its page name is ORG.FREED...SYSUPDATE1(5) β€” go forth and update things slayfully πŸ’–βœ¨πŸŒΈ

πŸ“¦ where this page comes from
  • arch rolling: systemd 262.1-1 Β· LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms