From 4316c9e1047ca63fc831aff1cc36aab55f54332e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 16 May 2016 16:25:46 +0200 Subject: lib: Add API to add/modify/remove remotes --- lib/flatpak-installation.c | 68 +++++++++- lib/flatpak-installation.h | 8 ++ lib/flatpak-remote-private.h | 9 +- lib/flatpak-remote.c | 303 +++++++++++++++++++++++++++++++++++++++++-- lib/flatpak-remote.h | 20 ++- 5 files changed, 389 insertions(+), 19 deletions(-) diff --git a/lib/flatpak-installation.c b/lib/flatpak-installation.c index 68e31b1..bef2381 100644 --- a/lib/flatpak-installation.c +++ b/lib/flatpak-installation.c @@ -688,6 +688,7 @@ flatpak_installation_list_remotes (FlatpakInstallation *self, GError **error) { g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir_clone = NULL; g_auto(GStrv) remote_names = NULL; g_autoptr(GPtrArray) remotes = g_ptr_array_new_with_free_func (g_object_unref); int i; @@ -696,13 +697,68 @@ flatpak_installation_list_remotes (FlatpakInstallation *self, if (remote_names == NULL) return NULL; + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case + it has local changes */ + dir_clone = flatpak_dir_clone (dir); + if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + return NULL; + for (i = 0; remote_names[i] != NULL; i++) g_ptr_array_add (remotes, - flatpak_remote_new (dir, remote_names[i])); + flatpak_remote_new_with_dir (remote_names[i], dir_clone)); return g_steal_pointer (&remotes); } +gboolean +flatpak_installation_modify_remote (FlatpakInstallation *self, + FlatpakRemote *remote, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir_clone = NULL; + + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case + it has local changes */ + dir_clone = flatpak_dir_clone (dir); + if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + return NULL; + + if (!flatpak_remote_commit (remote, dir_clone, cancellable, error)) + return FALSE; + + /* Make sure we pick up the new config */ + flatpak_installation_drop_caches (self, NULL, NULL); + + return TRUE; +} + +gboolean +flatpak_installation_remove_remote (FlatpakInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir_clone = NULL; + + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case + it has local changes */ + dir_clone = flatpak_dir_clone (dir); + if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + return NULL; + + if (!flatpak_dir_remove_remote (dir, FALSE, name, + cancellable, error)) + return FALSE; + + /* Make sure we pick up the new config */ + flatpak_installation_drop_caches (self, NULL, NULL); + + return TRUE; +} + /** * flatpak_installation_get_remote_by_name: * @self: a #FlatpakInstallation @@ -721,6 +777,7 @@ flatpak_installation_get_remote_by_name (FlatpakInstallation *self, GError **error) { g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir_clone = NULL; g_auto(GStrv) remote_names = NULL; int i; @@ -731,7 +788,14 @@ flatpak_installation_get_remote_by_name (FlatpakInstallation *self, for (i = 0; remote_names[i] != NULL; i++) { if (strcmp (remote_names[i], name) == 0) - return flatpak_remote_new (dir, remote_names[i]); + { + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case + it has local changes */ + dir_clone = flatpak_dir_clone (dir); + if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + return NULL; + return flatpak_remote_new_with_dir (remote_names[i], dir_clone); + } } g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, diff --git a/lib/flatpak-installation.h b/lib/flatpak-installation.h index 796d1e1..e6461a1 100644 --- a/lib/flatpak-installation.h +++ b/lib/flatpak-installation.h @@ -138,6 +138,14 @@ FLATPAK_EXTERN FlatpakRemote *flatpak_installation_get_remote_by_name (Fl const gchar *name, GCancellable *cancellable, GError **error); +FLATPAK_EXTERN gboolean flatpak_installation_modify_remote (FlatpakInstallation *self, + FlatpakRemote *remote, + GCancellable *cancellable, + GError **error); +FLATPAK_EXTERN gboolean flatpak_installation_remove_remote (FlatpakInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error); FLATPAK_EXTERN char * flatpak_installation_load_app_overrides (FlatpakInstallation *self, const char *app_id, GCancellable *cancellable, diff --git a/lib/flatpak-remote-private.h b/lib/flatpak-remote-private.h index 9f79679..71f8e04 100644 --- a/lib/flatpak-remote-private.h +++ b/lib/flatpak-remote-private.h @@ -29,7 +29,12 @@ #include #include -FlatpakRemote *flatpak_remote_new (FlatpakDir *dir, - const char *name); +FlatpakRemote *flatpak_remote_new_with_dir (const char *name, + FlatpakDir *dir); + +gboolean flatpak_remote_commit (FlatpakRemote *self, + FlatpakDir *dir, + GCancellable *cancellable, + GError **error); #endif /* __FLATPAK_REMOTE_PRIVATE_H__ */ diff --git a/lib/flatpak-remote.c b/lib/flatpak-remote.c index 6a860c5..13cb37f 100644 --- a/lib/flatpak-remote.c +++ b/lib/flatpak-remote.c @@ -52,6 +52,22 @@ struct _FlatpakRemotePrivate { char *name; FlatpakDir *dir; + + char *local_url; + char *local_title; + gboolean local_gpg_verify; + gboolean local_noenumerate; + gboolean local_disabled; + int local_prio; + + guint local_url_set : 1; + guint local_title_set : 1; + guint local_gpg_verify_set : 1; + guint local_noenumerate_set : 1; + guint local_disabled_set : 1; + guint local_prio_set : 1; + + GBytes *local_gpg_key; }; G_DEFINE_TYPE_WITH_PRIVATE (FlatpakRemote, flatpak_remote, G_TYPE_OBJECT) @@ -69,7 +85,13 @@ flatpak_remote_finalize (GObject *object) FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); g_free (priv->name); - g_object_unref (priv->dir); + if (priv->dir) + g_object_unref (priv->dir); + if (priv->local_gpg_key) + g_bytes_unref (priv->local_gpg_key); + + g_free (priv->local_url); + g_free (priv->local_title); G_OBJECT_CLASS (flatpak_remote_parent_class)->finalize (object); } @@ -173,6 +195,9 @@ flatpak_remote_get_appstream_dir (FlatpakRemote *self, FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); g_autofree char *subdir = NULL; + if (priv->dir == NULL) + return NULL; + if (arch == NULL) arch = flatpak_get_arch (); @@ -198,6 +223,9 @@ flatpak_remote_get_appstream_timestamp (FlatpakRemote *self, FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); g_autofree char *subdir = NULL; + if (priv->dir == NULL) + return NULL; + if (arch == NULL) arch = flatpak_get_arch (); @@ -218,15 +246,43 @@ char * flatpak_remote_get_url (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - OstreeRepo *repo = flatpak_dir_get_repo (priv->dir); char *url; - if (ostree_repo_remote_get_url (repo, priv->name, &url, NULL)) - return url; + if (priv->local_url_set) + return g_strdup (priv->local_url); + + if (priv->dir) + { + OstreeRepo *repo = flatpak_dir_get_repo (priv->dir); + if (ostree_repo_remote_get_url (repo, priv->name, &url, NULL)) + return url; + } return NULL; } +/** + * flatpak_remote_set_url: + * @self: a #FlatpakRemote + * @url: The new url + * + * Sets the repository URL of this remote. + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_url (FlatpakRemote *self, + const char *url) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + g_free (priv->local_url); + priv->local_url = g_strdup (url); + priv->local_url_set = TRUE; +} + /** * flatpak_remote_get_title: * @self: a #FlatpakRemote @@ -240,7 +296,35 @@ flatpak_remote_get_title (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - return flatpak_dir_get_remote_title (priv->dir, priv->name); + if (priv->local_title_set) + return g_strdup (priv->local_title); + + if (priv->dir) + return flatpak_dir_get_remote_title (priv->dir, priv->name); + + return NULL; +} + +/** + * flatpak_remote_set_title: + * @self: a #FlatpakRemote + * @title: The new title + * + * Sets the repository title of this remote. + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_title (FlatpakRemote *self, + const char *title) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + g_free (priv->local_title); + priv->local_title = g_strdup (title); + priv->local_title_set = TRUE; } /** @@ -256,7 +340,34 @@ flatpak_remote_get_noenumerate (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - return flatpak_dir_get_remote_noenumerate (priv->dir, priv->name); + if (priv->local_noenumerate_set) + return priv->local_noenumerate; + + if (priv->dir) + return flatpak_dir_get_remote_noenumerate (priv->dir, priv->name); + + return FALSE; +} + +/** + * flatpak_remote_set_noenumerate: + * @self: a #FlatpakRemote + * @noenumerate: a bool + * + * Sets the noenumeration config of this remote. See flatpak_remote_get_noenumerate(). + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_noenumerate (FlatpakRemote *self, + gboolean noenumerate) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + priv->local_noenumerate = noenumerate; + priv->local_noenumerate_set = TRUE; } /** @@ -272,7 +383,33 @@ flatpak_remote_get_disabled (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - return flatpak_dir_get_remote_disabled (priv->dir, priv->name); + if (priv->local_disabled_set) + return priv->local_disabled; + + if (priv->dir) + return flatpak_dir_get_remote_disabled (priv->dir, priv->name); + + return FALSE; +} +/** + * flatpak_remote_set_disabled: + * @self: a #FlatpakRemote + * @disabled: a bool + * + * Sets the disabled config of this remote. See flatpak_remote_get_disable(). + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_disabled (FlatpakRemote *self, + gboolean disabled) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + priv->local_disabled = disabled; + priv->local_disabled_set = TRUE; } /** @@ -288,7 +425,34 @@ flatpak_remote_get_prio (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - return flatpak_dir_get_remote_prio (priv->dir, priv->name); + if (priv->local_prio_set) + return priv->local_prio; + + if (priv->dir) + return flatpak_dir_get_remote_prio (priv->dir, priv->name); + + return 1; +} + +/** + * flatpak_remote_set_prio: + * @self: a #FlatpakRemote + * @prio: a bool + * + * Sets the prio config of this remote. See flatpak_remote_get_prio(). + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_prio (FlatpakRemote *self, + int prio) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + priv->local_prio = prio; + priv->local_prio_set = TRUE; } /** @@ -303,18 +467,67 @@ gboolean flatpak_remote_get_gpg_verify (FlatpakRemote *self) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); - OstreeRepo *repo = flatpak_dir_get_repo (priv->dir); gboolean res; - if (ostree_repo_remote_get_gpg_verify (repo, priv->name, &res, NULL)) - return res; + if (priv->local_gpg_verify_set) + return priv->local_gpg_verify; + + if (priv->dir) + { + OstreeRepo *repo = flatpak_dir_get_repo (priv->dir); + if (ostree_repo_remote_get_gpg_verify (repo, priv->name, &res, NULL)) + return res; + } return FALSE; } +/** + * flatpak_remote_set_gpg_verify: + * @self: a #FlatpakRemote + * @gpg_verify: a bool + * + * Sets the gpg_verify config of this remote. See flatpak_remote_get_gpg_verify(). + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_gpg_verify (FlatpakRemote *self, + gboolean gpg_verify) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + priv->local_gpg_verify = gpg_verify; + priv->local_gpg_verify_set = TRUE; +} + +/** + * flatpak_remote_set_gpg_key: + * @self: a #FlatpakRemote + * @gpg_key: a #GBytes with gpg binary key data + * + * Sets the trusted gpg key for this remote. + * + * Note: This is a local modification of this object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + */ +void +flatpak_remote_set_gpg_key (FlatpakRemote *self, + GBytes *gpg_key) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + + if (priv->local_gpg_key != NULL) + g_bytes_unref (priv->local_gpg_key); + priv->local_gpg_key = g_bytes_ref (gpg_key); +} + FlatpakRemote * -flatpak_remote_new (FlatpakDir *dir, - const char *name) +flatpak_remote_new_with_dir (const char *name, + FlatpakDir *dir) { FlatpakRemotePrivate *priv; FlatpakRemote *self = g_object_new (FLATPAK_TYPE_REMOTE, @@ -322,7 +535,69 @@ flatpak_remote_new (FlatpakDir *dir, NULL); priv = flatpak_remote_get_instance_private (self); - priv->dir = g_object_ref (dir); + if (dir) + priv->dir = g_object_ref (dir); return self; } + +/** + * flatpak_remote_new: + * @name: a name + * + * Returns a new remote object which can be used to configure a new remote. + * + * Note: This is a local configuration object, you must commit changes + * using flatpak_installation_modify_remote() for the changes to take + * effect. + * + * Returns: (transfer full): a new #FlatpakRemote + **/ +FlatpakRemote * +flatpak_remote_new (const char *name) +{ + return flatpak_remote_new_with_dir (name, NULL); +} + +gboolean +flatpak_remote_commit (FlatpakRemote *self, + FlatpakDir *dir, + GCancellable *cancellable, + GError **error) +{ + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + g_autofree char *url = NULL; + g_autoptr(GKeyFile) config = NULL; + g_autofree char *group = g_strdup_printf ("remote \"%s\"", priv->name); + + url = flatpak_remote_get_url (self); + if (url == NULL || *url == 0) + return flatpak_fail (error, "No url specified"); + + config = ostree_repo_copy_config (flatpak_dir_get_repo (dir)); + if (priv->local_url_set) + g_key_file_set_string (config, group, "url", priv->local_url); + + if (priv->local_title_set) + g_key_file_set_string (config, group, "title", priv->local_title); + + if (priv->local_gpg_verify_set) + { + g_key_file_set_boolean (config, group, "gpg-verify", priv->local_gpg_verify); + g_key_file_set_boolean (config, group, "gpg-verify-summary", priv->local_gpg_verify); + } + + if (priv->local_noenumerate_set) + g_key_file_set_boolean (config, group, "xa.noenumerate", priv->local_noenumerate); + + if (priv->local_disabled_set) + g_key_file_set_boolean (config, group, "xa.disable", priv->local_disabled); + + if (priv->local_prio_set) + { + g_autofree char *prio_as_string = g_strdup_printf ("%d", priv->local_prio); + g_key_file_set_string (config, group, "xa.prio", prio_as_string); + } + + return flatpak_dir_modify_remote (dir, priv->name, config, priv->local_gpg_key, cancellable, error); +} diff --git a/lib/flatpak-remote.h b/lib/flatpak-remote.h index dca8fc6..d17f89c 100644 --- a/lib/flatpak-remote.h +++ b/lib/flatpak-remote.h @@ -50,16 +50,34 @@ typedef struct G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRemote, g_object_unref) #endif -FLATPAK_EXTERN const char * flatpak_remote_get_name (FlatpakRemote * self); +FLATPAK_EXTERN FlatpakRemote * flatpak_remote_new (const char *name); + +FLATPAK_EXTERN const char * flatpak_remote_get_name (FlatpakRemote *self); FLATPAK_EXTERN GFile * flatpak_remote_get_appstream_dir (FlatpakRemote *self, const char *arch); FLATPAK_EXTERN GFile * flatpak_remote_get_appstream_timestamp (FlatpakRemote *self, const char *arch); FLATPAK_EXTERN char * flatpak_remote_get_url (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_url (FlatpakRemote *self, + const char *url); FLATPAK_EXTERN char * flatpak_remote_get_title (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_title (FlatpakRemote *self, + const char *title); FLATPAK_EXTERN gboolean flatpak_remote_get_gpg_verify (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_gpg_verify (FlatpakRemote *self, + gboolean gpg_verify); +FLATPAK_EXTERN void flatpak_remote_set_gpg_key (FlatpakRemote *self, + GBytes *gpg_key); FLATPAK_EXTERN gboolean flatpak_remote_get_noenumerate (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_noenumerate (FlatpakRemote *self, + gboolean noenumerate); FLATPAK_EXTERN gboolean flatpak_remote_get_disabled (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_disabled (FlatpakRemote *self, + gboolean disabled); FLATPAK_EXTERN int flatpak_remote_get_prio (FlatpakRemote *self); +FLATPAK_EXTERN void flatpak_remote_set_prio (FlatpakRemote *self, + int prio); + + #endif /* __FLATPAK_REMOTE_H__ */ -- cgit v1.2.1