mirror of
https://git.proxmox.com/git/fwupd
synced 2026-03-27 06:00:41 +00:00
Modernize and refactor the requirement checking code
Before we had FuInstallTask which represented the specific install action (install foo on bar), FuEngineRequest which described why the install task was created, and FuEngine. The latter being both reposible for calling *into* FuInstallTask and also *from* FuInstallTask as well. Depending on the code, we had XbNodes of component and release, *and* FwupdReleases as releases and lots of duplicated code to marshall the former into various forms of the latter. Create a FuRelease wrapper around FwupdRelease to replace FuInstallTask and to simplify the code. Make the FuRelease builder do the device requirement checks, and then use the engine to do checks requiring engine state and context.
This commit is contained in:
parent
16edfd345e
commit
0eeaad76ec
1054
src/fu-engine.c
1054
src/fu-engine.c
File diff suppressed because it is too large
Load Diff
@ -15,9 +15,8 @@
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-context.h"
|
||||
#include "fu-engine-request.h"
|
||||
#include "fu-install-task.h"
|
||||
#include "fu-plugin.h"
|
||||
#include "fu-release.h"
|
||||
#include "fu-security-attrs.h"
|
||||
|
||||
#define FU_TYPE_ENGINE (fu_engine_get_type())
|
||||
@ -160,13 +159,12 @@ fu_engine_composite_prepare(FuEngine *self, GPtrArray *devices, GError **error);
|
||||
gboolean
|
||||
fu_engine_composite_cleanup(FuEngine *self, GPtrArray *devices, GError **error);
|
||||
gboolean
|
||||
fu_engine_install(FuEngine *self,
|
||||
FuInstallTask *task,
|
||||
GBytes *blob_cab,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error);
|
||||
fu_engine_install_release(FuEngine *self,
|
||||
FuRelease *task,
|
||||
GBytes *blob_cab,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_engine_install_blob(FuEngine *self,
|
||||
FuDevice *device,
|
||||
@ -176,13 +174,13 @@ fu_engine_install_blob(FuEngine *self,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_engine_install_tasks(FuEngine *self,
|
||||
FuEngineRequest *request,
|
||||
GPtrArray *install_tasks,
|
||||
GBytes *blob_cab,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
fu_engine_install_releases(FuEngine *self,
|
||||
FuEngineRequest *request,
|
||||
GPtrArray *releases,
|
||||
GBytes *blob_cab,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
GPtrArray *
|
||||
fu_engine_get_details(FuEngine *self, FuEngineRequest *request, gint fd, GError **error);
|
||||
gboolean
|
||||
@ -221,11 +219,10 @@ fu_engine_add_plugin(FuEngine *self, FuPlugin *plugin);
|
||||
void
|
||||
fu_engine_add_runtime_version(FuEngine *self, const gchar *component_id, const gchar *version);
|
||||
gboolean
|
||||
fu_engine_check_trust(FuEngine *self, FuInstallTask *task, GError **error);
|
||||
fu_engine_check_trust(FuEngine *self, FuRelease *task, GError **error);
|
||||
gboolean
|
||||
fu_engine_check_requirements(FuEngine *self,
|
||||
FuEngineRequest *request,
|
||||
FuInstallTask *task,
|
||||
FuRelease *release,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
void
|
||||
|
||||
@ -1,551 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "FuInstallTask"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupd.h>
|
||||
|
||||
#include "fu-common-version.h"
|
||||
#include "fu-common.h"
|
||||
#include "fu-device-private.h"
|
||||
#include "fu-install-task.h"
|
||||
#include "fu-keyring-utils.h"
|
||||
|
||||
struct _FuInstallTask {
|
||||
GObject parent_instance;
|
||||
FuDevice *device;
|
||||
XbNode *component;
|
||||
FwupdReleaseFlags trust_flags;
|
||||
gboolean is_downgrade;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuInstallTask, fu_install_task, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* fu_install_task_get_device:
|
||||
* @self: a #FuInstallTask
|
||||
*
|
||||
* Gets the device for this task.
|
||||
*
|
||||
* Returns: (transfer none): the device
|
||||
**/
|
||||
FuDevice *
|
||||
fu_install_task_get_device(FuInstallTask *self)
|
||||
{
|
||||
g_return_val_if_fail(FU_IS_INSTALL_TASK(self), NULL);
|
||||
return self->device;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_get_component:
|
||||
* @self: a #FuInstallTask
|
||||
*
|
||||
* Gets the component for this task.
|
||||
*
|
||||
* Returns: (transfer none): the component
|
||||
**/
|
||||
XbNode *
|
||||
fu_install_task_get_component(FuInstallTask *self)
|
||||
{
|
||||
g_return_val_if_fail(FU_IS_INSTALL_TASK(self), NULL);
|
||||
return self->component;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_get_trust_flags:
|
||||
* @self: a #FuInstallTask
|
||||
*
|
||||
* Gets the trust flags for this task.
|
||||
*
|
||||
* NOTE: This is only set after fu_install_task_check_requirements() has been
|
||||
* called successfully.
|
||||
*
|
||||
* Returns: the #FwupdReleaseFlags, e.g. #FWUPD_TRUST_FLAG_PAYLOAD
|
||||
**/
|
||||
FwupdReleaseFlags
|
||||
fu_install_task_get_trust_flags(FuInstallTask *self)
|
||||
{
|
||||
g_return_val_if_fail(FU_IS_INSTALL_TASK(self), FALSE);
|
||||
return self->trust_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_get_is_downgrade:
|
||||
* @self: a #FuInstallTask
|
||||
*
|
||||
* Gets if this task is to downgrade firmware.
|
||||
*
|
||||
* NOTE: This is only set after fu_install_task_check_requirements() has been
|
||||
* called successfully.
|
||||
*
|
||||
* Returns: %TRUE if versions numbers are going backwards
|
||||
**/
|
||||
gboolean
|
||||
fu_install_task_get_is_downgrade(FuInstallTask *self)
|
||||
{
|
||||
g_return_val_if_fail(FU_IS_INSTALL_TASK(self), FALSE);
|
||||
return self->is_downgrade;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
fu_install_task_verfmts_to_string(GPtrArray *verfmts)
|
||||
{
|
||||
GString *str = g_string_new(NULL);
|
||||
for (guint i = 0; i < verfmts->len; i++) {
|
||||
XbNode *verfmt = g_ptr_array_index(verfmts, i);
|
||||
const gchar *tmp = xb_node_get_text(verfmt);
|
||||
g_string_append_printf(str, "%s;", tmp);
|
||||
}
|
||||
if (str->len > 0)
|
||||
g_string_truncate(str, str->len - 1);
|
||||
return g_string_free(str, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_install_task_check_verfmt(FuInstallTask *self,
|
||||
GPtrArray *verfmts,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FwupdVersionFormat fmt_dev = fu_device_get_version_format(self->device);
|
||||
g_autofree gchar *verfmts_str = NULL;
|
||||
|
||||
/* no device format */
|
||||
if (fmt_dev == FWUPD_VERSION_FORMAT_UNKNOWN && (flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
verfmts_str = fu_install_task_verfmts_to_string(verfmts);
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"release version format '%s' but no device version format",
|
||||
verfmts_str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* compare all version formats */
|
||||
for (guint i = 0; i < verfmts->len; i++) {
|
||||
XbNode *verfmt = g_ptr_array_index(verfmts, i);
|
||||
const gchar *tmp = xb_node_get_text(verfmt);
|
||||
FwupdVersionFormat fmt_rel = fwupd_version_format_from_string(tmp);
|
||||
if (fmt_dev == fmt_rel)
|
||||
return TRUE;
|
||||
}
|
||||
verfmts_str = fu_install_task_verfmts_to_string(verfmts);
|
||||
if ((flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Firmware version formats were different, "
|
||||
"device was '%s' and release is '%s'",
|
||||
fwupd_version_format_to_string(fmt_dev),
|
||||
verfmts_str);
|
||||
return FALSE;
|
||||
}
|
||||
g_warning("ignoring version format difference %s:%s",
|
||||
fwupd_version_format_to_string(fmt_dev),
|
||||
verfmts_str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_install_task_check_requirements_version_check(FuInstallTask *self, GError **error)
|
||||
{
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) reqs = NULL;
|
||||
|
||||
reqs = xb_node_query(fu_install_task_get_component(self), "requires/*", 0, &error_local);
|
||||
if (reqs == NULL) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
error_local->message);
|
||||
return FALSE;
|
||||
}
|
||||
for (guint i = 0; i < reqs->len; i++) {
|
||||
XbNode *req = g_ptr_array_index(reqs, i);
|
||||
if (g_strcmp0(xb_node_get_element(req), "firmware") == 0 &&
|
||||
xb_node_get_text(req) == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"no firmware requirement");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_check_requirements:
|
||||
* @self: a #FuInstallTask
|
||||
* @flags: install flags, e.g. #FWUPD_INSTALL_FLAG_ALLOW_OLDER
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Checks any requirements of this task. This will typically involve checking
|
||||
* that the device can accept the component (the GUIDs match) and that the
|
||||
* device can be upgraded with this firmware version.
|
||||
*
|
||||
* Returns: %TRUE if the requirements passed
|
||||
**/
|
||||
gboolean
|
||||
fu_install_task_check_requirements(FuInstallTask *self, FwupdInstallFlags flags, GError **error)
|
||||
{
|
||||
const gchar *branch_new;
|
||||
const gchar *branch_old;
|
||||
const gchar *protocol;
|
||||
const gchar *version;
|
||||
const gchar *version_release_raw;
|
||||
const gchar *version_lowest;
|
||||
gboolean matches_guid = FALSE;
|
||||
gint vercmp;
|
||||
g_autofree gchar *version_release = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) provides = NULL;
|
||||
g_autoptr(GPtrArray) verfmts = NULL;
|
||||
g_autoptr(XbNode) release = NULL;
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
g_autoptr(XbQuery) query = NULL;
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail(FU_IS_INSTALL_TASK(self), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* does this component provide a GUID the device has */
|
||||
provides =
|
||||
xb_node_query(self->component, "provides/firmware[@type='flashed']", 0, &error_local);
|
||||
if (provides == NULL) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND,
|
||||
"No supported devices found: %s",
|
||||
error_local->message);
|
||||
return FALSE;
|
||||
}
|
||||
for (guint i = 0; i < provides->len; i++) {
|
||||
XbNode *provide = g_ptr_array_index(provides, i);
|
||||
if (fu_device_has_guid(self->device, xb_node_get_text(provide))) {
|
||||
matches_guid = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matches_guid) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND,
|
||||
"No supported devices found");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* device requires a version check */
|
||||
if (fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED)) {
|
||||
if (!fu_install_task_check_requirements_version_check(self, error)) {
|
||||
g_prefix_error(error, "device requires firmware with a version check: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* does the protocol match */
|
||||
protocol =
|
||||
xb_node_query_text(self->component, "custom/value[@key='LVFS::UpdateProtocol']", NULL);
|
||||
if (fu_device_get_protocols(self->device)->len != 0 && protocol != NULL &&
|
||||
!fu_device_has_protocol(self->device, protocol) &&
|
||||
(flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_autofree gchar *str = NULL;
|
||||
str = fu_common_strjoin_array("|", fu_device_get_protocols(self->device));
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Device %s does not support %s, only %s",
|
||||
fu_device_get_name(self->device),
|
||||
protocol,
|
||||
str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check the device is not locked */
|
||||
if (fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_LOCKED)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Device %s [%s] is locked",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check the branch is not switching */
|
||||
branch_new = xb_node_query_text(self->component, "branch", NULL);
|
||||
branch_old = fu_device_get_branch(self->device);
|
||||
if ((flags & FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH) == 0 &&
|
||||
g_strcmp0(branch_old, branch_new) != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Device %s [%s] would switch firmware branch from %s to %s",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device),
|
||||
branch_old != NULL ? branch_old : "default",
|
||||
branch_new != NULL ? branch_new : "default");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* no update abilities */
|
||||
if (!fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_UPDATABLE)) {
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
g_string_append_printf(str,
|
||||
"Device %s [%s] does not currently allow updates",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device));
|
||||
if (fu_device_get_update_error(self->device) != NULL) {
|
||||
g_string_append_printf(str,
|
||||
": %s",
|
||||
fu_device_get_update_error(self->device));
|
||||
}
|
||||
g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, str->str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* called with online update, test if device is supposed to allow this */
|
||||
if ((flags & FWUPD_INSTALL_FLAG_OFFLINE) == 0 && (flags & FWUPD_INSTALL_FLAG_FORCE) == 0 &&
|
||||
fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_ONLY_OFFLINE)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Device %s [%s] only allows offline updates",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get device */
|
||||
version = fu_device_get_version(self->device);
|
||||
if (version == NULL) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"Device %s [%s] has no firmware version",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get latest release */
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
query = xb_query_new_full(xb_node_get_silo(self->component),
|
||||
"releases/release",
|
||||
XB_QUERY_FLAG_FORCE_NODE_CACHE,
|
||||
error);
|
||||
if (query == NULL)
|
||||
return FALSE;
|
||||
release = xb_node_query_first_full(self->component, query, NULL);
|
||||
#else
|
||||
release = xb_node_query_first(self->component, "releases/release", NULL);
|
||||
#endif
|
||||
if (release == NULL) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"%s [%s] has no firmware update metadata",
|
||||
fu_device_get_name(self->device),
|
||||
fu_device_get_id(self->device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* is this a downgrade or re-install */
|
||||
version_release_raw = xb_node_get_attr(release, "version");
|
||||
if (version_release_raw == NULL) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Release has no firmware version");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check the version formats match if set in the release */
|
||||
if ((flags & FWUPD_INSTALL_FLAG_FORCE) == 0 &&
|
||||
(flags & FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH) == 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 */
|
||||
version_lowest = fu_device_get_version_lowest(self->device);
|
||||
if (version_lowest != NULL &&
|
||||
fu_common_vercmp_full(version_lowest,
|
||||
version,
|
||||
fu_device_get_version_format(self->device)) > 0 &&
|
||||
(flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_VERSION_NEWER,
|
||||
"Specified firmware is older than the minimum "
|
||||
"required version '%s < %s'",
|
||||
version,
|
||||
version_lowest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check semver */
|
||||
if (fu_device_get_version_format(self->device) == FWUPD_VERSION_FORMAT_PLAIN) {
|
||||
version_release = g_strdup(version_release_raw);
|
||||
} else {
|
||||
version_release =
|
||||
fu_common_version_parse_from_format(version_release_raw,
|
||||
fu_device_get_version_format(self->device));
|
||||
}
|
||||
vercmp = fu_common_vercmp_full(version,
|
||||
version_release,
|
||||
fu_device_get_version_format(self->device));
|
||||
if (fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_ONLY_VERSION_UPGRADE) &&
|
||||
vercmp >= 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Device only supports version upgrades");
|
||||
return FALSE;
|
||||
}
|
||||
if (vercmp == 0 && (flags & FWUPD_INSTALL_FLAG_ALLOW_REINSTALL) == 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_VERSION_SAME,
|
||||
"Specified firmware is already installed '%s'",
|
||||
version_release);
|
||||
return FALSE;
|
||||
}
|
||||
self->is_downgrade = vercmp > 0;
|
||||
if (self->is_downgrade && (flags & FWUPD_INSTALL_FLAG_ALLOW_OLDER) == 0 &&
|
||||
(flags & FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH) == 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_VERSION_NEWER,
|
||||
"Specified firmware is older than installed '%s < %s'",
|
||||
version_release,
|
||||
version);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* verify */
|
||||
if (!fu_keyring_get_release_flags(release, &self->trust_flags, &error_local)) {
|
||||
if (g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) {
|
||||
g_warning("Ignoring verification for %s: %s",
|
||||
fu_device_get_name(self->device),
|
||||
error_local->message);
|
||||
} else {
|
||||
g_propagate_error(error, g_steal_pointer(&error_local));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_get_action_id:
|
||||
* @self: a #FuEngine
|
||||
*
|
||||
* Gets the PolicyKit action ID to use for the install operation.
|
||||
*
|
||||
* Returns: string, e.g. `org.freedesktop.fwupd.update-internal-trusted`
|
||||
**/
|
||||
const gchar *
|
||||
fu_install_task_get_action_id(FuInstallTask *self)
|
||||
{
|
||||
/* relax authentication checks for removable devices */
|
||||
if (!fu_device_has_flag(self->device, FWUPD_DEVICE_FLAG_INTERNAL)) {
|
||||
if (self->is_downgrade) {
|
||||
if (self->trust_flags & FWUPD_TRUST_FLAG_PAYLOAD)
|
||||
return "org.freedesktop.fwupd.downgrade-hotplug-trusted";
|
||||
return "org.freedesktop.fwupd.downgrade-hotplug";
|
||||
}
|
||||
if (self->trust_flags & FWUPD_TRUST_FLAG_PAYLOAD)
|
||||
return "org.freedesktop.fwupd.update-hotplug-trusted";
|
||||
return "org.freedesktop.fwupd.update-hotplug";
|
||||
}
|
||||
|
||||
/* internal device */
|
||||
if (self->is_downgrade) {
|
||||
if (self->trust_flags & FWUPD_TRUST_FLAG_PAYLOAD)
|
||||
return "org.freedesktop.fwupd.downgrade-internal-trusted";
|
||||
return "org.freedesktop.fwupd.downgrade-internal";
|
||||
}
|
||||
if (self->trust_flags & FWUPD_TRUST_FLAG_PAYLOAD)
|
||||
return "org.freedesktop.fwupd.update-internal-trusted";
|
||||
return "org.freedesktop.fwupd.update-internal";
|
||||
}
|
||||
|
||||
static void
|
||||
fu_install_task_init(FuInstallTask *self)
|
||||
{
|
||||
self->trust_flags = FWUPD_TRUST_FLAG_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_install_task_finalize(GObject *object)
|
||||
{
|
||||
FuInstallTask *self = FU_INSTALL_TASK(object);
|
||||
|
||||
if (self->component != NULL)
|
||||
g_object_unref(self->component);
|
||||
if (self->device != NULL)
|
||||
g_object_unref(self->device);
|
||||
|
||||
G_OBJECT_CLASS(fu_install_task_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_install_task_class_init(FuInstallTaskClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = fu_install_task_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_compare:
|
||||
* @task1: first task to compare.
|
||||
* @task2: second task to compare.
|
||||
*
|
||||
* Compares two install tasks.
|
||||
*
|
||||
* Returns: 1, 0 or -1 if @task1 is greater, equal, or less than @task2, respectively.
|
||||
**/
|
||||
gint
|
||||
fu_install_task_compare(FuInstallTask *task1, FuInstallTask *task2)
|
||||
{
|
||||
FuDevice *device1 = fu_install_task_get_device(task1);
|
||||
FuDevice *device2 = fu_install_task_get_device(task2);
|
||||
if (fu_device_get_order(device1) < fu_device_get_order(device2))
|
||||
return -1;
|
||||
if (fu_device_get_order(device1) > fu_device_get_order(device2))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_new:
|
||||
* @device: a device
|
||||
* @component: a Xmlb node
|
||||
*
|
||||
* Creates a new install task that may or may not be valid.
|
||||
*
|
||||
* Returns: (transfer full): the #FuInstallTask
|
||||
**/
|
||||
FuInstallTask *
|
||||
fu_install_task_new(FuDevice *device, XbNode *component)
|
||||
{
|
||||
FuInstallTask *self;
|
||||
self = g_object_new(FU_TYPE_TASK, NULL);
|
||||
if (component != NULL)
|
||||
self->component = g_object_ref(component);
|
||||
if (device != NULL)
|
||||
self->device = g_object_ref(device);
|
||||
return FU_INSTALL_TASK(self);
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <xmlb.h>
|
||||
|
||||
#include "fu-device.h"
|
||||
|
||||
#define FU_TYPE_TASK (fu_install_task_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuInstallTask, fu_install_task, FU, INSTALL_TASK, GObject)
|
||||
|
||||
FuInstallTask *
|
||||
fu_install_task_new(FuDevice *device, XbNode *component);
|
||||
FuDevice *
|
||||
fu_install_task_get_device(FuInstallTask *self);
|
||||
XbNode *
|
||||
fu_install_task_get_component(FuInstallTask *self);
|
||||
FwupdReleaseFlags
|
||||
fu_install_task_get_trust_flags(FuInstallTask *self);
|
||||
gboolean
|
||||
fu_install_task_get_is_downgrade(FuInstallTask *self);
|
||||
gboolean
|
||||
fu_install_task_check_requirements(FuInstallTask *self, FwupdInstallFlags flags, GError **error);
|
||||
const gchar *
|
||||
fu_install_task_get_action_id(FuInstallTask *self);
|
||||
gint
|
||||
fu_install_task_compare(FuInstallTask *task1, FuInstallTask *task2);
|
||||
215
src/fu-main.c
215
src/fu-main.c
@ -40,7 +40,7 @@
|
||||
#include "fu-debug.h"
|
||||
#include "fu-device-private.h"
|
||||
#include "fu-engine.h"
|
||||
#include "fu-install-task.h"
|
||||
#include "fu-release.h"
|
||||
#include "fu-security-attrs-private.h"
|
||||
|
||||
#ifdef HAVE_POLKIT
|
||||
@ -364,9 +364,10 @@ typedef struct {
|
||||
#ifdef HAVE_POLKIT
|
||||
PolkitSubject *subject;
|
||||
#endif
|
||||
GPtrArray *install_tasks;
|
||||
GPtrArray *releases;
|
||||
GPtrArray *action_ids;
|
||||
GPtrArray *checksums;
|
||||
GPtrArray *errors;
|
||||
guint64 flags;
|
||||
GBytes *blob_cab;
|
||||
FuMainPrivate *priv;
|
||||
@ -390,12 +391,14 @@ fu_main_auth_helper_free(FuMainAuthHelper *helper)
|
||||
g_object_unref(helper->silo);
|
||||
if (helper->request != NULL)
|
||||
g_object_unref(helper->request);
|
||||
if (helper->install_tasks != NULL)
|
||||
g_ptr_array_unref(helper->install_tasks);
|
||||
if (helper->releases != NULL)
|
||||
g_ptr_array_unref(helper->releases);
|
||||
if (helper->action_ids != NULL)
|
||||
g_ptr_array_unref(helper->action_ids);
|
||||
if (helper->checksums != NULL)
|
||||
g_ptr_array_unref(helper->checksums);
|
||||
if (helper->errors != NULL)
|
||||
g_ptr_array_unref(helper->errors);
|
||||
g_free(helper->device_id);
|
||||
g_free(helper->remote_id);
|
||||
g_free(helper->key);
|
||||
@ -807,13 +810,13 @@ fu_main_authorize_install_queue(FuMainAuthHelper *helper_ref)
|
||||
|
||||
/* all authenticated, so install all the things */
|
||||
priv->update_in_progress = TRUE;
|
||||
ret = fu_engine_install_tasks(helper->priv->engine,
|
||||
helper->request,
|
||||
helper->install_tasks,
|
||||
helper->blob_cab,
|
||||
progress,
|
||||
helper->flags,
|
||||
&error);
|
||||
ret = fu_engine_install_releases(helper->priv->engine,
|
||||
helper->request,
|
||||
helper->releases,
|
||||
helper->blob_cab,
|
||||
progress,
|
||||
helper->flags,
|
||||
&error);
|
||||
priv->update_in_progress = FALSE;
|
||||
if (priv->pending_sigterm)
|
||||
g_main_loop_quit(priv->loop);
|
||||
@ -845,11 +848,126 @@ g_ptr_array_find(GPtrArray *haystack, gconstpointer needle, guint *index_)
|
||||
#endif
|
||||
|
||||
static gint
|
||||
fu_main_install_task_sort_cb(gconstpointer a, gconstpointer b)
|
||||
fu_main_release_sort_cb(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
FuInstallTask *task_a = *((FuInstallTask **)a);
|
||||
FuInstallTask *task_b = *((FuInstallTask **)b);
|
||||
return fu_install_task_compare(task_a, task_b);
|
||||
FuRelease *release1 = *((FuRelease **)a);
|
||||
FuRelease *release2 = *((FuRelease **)b);
|
||||
return fu_release_compare(release1, release2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_main_install_with_helper_device(FuMainAuthHelper *helper,
|
||||
XbNode *component,
|
||||
FuDevice *device,
|
||||
GError **error)
|
||||
{
|
||||
FuMainPrivate *priv = helper->priv;
|
||||
const gchar *action_id;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) releases = NULL;
|
||||
|
||||
/* is this component valid for the device */
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, helper->request);
|
||||
if (!fu_release_load(release,
|
||||
component,
|
||||
NULL,
|
||||
helper->flags | FWUPD_INSTALL_FLAG_FORCE,
|
||||
&error_local)) {
|
||||
g_ptr_array_add(helper->errors, g_steal_pointer(&error_local));
|
||||
return TRUE;
|
||||
}
|
||||
if (!fu_engine_check_requirements(priv->engine,
|
||||
release,
|
||||
helper->flags | FWUPD_INSTALL_FLAG_FORCE,
|
||||
&error_local)) {
|
||||
if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND)) {
|
||||
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(helper->errors, g_steal_pointer(&error_local));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* possibly update version format */
|
||||
fu_engine_md_refresh_device_from_component(priv->engine, device, component);
|
||||
|
||||
/* sync update message from CAB */
|
||||
fu_device_incorporate_from_component(device, component);
|
||||
|
||||
/* install each intermediate release */
|
||||
releases = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_INSTALL_ALL_RELEASES)) {
|
||||
g_autoptr(GPtrArray) rels = NULL;
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
g_autoptr(XbQuery) query = NULL;
|
||||
#endif
|
||||
/* we get this one "for free" */
|
||||
g_ptr_array_add(releases, g_object_ref(release));
|
||||
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
query = xb_query_new_full(xb_node_get_silo(component),
|
||||
"releases/release",
|
||||
XB_QUERY_FLAG_FORCE_NODE_CACHE,
|
||||
error);
|
||||
if (query == NULL)
|
||||
return FALSE;
|
||||
rels = xb_node_query_full(component, query, NULL);
|
||||
#else
|
||||
rels = xb_node_query(component, "releases/release", 0, NULL);
|
||||
#endif
|
||||
/* add all but the the first entry */
|
||||
for (guint i = 1; i < rels->len; i++) {
|
||||
XbNode *rel = g_ptr_array_index(rels, i);
|
||||
g_autoptr(FuRelease) release2 = fu_release_new();
|
||||
g_autoptr(GError) error_loop = NULL;
|
||||
fu_release_set_device(release2, device);
|
||||
fu_release_set_request(release2, helper->request);
|
||||
if (!fu_release_load(release2,
|
||||
component,
|
||||
rel,
|
||||
helper->flags,
|
||||
&error_loop)) {
|
||||
g_ptr_array_add(helper->errors, g_steal_pointer(&error_loop));
|
||||
continue;
|
||||
}
|
||||
g_ptr_array_add(releases, g_object_ref(release2));
|
||||
}
|
||||
} else {
|
||||
g_ptr_array_add(releases, g_object_ref(release));
|
||||
}
|
||||
|
||||
/* make a second pass */
|
||||
for (guint i = 0; i < releases->len; i++) {
|
||||
FuRelease *release_tmp = g_ptr_array_index(releases, i);
|
||||
if (!fu_engine_check_requirements(priv->engine,
|
||||
release_tmp,
|
||||
helper->flags,
|
||||
&error_local)) {
|
||||
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);
|
||||
g_ptr_array_add(helper->errors, g_steal_pointer(&error_local));
|
||||
continue;
|
||||
}
|
||||
if (!fu_engine_check_trust(priv->engine, release_tmp, &error_local)) {
|
||||
g_ptr_array_add(helper->errors, g_steal_pointer(&error_local));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get the action IDs for the valid device */
|
||||
action_id = fu_release_get_action_id(release_tmp);
|
||||
if (!g_ptr_array_find(helper->action_ids, action_id, NULL))
|
||||
g_ptr_array_add(helper->action_ids, g_strdup(action_id));
|
||||
g_ptr_array_add(helper->releases, g_object_ref(release_tmp));
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -859,7 +977,6 @@ fu_main_install_with_helper(FuMainAuthHelper *helper_ref, GError **error)
|
||||
g_autoptr(FuMainAuthHelper) helper = helper_ref;
|
||||
g_autoptr(GPtrArray) components = NULL;
|
||||
g_autoptr(GPtrArray) devices_possible = NULL;
|
||||
g_autoptr(GPtrArray) errors = NULL;
|
||||
|
||||
/* get a list of devices that in some way match the device_id */
|
||||
if (g_strcmp0(helper->device_id, FWUPD_DEVICE_ID_ANY) == 0) {
|
||||
@ -890,73 +1007,25 @@ fu_main_install_with_helper(FuMainAuthHelper *helper_ref, GError **error)
|
||||
if (components == NULL)
|
||||
return FALSE;
|
||||
helper->action_ids = g_ptr_array_new_with_free_func(g_free);
|
||||
helper->install_tasks = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
errors = g_ptr_array_new_with_free_func((GDestroyNotify)g_error_free);
|
||||
helper->releases = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
helper->errors = g_ptr_array_new_with_free_func((GDestroyNotify)g_error_free);
|
||||
|
||||
/* do any devices pass the requirements */
|
||||
for (guint i = 0; i < components->len; i++) {
|
||||
XbNode *component = g_ptr_array_index(components, i);
|
||||
|
||||
/* do any devices pass the requirements */
|
||||
for (guint j = 0; j < devices_possible->len; j++) {
|
||||
FuDevice *device = g_ptr_array_index(devices_possible, j);
|
||||
const gchar *action_id;
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* is this component valid for the device */
|
||||
task = fu_install_task_new(device, component);
|
||||
if (!fu_engine_check_requirements(priv->engine,
|
||||
helper->request,
|
||||
task,
|
||||
helper->flags | FWUPD_INSTALL_FLAG_FORCE,
|
||||
&error_local)) {
|
||||
if (!g_error_matches(error_local,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND)) {
|
||||
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,
|
||||
helper->request,
|
||||
task,
|
||||
helper->flags,
|
||||
&error_local)) {
|
||||
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);
|
||||
g_ptr_array_add(errors, g_steal_pointer(&error_local));
|
||||
continue;
|
||||
}
|
||||
if (!fu_engine_check_trust(priv->engine, task, &error_local)) {
|
||||
g_ptr_array_add(errors, g_steal_pointer(&error_local));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if component should have an update message from CAB */
|
||||
fu_device_incorporate_from_component(device, component);
|
||||
|
||||
/* get the action IDs for the valid device */
|
||||
action_id = fu_install_task_get_action_id(task);
|
||||
if (!g_ptr_array_find(helper->action_ids, action_id, NULL))
|
||||
g_ptr_array_add(helper->action_ids, g_strdup(action_id));
|
||||
g_ptr_array_add(helper->install_tasks, g_steal_pointer(&task));
|
||||
if (!fu_main_install_with_helper_device(helper, component, device, error))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* order the install tasks by the device priority */
|
||||
g_ptr_array_sort(helper->install_tasks, fu_main_install_task_sort_cb);
|
||||
g_ptr_array_sort(helper->releases, fu_main_release_sort_cb);
|
||||
|
||||
/* nothing suitable */
|
||||
if (helper->install_tasks->len == 0) {
|
||||
GError *error_tmp = fu_common_error_array_get_best(errors);
|
||||
if (helper->releases->len == 0) {
|
||||
GError *error_tmp = fu_common_error_array_get_best(helper->errors);
|
||||
g_propagate_error(error, error_tmp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
1067
src/fu-release.c
Normal file
1067
src/fu-release.c
Normal file
File diff suppressed because it is too large
Load Diff
64
src/fu-release.h
Normal file
64
src/fu-release.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupd.h>
|
||||
#include <xmlb.h>
|
||||
|
||||
#include "fu-config.h"
|
||||
#include "fu-device.h"
|
||||
#include "fu-engine-request.h"
|
||||
|
||||
#define FU_TYPE_RELEASE (fu_release_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuRelease, fu_release, FU, RELEASE, FwupdRelease)
|
||||
|
||||
FuRelease *
|
||||
fu_release_new(void);
|
||||
|
||||
#define fu_release_get_version(r) fwupd_release_get_version(FWUPD_RELEASE(r))
|
||||
#define fu_release_get_branch(r) fwupd_release_get_branch(FWUPD_RELEASE(r))
|
||||
#define fu_release_get_checksums(r) fwupd_release_get_checksums(FWUPD_RELEASE(r))
|
||||
#define fu_release_add_flag(r, v) fwupd_release_add_flag(FWUPD_RELEASE(r), v)
|
||||
#define fu_release_add_tag(r, v) fwupd_release_add_tag(FWUPD_RELEASE(r), v)
|
||||
#define fu_release_add_metadata(r, v) fwupd_release_add_metadata(FWUPD_RELEASE(r), v)
|
||||
|
||||
FuDevice *
|
||||
fu_release_get_device(FuRelease *self);
|
||||
GBytes *
|
||||
fu_release_get_fw_blob(FuRelease *self);
|
||||
FuEngineRequest *
|
||||
fu_release_get_request(FuRelease *self);
|
||||
const gchar *
|
||||
fu_release_get_builder_script(FuRelease *self);
|
||||
const gchar *
|
||||
fu_release_get_builder_output(FuRelease *self);
|
||||
GPtrArray *
|
||||
fu_release_get_soft_reqs(FuRelease *self);
|
||||
GPtrArray *
|
||||
fu_release_get_hard_reqs(FuRelease *self);
|
||||
|
||||
void
|
||||
fu_release_set_request(FuRelease *self, FuEngineRequest *request);
|
||||
void
|
||||
fu_release_set_device(FuRelease *self, FuDevice *device);
|
||||
void
|
||||
fu_release_set_remote(FuRelease *self, FwupdRemote *remote);
|
||||
void
|
||||
fu_release_set_config(FuRelease *self, FuConfig *config);
|
||||
|
||||
gboolean
|
||||
fu_release_load(FuRelease *self,
|
||||
XbNode *component,
|
||||
XbNode *rel,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
FwupdReleaseFlags
|
||||
fu_release_get_trust_flags(FuRelease *self);
|
||||
const gchar *
|
||||
fu_release_get_action_id(FuRelease *self);
|
||||
gint
|
||||
fu_release_compare(FuRelease *release1, FuRelease *release2);
|
||||
@ -24,7 +24,6 @@
|
||||
#include "fu-engine.h"
|
||||
#include "fu-hash.h"
|
||||
#include "fu-history.h"
|
||||
#include "fu-install-task.h"
|
||||
#include "fu-plugin-list.h"
|
||||
#include "fu-plugin-private.h"
|
||||
#include "fu-progressbar.h"
|
||||
@ -206,12 +205,15 @@ fu_engine_requirements_missing_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <requires>"
|
||||
" <id compare=\"ge\" version=\"1.2.3\">not.going.to.exist</id>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy version */
|
||||
@ -226,8 +228,11 @@ fu_engine_requirements_missing_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
|
||||
g_assert_false(ret);
|
||||
}
|
||||
@ -240,12 +245,15 @@ fu_engine_requirements_soft_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <suggests>"
|
||||
" <id compare=\"ge\" version=\"1.2.3\">not.going.to.exist</id>"
|
||||
" </suggests>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy version */
|
||||
@ -260,8 +268,11 @@ fu_engine_requirements_soft_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_FORCE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_FORCE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -274,12 +285,15 @@ fu_engine_requirements_client_fail_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <requires>"
|
||||
" <client>detach-action</client>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* make the component require one thing */
|
||||
@ -291,8 +305,11 @@ fu_engine_requirements_client_fail_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_false(ret);
|
||||
}
|
||||
@ -305,12 +322,15 @@ fu_engine_requirements_client_invalid_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <requires>"
|
||||
" <client>hello-dave</client>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* make the component require one thing */
|
||||
@ -322,8 +342,11 @@ fu_engine_requirements_client_invalid_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
|
||||
g_assert_false(ret);
|
||||
}
|
||||
@ -336,12 +359,15 @@ fu_engine_requirements_client_pass_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <requires>"
|
||||
" <client>detach-action</client>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy version */
|
||||
@ -356,8 +382,11 @@ fu_engine_requirements_client_pass_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -368,9 +397,8 @@ fu_engine_requirements_version_require_func(gconstpointer user_data)
|
||||
FuTest *self = (FuTest *)user_data;
|
||||
gboolean ret;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -404,14 +432,64 @@ fu_engine_requirements_version_require_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_true(
|
||||
g_str_has_prefix(error->message, "device requires firmware with a version check"));
|
||||
g_assert_false(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_requirements_version_lowest_func(gconstpointer user_data)
|
||||
{
|
||||
FuTest *self = (FuTest *)user_data;
|
||||
gboolean ret;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
const gchar *xml =
|
||||
"<component>"
|
||||
" <provides>"
|
||||
" <firmware type=\"flashed\">12345678-1234-1234-1234-123456789012</firmware>"
|
||||
" </provides>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.2\">"
|
||||
" </release>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy device */
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_version(device, "1.2.3");
|
||||
fu_device_set_version_lowest(device, "1.2.3");
|
||||
fu_device_add_vendor_id(device, "FFFF");
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_UNSIGNED_PAYLOAD);
|
||||
fu_device_add_guid(device, "12345678-1234-1234-1234-123456789012");
|
||||
|
||||
/* make the component require one thing */
|
||||
silo = xb_silo_new_from_xml(xml, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(silo);
|
||||
component = xb_silo_query_first(silo, "component", &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_true(
|
||||
g_str_has_prefix(error->message, "Specified firmware is older than the minimum"));
|
||||
g_assert_false(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_requirements_unsupported_func(gconstpointer user_data)
|
||||
{
|
||||
@ -420,12 +498,15 @@ fu_engine_requirements_unsupported_func(gconstpointer user_data)
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *xml = "<component>"
|
||||
" <requires>"
|
||||
" <UNKNOWN compare=\"ge\" version=\"2.6.0\"/>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy version */
|
||||
@ -440,8 +521,11 @@ fu_engine_requirements_unsupported_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_false(ret);
|
||||
}
|
||||
@ -455,7 +539,7 @@ fu_engine_requirements_child_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) child = fu_device_new();
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -496,8 +580,12 @@ fu_engine_requirements_child_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -511,7 +599,7 @@ fu_engine_requirements_child_fail_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) child = fu_device_new();
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -552,8 +640,12 @@ fu_engine_requirements_child_fail_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_nonnull(
|
||||
g_strstr_len(error->message, -1, "Not compatible with child device version"));
|
||||
@ -565,7 +657,7 @@ fu_engine_requirements_func(gconstpointer user_data)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
@ -574,6 +666,9 @@ fu_engine_requirements_func(gconstpointer user_data)
|
||||
" <requires>"
|
||||
" <id compare=\"ge\" version=\"1.2.3\">org.test.dummy</id>"
|
||||
" </requires>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.3\"/>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up some dummy versions */
|
||||
@ -589,8 +684,11 @@ fu_engine_requirements_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(NULL, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -603,7 +701,7 @@ fu_engine_requirements_device_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -647,8 +745,12 @@ fu_engine_requirements_device_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -661,7 +763,7 @@ fu_engine_requirements_device_plain_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -694,8 +796,12 @@ fu_engine_requirements_device_plain_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -706,9 +812,8 @@ fu_engine_requirements_version_format_func(gconstpointer user_data)
|
||||
FuTest *self = (FuTest *)user_data;
|
||||
gboolean ret;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -743,8 +848,9 @@ fu_engine_requirements_version_format_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_nonnull(
|
||||
g_strstr_len(error->message, -1, "Firmware version formats were different"));
|
||||
@ -757,9 +863,8 @@ fu_engine_requirements_only_upgrade_func(gconstpointer user_data)
|
||||
FuTest *self = (FuTest *)user_data;
|
||||
gboolean ret;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -789,12 +894,9 @@ fu_engine_requirements_only_upgrade_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine,
|
||||
request,
|
||||
task,
|
||||
FWUPD_INSTALL_FLAG_ALLOW_OLDER,
|
||||
&error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_nonnull(g_strstr_len(error->message, -1, "Device only supports version upgrades"));
|
||||
g_assert_false(ret);
|
||||
@ -811,8 +913,8 @@ fu_engine_requirements_sibling_device_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) parent = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task1 = NULL;
|
||||
g_autoptr(FuInstallTask) task2 = NULL;
|
||||
g_autoptr(FuRelease) release1 = fu_release_new();
|
||||
g_autoptr(FuRelease) release2 = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -879,8 +981,12 @@ fu_engine_requirements_sibling_device_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task1 = fu_install_task_new(device1, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task1, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release1, device1);
|
||||
fu_release_set_request(release1, request);
|
||||
ret = fu_release_load(release1, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release1, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_false(ret);
|
||||
g_clear_error(&error);
|
||||
@ -900,8 +1006,12 @@ fu_engine_requirements_sibling_device_func(gconstpointer user_data)
|
||||
fu_engine_add_device(engine, device2);
|
||||
|
||||
/* check this passes */
|
||||
task2 = fu_install_task_new(device1, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task2, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release2, device1);
|
||||
fu_release_set_request(release2, request);
|
||||
ret = fu_release_load(release2, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release2, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -915,7 +1025,7 @@ fu_engine_requirements_other_device_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device2 = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -966,8 +1076,12 @@ fu_engine_requirements_other_device_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device1, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device1);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -981,8 +1095,8 @@ fu_engine_requirements_protocol_check_func(gconstpointer user_data)
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(FuInstallTask) task1 = NULL;
|
||||
g_autoptr(FuInstallTask) task2 = NULL;
|
||||
g_autoptr(FuRelease) release1 = fu_release_new();
|
||||
g_autoptr(FuRelease) release2 = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -1045,16 +1159,17 @@ fu_engine_requirements_protocol_check_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this fails */
|
||||
task1 = fu_install_task_new(device1, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task1, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release1, device1);
|
||||
fu_release_set_request(release1, request);
|
||||
ret = fu_release_load(release1, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_false(ret);
|
||||
g_clear_error(&error);
|
||||
|
||||
/* check this passes */
|
||||
task2 = fu_install_task_new(device2, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task2, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
|
||||
fu_release_set_device(release2, device2);
|
||||
fu_release_set_request(release2, request);
|
||||
ret = fu_release_load(release2, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -1068,7 +1183,7 @@ fu_engine_requirements_parent_device_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device2 = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
@ -1121,8 +1236,12 @@ fu_engine_requirements_parent_device_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check this passes */
|
||||
task = fu_install_task_new(device2, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device2);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
}
|
||||
@ -1372,7 +1491,7 @@ fu_engine_require_hwid_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GBytes) blob_cab = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
@ -1423,8 +1542,12 @@ fu_engine_require_hwid_func(gconstpointer user_data)
|
||||
g_assert_nonnull(component);
|
||||
|
||||
/* check requirements */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_check_requirements(engine, request, task, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_check_requirements(engine, release, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE);
|
||||
g_assert_nonnull(error);
|
||||
g_assert_cmpstr(error->message,
|
||||
@ -1717,7 +1840,7 @@ fu_engine_history_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuHistory) history = NULL;
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(FwupdDevice) device3 = NULL;
|
||||
g_autoptr(FwupdDevice) device4 = NULL;
|
||||
@ -1784,14 +1907,16 @@ fu_engine_history_func(gconstpointer user_data)
|
||||
fu_device_set_metadata_integer(device, "nr-update", 0);
|
||||
|
||||
/* install it */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
fu_release_set_device(release, device);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_install_release(engine,
|
||||
release,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
|
||||
@ -1860,13 +1985,18 @@ fu_engine_multiple_rels_func(gconstpointer user_data)
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GBytes) blob_cab = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo_empty = xb_silo_new();
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
g_autoptr(FuEngineRequest) request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
g_autoptr(GPtrArray) releases = NULL;
|
||||
g_autoptr(GPtrArray) rels = NULL;
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
g_autoptr(XbQuery) query = NULL;
|
||||
#endif
|
||||
|
||||
/* ensure empty tree */
|
||||
fu_self_test_mkroot();
|
||||
@ -1921,15 +2051,40 @@ fu_engine_multiple_rels_func(gconstpointer user_data)
|
||||
/* set up counter */
|
||||
fu_device_set_metadata_integer(device, "nr-update", 0);
|
||||
|
||||
/* install it */
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
/* get all */
|
||||
#if LIBXMLB_CHECK_VERSION(0, 2, 0)
|
||||
query = xb_query_new_full(xb_node_get_silo(component),
|
||||
"releases/release",
|
||||
XB_QUERY_FLAG_FORCE_NODE_CACHE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(query);
|
||||
rels = xb_node_query_full(component, query, &error);
|
||||
#else
|
||||
rels = xb_node_query(component, "releases/release", 0, &error);
|
||||
#endif
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(rels);
|
||||
|
||||
releases = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
for (guint i = 0; i < rels->len; i++) {
|
||||
XbNode *rel = g_ptr_array_index(rels, i);
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
fu_release_set_device(release, device);
|
||||
ret = fu_release_load(release, component, rel, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
g_ptr_array_add(releases, g_object_ref(release));
|
||||
}
|
||||
|
||||
/* install them */
|
||||
ret = fu_engine_install_releases(engine,
|
||||
request,
|
||||
releases,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
|
||||
@ -1948,7 +2103,7 @@ fu_engine_history_inherit(gconstpointer user_data)
|
||||
g_autofree gchar *history_db = NULL;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GBytes) blob_cab = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@ -2016,14 +2171,16 @@ fu_engine_history_inherit(gconstpointer user_data)
|
||||
|
||||
/* install it */
|
||||
g_setenv("FWUPD_PLUGIN_TEST", "requires-activation", TRUE);
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
fu_release_set_device(release, device);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_install_release(engine,
|
||||
release,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
|
||||
@ -2045,13 +2202,12 @@ fu_engine_history_inherit(gconstpointer user_data)
|
||||
fu_progress_reset(progress);
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_version(device, "1.2.2");
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
ret = fu_engine_install_release(engine,
|
||||
release,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
g_object_unref(engine);
|
||||
@ -2097,7 +2253,7 @@ fu_engine_install_needs_reboot(gconstpointer user_data)
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GBytes) blob_cab = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@ -2155,14 +2311,16 @@ fu_engine_install_needs_reboot(gconstpointer user_data)
|
||||
|
||||
/* install it */
|
||||
g_setenv("FWUPD_PLUGIN_TEST", "requires-reboot", TRUE);
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
fu_release_set_device(release, device);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_install_release(engine,
|
||||
release,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
|
||||
@ -2185,7 +2343,7 @@ fu_engine_history_error_func(gconstpointer user_data)
|
||||
g_autoptr(FuDevice) device = fu_device_new_with_context(self->ctx);
|
||||
g_autoptr(FuEngine) engine = fu_engine_new(FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuHistory) history = NULL;
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GBytes) blob_cab = NULL;
|
||||
g_autoptr(GError) error2 = NULL;
|
||||
@ -2240,14 +2398,16 @@ fu_engine_history_error_func(gconstpointer user_data)
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(component);
|
||||
task = fu_install_task_new(device, component);
|
||||
ret = fu_engine_install(engine,
|
||||
task,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
FWUPD_FEATURE_FLAG_NONE,
|
||||
&error);
|
||||
fu_release_set_device(release, device);
|
||||
ret = fu_release_load(release, component, NULL, FWUPD_INSTALL_FLAG_NONE, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
ret = fu_engine_install_release(engine,
|
||||
release,
|
||||
blob_cab,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert_cmpstr(error->message, ==, "device was not in supported mode");
|
||||
g_assert_false(ret);
|
||||
@ -3259,7 +3419,7 @@ fu_plugin_composite_func(gconstpointer user_data)
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GPtrArray) components = NULL;
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(GPtrArray) install_tasks =
|
||||
g_autoptr(GPtrArray) releases =
|
||||
g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(XbSilo) silo_empty = xb_silo_new();
|
||||
@ -3361,12 +3521,17 @@ fu_plugin_composite_func(gconstpointer user_data)
|
||||
/* do any devices pass the requirements */
|
||||
for (guint j = 0; j < devices->len; j++) {
|
||||
FuDevice *device = g_ptr_array_index(devices, j);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* is this component valid for the device */
|
||||
task = fu_install_task_new(device, component);
|
||||
if (!fu_engine_check_requirements(engine, request, task, 0, &error_local)) {
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, request);
|
||||
if (!fu_release_load(release,
|
||||
component,
|
||||
NULL,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error_local)) {
|
||||
g_debug("requirement on %s:%s failed: %s",
|
||||
fu_device_get_id(device),
|
||||
xb_node_query_text(component, "id", NULL),
|
||||
@ -3374,19 +3539,19 @@ fu_plugin_composite_func(gconstpointer user_data)
|
||||
continue;
|
||||
}
|
||||
|
||||
g_ptr_array_add(install_tasks, g_steal_pointer(&task));
|
||||
g_ptr_array_add(releases, g_steal_pointer(&release));
|
||||
}
|
||||
}
|
||||
g_assert_cmpint(install_tasks->len, ==, 3);
|
||||
g_assert_cmpint(releases->len, ==, 3);
|
||||
|
||||
/* install the cab */
|
||||
ret = fu_engine_install_tasks(engine,
|
||||
request,
|
||||
install_tasks,
|
||||
blob,
|
||||
progress,
|
||||
FWUPD_DEVICE_FLAG_NONE,
|
||||
&error);
|
||||
ret = fu_engine_install_releases(engine,
|
||||
request,
|
||||
releases,
|
||||
blob,
|
||||
progress,
|
||||
FWUPD_DEVICE_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
|
||||
@ -3628,39 +3793,43 @@ fu_progressbar_func(gconstpointer user_data)
|
||||
}
|
||||
|
||||
static gint
|
||||
fu_install_task_compare_func_cb(gconstpointer a, gconstpointer b)
|
||||
fu_release_compare_func_cb(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
FuInstallTask *task_a = *((FuInstallTask **)a);
|
||||
FuInstallTask *task_b = *((FuInstallTask **)b);
|
||||
return fu_install_task_compare(task_a, task_b);
|
||||
FuRelease *release1 = *((FuRelease **)a);
|
||||
FuRelease *release2 = *((FuRelease **)b);
|
||||
return fu_release_compare(release1, release2);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_install_task_compare_func(gconstpointer user_data)
|
||||
fu_release_compare_func(gconstpointer user_data)
|
||||
{
|
||||
FuDevice *device_tmp;
|
||||
g_autoptr(GPtrArray) install_tasks = NULL;
|
||||
g_autoptr(GPtrArray) releases = g_ptr_array_new();
|
||||
g_autoptr(FuDevice) device1 = fu_device_new();
|
||||
g_autoptr(FuDevice) device2 = fu_device_new();
|
||||
g_autoptr(FuDevice) device3 = fu_device_new();
|
||||
|
||||
install_tasks = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
g_autoptr(FuRelease) release1 = fu_release_new();
|
||||
g_autoptr(FuRelease) release2 = fu_release_new();
|
||||
g_autoptr(FuRelease) release3 = fu_release_new();
|
||||
|
||||
fu_device_set_order(device1, 99);
|
||||
g_ptr_array_add(install_tasks, fu_install_task_new(device1, NULL));
|
||||
fu_release_set_device(release1, device1);
|
||||
g_ptr_array_add(releases, release1);
|
||||
fu_device_set_order(device2, 11);
|
||||
g_ptr_array_add(install_tasks, fu_install_task_new(device2, NULL));
|
||||
fu_release_set_device(release2, device2);
|
||||
g_ptr_array_add(releases, release2);
|
||||
fu_device_set_order(device3, 33);
|
||||
g_ptr_array_add(install_tasks, fu_install_task_new(device3, NULL));
|
||||
fu_release_set_device(release3, device3);
|
||||
g_ptr_array_add(releases, release3);
|
||||
|
||||
/* order the install tasks */
|
||||
g_ptr_array_sort(install_tasks, fu_install_task_compare_func_cb);
|
||||
g_assert_cmpint(install_tasks->len, ==, 3);
|
||||
device_tmp = fu_install_task_get_device(g_ptr_array_index(install_tasks, 0));
|
||||
g_ptr_array_sort(releases, fu_release_compare_func_cb);
|
||||
g_assert_cmpint(releases->len, ==, 3);
|
||||
device_tmp = fu_release_get_device(g_ptr_array_index(releases, 0));
|
||||
g_assert_cmpint(fu_device_get_order(device_tmp), ==, 11);
|
||||
device_tmp = fu_install_task_get_device(g_ptr_array_index(install_tasks, 1));
|
||||
device_tmp = fu_release_get_device(g_ptr_array_index(releases, 1));
|
||||
g_assert_cmpint(fu_device_get_order(device_tmp), ==, 33);
|
||||
device_tmp = fu_install_task_get_device(g_ptr_array_index(install_tasks, 2));
|
||||
device_tmp = fu_release_get_device(g_ptr_array_index(releases, 2));
|
||||
g_assert_cmpint(fu_device_get_order(device_tmp), ==, 99);
|
||||
}
|
||||
|
||||
@ -3729,7 +3898,7 @@ main(int argc, char **argv)
|
||||
g_test_add_data_func("/fwupd/device-list{remove-chain}",
|
||||
self,
|
||||
fu_device_list_remove_chain_func);
|
||||
g_test_add_data_func("/fwupd/install-task{compare}", self, fu_install_task_compare_func);
|
||||
g_test_add_data_func("/fwupd/release{compare}", self, fu_release_compare_func);
|
||||
g_test_add_data_func("/fwupd/engine{device-unlock}", self, fu_engine_device_unlock_func);
|
||||
g_test_add_data_func("/fwupd/engine{multiple-releases}",
|
||||
self,
|
||||
@ -3772,6 +3941,9 @@ main(int argc, char **argv)
|
||||
g_test_add_data_func("/fwupd/engine{requirements-version-require}",
|
||||
self,
|
||||
fu_engine_requirements_version_require_func);
|
||||
g_test_add_data_func("/fwupd/engine{requirements-version-lowest}",
|
||||
self,
|
||||
fu_engine_requirements_version_lowest_func);
|
||||
g_test_add_data_func("/fwupd/engine{requirements-parent-device}",
|
||||
self,
|
||||
fu_engine_requirements_parent_device_func);
|
||||
|
||||
@ -1103,11 +1103,11 @@ fu_util_firmware_dump(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
static gint
|
||||
fu_util_install_task_sort_cb(gconstpointer a, gconstpointer b)
|
||||
fu_util_release_sort_cb(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
FuInstallTask *task1 = *((FuInstallTask **)a);
|
||||
FuInstallTask *task2 = *((FuInstallTask **)b);
|
||||
return fu_install_task_compare(task1, task2);
|
||||
FuRelease *release1 = *((FuRelease **)a);
|
||||
FuRelease *release2 = *((FuRelease **)b);
|
||||
return fu_release_compare(release1, release2);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1175,7 +1175,7 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
g_autoptr(GPtrArray) components = NULL;
|
||||
g_autoptr(GPtrArray) devices_possible = NULL;
|
||||
g_autoptr(GPtrArray) errors = NULL;
|
||||
g_autoptr(GPtrArray) install_tasks = NULL;
|
||||
g_autoptr(GPtrArray) releases = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
|
||||
/* load engine */
|
||||
@ -1229,21 +1229,23 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
|
||||
/* for each component in the silo */
|
||||
errors = g_ptr_array_new_with_free_func((GDestroyNotify)g_error_free);
|
||||
install_tasks = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
releases = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
for (guint i = 0; i < components->len; i++) {
|
||||
XbNode *component = g_ptr_array_index(components, i);
|
||||
|
||||
/* do any devices pass the requirements */
|
||||
for (guint j = 0; j < devices_possible->len; j++) {
|
||||
FuDevice *device = g_ptr_array_index(devices_possible, j);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(FuRelease) release = fu_release_new();
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* is this component valid for the device */
|
||||
task = fu_install_task_new(device, component);
|
||||
fu_release_set_device(release, device);
|
||||
fu_release_set_request(release, priv->request);
|
||||
if (!fu_release_load(release, component, NULL, priv->flags, error))
|
||||
return FALSE;
|
||||
if (!fu_engine_check_requirements(priv->engine,
|
||||
priv->request,
|
||||
task,
|
||||
release,
|
||||
priv->flags | FWUPD_INSTALL_FLAG_FORCE,
|
||||
&error_local)) {
|
||||
g_debug("first pass requirement on %s:%s failed: %s",
|
||||
@ -1257,8 +1259,7 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
/* 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,
|
||||
priv->request,
|
||||
task,
|
||||
release,
|
||||
priv->flags,
|
||||
&error_local)) {
|
||||
g_debug("second pass requirement on %s:%s failed: %s",
|
||||
@ -1273,15 +1274,15 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
fu_device_incorporate_from_component(device, component);
|
||||
|
||||
/* success */
|
||||
g_ptr_array_add(install_tasks, g_steal_pointer(&task));
|
||||
g_ptr_array_add(releases, g_steal_pointer(&release));
|
||||
}
|
||||
}
|
||||
|
||||
/* order the install tasks by the device priority */
|
||||
g_ptr_array_sort(install_tasks, fu_util_install_task_sort_cb);
|
||||
g_ptr_array_sort(releases, fu_util_release_sort_cb);
|
||||
|
||||
/* nothing suitable */
|
||||
if (install_tasks->len == 0) {
|
||||
if (releases->len == 0) {
|
||||
GError *error_tmp = fu_common_error_array_get_best(errors);
|
||||
g_propagate_error(error, error_tmp);
|
||||
return FALSE;
|
||||
@ -1294,13 +1295,13 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
priv);
|
||||
|
||||
/* install all the tasks */
|
||||
if (!fu_engine_install_tasks(priv->engine,
|
||||
priv->request,
|
||||
install_tasks,
|
||||
blob_cab,
|
||||
priv->progress,
|
||||
priv->flags,
|
||||
error))
|
||||
if (!fu_engine_install_releases(priv->engine,
|
||||
priv->request,
|
||||
releases,
|
||||
blob_cab,
|
||||
priv->progress,
|
||||
priv->flags,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
fu_util_display_current_message(priv);
|
||||
|
||||
@ -40,7 +40,7 @@ daemon_src = [
|
||||
'fu-engine-request.c',
|
||||
'fu-history.c',
|
||||
'fu-idle.c',
|
||||
'fu-install-task.c',
|
||||
'fu-release.c',
|
||||
'fu-keyring-utils.c',
|
||||
'fu-plugin-list.c',
|
||||
'fu-remote-list.c',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user