mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 07:04:54 +00:00
Add ModifyRemote as an easy way to enable and disable remotes like the LVFS
For example: $ fwupdmgr modify-remote lvfs-testing Enabled true
This commit is contained in:
parent
f4cc7cc1ac
commit
a6bd5580d3
@ -1296,6 +1296,61 @@ fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError
|
||||
return fwupd_client_parse_remotes_from_data (val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_modify_remote:
|
||||
* @client: A #FwupdClient
|
||||
* @remote_id: the remote ID, e.g. "lvfs-testing"
|
||||
* @key: the key, e.g. "Enabled"
|
||||
* @value: the key, e.g. "true"
|
||||
* @cancellable: the #GCancellable, or %NULL
|
||||
* @error: the #GError, or %NULL
|
||||
*
|
||||
* Modifies a system remote in a specific way.
|
||||
*
|
||||
* NOTE: User authentication may be required to complete this action.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
*
|
||||
* Since: 0.9.8
|
||||
**/
|
||||
gboolean
|
||||
fwupd_client_modify_remote (FwupdClient *client,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
FwupdClientPrivate *priv = GET_PRIVATE (client);
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE);
|
||||
g_return_val_if_fail (remote_id != NULL, FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* connect */
|
||||
if (!fwupd_client_connect (client, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* call into daemon */
|
||||
val = g_dbus_proxy_call_sync (priv->proxy,
|
||||
"ModifyRemote",
|
||||
g_variant_new ("(sss)", remote_id, key, value),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
error);
|
||||
if (val == NULL) {
|
||||
if (error != NULL)
|
||||
fwupd_client_fixup_dbus_error (*error);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static FwupdRemote *
|
||||
fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
|
||||
{
|
||||
|
@ -122,6 +122,12 @@ gboolean fwupd_client_update_metadata_with_id (FwupdClient *client,
|
||||
const gchar *signature_fn,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_remote (FwupdClient *client,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FwupdStatus fwupd_client_get_status (FwupdClient *client);
|
||||
guint fwupd_client_get_percentage (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_daemon_version (FwupdClient *client);
|
||||
|
@ -41,6 +41,7 @@ struct _FwupdRemote
|
||||
gchar *filename_asc;
|
||||
gchar *filename_cache;
|
||||
gchar *filename_cache_sig;
|
||||
gchar *filename_source;
|
||||
gboolean enabled;
|
||||
SoupURI *uri;
|
||||
SoupURI *uri_asc;
|
||||
@ -104,6 +105,13 @@ fwupd_remote_set_id (FwupdRemote *self, const gchar *id)
|
||||
g_strdelimit (self->id, ".", '\0');
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_remote_set_filename_source (FwupdRemote *self, const gchar *filename_source)
|
||||
{
|
||||
g_free (self->filename_source);
|
||||
self->filename_source = g_strdup (filename_source);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
fwupd_remote_get_suffix_for_keyring_kind (FwupdKeyringKind keyring_kind)
|
||||
{
|
||||
@ -350,6 +358,7 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
self->order_after = g_strsplit_set (order_after, ",:;", -1);
|
||||
|
||||
/* success */
|
||||
fwupd_remote_set_filename_source (self, filename);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -403,6 +412,23 @@ fwupd_remote_get_filename_cache_sig (FwupdRemote *self)
|
||||
return self->filename_cache_sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_filename_source:
|
||||
* @self: A #FwupdRemote
|
||||
*
|
||||
* Gets the path and filename of the remote itself, typically a `.conf` file.
|
||||
*
|
||||
* Returns: a string, or %NULL for unset
|
||||
*
|
||||
* Since: 0.9.8
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_remote_get_filename_source (FwupdRemote *self)
|
||||
{
|
||||
g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
|
||||
return self->filename_source;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_priority:
|
||||
* @self: A #FwupdRemote
|
||||
@ -767,6 +793,10 @@ fwupd_remote_to_variant_builder (FwupdRemote *self, GVariantBuilder *builder)
|
||||
g_variant_builder_add (builder, "{sv}", "FilenameCache",
|
||||
g_variant_new_string (self->filename_cache));
|
||||
}
|
||||
if (self->filename_source != NULL) {
|
||||
g_variant_builder_add (builder, "{sv}", "FilenameSource",
|
||||
g_variant_new_string (self->filename_source));
|
||||
}
|
||||
g_variant_builder_add (builder, "{sv}", "Enabled",
|
||||
g_variant_new_boolean (self->enabled));
|
||||
}
|
||||
@ -793,6 +823,8 @@ fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
|
||||
fwupd_remote_set_metadata_uri (self, g_variant_get_string (value, NULL));
|
||||
if (g_strcmp0 (key, "FilenameCache") == 0)
|
||||
fwupd_remote_set_filename_cache (self, g_variant_get_string (value, NULL));
|
||||
if (g_strcmp0 (key, "FilenameSource") == 0)
|
||||
fwupd_remote_set_filename_source (self, g_variant_get_string (value, NULL));
|
||||
}
|
||||
while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) {
|
||||
if (g_strcmp0 (key, "Username") == 0) {
|
||||
@ -932,6 +964,7 @@ fwupd_remote_finalize (GObject *obj)
|
||||
g_free (self->filename_asc);
|
||||
g_free (self->filename_cache);
|
||||
g_free (self->filename_cache_sig);
|
||||
g_free (self->filename_source);
|
||||
g_strfreev (self->order_after);
|
||||
g_strfreev (self->order_before);
|
||||
if (self->uri != NULL)
|
||||
|
@ -50,6 +50,7 @@ const gchar *fwupd_remote_get_username (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_password (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_filename_cache (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_filename_cache_sig (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_filename_source (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_firmware_base_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_metadata_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_metadata_uri_sig (FwupdRemote *self);
|
||||
|
@ -101,4 +101,15 @@
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.fwupd.modify-remote">
|
||||
<description>Modify a configured remote</description>
|
||||
<!-- TRANSLATORS: this is the PolicyKit modal dialog -->
|
||||
<message>Authentication is required to modify a configured remote used for firmware updates</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
||||
|
@ -496,6 +496,61 @@ fu_engine_load_verify_store (GError **error)
|
||||
return g_steal_pointer (&store);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_engine_modify_remote:
|
||||
* @self: A #FuEngine
|
||||
* @remote_id: A remote ID
|
||||
* @key: the key, e.g. "Enabled"
|
||||
* @value: the key, e.g. "true"
|
||||
* @error: A #GError, or %NULL
|
||||
*
|
||||
* Updates the verification store entry for a specific device.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
gboolean
|
||||
fu_engine_modify_remote (FuEngine *self,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GError **error)
|
||||
{
|
||||
FwupdRemote *remote;
|
||||
const gchar *filename;
|
||||
const gchar *keys[] = { "Enabled", "MetadataURI", "FirmwareBaseURI", NULL };
|
||||
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
|
||||
|
||||
/* check remote is valid */
|
||||
remote = fu_config_get_remote_by_id (self->config, remote_id);
|
||||
if (remote == NULL) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND,
|
||||
"remote %s not found", remote_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check keys are valid */
|
||||
if (!g_strv_contains (keys, key)) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_FOUND,
|
||||
"key %s not supported", key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* modify the remote filename */
|
||||
filename = fwupd_remote_get_filename_source (remote);
|
||||
if (!g_key_file_load_from_file (keyfile, filename,
|
||||
G_KEY_FILE_KEEP_COMMENTS,
|
||||
error)) {
|
||||
g_prefix_error (error, "failed to load %s: ", filename);
|
||||
return FALSE;
|
||||
}
|
||||
g_key_file_set_string (keyfile, "fwupd Remote", key, value);
|
||||
return g_key_file_save_to_file (keyfile, filename, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_engine_verify_update:
|
||||
* @self: A #FuEngine
|
||||
|
@ -80,6 +80,11 @@ gboolean fu_engine_verify (FuEngine *self,
|
||||
gboolean fu_engine_verify_update (FuEngine *self,
|
||||
const gchar *device_id,
|
||||
GError **error);
|
||||
gboolean fu_engine_modify_remote (FuEngine *self,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GError **error);
|
||||
gboolean fu_engine_install (FuEngine *self,
|
||||
const gchar *device_id,
|
||||
AsStore *store,
|
||||
|
@ -242,6 +242,9 @@ typedef struct {
|
||||
GBytes *blob_cab;
|
||||
FuMainPrivate *priv;
|
||||
gchar *device_id;
|
||||
gchar *remote_id;
|
||||
gchar *key;
|
||||
gchar *value;
|
||||
} FuMainAuthHelper;
|
||||
|
||||
static void
|
||||
@ -252,6 +255,9 @@ fu_main_auth_helper_free (FuMainAuthHelper *helper)
|
||||
if (helper->store != NULL)
|
||||
g_object_unref (helper->store);
|
||||
g_free (helper->device_id);
|
||||
g_free (helper->remote_id);
|
||||
g_free (helper->key);
|
||||
g_free (helper->value);
|
||||
g_object_unref (helper->invocation);
|
||||
g_free (helper);
|
||||
}
|
||||
@ -336,6 +342,35 @@ fu_main_authorize_verify_update_cb (GObject *source, GAsyncResult *res, gpointer
|
||||
g_dbus_method_invocation_return_value (helper->invocation, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_main_authorize_modify_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
g_autoptr(FuMainAuthHelper) helper = (FuMainAuthHelper *) user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(PolkitAuthorizationResult) auth = NULL;
|
||||
|
||||
/* get result */
|
||||
auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
|
||||
res, &error);
|
||||
if (!fu_main_authorization_is_valid (auth, &error)) {
|
||||
g_dbus_method_invocation_return_gerror (helper->invocation, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* authenticated */
|
||||
if (!fu_engine_modify_remote (helper->priv->engine,
|
||||
helper->remote_id,
|
||||
helper->key,
|
||||
helper->value,
|
||||
&error)) {
|
||||
g_dbus_method_invocation_return_gerror (helper->invocation, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
g_dbus_method_invocation_return_value (helper->invocation, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_main_authorize_install_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
@ -516,6 +551,36 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
helper);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (method_name, "ModifyRemote") == 0) {
|
||||
FuMainAuthHelper *helper;
|
||||
const gchar *remote_id = NULL;
|
||||
const gchar *key = NULL;
|
||||
const gchar *value = NULL;
|
||||
g_autoptr(PolkitSubject) subject = NULL;
|
||||
|
||||
/* check the id exists */
|
||||
g_variant_get (parameters, "(&s&s&s)", &remote_id, &key, &value);
|
||||
g_debug ("Called %s(%s,%s=%s)", method_name, remote_id, key, value);
|
||||
|
||||
/* create helper object */
|
||||
helper = g_new0 (FuMainAuthHelper, 1);
|
||||
helper->invocation = g_object_ref (invocation);
|
||||
helper->remote_id = g_strdup (remote_id);
|
||||
helper->key = g_strdup (key);
|
||||
helper->value = g_strdup (value);
|
||||
helper->priv = priv;
|
||||
|
||||
/* authenticate */
|
||||
subject = polkit_system_bus_name_new (sender);
|
||||
polkit_authority_check_authorization (helper->priv->authority, subject,
|
||||
"org.freedesktop.fwupd.modify-remote",
|
||||
NULL,
|
||||
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
|
||||
NULL,
|
||||
fu_main_authorize_modify_remote_cb,
|
||||
helper);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (method_name, "VerifyUpdate") == 0) {
|
||||
FuMainAuthHelper *helper;
|
||||
const gchar *device_id = NULL;
|
||||
|
@ -1409,6 +1409,21 @@ fu_util_update (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_modify_remote (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
if (g_strv_length (values) < 3) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"Invalid arguments: expected REMOTE-ID KEY VALUE");
|
||||
return FALSE;
|
||||
}
|
||||
return fwupd_client_modify_remote (priv->client,
|
||||
values[0], values[1], values[2],
|
||||
NULL, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_downgrade (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
@ -1737,6 +1752,12 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Dump SMBIOS data from a file"),
|
||||
fu_util_smbios_dump);
|
||||
fu_util_add (priv->cmd_array,
|
||||
"modify-remote",
|
||||
NULL,
|
||||
/* TRANSLATORS: command description */
|
||||
_("Modifies a given remote"),
|
||||
fu_util_modify_remote);
|
||||
|
||||
/* do stuff on ctrl+c */
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
|
@ -339,6 +339,44 @@
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<method name='ModifyRemote'>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
Modifies a remote in some way.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
<arg type='s' name='remote_id' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>
|
||||
Remote ID, e.g. 'lvfs-testing'.
|
||||
</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
<arg type='s' name='key' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>
|
||||
The key, e.g. 'Enabled'.
|
||||
</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
<arg type='s' name='value' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>
|
||||
The value of the correct type, e.g. a URL.
|
||||
</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<signal name='Changed'>
|
||||
<doc:doc>
|
||||
|
Loading…
Reference in New Issue
Block a user