lib: Add xdg_app_installation_install

This commit is contained in:
Alexander Larsson committed 2015-12-15 12:26:59 +01:00
1 parent 1a2b5adffe
commit 9285d055ab
7 files changed
+285 -10

No files matched your search

+2 -2
View File
@@ -144,7 +144,7 @@ xdg_app_builtin_install_runtime (int argc, char **argv, GCancellable *cancellabl
goto out;
}
if (!xdg_app_dir_pull (dir, repository, ref,
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
cancellable, error))
goto out;
@@ -219,7 +219,7 @@ xdg_app_builtin_install_app (int argc, char **argv, GCancellable *cancellable, G
goto out;
}
if (!xdg_app_dir_pull (dir, repository, ref,
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
cancellable, error))
goto out;
+2 -2
View File
@@ -78,7 +78,7 @@ xdg_app_builtin_update_runtime (int argc, char **argv, GCancellable *cancellable
if (repository == NULL)
return FALSE;
if (!xdg_app_dir_pull (dir, repository, ref,
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
cancellable, error))
return FALSE;
@@ -148,7 +148,7 @@ xdg_app_builtin_update_app (int argc, char **argv, GCancellable *cancellable, GE
if (repository == NULL)
return FALSE;
if (!xdg_app_dir_pull (dir, repository, ref,
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
cancellable, error))
return FALSE;
+16 -5
View File
@@ -556,22 +556,27 @@ gboolean
xdg_app_dir_pull (XdgAppDir *self,
const char *repository,
const char *ref,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
GSConsole *console = NULL;
g_autoptr(OstreeAsyncProgress) progress = NULL;
g_autoptr(OstreeAsyncProgress) console_progress = NULL;
const char *refs[2];
if (!xdg_app_dir_ensure_repo (self, cancellable, error))
goto out;
console = gs_console_get ();
if (console)
if (progress == NULL)
{
gs_console_begin_status_line (console, "", NULL, NULL);
progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, console);
console = gs_console_get ();
if (console)
{
gs_console_begin_status_line (console, "", NULL, NULL);
console_progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, console);
progress = console_progress;
}
}
refs[0] = ref;
@@ -1986,6 +1991,12 @@ xdg_app_dir_new (GFile *path, gboolean user)
return g_object_new (XDG_APP_TYPE_DIR, "path", path, "user", user, NULL);
}
XdgAppDir*
xdg_app_dir_clone (XdgAppDir *self)
{
return xdg_app_dir_new (self->basedir, self->user);
}
XdgAppDir *
xdg_app_dir_get_system (void)
{
+2
View File
@@ -70,6 +70,7 @@ GKeyFile * xdg_app_deploy_get_metadata (XdgAppDeploy *deploy);
XdgAppDir* xdg_app_dir_new (GFile *basedir,
gboolean user);
XdgAppDir* xdg_app_dir_clone (XdgAppDir *self);
XdgAppDir *xdg_app_dir_get (gboolean user);
XdgAppDir *xdg_app_dir_get_system (void);
XdgAppDir *xdg_app_dir_get_user (void);
@@ -111,6 +112,7 @@ gboolean xdg_app_dir_ensure_repo (XdgAppDir *self,
gboolean xdg_app_dir_pull (XdgAppDir *self,
const char *repository,
const char *ref,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error);
gboolean xdg_app_dir_list_refs_for_name (XdgAppDir *self,
+29 -1
View File
@@ -4,6 +4,16 @@
#include <xdg-app.h>
static void
progress_cb (const char *status,
guint progress,
gboolean estimating,
gpointer user_data)
{
g_print ("status: %s, progress: %d estimating: %d, user_data: %p\n", status, progress, estimating, user_data);
}
int
main (int argc, char *argv[])
{
@@ -15,10 +25,29 @@ main (int argc, char *argv[])
XdgAppInstalledRef **runtimes;
XdgAppRemoteRef *remote_ref;
XdgAppRemote **remotes;
GError *error = NULL;
int i, j;
installation = xdg_app_installation_new_user ();
if (argc == 3)
{
app1 = xdg_app_installation_install (installation,
argv[1],
XDG_APP_REF_KIND_APP,
argv[2],
NULL, NULL,
progress_cb, (gpointer)0xdeadbeef,
NULL, &error);
if (app1 == NULL)
g_print ("Error: %s\n", error->message);
else
g_print ("Installed %s: %s\n", argv[2],
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,
@@ -97,7 +126,6 @@ main (int argc, char *argv[])
for (i = 0; remotes[i] != NULL; i++)
{
GError *error = NULL;
g_print ("\nRemote: %s %s %s %d %d\n",
xdg_app_remote_get_name (remotes[i]),
xdg_app_remote_get_url (remotes[i]),
+219
View File
@@ -20,6 +20,7 @@
#include "config.h"
#include "libgsystem.h"
#include "xdg-app-utils.h"
#include "xdg-app-installation.h"
#include "xdg-app-installed-ref-private.h"
@@ -345,3 +346,221 @@ xdg_app_installation_load_app_overrides (XdgAppInstallation *self,
return metadata_contents;
}
static void
progress_cb (OstreeAsyncProgress *progress, gpointer user_data)
{
XdgAppProgressCallback progress_cb = g_object_get_data (G_OBJECT (progress), "callback");
guint last_progress = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT (progress), "last_progress"));
GString *buf;
g_autofree char *status = NULL;
guint outstanding_fetches;
guint outstanding_metadata_fetches;
guint outstanding_writes;
guint n_scanned_metadata;
guint fetched_delta_parts;
guint total_delta_parts;
guint64 bytes_transferred;
guint64 total_delta_part_size;
guint fetched;
guint metadata_fetched;
guint requested;
guint64 ellapsed_time;
guint new_progress = 0;
gboolean estimating = FALSE;
buf = g_string_new ("");
status = ostree_async_progress_get_status (progress);
outstanding_fetches = ostree_async_progress_get_uint (progress, "outstanding-fetches");
outstanding_metadata_fetches = ostree_async_progress_get_uint (progress, "outstanding-metadata-fetches");
outstanding_writes = ostree_async_progress_get_uint (progress, "outstanding-writes");
n_scanned_metadata = ostree_async_progress_get_uint (progress, "scanned-metadata");
fetched_delta_parts = ostree_async_progress_get_uint (progress, "fetched-delta-parts");
total_delta_parts = ostree_async_progress_get_uint (progress, "total-delta-parts");
total_delta_part_size = ostree_async_progress_get_uint64 (progress, "total-delta-part-size");
bytes_transferred = ostree_async_progress_get_uint64 (progress, "bytes-transferred");
fetched = ostree_async_progress_get_uint (progress, "fetched");
metadata_fetched = ostree_async_progress_get_uint (progress, "metadata-fetched");
requested = ostree_async_progress_get_uint (progress, "requested");
ellapsed_time = (g_get_monotonic_time () - ostree_async_progress_get_uint64 (progress, "start-time")) / G_USEC_PER_SEC;
if (status)
{
g_string_append (buf, status);
}
else if (outstanding_fetches)
{
guint64 bytes_sec = bytes_transferred / ellapsed_time;
g_autofree char *formatted_bytes_transferred =
g_format_size_full (bytes_transferred, 0);
g_autofree char *formatted_bytes_sec = NULL;
if (!bytes_sec) // Ignore first second
formatted_bytes_sec = g_strdup ("-");
else
{
formatted_bytes_sec = g_format_size (bytes_sec);
}
if (total_delta_parts > 0)
{
g_autofree char *formatted_total =
g_format_size (total_delta_part_size);
g_string_append_printf (buf, "Receiving delta parts: %u/%u %s/s %s/%s",
fetched_delta_parts, total_delta_parts,
formatted_bytes_sec, formatted_bytes_transferred,
formatted_total);
new_progress = (100 * bytes_transferred) / total_delta_part_size;
}
else if (outstanding_metadata_fetches)
{
/* At this point we don't really know how much data there is, so we have to make a guess.
* Since its really hard to figure out early how much data there is we report 1% until
* all objects are scanned. */
new_progress = 1;
estimating = TRUE;
g_string_append_printf (buf, "Receiving metadata objects: %u/(estimating) %s/s %s",
metadata_fetched, formatted_bytes_sec, formatted_bytes_transferred);
}
else
{
new_progress = (100 * fetched) / requested;
g_string_append_printf (buf, "Receiving objects: %u%% (%u/%u) %s/s %s",
(guint)((((double)fetched) / requested) * 100),
fetched, requested, formatted_bytes_sec, formatted_bytes_transferred);
}
}
else if (outstanding_writes)
{
g_string_append_printf (buf, "Writing objects: %u", outstanding_writes);
}
else
{
g_string_append_printf (buf, "Scanning metadata: %u", n_scanned_metadata);
}
if (new_progress < last_progress)
new_progress = last_progress;
g_object_set_data (G_OBJECT (progress), "last_progress", GUINT_TO_POINTER(new_progress));
progress_cb (buf->str, new_progress, estimating, user_data);
g_string_free (buf, TRUE);
}
/**
* 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_install (XdgAppInstallation *self,
const char *remote_name,
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;
gboolean created_deploy_base = FALSE;
g_autoptr(GFile) deploy_base = NULL;
g_autoptr(XdgAppDir) dir_clone = NULL;
g_autoptr(GMainContext) main_context = NULL;
g_autoptr(OstreeAsyncProgress) ostree_progress = NULL;
XdgAppInstalledRef *result = 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);
deploy_base = xdg_app_dir_get_deploy_dir (priv->dir, ref);
if (g_file_query_exists (deploy_base, cancellable))
{
xdg_app_fail (error, "%s branch %s already installed", name, version);
goto out;
}
/* 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;
if (!g_file_make_directory_with_parents (deploy_base, cancellable, error))
goto out;
created_deploy_base = TRUE;
if (!xdg_app_dir_set_origin (priv->dir, ref, remote_name, cancellable, error))
goto out;
if (!xdg_app_dir_deploy (priv->dir, 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))
goto out;
if (!xdg_app_dir_update_exports (priv->dir, name, cancellable, error))
goto out;
}
xdg_app_dir_cleanup_removed (priv->dir, cancellable, NULL);
result = get_ref (self, ref, cancellable);
out:
if (main_context)
g_main_context_pop_thread_default (main_context);
if (created_deploy_base && result == NULL)
gs_shutil_rm_rf (deploy_base, cancellable, NULL);
return result;
}
+15
View File
@@ -55,6 +55,11 @@ XDG_APP_EXTERN XdgAppInstallation *xdg_app_installation_new_user (void);
XDG_APP_EXTERN XdgAppInstallation *xdg_app_installation_new_for_path (GFile *path,
gboolean user);
typedef void (*XdgAppProgressCallback)(const char *status,
guint progress,
gboolean estimating,
gpointer user_data);
XDG_APP_EXTERN gboolean xdg_app_installation_get_is_user (XdgAppInstallation *self);
XDG_APP_EXTERN XdgAppInstalledRef **xdg_app_installation_list_installed_refs (XdgAppInstallation *self,
XdgAppRefKind kind,
@@ -78,5 +83,15 @@ XDG_APP_EXTERN char * xdg_app_installation_load_app_overrides
const char *app_id,
GCancellable *cancellable,
GError **error);
XDG_APP_EXTERN XdgAppInstalledRef * xdg_app_installation_install (XdgAppInstallation *self,
const char *remote_name,
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__ */