mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-16 10:06:41 +00:00
Move the remotes parsing from the client to the server
This allows us to load the metadata stores in a more sensible way in the future.
This commit is contained in:
parent
f0bde3e4af
commit
4c36970445
@ -287,6 +287,26 @@ fwupd_client_parse_devices_from_variant (GVariant *val)
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GPtrArray *
|
||||||
|
fwupd_client_parse_remotes_from_data (GVariant *devices)
|
||||||
|
{
|
||||||
|
GPtrArray *remotes = NULL;
|
||||||
|
gsize sz;
|
||||||
|
g_autoptr(GVariant) untuple = NULL;
|
||||||
|
|
||||||
|
remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||||
|
untuple = g_variant_get_child_value (devices, 0);
|
||||||
|
sz = g_variant_n_children (untuple);
|
||||||
|
for (guint i = 0; i < sz; i++) {
|
||||||
|
FwupdRemote *remote;
|
||||||
|
g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i);
|
||||||
|
remote = fwupd_remote_new_from_data (data);
|
||||||
|
g_ptr_array_add (remotes, remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
return remotes;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fwupd_client_fixup_dbus_error (GError *error)
|
fwupd_client_fixup_dbus_error (GError *error)
|
||||||
{
|
{
|
||||||
@ -1251,131 +1271,6 @@ fwupd_client_update_metadata_with_id (FwupdClient *client,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GPtrArray *
|
|
||||||
fwupd_client_get_config_paths (void)
|
|
||||||
{
|
|
||||||
GPtrArray *paths = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
const gchar *remotes_dir;
|
|
||||||
const gchar *system_prefixlibdir = "/usr/lib/fwupd";
|
|
||||||
const gchar *system_sysconfdir = "/etc/fwupd";
|
|
||||||
g_autofree gchar *sysconfdir = NULL;
|
|
||||||
|
|
||||||
/* only set by the self test program */
|
|
||||||
remotes_dir = g_getenv ("FU_SELF_TEST_REMOTES_DIR");
|
|
||||||
if (remotes_dir != NULL) {
|
|
||||||
g_ptr_array_add (paths, g_strdup (remotes_dir));
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* use sysconfig, and then fall back to /etc */
|
|
||||||
sysconfdir = g_build_filename (SYSCONFDIR, "fwupd", NULL);
|
|
||||||
if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS)) {
|
|
||||||
g_ptr_array_add (paths, g_steal_pointer (&sysconfdir));
|
|
||||||
} else {
|
|
||||||
g_debug ("falling back to system path");
|
|
||||||
if (g_file_test (system_sysconfdir, G_FILE_TEST_EXISTS))
|
|
||||||
g_ptr_array_add (paths, g_strdup (system_sysconfdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add in system-wide locations */
|
|
||||||
if (g_file_test (system_prefixlibdir, G_FILE_TEST_EXISTS))
|
|
||||||
g_ptr_array_add (paths, g_strdup (system_prefixlibdir));
|
|
||||||
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fwupd_client_add_remotes_for_path (FwupdClient *client,
|
|
||||||
GPtrArray *remotes,
|
|
||||||
const gchar *path,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
const gchar *tmp;
|
|
||||||
g_autofree gchar *path_remotes = NULL;
|
|
||||||
g_autoptr(GDir) dir = NULL;
|
|
||||||
|
|
||||||
path_remotes = g_build_filename (path, "remotes.d", NULL);
|
|
||||||
if (!g_file_test (path_remotes, G_FILE_TEST_EXISTS))
|
|
||||||
return TRUE;
|
|
||||||
dir = g_dir_open (path_remotes, 0, error);
|
|
||||||
if (dir == NULL)
|
|
||||||
return FALSE;
|
|
||||||
while ((tmp = g_dir_read_name (dir)) != NULL) {
|
|
||||||
g_autofree gchar *filename = g_build_filename (path_remotes, tmp, NULL);
|
|
||||||
g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
|
|
||||||
g_debug ("loading from %s", filename);
|
|
||||||
if (!fwupd_remote_load_from_filename (remote, filename,
|
|
||||||
cancellable, error))
|
|
||||||
return FALSE;
|
|
||||||
g_ptr_array_add (remotes, g_steal_pointer (&remote));
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
|
||||||
fwupd_client_remote_sort_cb (gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
FwupdRemote *remote_a = *((FwupdRemote **) a);
|
|
||||||
FwupdRemote *remote_b = *((FwupdRemote **) b);
|
|
||||||
|
|
||||||
/* use priority first */
|
|
||||||
if (fwupd_remote_get_priority (remote_a) < fwupd_remote_get_priority (remote_b))
|
|
||||||
return 1;
|
|
||||||
if (fwupd_remote_get_priority (remote_a) > fwupd_remote_get_priority (remote_b))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* fall back to name */
|
|
||||||
return g_strcmp0 (fwupd_remote_get_id (remote_a),
|
|
||||||
fwupd_remote_get_id (remote_b));
|
|
||||||
}
|
|
||||||
|
|
||||||
static FwupdRemote *
|
|
||||||
fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < remotes->len; i++) {
|
|
||||||
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
|
||||||
if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
|
|
||||||
return remote;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static guint
|
|
||||||
fwupd_client_remotes_depsolve_with_direction (GPtrArray *remotes, gint inc)
|
|
||||||
{
|
|
||||||
guint cnt = 0;
|
|
||||||
for (guint i = 0; i < remotes->len; i++) {
|
|
||||||
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
|
||||||
gchar **order = inc < 0 ? fwupd_remote_get_order_after (remote) :
|
|
||||||
fwupd_remote_get_order_before (remote);
|
|
||||||
if (order == NULL)
|
|
||||||
continue;
|
|
||||||
for (guint j = 0; order[j] != NULL; j++) {
|
|
||||||
FwupdRemote *remote2;
|
|
||||||
if (g_strcmp0 (order[j], fwupd_remote_get_id (remote)) == 0) {
|
|
||||||
g_warning ("ignoring self-dep remote %s", order[j]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
remote2 = fwupd_client_get_remote_by_id_noref (remotes, order[j]);
|
|
||||||
if (remote2 == NULL) {
|
|
||||||
g_warning ("ignoring unfound remote %s", order[j]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fwupd_remote_get_priority (remote) > fwupd_remote_get_priority (remote2))
|
|
||||||
continue;
|
|
||||||
g_debug ("ordering %s=%s+%i",
|
|
||||||
fwupd_remote_get_id (remote),
|
|
||||||
fwupd_remote_get_id (remote2),
|
|
||||||
inc);
|
|
||||||
fwupd_remote_set_priority (remote, fwupd_remote_get_priority (remote2) + inc);
|
|
||||||
|
|
||||||
/* increment changes counter */
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* fwupd_client_get_remotes:
|
* fwupd_client_get_remotes:
|
||||||
* @client: A #FwupdClient
|
* @client: A #FwupdClient
|
||||||
@ -1391,64 +1286,42 @@ fwupd_client_remotes_depsolve_with_direction (GPtrArray *remotes, gint inc)
|
|||||||
GPtrArray *
|
GPtrArray *
|
||||||
fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError **error)
|
fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError **error)
|
||||||
{
|
{
|
||||||
guint depsolve_check;
|
FwupdClientPrivate *priv = GET_PRIVATE (client);
|
||||||
g_autoptr(GPtrArray) paths = NULL;
|
g_autoptr(GVariant) val = NULL;
|
||||||
g_autoptr(GPtrArray) remotes = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
|
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
|
||||||
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
|
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
/* get a list of all config paths */
|
/* connect */
|
||||||
paths = fwupd_client_get_config_paths ();
|
if (!fwupd_client_connect (client, cancellable, error))
|
||||||
if (paths->len == 0) {
|
return NULL;
|
||||||
g_set_error_literal (error,
|
|
||||||
FWUPD_ERROR,
|
/* call into daemon */
|
||||||
FWUPD_ERROR_NOT_FOUND,
|
val = g_dbus_proxy_call_sync (priv->proxy,
|
||||||
"No search paths found");
|
"GetRemotes",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
if (val == NULL) {
|
||||||
|
if (error != NULL)
|
||||||
|
fwupd_client_fixup_dbus_error (*error);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return fwupd_client_parse_remotes_from_data (val);
|
||||||
|
}
|
||||||
|
|
||||||
/* look for all remotes */
|
static FwupdRemote *
|
||||||
remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
|
||||||
for (guint i = 0; i < paths->len; i++) {
|
{
|
||||||
const gchar *path = g_ptr_array_index (paths, i);
|
for (guint i = 0; i < remotes->len; i++) {
|
||||||
g_debug ("using config path of %s", path);
|
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
||||||
if (!fwupd_client_add_remotes_for_path (client, remotes, path,
|
if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
|
||||||
cancellable, error))
|
return remote;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
/* nothing found */
|
|
||||||
if (remotes->len == 0) {
|
|
||||||
g_set_error_literal (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_FOUND,
|
|
||||||
"No remotes found in search paths");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* depsolve */
|
|
||||||
for (depsolve_check = 0; depsolve_check < 100; depsolve_check++) {
|
|
||||||
guint cnt = 0;
|
|
||||||
cnt += fwupd_client_remotes_depsolve_with_direction (remotes, 1);
|
|
||||||
cnt += fwupd_client_remotes_depsolve_with_direction (remotes, -1);
|
|
||||||
if (cnt == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (depsolve_check == 100) {
|
|
||||||
g_set_error_literal (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_INTERNAL,
|
|
||||||
"Cannot depsolve remotes ordering");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* order these by priority, then name */
|
|
||||||
g_ptr_array_sort (remotes, fwupd_client_remote_sort_cb);
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return g_steal_pointer (&remotes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
FwupdRemote *fwupd_remote_new_from_data (GVariant *data);
|
||||||
|
GVariant *fwupd_remote_to_data (FwupdRemote *self,
|
||||||
|
const gchar *type_string);
|
||||||
gboolean fwupd_remote_load_from_filename (FwupdRemote *self,
|
gboolean fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
@ -368,6 +368,94 @@ fwupd_remote_get_id (FwupdRemote *self)
|
|||||||
return self->id;
|
return self->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fwupd_remote_to_variant_builder (FwupdRemote *self, GVariantBuilder *builder)
|
||||||
|
{
|
||||||
|
if (self->id != NULL) {
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Id",
|
||||||
|
g_variant_new_string (self->id));
|
||||||
|
}
|
||||||
|
if (self->username != NULL) {
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Username",
|
||||||
|
g_variant_new_string (self->username));
|
||||||
|
}
|
||||||
|
if (self->password != NULL) {
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Password",
|
||||||
|
g_variant_new_string (self->password));
|
||||||
|
}
|
||||||
|
if (self->url != NULL) {
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Url",
|
||||||
|
g_variant_new_string (self->url));
|
||||||
|
}
|
||||||
|
if (self->priority != 0) {
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Priority",
|
||||||
|
g_variant_new_int32 (self->priority));
|
||||||
|
}
|
||||||
|
g_variant_builder_add (builder, "{sv}", "Enabled",
|
||||||
|
g_variant_new_boolean (self->enabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
|
||||||
|
{
|
||||||
|
GVariant *value;
|
||||||
|
const gchar *key;
|
||||||
|
g_autoptr(GVariantIter) iter2 = g_variant_iter_copy (iter);
|
||||||
|
g_autoptr(GVariantIter) iter3 = g_variant_iter_copy (iter);
|
||||||
|
|
||||||
|
/* three passes, as we have to construct Id -> Url -> * */
|
||||||
|
while (g_variant_iter_loop (iter, "{sv}", &key, &value)) {
|
||||||
|
if (g_strcmp0 (key, "Id") == 0)
|
||||||
|
fwupd_remote_set_id (self, g_variant_get_string (value, NULL));
|
||||||
|
}
|
||||||
|
while (g_variant_iter_loop (iter2, "{sv}", &key, &value)) {
|
||||||
|
if (g_strcmp0 (key, "Url") == 0)
|
||||||
|
fwupd_remote_set_url (self, g_variant_get_string (value, NULL));
|
||||||
|
}
|
||||||
|
while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) {
|
||||||
|
if (g_strcmp0 (key, "Username") == 0) {
|
||||||
|
fwupd_remote_set_username (self, g_variant_get_string (value, NULL));
|
||||||
|
} else if (g_strcmp0 (key, "Password") == 0) {
|
||||||
|
fwupd_remote_set_password (self, g_variant_get_string (value, NULL));
|
||||||
|
} else if (g_strcmp0 (key, "Enabled") == 0) {
|
||||||
|
self->enabled = g_variant_get_boolean (value);
|
||||||
|
} else if (g_strcmp0 (key, "Priority") == 0) {
|
||||||
|
self->priority = g_variant_get_int32 (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fwupd_remote_to_data:
|
||||||
|
* @remote: A #FwupdRemote
|
||||||
|
* @type_string: The Gvariant type string, e.g. "a{sv}" or "(a{sv})"
|
||||||
|
*
|
||||||
|
* Creates a GVariant from the remote data.
|
||||||
|
*
|
||||||
|
* Returns: the GVariant, or %NULL for error
|
||||||
|
*
|
||||||
|
* Since: 0.9.5
|
||||||
|
**/
|
||||||
|
GVariant *
|
||||||
|
fwupd_remote_to_data (FwupdRemote *self, const gchar *type_string)
|
||||||
|
{
|
||||||
|
GVariantBuilder builder;
|
||||||
|
|
||||||
|
g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
|
||||||
|
g_return_val_if_fail (type_string != NULL, NULL);
|
||||||
|
|
||||||
|
/* create an array with all the metadata in */
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||||
|
fwupd_remote_to_variant_builder (self, &builder);
|
||||||
|
|
||||||
|
/* supported types */
|
||||||
|
if (g_strcmp0 (type_string, "a{sv}") == 0)
|
||||||
|
return g_variant_new ("a{sv}", &builder);
|
||||||
|
if (g_strcmp0 (type_string, "(a{sv})") == 0)
|
||||||
|
return g_variant_new ("(a{sv})", &builder);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fwupd_remote_get_property (GObject *obj, guint prop_id,
|
fwupd_remote_get_property (GObject *obj, guint prop_id,
|
||||||
GValue *value, GParamSpec *pspec)
|
GValue *value, GParamSpec *pspec)
|
||||||
@ -464,6 +552,39 @@ fwupd_remote_finalize (GObject *obj)
|
|||||||
G_OBJECT_CLASS (fwupd_remote_parent_class)->finalize (obj);
|
G_OBJECT_CLASS (fwupd_remote_parent_class)->finalize (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fwupd_remote_new_from_data:
|
||||||
|
* @data: a #GVariant
|
||||||
|
*
|
||||||
|
* Creates a new remote using packed data.
|
||||||
|
*
|
||||||
|
* Returns: a new #FwupdRemote, or %NULL if @data was invalid
|
||||||
|
*
|
||||||
|
* Since: 0.9.5
|
||||||
|
**/
|
||||||
|
FwupdRemote *
|
||||||
|
fwupd_remote_new_from_data (GVariant *data)
|
||||||
|
{
|
||||||
|
FwupdRemote *rel = NULL;
|
||||||
|
const gchar *type_string;
|
||||||
|
g_autoptr(GVariantIter) iter = NULL;
|
||||||
|
|
||||||
|
type_string = g_variant_get_type_string (data);
|
||||||
|
if (g_strcmp0 (type_string, "(a{sv})") == 0) {
|
||||||
|
rel = fwupd_remote_new ();
|
||||||
|
g_variant_get (data, "(a{sv})", &iter);
|
||||||
|
fwupd_remote_set_from_variant_iter (rel, iter);
|
||||||
|
fwupd_remote_set_from_variant_iter (rel, iter);
|
||||||
|
} else if (g_strcmp0 (type_string, "a{sv}") == 0) {
|
||||||
|
rel = fwupd_remote_new ();
|
||||||
|
g_variant_get (data, "a{sv}", &iter);
|
||||||
|
fwupd_remote_set_from_variant_iter (rel, iter);
|
||||||
|
} else {
|
||||||
|
g_warning ("type %s not known", type_string);
|
||||||
|
}
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fwupd_remote_new:
|
* fwupd_remote_new:
|
||||||
*
|
*
|
||||||
|
232
src/fu-config.c
232
src/fu-config.c
@ -26,12 +26,17 @@
|
|||||||
|
|
||||||
#include "fu-config.h"
|
#include "fu-config.h"
|
||||||
|
|
||||||
|
#include "fwupd-error.h"
|
||||||
|
#include "fwupd-remote-private.h"
|
||||||
|
|
||||||
static void fu_config_finalize (GObject *obj);
|
static void fu_config_finalize (GObject *obj);
|
||||||
|
|
||||||
struct _FuConfig
|
struct _FuConfig
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
GKeyFile *keyfile;
|
GKeyFile *keyfile;
|
||||||
|
GPtrArray *remotes;
|
||||||
|
GPtrArray *monitors;
|
||||||
GPtrArray *blacklist_devices;
|
GPtrArray *blacklist_devices;
|
||||||
GPtrArray *blacklist_plugins;
|
GPtrArray *blacklist_plugins;
|
||||||
gboolean enable_option_rom;
|
gboolean enable_option_rom;
|
||||||
@ -47,15 +52,217 @@ fu_config_get_sysconfig_dir (void)
|
|||||||
return "/etc";
|
return "/etc";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GPtrArray *
|
||||||
|
fu_config_get_config_paths (void)
|
||||||
|
{
|
||||||
|
GPtrArray *paths = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
const gchar *remotes_dir;
|
||||||
|
const gchar *system_prefixlibdir = "/usr/lib/fwupd";
|
||||||
|
const gchar *system_sysconfdir = "/etc/fwupd";
|
||||||
|
g_autofree gchar *sysconfdir = NULL;
|
||||||
|
|
||||||
|
/* only set by the self test program */
|
||||||
|
remotes_dir = g_getenv ("FU_SELF_TEST_REMOTES_DIR");
|
||||||
|
if (remotes_dir != NULL) {
|
||||||
|
g_ptr_array_add (paths, g_strdup (remotes_dir));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* use sysconfig, and then fall back to /etc */
|
||||||
|
sysconfdir = g_build_filename (SYSCONFDIR, "fwupd", NULL);
|
||||||
|
if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS)) {
|
||||||
|
g_ptr_array_add (paths, g_steal_pointer (&sysconfdir));
|
||||||
|
} else {
|
||||||
|
g_debug ("falling back to system path");
|
||||||
|
if (g_file_test (system_sysconfdir, G_FILE_TEST_EXISTS))
|
||||||
|
g_ptr_array_add (paths, g_strdup (system_sysconfdir));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add in system-wide locations */
|
||||||
|
if (g_file_test (system_prefixlibdir, G_FILE_TEST_EXISTS))
|
||||||
|
g_ptr_array_add (paths, g_strdup (system_prefixlibdir));
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_config_monitor_changed_cb (GFileMonitor *monitor,
|
||||||
|
GFile *file,
|
||||||
|
GFile *other_file,
|
||||||
|
GFileMonitorEvent event_type,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
FuConfig *self = FU_CONFIG (user_data);
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autofree gchar *filename = g_file_get_path (file);
|
||||||
|
g_debug ("%s changed, reloading all configs", filename);
|
||||||
|
if (!fu_config_load (self, &error))
|
||||||
|
g_warning ("failed to rescan config: %s", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_config_add_remotes_for_path (FuConfig *self, const gchar *path, GError **error)
|
||||||
|
{
|
||||||
|
const gchar *tmp;
|
||||||
|
g_autofree gchar *path_remotes = NULL;
|
||||||
|
g_autoptr(GDir) dir = NULL;
|
||||||
|
|
||||||
|
path_remotes = g_build_filename (path, "remotes.d", NULL);
|
||||||
|
if (!g_file_test (path_remotes, G_FILE_TEST_EXISTS))
|
||||||
|
return TRUE;
|
||||||
|
dir = g_dir_open (path_remotes, 0, error);
|
||||||
|
if (dir == NULL)
|
||||||
|
return FALSE;
|
||||||
|
while ((tmp = g_dir_read_name (dir)) != NULL) {
|
||||||
|
GFileMonitor *monitor;
|
||||||
|
g_autofree gchar *filename = g_build_filename (path_remotes, tmp, NULL);
|
||||||
|
g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
|
||||||
|
g_autoptr(GFile) file = g_file_new_for_path (filename);
|
||||||
|
g_debug ("loading from %s", filename);
|
||||||
|
if (!fwupd_remote_load_from_filename (remote, filename,
|
||||||
|
NULL, error))
|
||||||
|
return FALSE;
|
||||||
|
g_ptr_array_add (self->remotes, g_steal_pointer (&remote));
|
||||||
|
|
||||||
|
/* set up a notify watch */
|
||||||
|
monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, error);
|
||||||
|
if (monitor == NULL)
|
||||||
|
return FALSE;
|
||||||
|
g_signal_connect (monitor, "changed",
|
||||||
|
G_CALLBACK (fu_config_monitor_changed_cb), self);
|
||||||
|
g_ptr_array_add (self->monitors, monitor);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
fu_config_remote_sort_cb (gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
FwupdRemote *remote_a = *((FwupdRemote **) a);
|
||||||
|
FwupdRemote *remote_b = *((FwupdRemote **) b);
|
||||||
|
|
||||||
|
/* use priority first */
|
||||||
|
if (fwupd_remote_get_priority (remote_a) < fwupd_remote_get_priority (remote_b))
|
||||||
|
return 1;
|
||||||
|
if (fwupd_remote_get_priority (remote_a) > fwupd_remote_get_priority (remote_b))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* fall back to name */
|
||||||
|
return g_strcmp0 (fwupd_remote_get_id (remote_a),
|
||||||
|
fwupd_remote_get_id (remote_b));
|
||||||
|
}
|
||||||
|
|
||||||
|
static FwupdRemote *
|
||||||
|
fu_config_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
|
||||||
|
{
|
||||||
|
for (guint i = 0; i < remotes->len; i++) {
|
||||||
|
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
||||||
|
if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
|
||||||
|
return remote;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
fu_config_remotes_depsolve_with_direction (FuConfig *self, gint inc)
|
||||||
|
{
|
||||||
|
guint cnt = 0;
|
||||||
|
for (guint i = 0; i < self->remotes->len; i++) {
|
||||||
|
FwupdRemote *remote = g_ptr_array_index (self->remotes, i);
|
||||||
|
gchar **order = inc < 0 ? fwupd_remote_get_order_after (remote) :
|
||||||
|
fwupd_remote_get_order_before (remote);
|
||||||
|
if (order == NULL)
|
||||||
|
continue;
|
||||||
|
for (guint j = 0; order[j] != NULL; j++) {
|
||||||
|
FwupdRemote *remote2;
|
||||||
|
if (g_strcmp0 (order[j], fwupd_remote_get_id (remote)) == 0) {
|
||||||
|
g_warning ("ignoring self-dep remote %s", order[j]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
remote2 = fu_config_get_remote_by_id_noref (self->remotes, order[j]);
|
||||||
|
if (remote2 == NULL) {
|
||||||
|
g_warning ("ignoring unfound remote %s", order[j]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fwupd_remote_get_priority (remote) > fwupd_remote_get_priority (remote2))
|
||||||
|
continue;
|
||||||
|
g_debug ("ordering %s=%s+%i",
|
||||||
|
fwupd_remote_get_id (remote),
|
||||||
|
fwupd_remote_get_id (remote2),
|
||||||
|
inc);
|
||||||
|
fwupd_remote_set_priority (remote, fwupd_remote_get_priority (remote2) + inc);
|
||||||
|
|
||||||
|
/* increment changes counter */
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_config_load_remotes (FuConfig *self, GError **error)
|
||||||
|
{
|
||||||
|
guint depsolve_check;
|
||||||
|
g_autoptr(GPtrArray) paths = NULL;
|
||||||
|
|
||||||
|
/* get a list of all config paths */
|
||||||
|
paths = fu_config_get_config_paths ();
|
||||||
|
if (paths->len == 0) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_FOUND,
|
||||||
|
"No search paths found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for all remotes */
|
||||||
|
for (guint i = 0; i < paths->len; i++) {
|
||||||
|
const gchar *path = g_ptr_array_index (paths, i);
|
||||||
|
g_debug ("using config path of %s", path);
|
||||||
|
if (!fu_config_add_remotes_for_path (self, path, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* depsolve */
|
||||||
|
for (depsolve_check = 0; depsolve_check < 100; depsolve_check++) {
|
||||||
|
guint cnt = 0;
|
||||||
|
cnt += fu_config_remotes_depsolve_with_direction (self, 1);
|
||||||
|
cnt += fu_config_remotes_depsolve_with_direction (self, -1);
|
||||||
|
if (cnt == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (depsolve_check == 100) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"Cannot depsolve remotes ordering");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* order these by priority, then name */
|
||||||
|
g_ptr_array_sort (self->remotes, fu_config_remote_sort_cb);
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_config_load (FuConfig *self, GError **error)
|
fu_config_load (FuConfig *self, GError **error)
|
||||||
{
|
{
|
||||||
|
GFileMonitor *monitor;
|
||||||
g_autofree gchar *config_file = NULL;
|
g_autofree gchar *config_file = NULL;
|
||||||
g_auto(GStrv) devices = NULL;
|
g_auto(GStrv) devices = NULL;
|
||||||
g_auto(GStrv) plugins = NULL;
|
g_auto(GStrv) plugins = NULL;
|
||||||
|
g_autoptr(GFile) file = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (FU_IS_CONFIG (self), FALSE);
|
g_return_val_if_fail (FU_IS_CONFIG (self), FALSE);
|
||||||
|
|
||||||
|
/* ensure empty in case we're called from a monitor change */
|
||||||
|
g_ptr_array_set_size (self->blacklist_devices, 0);
|
||||||
|
g_ptr_array_set_size (self->blacklist_plugins, 0);
|
||||||
|
g_ptr_array_set_size (self->monitors, 0);
|
||||||
|
g_ptr_array_set_size (self->remotes, 0);
|
||||||
|
|
||||||
/* load the main daemon config file */
|
/* load the main daemon config file */
|
||||||
config_file = g_build_filename (fu_config_get_sysconfig_dir (),
|
config_file = g_build_filename (fu_config_get_sysconfig_dir (),
|
||||||
"fwupd.conf", NULL);
|
"fwupd.conf", NULL);
|
||||||
@ -64,6 +271,15 @@ fu_config_load (FuConfig *self, GError **error)
|
|||||||
G_KEY_FILE_NONE, error))
|
G_KEY_FILE_NONE, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* set up a notify watch */
|
||||||
|
file = g_file_new_for_path (config_file);
|
||||||
|
monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, error);
|
||||||
|
if (monitor == NULL)
|
||||||
|
return FALSE;
|
||||||
|
g_signal_connect (monitor, "changed",
|
||||||
|
G_CALLBACK (fu_config_monitor_changed_cb), self);
|
||||||
|
g_ptr_array_add (self->monitors, monitor);
|
||||||
|
|
||||||
/* optional, at the moment */
|
/* optional, at the moment */
|
||||||
self->enable_option_rom =
|
self->enable_option_rom =
|
||||||
g_key_file_get_boolean (self->keyfile,
|
g_key_file_get_boolean (self->keyfile,
|
||||||
@ -97,9 +313,21 @@ fu_config_load (FuConfig *self, GError **error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* load remotes */
|
||||||
|
if (!fu_config_load_remotes (self, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPtrArray *
|
||||||
|
fu_config_get_remotes (FuConfig *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (FU_IS_CONFIG (self), NULL);
|
||||||
|
return self->remotes;
|
||||||
|
}
|
||||||
|
|
||||||
GPtrArray *
|
GPtrArray *
|
||||||
fu_config_get_blacklist_devices (FuConfig *self)
|
fu_config_get_blacklist_devices (FuConfig *self)
|
||||||
{
|
{
|
||||||
@ -134,6 +362,8 @@ fu_config_init (FuConfig *self)
|
|||||||
self->keyfile = g_key_file_new ();
|
self->keyfile = g_key_file_new ();
|
||||||
self->blacklist_devices = g_ptr_array_new_with_free_func (g_free);
|
self->blacklist_devices = g_ptr_array_new_with_free_func (g_free);
|
||||||
self->blacklist_plugins = g_ptr_array_new_with_free_func (g_free);
|
self->blacklist_plugins = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
self->remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||||
|
self->monitors = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -144,6 +374,8 @@ fu_config_finalize (GObject *obj)
|
|||||||
g_key_file_unref (self->keyfile);
|
g_key_file_unref (self->keyfile);
|
||||||
g_ptr_array_unref (self->blacklist_devices);
|
g_ptr_array_unref (self->blacklist_devices);
|
||||||
g_ptr_array_unref (self->blacklist_plugins);
|
g_ptr_array_unref (self->blacklist_plugins);
|
||||||
|
g_ptr_array_unref (self->remotes);
|
||||||
|
g_ptr_array_unref (self->monitors);
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_config_parent_class)->finalize (obj);
|
G_OBJECT_CLASS (fu_config_parent_class)->finalize (obj);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ gboolean fu_config_load (FuConfig *self,
|
|||||||
GPtrArray *fu_config_get_blacklist_devices (FuConfig *self);
|
GPtrArray *fu_config_get_blacklist_devices (FuConfig *self);
|
||||||
GPtrArray *fu_config_get_blacklist_plugins (FuConfig *self);
|
GPtrArray *fu_config_get_blacklist_plugins (FuConfig *self);
|
||||||
gboolean fu_config_get_enable_option_rom (FuConfig *self);
|
gboolean fu_config_get_enable_option_rom (FuConfig *self);
|
||||||
|
GPtrArray *fu_config_get_remotes (FuConfig *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "fwupd-common-private.h"
|
#include "fwupd-common-private.h"
|
||||||
#include "fwupd-enums-private.h"
|
#include "fwupd-enums-private.h"
|
||||||
#include "fwupd-release-private.h"
|
#include "fwupd-release-private.h"
|
||||||
|
#include "fwupd-remote-private.h"
|
||||||
#include "fwupd-resources.h"
|
#include "fwupd-resources.h"
|
||||||
|
|
||||||
#include "fu-config.h"
|
#include "fu-config.h"
|
||||||
@ -1911,6 +1912,32 @@ fu_main_get_details_local_from_fd (FuMainPrivate *priv, gint fd, GError **error)
|
|||||||
return g_variant_new ("(a{sa{sv}})", &builder);
|
return g_variant_new ("(a{sa{sv}})", &builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
fu_main_get_remotes_as_variant (FuMainPrivate *priv, GError **error)
|
||||||
|
{
|
||||||
|
GVariantBuilder builder;
|
||||||
|
GPtrArray *remotes;
|
||||||
|
|
||||||
|
/* get the list of remotes */
|
||||||
|
remotes = fu_config_get_remotes (priv->config);
|
||||||
|
if (remotes->len == 0) {
|
||||||
|
g_set_error (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"no remotes configured");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||||
|
for (guint i = 0; i < remotes->len; i++) {
|
||||||
|
GVariant *tmp;
|
||||||
|
FwupdRemote *remote = g_ptr_array_index (remotes, i);
|
||||||
|
tmp = fwupd_remote_to_data (remote, "a{sv}");
|
||||||
|
g_variant_builder_add_value (&builder, tmp);
|
||||||
|
}
|
||||||
|
return g_variant_new ("(aa{sv})", &builder);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||||
const gchar *object_path, const gchar *interface_name,
|
const gchar *object_path, const gchar *interface_name,
|
||||||
@ -1995,6 +2022,18 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return variant */
|
||||||
|
if (g_strcmp0 (method_name, "GetRemotes") == 0) {
|
||||||
|
g_debug ("Called %s()", method_name);
|
||||||
|
val = fu_main_get_remotes_as_variant (priv, &error);
|
||||||
|
if (val == NULL) {
|
||||||
|
fu_main_invocation_return_error (priv, invocation, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fu_main_invocation_return_value (priv, invocation, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* return '' */
|
/* return '' */
|
||||||
if (g_strcmp0 (method_name, "ClearResults") == 0) {
|
if (g_strcmp0 (method_name, "ClearResults") == 0) {
|
||||||
FuDeviceItem *item = NULL;
|
FuDeviceItem *item = NULL;
|
||||||
|
@ -1227,7 +1227,7 @@ fu_util_get_remotes (FuUtilPrivate *priv, gchar **values, GError **error)
|
|||||||
if (uri != NULL) {
|
if (uri != NULL) {
|
||||||
g_autofree gchar *uri_str = soup_uri_to_string (uri, FALSE);
|
g_autofree gchar *uri_str = soup_uri_to_string (uri, FALSE);
|
||||||
/* TRANSLATORS: remote URI */
|
/* TRANSLATORS: remote URI */
|
||||||
fu_util_print_data (_("URI"), uri_str);
|
fu_util_print_data (_("URL"), uri_str);
|
||||||
}
|
}
|
||||||
uri = fwupd_remote_get_uri_asc (remote);
|
uri = fwupd_remote_get_uri_asc (remote);
|
||||||
if (uri != NULL) {
|
if (uri != NULL) {
|
||||||
|
@ -294,6 +294,24 @@
|
|||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<!--***********************************************************-->
|
||||||
|
<method name='GetRemotes'>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>
|
||||||
|
Gets the list of remotes.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
<arg type='aa{sv}' name='results' direction='out'>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>
|
||||||
|
<doc:para>The array remotes, with properties</doc:para>
|
||||||
|
</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
<!--***********************************************************-->
|
<!--***********************************************************-->
|
||||||
<method name='ClearResults'>
|
<method name='ClearResults'>
|
||||||
<doc:doc>
|
<doc:doc>
|
||||||
|
Loading…
Reference in New Issue
Block a user