summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2021-04-07 21:03:15 +0000
committerColin Walters <walters@verbum.org>2021-04-08 21:10:00 +0000
commitfce69cdf70ca959410ffd324ee978300cc72a5e0 (patch)
treecb0030610190b0375d5bf97766750a7a1aee33d0
parent9332955b5f523b730cf332a8bd9619c40894bbe7 (diff)
downloadostree-fce69cdf70ca959410ffd324ee978300cc72a5e0.tar.gz
repo: Add ostree_repo_write_symlink
Continuation of the addition of `ostree_repo_write_regfile_inline()`. This will be helpful for ostree-rs-ext and importing from tar, it's quite inefficient and awkward for small files to end up creating a whole `GInputStream` and `GFileInfo` and etc. for small files.
-rw-r--r--apidoc/ostree-sections.txt1
-rw-r--r--src/libostree/libostree-devel.sym1
-rw-r--r--src/libostree/ostree-repo-commit.c41
-rw-r--r--src/libostree/ostree-repo.h10
-rwxr-xr-xtests/test-core.js1
-rw-r--r--tests/test-repo.c12
6 files changed, 66 insertions, 0 deletions
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt
index 3f48ef3a..65b9e7fd 100644
--- a/apidoc/ostree-sections.txt
+++ b/apidoc/ostree-sections.txt
@@ -356,6 +356,7 @@ ostree_repo_write_metadata_async
ostree_repo_write_metadata_finish
ostree_repo_write_content
ostree_repo_write_regfile_inline
+ostree_repo_write_symlink
ostree_repo_write_metadata_trusted
ostree_repo_write_metadata_stream_trusted
ostree_repo_write_content_trusted
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym
index c4a70938..e218ddda 100644
--- a/src/libostree/libostree-devel.sym
+++ b/src/libostree/libostree-devel.sym
@@ -25,6 +25,7 @@
LIBOSTREE_2021.2 {
global:
ostree_repo_write_regfile_inline;
+ ostree_repo_write_symlink;
} LIBOSTREE_2021.1;
/* Stub section for the stable release *after* this development one; don't
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 409738ad..ae93eedb 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -2814,6 +2814,47 @@ ostree_repo_write_regfile_inline (OstreeRepo *self,
return ostree_checksum_from_bytes (csum);
}
+/**
+ * ostree_repo_write_symlink:
+ * @self: repo
+ * @expected_checksum: (allow-none): The expected checksum
+ * @uid: User id
+ * @gid: Group id
+ * @xattrs: (allow-none): Extended attributes, GVariant of type (ayay)
+ * @symlink_target: Target of the symbolic link
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Synchronously create a symlink object.
+ *
+ * Unlike `ostree_repo_write_content()`, if @expected_checksum is provided,
+ * this function will not check for the presence of the object beforehand.
+ *
+ * Returns: (transfer full): Checksum (as a hex string) of the committed file
+ * Since: 2021.2
+ */
+char *
+ostree_repo_write_symlink (OstreeRepo *self,
+ const char *expected_checksum,
+ guint32 uid,
+ guint32 gid,
+ GVariant *xattrs,
+ const char *symlink_target,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_assert (symlink_target != NULL);
+
+ g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (S_IFLNK | 0777, uid, gid);
+ g_file_info_set_attribute_byte_string (finfo, "standard::symlink-target", symlink_target);
+ g_autofree guint8* csum = NULL;
+ if (!write_content_object (self, expected_checksum,
+ NULL, finfo, xattrs, &csum,
+ cancellable, error))
+ return NULL;
+ return ostree_checksum_from_bytes (csum);
+}
+
typedef struct {
OstreeRepo *repo;
char *expected_checksum;
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index cd50fc43..7e08361b 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -436,6 +436,16 @@ char * ostree_repo_write_regfile_inline (OstreeRepo *self,
GError **error);
_OSTREE_PUBLIC
+char * ostree_repo_write_symlink (OstreeRepo *self,
+ const char *expected_checksum,
+ guint32 uid,
+ guint32 gid,
+ GVariant *xattrs,
+ const char *symlink_target,
+ GCancellable *cancellable,
+ GError **error);
+
+_OSTREE_PUBLIC
gboolean ostree_repo_write_metadata_trusted (OstreeRepo *self,
OstreeObjectType objtype,
const char *checksum,
diff --git a/tests/test-core.js b/tests/test-core.js
index 8f460a5f..5f3e9fe3 100755
--- a/tests/test-core.js
+++ b/tests/test-core.js
@@ -56,6 +56,7 @@ let inline_checksum = repo.write_regfile_inline(null, 0, 0, regfile_mode, null,
assertEquals(inline_checksum, "8aaa9dc13a0c5839fe4a277756798c609c53fac6fa2290314ecfef9041065873");
let written = false;
try {
+ // Changed an a to b from above to make the checksum not match
repo.write_regfile_inline("8baa9dc13a0c5839fe4a277756798c609c53fac6fa2290314ecfef9041065873", 0, 0, regfile_mode, null, inline_content, null);
written = true;
} catch (e) {
diff --git a/tests/test-repo.c b/tests/test-repo.c
index ad81a7d6..35e929f9 100644
--- a/tests/test-repo.c
+++ b/tests/test-repo.c
@@ -236,6 +236,18 @@ test_write_regfile_api (Fixture *fixture,
g_assert_no_error (error);
g_assert_cmpstr (checksum, ==, "4f600d252338f93279c51c964915cb2c26f0d09082164c54890d1a3c78cdeb1e");
g_clear_pointer (&checksum, g_free);
+
+ // Test symlinks
+ g_clear_pointer (&xattrs, g_variant_unref);
+ g_variant_builder_init (&xattrs_builder, (GVariantType*)"a(ayay)");
+ g_variant_builder_add (&xattrs_builder, "(^ay^ay)", "security.selinux", "system_u:object_r:bin_t:s0");
+ g_clear_pointer (&xattrs, g_variant_unref);
+ xattrs = g_variant_ref_sink (g_variant_builder_end (&xattrs_builder));
+
+ g_clear_pointer (&checksum, g_free);
+ checksum = ostree_repo_write_symlink (repo, NULL, 0, 0, xattrs, "bash", NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (checksum, ==, "23a2e97d21d960ac7a4e39a8721b1baff7b213e00e5e5641334f50506012fcff");
}
int