repo-file: Base OstreeRepoFile on trees instead of commits

We want an OstreeRepoFile to be the way to represent a filesystem tree
inside an ostree repository. In order to do this, we need to drop the
commit from an OstreeRepoFile, and make that go to callers.

Switch all current users of ostree_repo_file_new_root to
ostree_repo_read_commit, and make the actual constructor private.

https://bugzilla.gnome.org/show_bug.cgi?id=707727
This commit is contained in:
Jasper St. Pierre 2013-09-06 23:27:45 -04:00
parent ac2d61dd51
commit 33db74d0ce
7 changed files with 111 additions and 119 deletions

@ -1 +1 @@
Subproject commit 7b9901e3fc8aa58cf9c0579c29340506269ebfbd
Subproject commit bd2c1e436b270b39ca262765e775b4556d6bd50b

View File

@ -33,10 +33,6 @@ struct OstreeRepoFile
GObject parent_instance;
OstreeRepo *repo;
char *commit;
GError *commit_resolve_error;
OstreeRepoFile *parent;
int index;
char *name;
@ -65,8 +61,6 @@ ostree_repo_file_finalize (GObject *object)
g_free (self->cached_file_checksum);
g_free (self->tree_contents_checksum);
g_free (self->tree_metadata_checksum);
g_free (self->commit);
g_clear_error (&self->commit_resolve_error);
g_free (self->name);
G_OBJECT_CLASS (ostree_repo_file_parent_class)->finalize (object);
@ -110,40 +104,30 @@ set_error_noent (GFile *self, GError **error)
return FALSE;
}
/**
* ostree_repo_file_new_root:
* @repo: Containing repo
* @commit: SHA256 checksum
*
* Returns: (transfer full): A new #OstreeRepoFile corresponding to commit contents
*/
GFile *
ostree_repo_file_new_root (OstreeRepo *repo,
const char *commit)
static OstreeRepoFile *
ostree_repo_file_new_root (OstreeRepo *repo,
const char *contents_checksum,
const char *metadata_checksum)
{
OstreeRepoFile *self;
g_return_val_if_fail (repo != NULL, NULL);
g_return_val_if_fail (commit != NULL, NULL);
g_return_val_if_fail (strlen (commit) == 64, NULL);
g_return_val_if_fail (contents_checksum != NULL, NULL);
g_return_val_if_fail (strlen (contents_checksum) == 64, NULL);
g_return_val_if_fail (metadata_checksum != NULL, NULL);
g_return_val_if_fail (strlen (metadata_checksum) == 64, NULL);
self = g_object_new (OSTREE_TYPE_REPO_FILE, NULL);
self->repo = g_object_ref (repo);
self->commit = g_strdup (commit);
self->tree_contents_checksum = g_strdup (contents_checksum);
self->tree_metadata_checksum = g_strdup (metadata_checksum);
return G_FILE (self);
return self;
}
/**
* ostree_repo_file_new_child:
* @parent:
* @name: Name for new child
*
* Returns: (transfer full): A new child file with the given name
*/
GFile *
static OstreeRepoFile *
ostree_repo_file_new_child (OstreeRepoFile *parent,
const char *name)
const char *name)
{
OstreeRepoFile *self;
size_t len;
@ -156,51 +140,66 @@ ostree_repo_file_new_child (OstreeRepoFile *parent,
if (self->name[len-1] == '/')
self->name[len-1] = '\0';
return G_FILE (self);
return self;
}
static gboolean
do_resolve_commit (OstreeRepoFile *self,
GError **error)
OstreeRepoFile *
_ostree_repo_file_new_for_commit (OstreeRepo *repo,
const char *commit,
GError **error)
{
gboolean ret = FALSE;
gs_unref_variant GVariant *commit = NULL;
gs_unref_variant GVariant *root_contents = NULL;
gs_unref_variant GVariant *root_metadata = NULL;
OstreeRepoFile *ret = NULL;
gs_unref_variant GVariant *commit_v = NULL;
gs_unref_variant GVariant *tree_contents_csum_v = NULL;
gs_unref_variant GVariant *tree_metadata_csum_v = NULL;
char tmp_checksum[65];
char tree_contents_csum[65];
char tree_metadata_csum[65];
g_assert (self->parent == NULL);
g_return_val_if_fail (repo != NULL, NULL);
g_return_val_if_fail (commit != NULL, NULL);
g_return_val_if_fail (strlen (commit) == 64, NULL);
if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_COMMIT,
self->commit, &commit, error))
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
commit, &commit_v, error))
goto out;
/* PARSE OSTREE_OBJECT_TYPE_COMMIT */
g_variant_get_child (commit, 6, "@ay", &tree_contents_csum_v);
g_variant_get_child (commit_v, 6, "@ay", &tree_contents_csum_v);
ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_contents_csum_v),
tree_contents_csum);
ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_contents_csum_v), tmp_checksum);
g_variant_get_child (commit_v, 7, "@ay", &tree_metadata_csum_v);
ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_metadata_csum_v),
tree_metadata_csum);
ret = ostree_repo_file_new_root (repo, tree_contents_csum, tree_metadata_csum);
out:
return ret;
}
static gboolean
do_resolve (OstreeRepoFile *self,
GError **error)
{
gboolean ret = FALSE;
gs_unref_variant GVariant *root_contents = NULL;
gs_unref_variant GVariant *root_metadata = NULL;
g_assert (self->parent == NULL);
if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE,
tmp_checksum,
&root_contents, error))
self->tree_contents_checksum, &root_contents, error))
goto out;
g_variant_get_child (commit, 7, "@ay", &tree_metadata_csum_v);
ostree_checksum_inplace_from_bytes (g_variant_get_data (tree_metadata_csum_v), tmp_checksum);
if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META,
tmp_checksum,
&root_metadata, error))
self->tree_metadata_checksum, &root_metadata, error))
goto out;
self->tree_metadata = root_metadata;
root_metadata = NULL;
self->tree_contents = root_contents;
root_contents = NULL;
self->tree_contents_checksum = ostree_checksum_from_bytes_v (tree_contents_csum_v);
self->tree_metadata_checksum = ostree_checksum_from_bytes_v (tree_metadata_csum_v);
ret = TRUE;
out:
@ -217,12 +216,15 @@ do_resolve_nonroot (OstreeRepoFile *self,
gs_unref_variant GVariant *container = NULL;
gs_unref_variant GVariant *tree_contents = NULL;
gs_unref_variant GVariant *tree_metadata = NULL;
gs_unref_variant GVariant *content_csum_v = NULL;
gs_unref_variant GVariant *contents_csum_v = NULL;
gs_unref_variant GVariant *metadata_csum_v = NULL;
gs_free char *tmp_checksum = NULL;
if (!ostree_repo_file_ensure_resolved (self->parent, error))
goto out;
i = ostree_repo_file_tree_find_child (self->parent, self->name, &is_dir, &container);
if (i < 0)
{
set_error_noent ((GFile*)self, error);
@ -239,15 +241,15 @@ do_resolve_nonroot (OstreeRepoFile *self,
g_clear_pointer (&files_variant, (GDestroyNotify) g_variant_unref);
g_variant_get_child (container, i, "(&s@ay@ay)",
&name, &content_csum_v, &metadata_csum_v);
&name, &contents_csum_v, &metadata_csum_v);
g_free (tmp_checksum);
tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v);
tmp_checksum = ostree_checksum_from_bytes_v (contents_csum_v);
if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE,
tmp_checksum, &tree_contents,
error))
goto out;
g_free (tmp_checksum);
tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v);
if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META,
@ -259,7 +261,7 @@ do_resolve_nonroot (OstreeRepoFile *self,
tree_contents = NULL;
self->tree_metadata = tree_metadata;
tree_metadata = NULL;
self->tree_contents_checksum = ostree_checksum_from_bytes_v (content_csum_v);
self->tree_contents_checksum = ostree_checksum_from_bytes_v (contents_csum_v);
self->tree_metadata_checksum = ostree_checksum_from_bytes_v (metadata_csum_v);
}
else
@ -274,36 +276,26 @@ gboolean
ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
GError **error)
{
if (self->commit_resolve_error != NULL)
goto out;
gboolean ret = FALSE;
if (self->parent == NULL)
{
if (self->tree_contents == NULL)
(void)do_resolve_commit (self, &(self->commit_resolve_error));
}
else if (self->index == -1)
{
if (!ostree_repo_file_ensure_resolved (self->parent, error))
goto out;
(void)do_resolve_nonroot (self, &(self->commit_resolve_error));
}
out:
if (self->commit_resolve_error)
{
if (error)
*error = g_error_copy (self->commit_resolve_error);
return FALSE;
if (!do_resolve (self, error))
goto out;
}
else
return TRUE;
}
{
if (self->index == -1)
{
if (!do_resolve_nonroot (self, error))
goto out;
}
}
const char *
ostree_repo_file_get_commit (OstreeRepoFile *self)
{
return ostree_repo_file_get_root (self)->commit;
ret = TRUE;
out:
return ret;
}
gboolean
@ -507,7 +499,10 @@ ostree_repo_file_get_uri (GFile *file)
path = gs_file_get_path_cached (file);
uri_path = g_filename_to_uri (path, NULL, NULL);
g_assert (g_str_has_prefix (uri_path, "file://"));
ret = g_strconcat ("ostree://", self->commit, uri_path+strlen("file://"), NULL);
ret = g_strconcat ("ostree://",
self->tree_contents_checksum, "/", self->tree_metadata_checksum,
uri_path+strlen("file://"),
NULL);
g_free (uri_path);
return ret;
@ -533,9 +528,9 @@ ostree_repo_file_dup (GFile *file)
OstreeRepoFile *self = OSTREE_REPO_FILE (file);
if (self->parent)
return ostree_repo_file_new_child (self->parent, self->name);
return G_FILE (ostree_repo_file_new_child (self->parent, self->name));
else
return ostree_repo_file_new_root (self->repo, self->commit);
return G_FILE (ostree_repo_file_new_root (self->repo, self->tree_contents_checksum, self->tree_metadata_checksum));
}
static guint
@ -546,7 +541,7 @@ ostree_repo_file_hash (GFile *file)
if (self->parent)
return g_file_hash (self->parent) + g_str_hash (self->name);
else
return g_str_hash (self->commit);
return g_str_hash (self->tree_contents_checksum) + g_str_hash (self->tree_metadata_checksum);
}
static gboolean
@ -558,12 +553,13 @@ ostree_repo_file_equal (GFile *file1,
if (self1->parent && self2->parent)
{
return g_str_equal (self1->name, self2->name)
&& g_file_equal ((GFile*)self1->parent, (GFile*)self2->parent);
return (g_str_equal (self1->name, self2->name) &&
g_file_equal ((GFile*)self1->parent, (GFile*)self2->parent));
}
else if (!self1->parent && !self2->parent)
{
return g_str_equal (self1->commit, self2->commit);
return (g_str_equal (self1->tree_contents_checksum, self2->tree_contents_checksum) &&
g_str_equal (self1->tree_metadata_checksum, self2->tree_metadata_checksum));
}
else
return FALSE;
@ -654,7 +650,7 @@ ostree_repo_file_resolve_relative_path (GFile *file,
else
filename = g_strdup (relative_path);
parent = (OstreeRepoFile*)ostree_repo_file_new_child (self, filename);
parent = ostree_repo_file_new_child (self, filename);
g_free (filename);
if (!rest)

View File

@ -42,12 +42,6 @@ struct _OstreeRepoFileClass
GType ostree_repo_file_get_type (void) G_GNUC_CONST;
GFile * ostree_repo_file_new_root (OstreeRepo *repo,
const char *commit);
GFile * ostree_repo_file_new_child (OstreeRepoFile *parent,
const char *name);
gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
GError **error);
@ -68,12 +62,11 @@ void ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
const char *ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self);
const char *ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self);
gboolean ostree_repo_file_is_tree (OstreeRepoFile *self);
GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
const char * ostree_repo_file_get_checksum (OstreeRepoFile *self);
const char * ostree_repo_file_get_commit (OstreeRepoFile *self);
int ostree_repo_file_tree_find_child (OstreeRepoFile *self,
const char *name,
gboolean *is_dir,
@ -87,8 +80,5 @@ gboolean ostree_repo_file_tree_query_child (OstreeRepoFile *self,
GCancellable *cancellable,
GError **error);
GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
G_END_DECLS

View File

@ -111,5 +111,10 @@ _ostree_repo_update_refs (OstreeRepo *self,
GCancellable *cancellable,
GError **error);
OstreeRepoFile *
_ostree_repo_file_new_for_commit (OstreeRepo *repo,
const char *commit,
GError **error);
G_END_DECLS

View File

@ -1413,18 +1413,21 @@ ostree_repo_read_commit (OstreeRepo *self,
GError **error)
{
gboolean ret = FALSE;
gs_unref_object GFile *ret_root = NULL;
gs_unref_object OstreeRepoFile *ret_root = NULL;
gs_free char *resolved_rev = NULL;
if (!ostree_repo_resolve_rev (self, rev, FALSE, &resolved_rev, error))
goto out;
ret_root = ostree_repo_file_new_root (self, resolved_rev);
if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)ret_root, error))
ret_root = _ostree_repo_file_new_for_commit (self, resolved_rev, error);
if (!ret_root)
goto out;
if (!ostree_repo_file_ensure_resolved (ret_root, error))
goto out;
ret = TRUE;
ot_transfer_out_value(out_root, &ret_root);
ot_transfer_out_value(out_root, (GFile **) &ret_root);
out:
return ret;
}

