sysupdate: Run ListFeatures in offline mode

Historically, the ListFeatures API (in both D-Bus and now varlink) was
run without an `--offline` flag. This appears like it’s an oversight, but
actually `verb_features()` always unconditionally loaded in offline
mode.

In any case, there doesn’t appear to be a reason for the context to be
online (i.e. for it to check sources for available updates). Features are
defined in local config files and are loaded by `read_features()`, which
is called in both offline and online mode.

When the varlink ListFeatures API was added, it was put into online mode
in order to match the lack of `--offline` argument in the existing D-Bus
API implementation. Change both of them to be explicitly in offline mode.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This commit is contained in:
Philip Withnall
2026-07-09 13:55:01 +01:00
parent f6cd126137
commit a8a88fc3ba
2 changed files with 41 additions and 12 deletions

View File

@@ -1409,14 +1409,7 @@ static int context_enumerate_targets(Context *context, Set **targets) {
return 0;
}
/* Load a Context to point to the target given by the TargetIdentifier. The TargetIdentifier will have been
* syntactically validated by dispatch_target_identifier(), but might still point to components which dont
* exist, images which the user isnt privileged to access, etc. This function validates the TargetIdentifier
* against an enumerated list of known targets, which are safe to update without additional permissions. */
static int context_load_online_from_target(
Context *context,
ProcessImageFlags process_image_flags,
ReadDefinitionsFlags read_definitions_flags) {
static int context_load_paths_from_target(Context *context) {
int r;
assert(context);
@@ -1507,9 +1500,45 @@ static int context_load_online_from_target(
assert_not_reached();
}
return 0;
}
/* Load a Context to point to the target given by the TargetIdentifier. The TargetIdentifier will have been
* syntactically validated by dispatch_target_identifier(), but might still point to components which dont
* exist, images which the user isnt privileged to access, etc. This function validates the TargetIdentifier
* against an enumerated list of known targets, which are safe to update without additional permissions. */
static int context_load_online_from_target(
Context *context,
ProcessImageFlags process_image_flags,
ReadDefinitionsFlags read_definitions_flags) {
int r;
assert(context);
assert(context->target_identifier.class != _TARGET_CLASS_INVALID);
r = context_load_paths_from_target(context);
if (r < 0)
return r;
return context_load_online(context, process_image_flags, read_definitions_flags);
}
static int context_load_offline_from_target(
Context *context,
ProcessImageFlags process_image_flags,
ReadDefinitionsFlags read_definitions_flags) {
int r;
assert(context);
assert(context->target_identifier.class != _TARGET_CLASS_INVALID);
r = context_load_paths_from_target(context);
if (r < 0)
return r;
return context_load_offline(context, process_image_flags, read_definitions_flags);
}
static int context_on_acquire_progress(const Transfer *t, const Instance *inst, unsigned percentage) {
const Context *c = ASSERT_PTR(t->context);
size_t i, n = c->n_transfers;
@@ -2431,10 +2460,10 @@ static int vl_method_list_features(sd_varlink *link, sd_json_variant *parameters
if (getenv_bool("SYSTEMD_SYSUPDATE_NO_VERIFY") > 0)
context.verify = 0;
/* ListFeatures is always online */
context.offline = false;
/* ListFeatures is always offline */
context.offline = true;
r = context_load_online_from_target(
r = context_load_offline_from_target(
&context,
PROCESS_IMAGE_READ_ONLY,
READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);

View File

@@ -1380,7 +1380,7 @@ static int target_method_list_features(sd_bus_message *msg, void *userdata, sd_b
if (flags != 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Flags must be 0");
r = sysupdate_run_simple(&json, t, "features", NULL);
r = sysupdate_run_simple(&json, t, "--offline", "features", NULL);
if (r < 0)
return r;