]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysupdate: Run ListFeatures in offline mode
authorPhilip Withnall <pwithnall@gnome.org>
Thu, 9 Jul 2026 12:55:01 +0000 (13:55 +0100)
committerPhilip Withnall <pwithnall@gnome.org>
Tue, 14 Jul 2026 13:58:02 +0000 (14:58 +0100)
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>
src/sysupdate/sysupdate.c
src/sysupdate/sysupdated.c

index 01c5c2dd56bb4035c5aabf7cd508476dc2162943..6270dc707c232b30f9166bcc14575cd9037266d4 100644 (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 don’t
- * exist, images which the user isn’t 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 don’t
+ * exist, images which the user isn’t 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);
index bc5a2439b5a3e939645e385cd4fee0caaa0dbf0e..d2a8297d82075fbd5ec2ba797fbc67761974534a 100644 (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;