View File

@ -209,18 +209,17 @@ checkout_deployment_tree (GFile *sysroot,
{
gboolean ret = FALSE;
const char *csum = ot_deployment_get_csum (deployment);
gs_unref_object OstreeRepoFile *root = NULL;
gs_unref_object GFile *root = NULL;
gs_unref_object GFileInfo *file_info = NULL;
gs_free char *checkout_target_name = NULL;
gs_unref_object GFile *osdeploy_path = NULL;
gs_unref_object GFile *deploy_target_path = NULL;
gs_unref_object GFile *deploy_parent = NULL;
root = (OstreeRepoFile*)ostree_repo_file_new_root (repo, csum);
if (!ostree_repo_file_ensure_resolved (root, error))
if (!ostree_repo_read_commit (repo, csum, &root, cancellable, error))
goto out;
file_info = g_file_query_info ((GFile*)root, OSTREE_GIO_FAST_QUERYINFO,
file_info = g_file_query_info (root, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, error);
if (!file_info)
@ -239,7 +238,7 @@ checkout_deployment_tree (GFile *sysroot,
g_print ("ostadmin: Creating deployment %s\n",
gs_file_get_path_cached (deploy_target_path));
if (!ostree_repo_checkout_tree (repo, 0, 0, deploy_target_path, root,
if (!ostree_repo_checkout_tree (repo, 0, 0, deploy_target_path, OSTREE_REPO_FILE (root),
file_info, cancellable, error))
goto out;

View File

@ -56,20 +56,19 @@ process_one_checkout (OstreeRepo *repo,
{
gboolean ret = FALSE;
GError *tmp_error = NULL;
gs_unref_object OstreeRepoFile *root = NULL;
gs_unref_object OstreeRepoFile *subtree = NULL;
gs_unref_object GFile *root = NULL;
gs_unref_object GFile *subtree = NULL;
gs_unref_object GFileInfo *file_info = NULL;
root = (OstreeRepoFile*)ostree_repo_file_new_root (repo, resolved_commit);
if (!ostree_repo_file_ensure_resolved (root, error))
if (!ostree_repo_read_commit (repo, resolved_commit, &root, cancellable, error))
goto out;
if (subpath)
subtree = (OstreeRepoFile*)g_file_resolve_relative_path ((GFile*)root, subpath);
subtree = g_file_resolve_relative_path (root, subpath);
else
subtree = g_object_ref (root);
file_info = g_file_query_info ((GFile*)subtree, OSTREE_GIO_FAST_QUERYINFO,
file_info = g_file_query_info (subtree, OSTREE_GIO_FAST_QUERYINFO,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, &tmp_error);
if (!file_info)
@ -89,7 +88,7 @@ process_one_checkout (OstreeRepo *repo,
if (!ostree_repo_checkout_tree (repo, opt_user_mode ? OSTREE_REPO_CHECKOUT_MODE_USER : 0,
opt_union ? OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES : 0,
target, subtree, file_info, cancellable, error))
target, OSTREE_REPO_FILE (subtree), file_info, cancellable, error))
goto out;
ret = TRUE;