ORG.FREED....PORTABLE1(5)
๐ NAME ๐
org.freedesktop.portable1 โ the D-Bus interface of systemd-portabled. That's the whole name, bestie, short and sweet.
๐ธ INTRODUCTION ๐ธ
systemd-portabled.service(8) is a system service, and its whole thing is that it can attach, detach, and inspect portable services. Iconic behaviour honestly. This page right here is all about the D-Bus interface it puts out. ๐
๐ฆ THE MANAGER OBJECT ๐ฆ
So the service exposes these interfaces on the Manager object, on the bus. Here's the whole shape of it, no cap:
node /org/freedesktop/portable1 {
interface org.freedesktop.portable1.Manager {
methods:
GetImage(in s image,
out o object);
ListImages(out a(ssbtttso) images);
GetImageOSRelease(in s image,
out a{ss} os_release);
GetImageMetadata(in s image,
in as matches,
out s image,
out ay os_release,
out a{say} units);
GetImageMetadataWithExtensions(in s image,
in as extensions,
in as matches,
in t flags,
out s image,
out ay os_release,
out a{say} extensions,
out a{say} units);
GetImageState(in s image,
out s state);
GetImageStateWithExtensions(in s image,
in as extensions,
in t flags,
out s state);
AttachImage(in s image,
in as matches,
in s profile,
in b runtime,
in s copy_mode,
out a(sss) changes);
AttachImageWithExtensions(in s image,
in as extensions,
in as matches,
in s profile,
in s copy_mode,
in t flags,
out a(sss) changes);
DetachImage(in s image,
in b runtime,
out a(sss) changes);
DetachImageWithExtensions(in s image,
in as extensions,
in t flags,
out a(sss) changes);
ReattachImage(in s image,
in as matches,
in s profile,
in b runtime,
in s copy_mode,
out a(sss) changes_removed,
out a(sss) changes_updated);
ReattachImageWithExtensions(in s image,
in as extensions,
in as matches,
in s profile,
in s copy_mode,
in t flags,
out a(sss) changes_removed,
out a(sss) changes_updated);
RemoveImage(in s image);
MarkImageReadOnly(in s image,
in b read_only);
SetImageLimit(in s image,
in t limit);
SetPoolLimit(in t limit);
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s PoolPath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t PoolUsage = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t PoolLimit = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly as Profiles = ['...', ...];
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
};
โจ Methods โจ
GetImage()โ you hand it a name, it hands you back the image object path of that image. Match made in heaven.ListImages()โ returns an array of every image currently known. Each structure in that array is stacked like this: image name, type, read-only flag, creation time, modification time, current disk space, usage, and image object path. Eight little fields, all lined up. ๐GetImageOSRelease()โ pulls the OS release info out of an image. What you get back is an array of key-value pairs, read straight from theos-release(5)file inside the image. Super useful for clocking which operating system a portable service is actually running. ๐ฆGetImageMetadata()โ grabs metadata tied to an image. You get the image name, the image'sos-release(5)content as a (streamable) array of bytes, and a list of the portable units chilling inside the image โ each one as a string (the unit name) plus an array of bytes holding its content.GetImageMetadataWithExtensions()โ also grabs metadata for an image, but this one is a superset ofGetImageMetadata(). The extra: a list of extensions comes in as an input parameter, and those were overlaid on top of the main image viaAttachImageWithExtensions(). For each extension named in the input arguments you get back the path of that extension plus an array of bytes containing the respectiveextension-releasefile's content โ one such structure per extension. โจGetImageState()โ returns the image state, as one of these strings:detachedattachedattached-runtimeenabledenabled-runtimerunningrunning-runtime
GetImageStateWithExtensions()โ a superset ofGetImageState(), with extra support for a list of extensions as input parameters. You need that list to even query the state if the image was attached in that particular way. Theflagsparameter is currently unused and reserved for future purposes, so likeโฆ it's there, it's just vibing. ๐AttachImage()โ attaches a portable image to the system. Let's break down what you're feeding it:- an image path or name,
- a list of strings used to search for unit files inside the image (partial or complete matches),
- a string saying which portable profile to use for the image (peep the Profiles property for the list of available profiles),
- a boolean for whether to attach the image only for the current boot session,
- and a string for the preferred copy mode โ copy the image, or just symlink it. The possible values are:
- (empty)
copysymlinkmixed
Okay so about those copy modes, fr fr: pass an empty string and the security profile drop-ins and images get symlinked while unit files get copied. copy copies. symlink prefers linking when it's possible (say, a unit has to be copied out of an image). And mixed prefers linking the resources owned by the OS (like the portable profile sitting in the host's /usr/ tree) but copies the resources owned by the portable image (like the unit files and the images).
This method returns the list of changes applied to the system โ for example, which unit got added and is now available as a system service. Every change is a triplet of strings: the type of change applied, the path it was applied on, and the source (if any). The type of change applied will be one of:
copysymlinkwritemkdir
Heads up bestie: an image cannot be attached if a unit that it contains is already present on the system. And this method only returns after all the listed operations are completed, and thanks to all the I/O involved it might take a minute. Be patient. ๐ญ
In place of the image path a .v/ versioned directory may be specified, see systemd.v(7) for details.
In place of the directory path a .v/ versioned directory may be specified, see systemd.v(7) for details.
(Yes, they said it twice. Yes, we're keeping both. Every detail stays, that's the rule. ๐ )
AttachImageWithExtensions()โ attaches a portable image to the system. Superset ofAttachImage(), and the addition is a list of extensions as an input parameter, which get overlaid on top of the main image. โ ๏ธ Important: when you attach using this method, you have to detach by passing the same arguments throughDetachImageWithExtensions(). For more details on this functionality, see theMountImages=entry onsystemd.exec(5)andsystemd-sysext(8).DetachImage()โ detaches a portable image from the system. It takes an image path or name, plus a boolean saying whether the image being detached was attached only for the current boot session or persistently. You get back the list of changes applied to the system โ for example, which unit was removed and is no longer available as a system service. Each change is a triplet of strings: the type of change applied, the path it was applied on, and the source (if any). The type of change applied will be one of:unlink
Okay and another heads up: an image cannot be detached if a unit that it contains is running. Also, this method only returns after all the listed operations are completed, and because of the I/O involved it might take some time. ๐ซถ
DetachImageWithExtensions()โ detaches a portable image from the system. Superset ofDetachImage(), plus a list of extensions as an input parameter โ the ones that were overlaid on top of the main image viaAttachImageWithExtensions().ReattachImage()โ the combo move. It's the effects ofAttachImage()andDetachImage()fused together, except the difference is you're allowed to reattach an image while one or more of its units are still running. ๐โ๏ธ The reattach will fail if no matching image is attached, so don't try it on nothing. The input parameters matchAttachImage(), and the return parameters are the combination of the return parameters ofDetachImage()(first array โ units that were removed) andAttachImage()(second array โ units that were updated or added).ReattachImageWithExtensions()โ reattaches a portable image to the system. Superset ofReattachImage(), plus a list of extensions as an input parameter, which will be overlaid on top of the main image. For more details on this functionality, see theMountImages=entry onsystemd.exec(5)andsystemd-sysext(8).RemoveImage()โ removes the image with the specified name. Gone. Poof. ๐MarkImageReadOnly()โ toggles the read-only flag of an image. Flip it on, flip it off. ๐SetPoolLimit()โ sets an overall quota limit on the pool of images.
SetImageLimit() sets a per-image quota limit. cute, contained, one image at a time bestie ๐
The AttachImageWithExtensions(), DetachImageWithExtensions() and ReattachImageWithExtensions() methods take in options as flags instead of booleans, so future-us can add more of them without breaking everything. it's giving foresight, it's giving growth mindset โจ
SD_SYSTEMD_PORTABLE_FORCE_ATTACH will bypass the safety checks that make sure the units are not running while the image is attached or detached. SD_SYSTEMD_PORTABLE_FORCE_EXTENSION will bypass the check that makes sure the extension-release.NAME file in the extension image matches the image name. They are defined as follows:
#define SD_SYSTEMD_PORTABLE_RUNTIME (UINT64_C(1) << 0)
#define SD_SYSTEMD_PORTABLE_FORCE_ATTACH (UINT64_C(1) << 1)
#define SD_SYSTEMD_PORTABLE_FORCE_EXTENSION (UINT64_C(1) << 2)
๐ Properties ๐
- PoolPath specifies the file system path where images are written to.
- PoolUsage specifies the current usage size of the image pool in bytes.
- PoolLimit specifies the size limit of the image pool in bytes.
- Profiles specifies the available runtime profiles for portable services.
๐ THE IMAGE OBJECT ๐
The service exposes the following interfaces on the Image object on the bus. look at her. main character energy, no cap ๐
node /org/freedesktop/portable1 {
interface org.freedesktop.portable1.Image {
methods:
GetOSRelease(out a{ss} os_release);
GetMetadata(in as matches,
out s image,
out ay os_release,
out a{say} units);
GetMetadataWithExtensions(in as extensions,
in as matches,
in t flags,
out s image,
out ay os_release,
out a{say} extensions,
out a{say} units);
GetState(out s state);
GetStateWithExtensions(in as extensions,
in t flags,
out s state);
Attach(in as matches,
in s profile,
in b runtime,
in s copy_mode,
out a(sss) changes);
AttachWithExtensions(in as extensions,
in as matches,
in s profile,
in s copy_mode,
in t flags,
out a(sss) changes);
Detach(in b runtime,
out a(sss) changes);
DetachWithExtensions(in as extensions,
in t flags,
out a(sss) changes);
Reattach(in as matches,
in s profile,
in b runtime,
in s copy_mode,
out a(sss) changes_removed,
out a(sss) changes_updated);
ReattachWithExtensions(in as extensions,
in as matches,
in s profile,
in s copy_mode,
in t flags,
out a(sss) changes_removed,
out a(sss) changes_updated);
Remove();
MarkReadOnly(in b read_only);
SetLimit(in t limit);
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s Name = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s Path = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s Type = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b ReadOnly = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t CreationTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t ModificationTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t Usage = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t Limit = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t UsageExclusive = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t LimitExclusive = ...;
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
};
๐ Methods ๐
The following methods implement the same operation as the respective methods on the Manager object (see above). The catch? These ones operate on the image object itself, so they do not take an image name parameter. โจ
Invoking the methods directly on the Manager object has the advantage of not requiring a GetImage() call just to get the image object for a specific image name. So calling the methods on the Manager object is a round trip optimization. iykyk ๐ฆ
List of methods:
GetOSRelease()GetMetadata()GetMetadataWithExtensions()GetState()Attach()AttachWithExtensions()Detach()DetachWithExtensions()Reattach()ReattachWithExtensions()Remove()MarkReadOnly()SetLimit()
๐ธ Properties ๐ธ
- Name specifies the image name.
- Path specifies the file system path where image is stored.
- Type specifies the image type.
- ReadOnly specifies whether the image is read-only.
- CreationTimestamp specifies the image creation timestamp.
- ModificationTimestamp specifies the image modification timestamp.
- Usage specifies the image disk usage.
- Limit specifies the image disk usage limit.
- UsageExclusive specifies the image disk usage (exclusive).
- LimitExclusive specifies the image disk usage limit (exclusive).
โญ VERSIONING โญ
These D-Bus interfaces follow the usual interface versioning guidelines[1]. periodt ๐
๐ฆ HISTORY ๐ฆ
The Manager Object
GetImageStateWithExtensions() was added in version 251.
The Image Object
GetStateWithExtensions() was added in version 251.
ReattachWithExtensions() was added in version 254.
๐ SEE ALSO ๐
systemd(1), systemd-portabled.service(8), portablectl(1)
๐ NOTES ๐
- the usual interface versioning guidelines
https://0pointer.de/blog/projects/versioning-dbus.html
and that's the whole page bestie, you ate that ๐ซถ this was systemd 262.1 rendering ORG.FREED....PORTABLE1(5) โ go forth and portable-ify ur services, ilysm, drink water, and remember: --force responsibly ๐โจ๐๐ฆ๐ธ
๐ฆ 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