From 537da0e98b53aec72c423388d1856e15b538a31d Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 9 Mar 2020 15:38:17 -0500 Subject: [PATCH] fu-engine: Make two passes of requirements checking Resolves installation for local CAB files that have `VersionFormat` set but not yet also set from metadata. In the first pass ignore the version format. This will rule out all other checks such as GUID and protocol. Then apply version format to the device if specified in the CAB. Lastly do a second pass with all requirements set. --- src/fu-engine.c | 10 ++++++---- src/fu-engine.h | 3 +++ src/fu-install-task.c | 14 ++++++++------ src/fu-main.c | 16 +++++++++++++++- src/fu-tool.c | 15 ++++++++++++++- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/fu-engine.c b/src/fu-engine.c index 1d2e5dc76..04de36abc 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -2811,12 +2811,9 @@ fu_engine_md_refresh_device_verfmt (FuEngine *self, FuDevice *device, XbNode *co } } -static void +void fu_engine_md_refresh_device_from_component (FuEngine *self, FuDevice *device, XbNode *component) { - /* set or clear the SUPPORTED flag */ - fu_engine_md_refresh_device_supported (self, device, component); - /* set the name */ if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_MD_SET_NAME)) fu_engine_md_refresh_device_name (self, device, component); @@ -2835,6 +2832,11 @@ fu_engine_md_refresh_devices (FuEngine *self) for (guint i = 0; i < devices->len; i++) { FuDevice *device = g_ptr_array_index (devices, i); g_autoptr(XbNode) component = fu_engine_get_component_by_guids (self, device); + + /* set or clear the SUPPORTED flag */ + fu_engine_md_refresh_device_supported (self, device, component); + + /* fixup the name and format as needed */ fu_engine_md_refresh_device_from_component (self, device, component); } } diff --git a/src/fu-engine.h b/src/fu-engine.h index 9713c7bc0..482c11de0 100644 --- a/src/fu-engine.h +++ b/src/fu-engine.h @@ -156,6 +156,9 @@ gboolean fu_engine_modify_config (FuEngine *self, GPtrArray *fu_engine_get_firmware_gtype_ids (FuEngine *engine); GType fu_engine_get_firmware_gtype_by_id (FuEngine *engine, const gchar *id); +void fu_engine_md_refresh_device_from_component (FuEngine *self, + FuDevice *device, + XbNode *component); /* for the self tests */ void fu_engine_add_device (FuEngine *self, diff --git a/src/fu-install-task.c b/src/fu-install-task.c index 1a465b79b..6c6336634 100644 --- a/src/fu-install-task.c +++ b/src/fu-install-task.c @@ -334,12 +334,14 @@ fu_install_task_check_requirements (FuInstallTask *self, } /* check the version formats match if set in the release */ - verfmts = xb_node_query (self->component, - "custom/value[@key='LVFS::VersionFormat']", - 0, NULL); - if (verfmts != NULL) { - if (!fu_install_task_check_verfmt (self, verfmts, flags, error)) - return FALSE; + if ((flags & FWUPD_INSTALL_FLAG_FORCE) == 0) { + verfmts = xb_node_query (self->component, + "custom/value[@key='LVFS::VersionFormat']", + 0, NULL); + if (verfmts != NULL) { + if (!fu_install_task_check_verfmt (self, verfmts, flags, error)) + return FALSE; + } } /* compare to the lowest supported version, if it exists */ diff --git a/src/fu-main.c b/src/fu-main.c index 9d87d29c1..bb6077da4 100644 --- a/src/fu-main.c +++ b/src/fu-main.c @@ -727,11 +727,25 @@ fu_main_install_with_helper (FuMainAuthHelper *helper_ref, GError **error) /* is this component valid for the device */ task = fu_install_task_new (device, component); + if (!fu_engine_check_requirements (priv->engine, + task, + helper->flags | FWUPD_INSTALL_FLAG_FORCE, + &error_local)) { + g_debug ("first pass requirement on %s:%s failed: %s", + fu_device_get_id (device), + xb_node_query_text (component, "id", NULL), + error_local->message); + g_ptr_array_add (errors, g_steal_pointer (&error_local)); + continue; + } + + /* make a second pass using possibly updated version format now */ + fu_engine_md_refresh_device_from_component (priv->engine, device, component); if (!fu_engine_check_requirements (priv->engine, task, helper->flags, &error_local)) { - g_debug ("requirement on %s:%s failed: %s", + g_debug ("second pass requirement on %s:%s failed: %s", fu_device_get_id (device), xb_node_query_text (component, "id", NULL), error_local->message); diff --git a/src/fu-tool.c b/src/fu-tool.c index a167d5dae..b07a2192c 100644 --- a/src/fu-tool.c +++ b/src/fu-tool.c @@ -878,10 +878,23 @@ fu_util_install (FuUtilPrivate *priv, gchar **values, GError **error) /* is this component valid for the device */ task = fu_install_task_new (device, component); + if (!fu_engine_check_requirements (priv->engine, + task, priv->flags | FWUPD_INSTALL_FLAG_FORCE, + &error_local)) { + g_debug ("first pass requirement on %s:%s failed: %s", + fu_device_get_id (device), + xb_node_query_text (component, "id", NULL), + error_local->message); + g_ptr_array_add (errors, g_steal_pointer (&error_local)); + continue; + } + + /* make a second pass using possibly updated version format now */ + fu_engine_md_refresh_device_from_component (priv->engine, device, component); if (!fu_engine_check_requirements (priv->engine, task, priv->flags, &error_local)) { - g_debug ("requirement on %s:%s failed: %s", + g_debug ("second pass requirement on %s:%s failed: %s", fu_device_get_id (device), xb_node_query_text (component, "id", NULL), error_local->message);