From da4d0245af9b937c7fe65540f022bc77bc0354ed Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Tue, 21 May 2019 22:01:09 +0900 Subject: [PATCH] lib/commit: Added new ostree_repo_write_archive_to_mtree_from_fd() Similar to ostree_repo_write_archive_to_mtree(), but takes a file descriptor to read the archive from instead of mandating a file path. Usefull for importing archives into an OSTree repo over a socket or from standard input in command line tools. Closes: #1862 Approved by: jlebon --- apidoc/ostree-sections.txt | 1 + src/libostree/libostree-devel.sym | 2 + src/libostree/ostree-libarchive-private.h | 30 +++++++- src/libostree/ostree-repo-libarchive.c | 94 +++++++++++++++++------ src/libostree/ostree-repo.h | 10 +++ 5 files changed, 110 insertions(+), 27 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 1a26e1eb..7a59b5a7 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -380,6 +380,7 @@ ostree_repo_devino_cache_get_type ostree_repo_write_directory_to_mtree ostree_repo_write_dfd_to_mtree ostree_repo_write_archive_to_mtree +ostree_repo_write_archive_to_mtree_from_fd ostree_repo_write_mtree ostree_repo_write_commit ostree_repo_write_commit_with_time diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 8d9a7bfc..cdbdbb32 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -19,6 +19,8 @@ /* Add new symbols here. Release commits should copy this section into -released.sym. */ LIBOSTREE_2019.3 { +global: + ostree_repo_write_archive_to_mtree_from_fd; } LIBOSTREE_2018.9; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-libarchive-private.h b/src/libostree/ostree-libarchive-private.h index 4a98b6d1..46da3e18 100644 --- a/src/libostree/ostree-libarchive-private.h +++ b/src/libostree/ostree-libarchive-private.h @@ -44,9 +44,9 @@ typedef struct archive OtAutoArchiveRead; G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveRead, archive_read_free) static inline OtAutoArchiveRead * -ot_open_archive_read (const char *path, GError **error) +ot_archive_read_new (void) { - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); + OtAutoArchiveRead *a = archive_read_new (); #ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL archive_read_support_filter_all (a); @@ -54,10 +54,34 @@ ot_open_archive_read (const char *path, GError **error) archive_read_support_compression_all (a); #endif archive_read_support_format_all (a); + + return a; +} + +static inline OtAutoArchiveRead * +ot_open_archive_read (const char *path, GError **error) +{ + g_autoptr(OtAutoArchiveRead) a = ot_archive_read_new (); + if (archive_read_open_filename (a, path, 8192) != ARCHIVE_OK) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "%s", archive_error_string (a)); + "archive_read_open_filename: %s", archive_error_string (a)); + return NULL; + } + + return g_steal_pointer (&a); +} + +static inline OtAutoArchiveRead * +ot_open_archive_read_fd (int fd, GError **error) +{ + g_autoptr(OtAutoArchiveRead) a = ot_archive_read_new (); + + if (archive_read_open_fd (a, fd, 8192) != ARCHIVE_OK) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "archive_read_open_fd: %s", archive_error_string (a)); return NULL; } diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index 2852e78e..1850f99f 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -901,6 +901,37 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, #endif } +#ifdef HAVE_LIBARCHIVE +static gboolean +write_archive_to_mtree (OstreeRepo *self, + OtAutoArchiveRead *archive, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + OstreeRepoImportArchiveOptions opts = { 0, }; + + opts.autocreate_parents = !!autocreate_parents; + + if (!ostree_repo_import_archive_to_mtree (self, &opts, archive, mtree, modifier, cancellable, error)) + goto out; + + if (archive_read_close (archive) != ARCHIVE_OK) + { + propagate_libarchive_error (error, archive); + goto out; + } + + ret = TRUE; + out: + (void)archive_read_close (archive); + return ret; +} +#endif + /** * ostree_repo_write_archive_to_mtree: * @self: An #OstreeRepo @@ -924,31 +955,46 @@ ostree_repo_write_archive_to_mtree (OstreeRepo *self, GError **error) { #ifdef HAVE_LIBARCHIVE - gboolean ret = FALSE; - g_autoptr(OtAutoArchiveRead) a = archive_read_new (); - OstreeRepoImportArchiveOptions opts = { 0, }; - - a = ot_open_archive_read (gs_file_get_path_cached (archive), error); - if (!a) - goto out; - opts.autocreate_parents = !!autocreate_parents; - - if (!ostree_repo_import_archive_to_mtree (self, &opts, a, mtree, modifier, cancellable, error)) - goto out; - - if (archive_read_close (a) != ARCHIVE_OK) - { - propagate_libarchive_error (error, a); - goto out; - } - - ret = TRUE; - out: + g_autoptr(OtAutoArchiveRead) a = ot_open_archive_read (gs_file_get_path_cached (archive), error); if (a) - { - (void)archive_read_close (a); - } - return ret; + return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, error); + + return FALSE; +#else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "This version of ostree is not compiled with libarchive support"); + return FALSE; +#endif +} + +/** + * ostree_repo_write_archive_to_mtree_from_fd: + * @self: An #OstreeRepo + * @fd: A file descriptor to read the archive from + * @mtree: The #OstreeMutableTree to write to + * @modifier: (allow-none): Optional commit modifier + * @autocreate_parents: Autocreate parent directories + * @cancellable: Cancellable + * @error: Error + * + * Read an archive from @fd and import it into the repository, writing + * its file structure to @mtree. + */ +gboolean +ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, + int fd, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, + GCancellable *cancellable, + GError **error) +{ +#ifdef HAVE_LIBARCHIVE + g_autoptr(OtAutoArchiveRead) a = ot_open_archive_read_fd (fd, error); + if (a) + return write_archive_to_mtree (self, a, mtree, modifier, autocreate_parents, cancellable, error); + + return FALSE; #else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "This version of ostree is not compiled with libarchive support"); diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index afa33155..b5af2f82 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -737,6 +737,16 @@ gboolean ostree_repo_write_archive_to_mtree (OstreeRepo * GCancellable *cancellable, GError **error); + +_OSTREE_PUBLIC +gboolean ostree_repo_write_archive_to_mtree_from_fd (OstreeRepo *self, + int fd, + OstreeMutableTree *mtree, + OstreeRepoCommitModifier *modifier, + gboolean autocreate_parents, + GCancellable *cancellable, + GError **error); + /** * OstreeRepoImportArchiveTranslatePathname: * @repo: Repo