sysext: use [] in json mode when giving the extension status

The json mode was returning the string `none` when unmerged and
an array for merged extensions. Return an empty array instead.

Instead of branching on the output format, always add an empty strv
for an unmerged hierarchy: the table code renders an empty strv as
the ersatz string ("-") in text mode and as an empty array in json
mode. This also changes the human-readable output from "none" to "-".

It also updated the TEST-50-DISSECT.sysext.sh test. Technically
this is a compatbility break but its also arguably a bugfix.
This commit is contained in:
Michael Vogt
2026-09-07 18:29:25 +02:00
committed by Lennart Poettering
parent 548f87538a
commit 7efa326b7a
4 changed files with 35 additions and 4 deletions
+10
View File
@@ -1,5 +1,15 @@
systemd System and Service Manager
CHANGES WITH 263:
Feature Removals and Incompatible Changes:
* The "extensions" field of "systemd-sysext status --json=" and
"systemd-confext status --json=" is now always an array. A hierarchy
that is not merged reports an empty array, instead of the string
"none" returned previously. In the human-readable table output a
hierarchy that is not merged is now shown as "-" instead of "none".
CHANGES WITH 262 in spe:
Announcements of Future Feature Removals and Incompatible Changes:
+1 -3
View File
@@ -10,7 +10,6 @@
#include "sd-json.h"
#include "sd-varlink.h"
#include "ansi-color.h"
#include "argv-util.h"
#include "blkid-util.h"
#include "blockdev-util.h"
@@ -2592,8 +2591,7 @@ static int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata)
r = table_add_many(
t,
TABLE_PATH, *p,
TABLE_STRING, "none",
TABLE_SET_COLOR, ansi_grey(),
TABLE_STRV, STRV_EMPTY,
TABLE_EMPTY);
if (r < 0)
return table_log_add_error(r);
+2
View File
@@ -1080,7 +1080,9 @@ systemd-confext merge
grep -q -F "MARKER_CONFEXT_123" /etc/testfile
(! /etc/testscript)
systemd-confext status
systemd-confext status --json=pretty | jq -e 'any(.[]; .hierarchy == "/etc" and .extensions == ["test"] and .since != null)' >/dev/null
systemd-confext unmerge
systemd-confext status --json=pretty | jq -e 'any(.[]; .hierarchy == "/etc" and .extensions == [] and .since == null)' >/dev/null
rm -rf /run/confexts/
cleanup_sysupdate_notify_confext_mutable() {
+22 -1
View File
@@ -363,6 +363,25 @@ extension_verify_mount_option() (
done
)
extension_verify_status_json() (
local root=${1:-}
local hierarchy=${2:?}
local expected_extensions=${3:?}
local status_json since_filter
# Whether a hierarchy is merged is told by "since", not by "extensions": an empty array is also
# reported for a hierarchy merged in mutable mode without any extensions.
if [[ "$expected_extensions" == "[]" ]]; then
since_filter='.since == null'
else
since_filter='.since != null'
fi
status_json=$(run_systemd_sysext "$root" status --json=pretty)
jq -e --arg h "$hierarchy" --argjson e "$expected_extensions" \
"any(.[]; .hierarchy == \$h and .extensions == \$e and $since_filter)" >/dev/null <<<"$status_json"
)
run_systemd_sysext() {
local root=${1:-}
shift
@@ -400,9 +419,11 @@ prepare_read_only_hierarchy "$fake_root" "$hierarchy"
run_systemd_sysext "$fake_root" merge
(! touch "$fake_root$hierarchy/should-still-fail-on-read-only-fs")
extension_verify_after_merge "$fake_root" "$hierarchy" -e -h
extension_verify_status_json "$fake_root" "$hierarchy" '["test-extension"]'
run_systemd_sysext "$fake_root" unmerge
extension_verify_after_unmerge "$fake_root" "$hierarchy" -h
extension_verify_status_json "$fake_root" "$hierarchy" '[]'
(! touch "$fake_root$hierarchy/should-still-fail-on-read-only-fs")
)
@@ -1270,7 +1291,7 @@ prepare_read_only_hierarchy "$fake_root" "$hierarchy"
# Should be a no-op, thus we also don't run unmerge afterwards (otherwise the test is broken)
run_systemd_sysext "$fake_root" merge
if run_systemd_sysext "$fake_root" status --json=pretty | jq -r '.[].extensions' | grep -v '^none$' ; then
if ! extension_verify_status_json "$fake_root" "$hierarchy" '[]'; then
echo >&2 "Extension got loaded for an initrd structure passed as --root= while the extension does not declare itself compatible with the initrd scope"
exit 1
fi