diff options
author | Colin Walters <walters@verbum.org> | 2016-02-22 11:18:30 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2016-02-22 17:02:31 -0500 |
commit | 30c5fb1a5116e517a9d2e4df9cdc1fbd0249c965 (patch) | |
tree | 6647dd8a3b974d9488b8703282050efbaab8020e /src/libostree/ostree-repo-libarchive.c | |
parent | 11b3050fd73562d8d0caed948a5b421a68d0d793 (diff) | |
download | ostree-30c5fb1a5116e517a9d2e4df9cdc1fbd0249c965.tar.gz |
libarchive: Make autocreate_parents imply autocreating root dir
Some Docker layers are just metadata in the `layer.json`. If one is
mapping Docker layers to OSTree commits, one needs to create a dummy
root directory, because OSTree doesn't support metadata-only commits.
Let's just push that logic down here because it's easier than special
casing it in higher levels.
Diffstat (limited to 'src/libostree/ostree-repo-libarchive.c')
-rw-r--r-- | src/libostree/ostree-repo-libarchive.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index 64410cb2..82c8dd51 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -292,6 +292,23 @@ write_libarchive_entry_to_mtree (OstreeRepo *self, } #endif +static gboolean +create_empty_dir_with_uidgid (OstreeRepo *self, + guint32 uid, + guint32 gid, + guint8 **out_csum, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GFileInfo) tmp_dir_info = g_file_info_new (); + + g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::uid", uid); + g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::gid", gid); + g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::mode", 0755 | S_IFDIR); + + return _ostree_repo_write_directory_meta (self, tmp_dir_info, NULL, out_csum, cancellable, error); +} + /** * ostree_repo_import_archive_to_mtree: * @self: An #OstreeRepo @@ -320,6 +337,7 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, g_autofree guchar *tmp_csum = NULL; int r; + while (TRUE) { r = archive_read_next_header (a, &entry); @@ -336,13 +354,13 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, */ if (opts->autocreate_parents && !tmp_csum) { - g_autoptr(GFileInfo) tmp_dir_info = g_file_info_new (); - - g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::uid", archive_entry_uid (entry)); - g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::gid", archive_entry_gid (entry)); - g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::mode", 0755 | S_IFDIR); - - if (!_ostree_repo_write_directory_meta (self, tmp_dir_info, NULL, &tmp_csum, cancellable, error)) + /* Here, we auto-pick the first uid/gid we find in the + * archive. Realistically this is probably always going to + * be root, but eh, at least we try to match. + */ + if (!create_empty_dir_with_uidgid (self, archive_entry_uid (entry), + archive_entry_gid (entry), + &tmp_csum, cancellable, error)) goto out; } @@ -352,6 +370,26 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self, goto out; } + /* If we didn't import anything at all, and autocreation of parents + * is enabled, automatically create a root directory. This is + * useful primarily when importing Docker image layers, which can + * just be metadata. + */ + if (!ostree_mutable_tree_get_metadata_checksum (mtree) && opts->autocreate_parents) + { + char tmp_checksum[65]; + + if (!tmp_csum) + { + /* We didn't have any archive entries to match, so pick uid 0, gid 0. */ + if (!create_empty_dir_with_uidgid (self, 0, 0, &tmp_csum, cancellable, error)) + goto out; + } + + ostree_checksum_inplace_from_bytes (tmp_csum, tmp_checksum); + ostree_mutable_tree_set_metadata_checksum (mtree, tmp_checksum); + } + ret = TRUE; out: return ret; |