mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-08 08:58:46 +03:00
core: Add internal GFile implementation for reading commits
The data structures we use for reading already-written commits versus building them don't need to be the same. It's cleaner if we can have generic code which operates on a GFile implementation for reads, because then we can share more generic code for walking and operating on filesystem trees via GIO.
This commit is contained in:
parent
3cd55cb9ab
commit
8b43c539cf
@ -25,6 +25,10 @@ libostree_la_SOURCES = libostree/ostree.h \
|
||||
libostree/ostree-core.h \
|
||||
libostree/ostree-repo.c \
|
||||
libostree/ostree-repo.h \
|
||||
libostree/ostree-repo-file.c \
|
||||
libostree/ostree-repo-file.h \
|
||||
libostree/ostree-repo-file-enumerator.c \
|
||||
libostree/ostree-repo-file-enumerator.h \
|
||||
libostree/ostree-checkout.c \
|
||||
libostree/ostree-checkout.h \
|
||||
$(NULL)
|
||||
|
@ -296,7 +296,7 @@ ostree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_set_xattrs (const char *path, GVariant *xattrs, GError **error)
|
||||
ostree_set_xattrs (const char *path, GVariant *xattrs, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int i, n;
|
||||
@ -790,7 +790,7 @@ unpack_file (const char *path,
|
||||
}
|
||||
}
|
||||
|
||||
if (!ostree_set_xattrs (dest_path, xattrs, error))
|
||||
if (!ostree_set_xattrs (dest_path, xattrs, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (ret_checksum)
|
||||
|
@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_MAX_METADATA_SIZE (1 << 26)
|
||||
|
||||
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,unix::*"
|
||||
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,standard::is-hidden,unix::*"
|
||||
|
||||
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||
|
||||
@ -98,7 +98,8 @@ char *ostree_get_relative_object_path (const char *checksum,
|
||||
GVariant *ostree_get_xattrs_for_path (const char *path,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_set_xattrs (const char *path, GVariant *xattrs, GError **error);
|
||||
gboolean ostree_set_xattrs (const char *path, GVariant *xattrs,
|
||||
GCancellable *cancellable, GError **error);
|
||||
|
||||
gboolean ostree_parse_metadata_file (const char *path,
|
||||
OstreeSerializedVariantType *out_type,
|
||||
|
142
libostree/ostree-repo-file-enumerator.c
Normal file
142
libostree/ostree-repo-file-enumerator.c
Normal file
@ -0,0 +1,142 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ostree-repo-file-enumerator.h"
|
||||
#include <string.h>
|
||||
|
||||
struct _OstreeRepoFileEnumerator
|
||||
{
|
||||
GFileEnumerator parent;
|
||||
|
||||
OstreeRepoFile *dir;
|
||||
char *attributes;
|
||||
GFileQueryInfoFlags flags;
|
||||
|
||||
int index;
|
||||
};
|
||||
|
||||
#define ostree_repo_file_enumerator_get_type _ostree_repo_file_enumerator_get_type
|
||||
G_DEFINE_TYPE (OstreeRepoFileEnumerator, ostree_repo_file_enumerator, G_TYPE_FILE_ENUMERATOR);
|
||||
|
||||
static GFileInfo *ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
static gboolean ostree_repo_file_enumerator_close (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_dispose (GObject *object)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = OSTREE_REPO_FILE_ENUMERATOR (object);
|
||||
|
||||
g_clear_object (&self->dir);
|
||||
g_free (self->attributes);
|
||||
|
||||
if (G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose)
|
||||
G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_finalize (GObject *object)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = OSTREE_REPO_FILE_ENUMERATOR (object);
|
||||
(void)self;
|
||||
|
||||
G_OBJECT_CLASS (ostree_repo_file_enumerator_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_class_init (OstreeRepoFileEnumeratorClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = ostree_repo_file_enumerator_finalize;
|
||||
gobject_class->dispose = ostree_repo_file_enumerator_dispose;
|
||||
|
||||
enumerator_class->next_file = ostree_repo_file_enumerator_next_file;
|
||||
enumerator_class->close_fn = ostree_repo_file_enumerator_close;
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_repo_file_enumerator_init (OstreeRepoFileEnumerator *self)
|
||||
{
|
||||
}
|
||||
|
||||
GFileEnumerator *
|
||||
_ostree_repo_file_enumerator_new (OstreeRepoFile *dir,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self;
|
||||
|
||||
self = g_object_new (OSTREE_TYPE_REPO_FILE_ENUMERATOR,
|
||||
"container", dir,
|
||||
NULL);
|
||||
|
||||
self->dir = g_object_ref (dir);
|
||||
self->attributes = g_strdup (attributes);
|
||||
self->flags = flags;
|
||||
|
||||
return G_FILE_ENUMERATOR (self);
|
||||
}
|
||||
|
||||
static GFileInfo *
|
||||
ostree_repo_file_enumerator_next_file (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoFileEnumerator *self = OSTREE_REPO_FILE_ENUMERATOR (enumerator);
|
||||
gboolean ret = FALSE;
|
||||
GFileInfo *info = NULL;
|
||||
|
||||
if (!_ostree_repo_file_tree_query_child (self->dir, self->index,
|
||||
self->attributes, self->flags,
|
||||
&info, cancellable, error))
|
||||
goto out;
|
||||
|
||||
self->index++;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (!ret)
|
||||
g_clear_object (&info);
|
||||
return info;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ostree_repo_file_enumerator_close (GFileEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
54
libostree/ostree-repo-file-enumerator.h
Normal file
54
libostree/ostree-repo-file-enumerator.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_REPO_FILE_ENUMERATOR
|
||||
#define _OSTREE_REPO_FILE_ENUMERATOR
|
||||
|
||||
#include "ostree-repo-file.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_REPO_FILE_ENUMERATOR (_ostree_repo_file_enumerator_get_type ())
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumerator))
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass))
|
||||
#define OSTREE_IS_REPO_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR))
|
||||
#define OSTREE_IS_REPO_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE_ENUMERATOR))
|
||||
#define OSTREE_REPO_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE_ENUMERATOR, OstreeRepoFileEnumeratorClass))
|
||||
|
||||
typedef struct _OstreeRepoFileEnumerator OstreeRepoFileEnumerator;
|
||||
typedef struct _OstreeRepoFileEnumeratorClass OstreeRepoFileEnumeratorClass;
|
||||
|
||||
struct _OstreeRepoFileEnumeratorClass
|
||||
{
|
||||
GFileEnumeratorClass parent_class;
|
||||
};
|
||||
|
||||
GType _ostree_repo_file_enumerator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GFileEnumerator * _ostree_repo_file_enumerator_new (OstreeRepoFile *dir,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
1427
libostree/ostree-repo-file.c
Normal file
1427
libostree/ostree-repo-file.c
Normal file
File diff suppressed because it is too large
Load Diff
114
libostree/ostree-repo-file.h
Normal file
114
libostree/ostree-repo-file.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#ifndef _OSTREE_REPO_FILE
|
||||
#define _OSTREE_REPO_FILE
|
||||
|
||||
#include "ostree-repo.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_REPO_FILE (_ostree_repo_file_get_type ())
|
||||
#define OSTREE_REPO_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFile))
|
||||
#define OSTREE_REPO_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass))
|
||||
#define OSTREE_IS_LOCAL_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_REPO_FILE))
|
||||
#define OSTREE_IS_LOCAL_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_REPO_FILE))
|
||||
#define OSTREE_REPO_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_REPO_FILE, OstreeRepoFileClass))
|
||||
|
||||
typedef struct _OstreeRepoFile OstreeRepoFile;
|
||||
typedef struct _OstreeRepoFileClass OstreeRepoFileClass;
|
||||
|
||||
struct _OstreeRepoFileClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType _ostree_repo_file_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GFile * _ostree_repo_file_new_root (OstreeRepo *repo,
|
||||
const char *commit);
|
||||
|
||||
OstreeRepoFile * _ostree_repo_file_new_empty_tree (OstreeRepo *repo);
|
||||
|
||||
GFile * _ostree_repo_file_new_child (OstreeRepoFile *parent,
|
||||
const char *name);
|
||||
|
||||
gboolean _ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
|
||||
GError **error);
|
||||
|
||||
gboolean _ostree_repo_file_get_xattrs (OstreeRepoFile *self,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
OstreeRepo * _ostree_repo_file_get_repo (OstreeRepoFile *self);
|
||||
OstreeRepoFile * _ostree_repo_file_get_root (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_make_empty_tree (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
|
||||
const char *checksum,
|
||||
GVariant *metadata);
|
||||
|
||||
void _ostree_repo_file_tree_set_content_checksum (OstreeRepoFile *self,
|
||||
const char *checksum);
|
||||
const char *_ostree_repo_file_tree_get_content_checksum (OstreeRepoFile *self);
|
||||
|
||||
gboolean _ostree_repo_file_is_tree (OstreeRepoFile *self);
|
||||
|
||||
const char * _ostree_repo_file_nontree_get_checksum (OstreeRepoFile *self);
|
||||
|
||||
GFile *_ostree_repo_file_nontree_get_local (OstreeRepoFile *self);
|
||||
|
||||
void _ostree_repo_file_tree_remove_child (OstreeRepoFile *self,
|
||||
const char *name);
|
||||
|
||||
void _ostree_repo_file_tree_add_file (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
const char *checksum);
|
||||
|
||||
void _ostree_repo_file_tree_add_dir (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
const char *content_checksum,
|
||||
const char *metadata_checksum);
|
||||
|
||||
int _ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
gboolean *is_dir,
|
||||
GVariant **out_container);
|
||||
|
||||
const char *_ostree_repo_file_tree_get_child_checksum (OstreeRepoFile *self,
|
||||
int n);
|
||||
|
||||
gboolean _ostree_repo_file_tree_query_child (OstreeRepoFile *self,
|
||||
int n,
|
||||
const char *attributes,
|
||||
GFileQueryInfoFlags flags,
|
||||
GFileInfo **out_info,
|
||||
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
|
||||
|
||||
#endif
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
#include "ostree-repo-file-enumerator.h"
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
@ -1016,142 +1017,6 @@ parsed_tree_data_free (ParsedTreeData *pdata)
|
||||
g_free (pdata);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_tree (OstreeRepo *self,
|
||||
const char *sha256,
|
||||
ParsedTreeData **out_pdata,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
ParsedTreeData *ret_pdata = NULL;
|
||||
int i, n;
|
||||
guint32 version;
|
||||
GVariant *tree_variant = NULL;
|
||||
GVariant *meta_variant = NULL;
|
||||
GVariant *files_variant = NULL;
|
||||
GVariant *dirs_variant = NULL;
|
||||
|
||||
if (!ostree_repo_load_variant_checked (self, OSTREE_SERIALIZED_TREE_VARIANT,
|
||||
sha256, &tree_variant, error))
|
||||
goto out;
|
||||
|
||||
/* PARSE OSTREE_SERIALIZED_TREE_VARIANT */
|
||||
g_variant_get (tree_variant, "(u@a{sv}@a(ss)@a(sss))",
|
||||
&version, &meta_variant, &files_variant, &dirs_variant);
|
||||
version = GUINT32_FROM_BE (version);
|
||||
|
||||
ret_pdata = parsed_tree_data_new ();
|
||||
n = g_variant_n_children (files_variant);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
const char *filename;
|
||||
const char *checksum;
|
||||
|
||||
g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum);
|
||||
|
||||
g_hash_table_insert (ret_pdata->files, g_strdup (filename), g_strdup (checksum));
|
||||
}
|
||||
|
||||
n = g_variant_n_children (dirs_variant);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
const char *dirname;
|
||||
const char *tree_checksum;
|
||||
const char *meta_checksum;
|
||||
ParsedTreeData *child_tree = NULL;
|
||||
GVariant *metadata = NULL;
|
||||
ParsedDirectoryData *child_dir = NULL;
|
||||
|
||||
g_variant_get_child (dirs_variant, i, "(&s&s&s)",
|
||||
&dirname, &tree_checksum, &meta_checksum);
|
||||
|
||||
if (!parse_tree (self, tree_checksum, &child_tree, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_load_variant_checked (self, OSTREE_SERIALIZED_DIRMETA_VARIANT,
|
||||
meta_checksum, &metadata, error))
|
||||
{
|
||||
parsed_tree_data_free (child_tree);
|
||||
goto out;
|
||||
}
|
||||
|
||||
child_dir = g_new0 (ParsedDirectoryData, 1);
|
||||
child_dir->tree_data = child_tree;
|
||||
child_dir->metadata_sha256 = g_strdup (meta_checksum);
|
||||
child_dir->meta_data = metadata;
|
||||
|
||||
g_hash_table_insert (ret_pdata->directories, g_strdup (dirname), child_dir);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (!ret)
|
||||
parsed_tree_data_free (ret_pdata);
|
||||
else
|
||||
*out_pdata = ret_pdata;
|
||||
if (tree_variant)
|
||||
g_variant_unref (tree_variant);
|
||||
if (meta_variant)
|
||||
g_variant_unref (meta_variant);
|
||||
if (files_variant)
|
||||
g_variant_unref (files_variant);
|
||||
if (dirs_variant)
|
||||
g_variant_unref (dirs_variant);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_commit_and_trees (OstreeRepo *self,
|
||||
const char *commit_sha256,
|
||||
GVariant **out_commit,
|
||||
ParsedDirectoryData **out_root_data,
|
||||
GError **error)
|
||||
{
|
||||
GVariant *ret_commit = NULL;
|
||||
ParsedDirectoryData *ret_root_data = NULL;
|
||||
ParsedTreeData *tree_data = NULL;
|
||||
char *ret_metadata_checksum = NULL;
|
||||
GVariant *root_metadata = NULL;
|
||||
gboolean ret = FALSE;
|
||||
const char *tree_contents_checksum;
|
||||
const char *tree_meta_checksum;
|
||||
|
||||
if (!ostree_repo_load_variant_checked (self, OSTREE_SERIALIZED_COMMIT_VARIANT,
|
||||
commit_sha256, &ret_commit, error))
|
||||
goto out;
|
||||
|
||||
/* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
|
||||
g_variant_get_child (ret_commit, 6, "&s", &tree_contents_checksum);
|
||||
g_variant_get_child (ret_commit, 7, "&s", &tree_meta_checksum);
|
||||
|
||||
if (!ostree_repo_load_variant_checked (self, OSTREE_SERIALIZED_DIRMETA_VARIANT,
|
||||
tree_meta_checksum, &root_metadata, error))
|
||||
goto out;
|
||||
|
||||
if (!parse_tree (self, tree_contents_checksum, &tree_data, error))
|
||||
goto out;
|
||||
|
||||
ret_root_data = g_new0 (ParsedDirectoryData, 1);
|
||||
ret_root_data->tree_data = tree_data;
|
||||
ret_root_data->metadata_sha256 = g_strdup (tree_meta_checksum);
|
||||
ret_root_data->meta_data = root_metadata;
|
||||
root_metadata = NULL;
|
||||
|
||||
ret = TRUE;
|
||||
*out_commit = ret_commit;
|
||||
ret_commit = NULL;
|
||||
*out_root_data = ret_root_data;
|
||||
ret_root_data = NULL;
|
||||
out:
|
||||
if (ret_commit)
|
||||
g_variant_unref (ret_commit);
|
||||
parsed_directory_data_free (ret_root_data);
|
||||
g_free (ret_metadata_checksum);
|
||||
if (root_metadata)
|
||||
g_variant_unref (root_metadata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
create_empty_gvariant_dict (void)
|
||||
{
|
||||
@ -1807,106 +1672,130 @@ ostree_repo_load_variant (OstreeRepo *self,
|
||||
|
||||
static gboolean
|
||||
checkout_tree (OstreeRepo *self,
|
||||
ParsedTreeData *tree,
|
||||
OstreeRepoFile *dir,
|
||||
const char *destination,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
static gboolean
|
||||
checkout_one_directory (OstreeRepo *self,
|
||||
const char *destination,
|
||||
const char *dirname,
|
||||
ParsedDirectoryData *dir,
|
||||
OstreeRepoFile *dir,
|
||||
GFileInfo *dir_info,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char *dest_path = NULL;
|
||||
guint32 version, uid, gid, mode;
|
||||
GVariant *xattr_variant = NULL;
|
||||
|
||||
dest_path = g_build_filename (destination, dirname, NULL);
|
||||
|
||||
/* PARSE OSTREE_SERIALIZED_DIRMETA_VARIANT */
|
||||
g_variant_get (dir->meta_data, "(uuuu@a(ayay))",
|
||||
&version, &uid, &gid, &mode,
|
||||
&xattr_variant);
|
||||
version = GUINT32_FROM_BE (version);
|
||||
uid = GUINT32_FROM_BE (uid);
|
||||
gid = GUINT32_FROM_BE (gid);
|
||||
mode = GUINT32_FROM_BE (mode);
|
||||
|
||||
if (mkdir (dest_path, (mode_t)mode) < 0)
|
||||
if (!_ostree_repo_file_get_xattrs (dir, &xattr_variant, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (mkdir (dest_path, (mode_t)g_file_info_get_attribute_uint32 (dir_info, "unix::mode")) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
g_prefix_error (error, "Failed to create directory '%s': ", dest_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!checkout_tree (self, dir->tree_data, dest_path, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_set_xattrs (dest_path, xattr_variant, error))
|
||||
if (!ostree_set_xattrs (dest_path, xattr_variant, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!checkout_tree (self, dir, dest_path, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_free (dest_path);
|
||||
g_variant_unref (xattr_variant);
|
||||
if (xattr_variant)
|
||||
g_variant_unref (xattr_variant);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
checkout_tree (OstreeRepo *self,
|
||||
ParsedTreeData *tree,
|
||||
OstreeRepoFile *dir,
|
||||
const char *destination,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoPrivate *priv = GET_PRIVATE (self);
|
||||
gboolean ret = FALSE;
|
||||
GHashTableIter hash_iter;
|
||||
gpointer key, value;
|
||||
GError *temp_error = NULL;
|
||||
GFileInfo *file_info = NULL;
|
||||
GFileEnumerator *dir_enum = NULL;
|
||||
GFile *child = NULL;
|
||||
char *object_path = NULL;
|
||||
char *dest_path = NULL;
|
||||
|
||||
g_hash_table_iter_init (&hash_iter, tree->files);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
dir_enum = g_file_enumerate_children ((GFile*)dir, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable,
|
||||
error);
|
||||
if (!dir_enum)
|
||||
goto out;
|
||||
|
||||
while ((file_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
|
||||
{
|
||||
const char *filename = key;
|
||||
const char *checksum = value;
|
||||
char *object_path;
|
||||
char *dest_path;
|
||||
const char *name;
|
||||
guint32 type;
|
||||
|
||||
object_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
dest_path = g_build_filename (destination, filename, NULL);
|
||||
|
||||
if (priv->archive)
|
||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
||||
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
||||
|
||||
child = g_file_get_child ((GFile*)dir, name);
|
||||
|
||||
if (type == G_FILE_TYPE_DIRECTORY)
|
||||
{
|
||||
if (!ostree_unpack_object (object_path, OSTREE_OBJECT_TYPE_FILE, dest_path, NULL, error))
|
||||
if (!checkout_one_directory (self, destination, name, (OstreeRepoFile*)child, file_info, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link (object_path, dest_path) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
g_free (object_path);
|
||||
g_free (dest_path);
|
||||
goto out;
|
||||
}
|
||||
g_free (object_path);
|
||||
g_free (dest_path);
|
||||
}
|
||||
}
|
||||
const char *checksum = _ostree_repo_file_nontree_get_checksum ((OstreeRepoFile*)child);
|
||||
|
||||
g_hash_table_iter_init (&hash_iter, tree->directories);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
dest_path = g_build_filename (destination, name, NULL);
|
||||
object_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
|
||||
if (priv->archive)
|
||||
{
|
||||
if (!ostree_unpack_object (object_path, OSTREE_OBJECT_TYPE_FILE, dest_path, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link (object_path, dest_path) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (object_path);
|
||||
object_path = NULL;
|
||||
g_free (dest_path);
|
||||
dest_path = NULL;
|
||||
g_clear_object (&file_info);
|
||||
g_clear_object (&child);
|
||||
}
|
||||
if (file_info == NULL && temp_error != NULL)
|
||||
{
|
||||
const char *dirname = key;
|
||||
ParsedDirectoryData *dir = value;
|
||||
|
||||
if (!checkout_one_directory (self, destination, dirname, dir, error))
|
||||
goto out;
|
||||
g_propagate_error (error, temp_error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_clear_object (&dir_enum);
|
||||
g_clear_object (&file_info);
|
||||
g_clear_object (&child);
|
||||
g_free (object_path);
|
||||
g_free (dest_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1914,13 +1803,13 @@ gboolean
|
||||
ostree_repo_checkout (OstreeRepo *self,
|
||||
const char *rev,
|
||||
const char *destination,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GVariant *commit = NULL;
|
||||
char *resolved = NULL;
|
||||
char *root_meta_sha = NULL;
|
||||
ParsedDirectoryData *root = NULL;
|
||||
OstreeRepoFile *root = NULL;
|
||||
GFileInfo *root_info = NULL;
|
||||
|
||||
if (g_file_test (destination, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
@ -1933,18 +1822,23 @@ ostree_repo_checkout (OstreeRepo *self,
|
||||
if (!resolve_rev (self, rev, FALSE, &resolved, error))
|
||||
goto out;
|
||||
|
||||
if (!load_commit_and_trees (self, resolved, &commit, &root, error))
|
||||
root = (OstreeRepoFile*)_ostree_repo_file_new_root (self, resolved);
|
||||
if (!_ostree_repo_file_ensure_resolved (root, error))
|
||||
goto out;
|
||||
|
||||
if (!checkout_one_directory (self, destination, NULL, root, error))
|
||||
root_info = g_file_query_info ((GFile*)root, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
NULL, error);
|
||||
if (!root_info)
|
||||
goto out;
|
||||
|
||||
if (!checkout_one_directory (self, destination, NULL, root, root_info, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_free (resolved);
|
||||
if (commit)
|
||||
g_variant_unref (commit);
|
||||
parsed_directory_data_free (root);
|
||||
g_free (root_meta_sha);
|
||||
g_clear_object (&root);
|
||||
g_clear_object (&root_info);
|
||||
return ret;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
*
|
||||
* Author: Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
/* ostree-repo.h */
|
||||
|
||||
#ifndef _OSTREE_REPO
|
||||
#define _OSTREE_REPO
|
||||
@ -120,9 +119,10 @@ gboolean ostree_repo_commit_from_filelist_fd (OstreeRepo *self,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_checkout (OstreeRepo *self,
|
||||
const char *ref,
|
||||
const char *destination,
|
||||
GError **error);
|
||||
const char *ref,
|
||||
const char *destination,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path,
|
||||
GFileInfo *fileinfo, gpointer user_data);
|
||||
|
@ -64,7 +64,7 @@ ostree_builtin_checkout (int argc, char **argv, const char *repo_path, GError **
|
||||
commit = argv[1];
|
||||
destination = argv[2];
|
||||
|
||||
if (!ostree_repo_checkout (repo, commit, destination, error))
|
||||
if (!ostree_repo_checkout (repo, commit, destination, NULL, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
|
@ -196,7 +196,7 @@ compose_branch_on_dir (OstreeRepo *repo,
|
||||
branchf = ot_util_new_file_for_path (branchpath);
|
||||
|
||||
g_print ("Checking out %s (commit %s)...\n", branch, branchrev);
|
||||
if (!ostree_repo_checkout (repo, branchrev, branchpath, error))
|
||||
if (!ostree_repo_checkout (repo, branchrev, branchpath, NULL, error))
|
||||
goto out;
|
||||
g_print ("...done\n");
|
||||
g_print ("Merging over destination...\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user