summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2016-04-27 12:41:41 +0200
committerAlexander Larsson <alexl@redhat.com>2016-04-27 12:41:41 +0200
commit64669a9a961c7422e751e6cb662c113cfdd58cfe (patch)
tree9b75ec3675f54f9d17997df20a6176cf303bd988
parentb8b3d319d4daa230a00e76e3ae46fd4d5a79b843 (diff)
downloadxdg-app-64669a9a961c7422e751e6cb662c113cfdd58cfe.tar.gz
common: Write and use the new deploydata file
Instead of separate "origin", "subpaths" and eventually "installed-size" files we store a single (extensible) gvariant with all this info, which means we need to seek less to get it. Also, we move this file into the deploy dir as some of the data differs for each deploy, and that way we can rely on the the active symlink to make the update atomic.
-rw-r--r--common/xdg-app-dir.c203
-rw-r--r--common/xdg-app-dir.h16
-rw-r--r--system-helper/xdg-app-system-helper.c2
3 files changed, 75 insertions, 146 deletions
diff --git a/common/xdg-app-dir.c b/common/xdg-app-dir.c
index 2b605a4..4b46c4f 100644
--- a/common/xdg-app-dir.c
+++ b/common/xdg-app-dir.c
@@ -600,6 +600,13 @@ xdg_app_dir_new_deploy_data (const char *origin,
GVariant *metadata)
{
char *empty_subpaths[] = {NULL};
+ GVariantBuilder builder;
+
+ if (metadata == NULL)
+ {
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ metadata = g_variant_builder_end (&builder);
+ }
return g_variant_ref_sink (g_variant_new ("(ss^ast@a{sv})",
origin,
@@ -660,7 +667,6 @@ xdg_app_create_deploy_data_from_old (XdgAppDir *self,
g_autoptr(GFile) root = NULL;
g_autoptr(GFile) origin = NULL;
guint64 installed_size;
- GVariantBuilder builder;
deploy_base = g_file_get_parent (deploy_dir);
commit = g_file_get_basename (deploy_dir);
@@ -676,9 +682,8 @@ xdg_app_create_deploy_data_from_old (XdgAppDir *self,
/* For backwards compat we return a 0 installed size, its to slow to regenerate */
installed_size = 0;
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
return xdg_app_dir_new_deploy_data (old_origin, commit, old_subpaths,
- installed_size, g_variant_builder_end (&builder));
+ installed_size, NULL);
}
GVariant *
@@ -701,7 +706,7 @@ xdg_app_dir_get_deploy_data (XdgAppDir *self,
return NULL;
}
- data_file = g_file_get_child (deploy_dir, "deploy_data");
+ data_file = g_file_get_child (deploy_dir, "deploy");
if (!g_file_load_contents (data_file, cancellable, &data, &data_size, NULL, &my_error))
{
if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
@@ -726,47 +731,17 @@ xdg_app_dir_get_origin (XdgAppDir *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GFile) deploy_base = NULL;
- g_autoptr(GFile) origin = NULL;
- char *repository = NULL;
+ g_autoptr(GVariant) deploy_data = NULL;
- deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
- if (!g_file_query_exists (deploy_base, cancellable))
+ deploy_data = xdg_app_dir_get_deploy_data (self, ref,
+ cancellable, error);
+ if (deploy_data == NULL)
{
xdg_app_fail (error, "%s is not installed", ref);
return NULL;
}
- origin = g_file_get_child (deploy_base, "origin");
- if (!g_file_load_contents (origin, cancellable, &repository, NULL, NULL, error))
- return NULL;
-
- return repository;
-}
-
-gboolean
-xdg_app_dir_set_origin (XdgAppDir *self,
- const char *ref,
- const char *remote,
- GCancellable *cancellable,
- GError **error)
-{
- g_autoptr(GFile) deploy_base = NULL;
- g_autoptr(GFile) origin = NULL;
-
- deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
- if (!g_file_query_exists (deploy_base, cancellable))
- {
- xdg_app_fail (error, "%s is not installed", ref);
- return FALSE;
- }
-
- origin = g_file_get_child (deploy_base, "origin");
- if (!g_file_replace_contents (origin, remote, strlen (remote), NULL, FALSE,
- G_FILE_CREATE_NONE, NULL, cancellable, error))
- return FALSE;
-
- return TRUE;
+ return g_strdup (xdg_app_deploy_data_get_origin (deploy_data));
}
char **
@@ -775,79 +750,23 @@ xdg_app_dir_get_subpaths (XdgAppDir *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GFile) deploy_base = NULL;
- g_autoptr(GFile) file = NULL;
- g_autofree char *data = NULL;
- g_autoptr(GError) my_error = NULL;
- g_autoptr(GPtrArray) subpaths = NULL;
- g_auto(GStrv) lines = NULL;
+ g_autoptr(GVariant) deploy_data = NULL;
+ char **subpaths;
int i;
- deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
- if (!g_file_query_exists (deploy_base, cancellable))
+ deploy_data = xdg_app_dir_get_deploy_data (self, ref,
+ cancellable, error);
+ if (deploy_data == NULL)
{
xdg_app_fail (error, "%s is not installed", ref);
return NULL;
}
- file = g_file_get_child (deploy_base, "subpaths");
- if (!g_file_load_contents (file, cancellable, &data, NULL, NULL, &my_error))
- {
- if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- data = g_strdup ("");
- else
- {
- g_propagate_error (error, g_steal_pointer (&my_error));
- return NULL;
- }
- }
-
- lines = g_strsplit (data, "\n", 0);
+ subpaths = (char **)xdg_app_deploy_data_get_subpaths (deploy_data);
+ for (i = 0; subpaths[i] != NULL; i++)
+ subpaths[i] = g_strdup (subpaths[i]);
- subpaths = g_ptr_array_new ();
- for (i = 0; lines[i] != NULL; i++)
- {
- lines[i] = g_strstrip (lines[i]);
- if (lines[i][0] == '/')
- g_ptr_array_add (subpaths, g_strdup (lines[i]));
- }
-
- g_ptr_array_add (subpaths, NULL);
- return (char **)g_ptr_array_free (subpaths, FALSE);
-}
-
-gboolean
-xdg_app_dir_set_subpaths (XdgAppDir *self,
- const char *ref,
- const char **subpaths,
- GCancellable *cancellable,
- GError **error)
-{
- g_autoptr(GFile) deploy_base = NULL;
- g_autoptr(GFile) file = NULL;
- g_autofree char *data = NULL;
-
- deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
- if (!g_file_query_exists (deploy_base, cancellable))
- {
- xdg_app_fail (error, "%s is not installed", ref);
- return FALSE;
- }
-
- file = g_file_get_child (deploy_base, "subpaths");
-
- if (subpaths == NULL || subpaths[0] == NULL)
- {
- g_file_delete (file, cancellable, NULL);
- return TRUE;
- }
-
- data = g_strjoinv ("\n", (char **)subpaths);
- if (!g_file_replace_contents (file, data, strlen (data), NULL, FALSE,
- G_FILE_CREATE_NONE, NULL, cancellable, error))
- return FALSE;
-
- return TRUE;
+ return subpaths;
}
gboolean
@@ -2421,8 +2340,11 @@ xdg_app_dir_update_exports (XdgAppDir *self,
gboolean
xdg_app_dir_deploy (XdgAppDir *self,
+ const char *origin,
const char *ref,
- const char *checksum,
+ const char *checksum_or_latest,
+ const char * const * subpaths,
+ GVariant *old_deploy_data,
GCancellable *cancellable,
GError **error)
{
@@ -2434,19 +2356,20 @@ xdg_app_dir_deploy (XdgAppDir *self,
g_autoptr(GFile) dotref = NULL;
g_autoptr(GFile) files_etc = NULL;
g_autoptr(GFile) metadata = NULL;
+ g_autoptr(GFile) deploy_data_file = NULL;
+ g_autoptr(GVariant) deploy_data = NULL;
g_autoptr(GFile) export = NULL;
g_autoptr(GKeyFile) keyfile = NULL;
- g_auto(GStrv) subpaths = NULL;
+ guint64 installed_size = 0;
+ const char *checksum;
if (!xdg_app_dir_ensure_repo (self, cancellable, error))
return FALSE;
deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
- if (checksum == NULL)
+ if (checksum_or_latest == NULL)
{
- g_autofree char *origin = xdg_app_dir_get_origin (self, ref, NULL, NULL);
-
g_debug ("No checksum specified, getting tip of %s", ref);
resolved_ref = xdg_app_dir_read_latest (self, origin, ref, cancellable, error);
@@ -2464,6 +2387,7 @@ xdg_app_dir_deploy (XdgAppDir *self,
g_autoptr(GFile) root = NULL;
g_autofree char *commit = NULL;
+ checksum = checksum_or_latest;
g_debug ("Looking for checksum %s in local repo", checksum);
if (!ostree_repo_read_commit (self->repo, checksum, &root, &commit, cancellable, NULL))
return xdg_app_fail (error, "%s is not available", ref);
@@ -2484,17 +2408,16 @@ xdg_app_dir_deploy (XdgAppDir *self,
return FALSE;
}
+ if (!xdg_app_repo_collect_sizes (self->repo, root, &installed_size, NULL, cancellable, error))
+ return FALSE;
+
file_info = g_file_query_info (root, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, error);
if (file_info == NULL)
return FALSE;
- subpaths = xdg_app_dir_get_subpaths (self, ref, cancellable, error);
- if (subpaths == NULL)
- return FALSE;
-
- if (*subpaths == NULL)
+ if (subpaths == NULL || *subpaths == NULL)
{
if (!ostree_repo_checkout_tree (self->repo,
OSTREE_REPO_CHECKOUT_MODE_USER,
@@ -2629,6 +2552,16 @@ xdg_app_dir_deploy (XdgAppDir *self,
return FALSE;
}
+ deploy_data = xdg_app_dir_new_deploy_data (origin,
+ checksum,
+ (char **)subpaths,
+ installed_size,
+ NULL);
+
+ deploy_data_file = g_file_get_child (checkoutdir, "deploy");
+ if (!xdg_app_variant_save (deploy_data_file, deploy_data, cancellable, error))
+ return FALSE;
+
if (!xdg_app_dir_set_active (self, ref, checksum, cancellable, error))
return FALSE;
@@ -2671,14 +2604,7 @@ xdg_app_dir_deploy_install (XdgAppDir *self,
/* After we create the deploy base we must goto out on errors */
created_deploy_base = TRUE;
- if (!xdg_app_dir_set_origin (self, ref, origin, cancellable, error))
- goto out;
-
- if (!xdg_app_dir_set_subpaths (self, ref, (const char **)subpaths,
- cancellable, error))
- goto out;
-
- if (!xdg_app_dir_deploy (self, ref, NULL, cancellable, error))
+ if (!xdg_app_dir_deploy (self, origin, ref, NULL, (const char * const *)subpaths, NULL, cancellable, error))
goto out;
if (g_str_has_prefix (ref, "app/"))
@@ -2712,22 +2638,36 @@ xdg_app_dir_deploy_install (XdgAppDir *self,
gboolean
xdg_app_dir_deploy_update (XdgAppDir *self,
const char *ref,
- const char *remote_name,
const char *checksum_or_latest,
GCancellable *cancellable,
GError **error)
{
g_autofree char *previous_deployment = NULL;
g_autoptr(GError) my_error = NULL;
+ g_autoptr(GVariant) old_deploy_data = NULL;
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
+ g_autofree const char **old_subpaths = NULL;
+ const char *old_active;
+ const char *old_origin;
if (!xdg_app_dir_lock (self, &lock,
cancellable, error))
return FALSE;
- previous_deployment = xdg_app_dir_read_active (self, ref, cancellable);
+ old_deploy_data = xdg_app_dir_get_deploy_data (self, ref,
+ cancellable, error);
+ if (old_deploy_data == NULL)
+ return FALSE;
- if (!xdg_app_dir_deploy (self, ref, checksum_or_latest,
+ old_origin = xdg_app_deploy_data_get_origin (old_deploy_data);
+ old_active = xdg_app_deploy_data_get_commit (old_deploy_data);
+ old_subpaths = xdg_app_deploy_data_get_subpaths (old_deploy_data);
+ if (!xdg_app_dir_deploy (self,
+ old_origin,
+ ref,
+ checksum_or_latest,
+ old_subpaths,
+ old_deploy_data,
cancellable, &my_error))
{
if (g_error_matches (my_error, XDG_APP_DIR_ERROR,
@@ -2738,13 +2678,10 @@ xdg_app_dir_deploy_update (XdgAppDir *self,
return FALSE;
}
- if (previous_deployment != NULL)
- {
- if (!xdg_app_dir_undeploy (self, ref, previous_deployment,
- FALSE,
- cancellable, error))
- return FALSE;
- }
+ if (!xdg_app_dir_undeploy (self, ref, old_active,
+ FALSE,
+ cancellable, error))
+ return FALSE;
if (g_str_has_prefix (ref, "app/"))
{
@@ -2984,7 +2921,7 @@ xdg_app_dir_update (XdgAppDir *self,
if (!no_deploy)
{
- if (!xdg_app_dir_deploy_update (self, ref, remote_name, checksum_or_latest,
+ if (!xdg_app_dir_deploy_update (self, ref, checksum_or_latest,
cancellable, error))
return FALSE;
}
diff --git a/common/xdg-app-dir.h b/common/xdg-app-dir.h
index 51a561a..ad80bd1 100644
--- a/common/xdg-app-dir.h
+++ b/common/xdg-app-dir.h
@@ -112,20 +112,10 @@ char * xdg_app_dir_get_origin (XdgAppDir *self,
const char *ref,
GCancellable *cancellable,
GError **error);
-gboolean xdg_app_dir_set_origin (XdgAppDir *self,
- const char *ref,
- const char *remote,
- GCancellable *cancellable,
- GError **error);
char ** xdg_app_dir_get_subpaths (XdgAppDir *self,
const char *ref,
GCancellable *cancellable,
GError **error);
-gboolean xdg_app_dir_set_subpaths (XdgAppDir *self,
- const char *ref,
- const char **subpaths,
- GCancellable *cancellable,
- GError **error);
GFile * xdg_app_dir_get_exports_dir (XdgAppDir *self);
GFile * xdg_app_dir_get_removed_dir (XdgAppDir *self);
GFile * xdg_app_dir_get_if_deployed (XdgAppDir *self,
@@ -244,13 +234,15 @@ gboolean xdg_app_dir_lock (XdgAppDir *self,
GCancellable *cancellable,
GError **error);
gboolean xdg_app_dir_deploy (XdgAppDir *self,
+ const char *origin,
const char *ref,
- const char *checksum,
+ const char *checksum_or_latest,
+ const char * const * subpaths,
+ GVariant *old_deploy_data,
GCancellable *cancellable,
GError **error);
gboolean xdg_app_dir_deploy_update (XdgAppDir *self,
const char *ref,
- const char *origin,
const char *checksum,
GCancellable *cancellable,
GError **error);
diff --git a/system-helper/xdg-app-system-helper.c b/system-helper/xdg-app-system-helper.c
index da33f6c..6c03a66 100644
--- a/system-helper/xdg-app-system-helper.c
+++ b/system-helper/xdg-app-system-helper.c
@@ -130,7 +130,7 @@ handle_deploy (XdgAppSystemHelper *object,
if (is_update)
{
/* TODO: This doesn't support a custom subpath */
- if (!xdg_app_dir_deploy_update (system, arg_ref, arg_origin,
+ if (!xdg_app_dir_deploy_update (system, arg_ref,
NULL,
NULL, &error))
{