From 4342959f6d0f94c0bbec067544b5593f7756b196 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 15 Dec 2015 12:43:56 +0100 Subject: [PATCH] lib: Add xdg_app_installation_update --- lib/test-lib.c | 17 +++++ lib/xdg-app-installation.c | 128 +++++++++++++++++++++++++++++++++++-- lib/xdg-app-installation.h | 9 +++ 3 files changed, 149 insertions(+), 5 deletions(-) diff --git a/lib/test-lib.c b/lib/test-lib.c index 91a7ba49..40f8fe54 100644 --- a/lib/test-lib.c +++ b/lib/test-lib.c @@ -48,6 +48,23 @@ main (int argc, char *argv[]) return 0; } + if (argc == 2) + { + app1 = xdg_app_installation_update (installation, + XDG_APP_REF_KIND_APP, + argv[1], + NULL, NULL, + progress_cb, (gpointer)0xdeadbeef, + NULL, &error); + if (app1 == NULL) + g_print ("Error: %s\n", error->message); + else + g_print ("Updated %s: %s\n", argv[1], + xdg_app_ref_get_commit (XDG_APP_REF (app1))); + + return 0; + } + g_print ("**** Listing all installed apps\n"); apps = xdg_app_installation_list_installed_refs (installation, XDG_APP_REF_KIND_APP, diff --git a/lib/xdg-app-installation.c b/lib/xdg-app-installation.c index 716e7b38..027e4828 100644 --- a/lib/xdg-app-installation.c +++ b/lib/xdg-app-installation.c @@ -536,22 +536,22 @@ xdg_app_installation_install (XdgAppInstallation *self, goto out; created_deploy_base = TRUE; - if (!xdg_app_dir_set_origin (priv->dir, ref, remote_name, cancellable, error)) + if (!xdg_app_dir_set_origin (dir_clone, ref, remote_name, cancellable, error)) goto out; - if (!xdg_app_dir_deploy (priv->dir, ref, NULL, cancellable, error)) + if (!xdg_app_dir_deploy (dir_clone, ref, NULL, cancellable, error)) goto out; if (kind == XDG_APP_REF_KIND_APP) { - if (!xdg_app_dir_make_current_ref (priv->dir, ref, cancellable, error)) + if (!xdg_app_dir_make_current_ref (dir_clone, ref, cancellable, error)) goto out; - if (!xdg_app_dir_update_exports (priv->dir, name, cancellable, error)) + if (!xdg_app_dir_update_exports (dir_clone, name, cancellable, error)) goto out; } - xdg_app_dir_cleanup_removed (priv->dir, cancellable, NULL); + xdg_app_dir_cleanup_removed (dir_clone, cancellable, NULL); result = get_ref (self, ref, cancellable); @@ -564,3 +564,121 @@ xdg_app_installation_install (XdgAppInstallation *self, return result; } + +/** + * xdg_app_installation_install: + * @self: a #XdgAppInstallation + * @progress: (scope call): the callback + * @cancellable: (nullable): a #GCancellable + * @error: return location for a #GError + * + * Lists the remotes. + * + * Returns: (transfer full): The ref for the newly installed app or %null on failure + */ +XdgAppInstalledRef * +xdg_app_installation_update (XdgAppInstallation *self, + XdgAppRefKind kind, + const char *name, + const char *arch, + const char *version, + XdgAppProgressCallback progress, + gpointer progress_data, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_autofree char *ref = NULL; + g_autoptr(XdgAppDir) dir_clone = NULL; + g_autoptr(GMainContext) main_context = NULL; + g_autoptr(OstreeAsyncProgress) ostree_progress = NULL; + g_autofree char *remote_name = NULL; + g_autofree char *previous_deployment = NULL; + XdgAppInstalledRef *result = NULL; + g_autoptr(GError) my_error = NULL; + + if (version == NULL) + version = "master"; + + if (arch == NULL) + arch = xdg_app_get_arch (); + + if (!xdg_app_is_valid_name (name)) + { + xdg_app_fail (error, "'%s' is not a valid name", name); + return NULL; + } + + if (!xdg_app_is_valid_branch (version)) + { + xdg_app_fail (error, "'%s' is not a valid branch name", version); + return NULL; + } + + if (kind == XDG_APP_REF_KIND_APP) + ref = xdg_app_build_app_ref (name, version, arch); + else + ref = xdg_app_build_runtime_ref (name, version, arch); + + remote_name = xdg_app_dir_get_origin (priv->dir, ref, cancellable, error); + if (remote_name == NULL) + return NULL; + + /* Pull, etc are not threadsafe, so we work on a copy */ + dir_clone = xdg_app_dir_clone (priv->dir); + + /* Work around ostree-pull spinning the default main context for the sync calls */ + main_context = g_main_context_new (); + g_main_context_push_thread_default (main_context); + + if (progress) + { + ostree_progress = ostree_async_progress_new_and_connect (progress_cb, progress_data); + g_object_set_data (G_OBJECT (ostree_progress), "callback", progress); + g_object_set_data (G_OBJECT (ostree_progress), "last_progress", GUINT_TO_POINTER(0)); + } + + if (!xdg_app_dir_pull (dir_clone, remote_name, ref, + ostree_progress, cancellable, error)) + goto out; + + previous_deployment = xdg_app_dir_read_active (dir_clone, ref, cancellable); + + if (!xdg_app_dir_deploy (dir_clone, ref, NULL, cancellable, &my_error)) + { + if (!g_error_matches (my_error, XDG_APP_DIR_ERROR, XDG_APP_DIR_ERROR_ALREADY_DEPLOYED)) + { + g_propagate_error (error, my_error); + goto out; + } + } + else + { + if (previous_deployment != NULL) + { + if (!xdg_app_dir_undeploy (dir_clone, ref, previous_deployment, + FALSE, + cancellable, error)) + goto out; + + if (!xdg_app_dir_prune (dir_clone, cancellable, error)) + goto out; + } + + if (kind == XDG_APP_REF_KIND_APP) + { + if (!xdg_app_dir_update_exports (dir_clone, name, cancellable, error)) + goto out; + } + } + + xdg_app_dir_cleanup_removed (dir_clone, cancellable, NULL); + + result = get_ref (self, ref, cancellable); + + out: + if (main_context) + g_main_context_pop_thread_default (main_context); + + return result; +} diff --git a/lib/xdg-app-installation.h b/lib/xdg-app-installation.h index 268d2af6..0cc346be 100644 --- a/lib/xdg-app-installation.h +++ b/lib/xdg-app-installation.h @@ -93,5 +93,14 @@ XDG_APP_EXTERN XdgAppInstalledRef * xdg_app_installation_install gpointer progress_data, GCancellable *cancellable, GError **error); +XDG_APP_EXTERN XdgAppInstalledRef * xdg_app_installation_update (XdgAppInstallation *self, + XdgAppRefKind kind, + const char *name, + const char *arch, + const char *version, + XdgAppProgressCallback progress, + gpointer progress_data, + GCancellable *cancellable, + GError **error); #endif /* __XDG_APP_INSTALLATION_H__ */