From a52cb7d78e304b088be29188a237ec034880e6f7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 8 Feb 2017 10:11:10 -0500 Subject: [PATCH] core: Add rpmostree.repo metadata to imported packages I'm watching https://github.com/rpm-software-management/libdnf/pull/199 and I really don't like it. We already have a place to put out-of-rpmdb metadata, which is in the ostree commit for imported packages. No need to involve a relational database for this (and further, one that would need to learn about multiple ostrees). We're not yet *using* this information in the UI, but we could; imagine changing the `status` `Packages:` to show packages-per-repo or so. We could also expose an `rpm-ostree pkg-info foo`. But for now, let's just start recording this. Closes: #610 Approved by: jlebon --- src/app/rpmostree-internals-builtin-unpack.c | 2 +- src/libpriv/rpmostree-core.c | 2 +- src/libpriv/rpmostree-unpacker.c | 67 +++++++++++++++++++- src/libpriv/rpmostree-unpacker.h | 3 + tests/vmcheck/test-layering-basic.sh | 5 ++ 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/app/rpmostree-internals-builtin-unpack.c b/src/app/rpmostree-internals-builtin-unpack.c index 4d505d15ac..0b034b03d6 100644 --- a/src/app/rpmostree-internals-builtin-unpack.c +++ b/src/app/rpmostree-internals-builtin-unpack.c @@ -94,7 +94,7 @@ rpmostree_internals_builtin_unpack (int argc, if (opt_ostree_convention) flags |= RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION; - unpacker = rpmostree_unpacker_new_at (AT_FDCWD, rpmpath, flags, error); + unpacker = rpmostree_unpacker_new_at (AT_FDCWD, rpmpath, NULL, flags, error); if (!unpacker) goto out; diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c index 2daaa48f58..e83ae7601e 100644 --- a/src/libpriv/rpmostree-core.c +++ b/src/libpriv/rpmostree-core.c @@ -1169,7 +1169,7 @@ import_one_package (RpmOstreeContext *self, flags |= RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED; /* TODO - tweak the unpacker flags for containers */ - unpacker = rpmostree_unpacker_new_at (AT_FDCWD, pkg_path, flags, error); + unpacker = rpmostree_unpacker_new_at (AT_FDCWD, pkg_path, pkg, flags, error); if (!unpacker) goto out; diff --git a/src/libpriv/rpmostree-unpacker.c b/src/libpriv/rpmostree-unpacker.c index 53bc9411b2..34e133ad0b 100644 --- a/src/libpriv/rpmostree-unpacker.c +++ b/src/libpriv/rpmostree-unpacker.c @@ -60,6 +60,7 @@ struct RpmOstreeUnpacker GHashTable *rpmfi_overrides; GString *tmpfiles_d; RpmOstreeUnpackerFlags flags; + DnfPackage *pkg; char *ostree_branch; }; @@ -265,8 +266,22 @@ build_rpmfi_overrides (RpmOstreeUnpacker *self) } } +/* + * rpmostree_unpacker_new_fd: + * @fd: Fd + * @pkg: (optional): Package reference, used for metadata + * @flags: flags + * @error: error + * + * Create a new unpacker instance. The @pkg argument, if + * specified, will be inspected and metadata such as the + * origin repo will be added to the final commit. + */ RpmOstreeUnpacker * -rpmostree_unpacker_new_fd (int fd, RpmOstreeUnpackerFlags flags, GError **error) +rpmostree_unpacker_new_fd (int fd, + DnfPackage *pkg, + RpmOstreeUnpackerFlags flags, + GError **error) { RpmOstreeUnpacker *ret = NULL; _cleanup_rpmheader_ Header hdr = NULL; @@ -288,6 +303,7 @@ rpmostree_unpacker_new_fd (int fd, RpmOstreeUnpackerFlags flags, GError **error) ret->flags = flags; ret->hdr = g_steal_pointer (&hdr); ret->cpio_offset = cpio_offset; + ret->pkg = pkg ? g_object_ref (pkg) : NULL; build_rpmfi_overrides (ret); @@ -299,8 +315,23 @@ rpmostree_unpacker_new_fd (int fd, RpmOstreeUnpackerFlags flags, GError **error) return ret; } +/* + * rpmostree_unpacker_new_at: + * @dfd: Fd + * @path: Path + * @pkg: (optional): Package reference, used for metadata + * @flags: flags + * @error: error + * + * Create a new unpacker instance. The @pkg argument, if + * specified, will be inspected and metadata such as the + * origin repo will be added to the final commit. + */ RpmOstreeUnpacker * -rpmostree_unpacker_new_at (int dfd, const char *path, RpmOstreeUnpackerFlags flags, GError **error) +rpmostree_unpacker_new_at (int dfd, const char *path, + DnfPackage *pkg, + RpmOstreeUnpackerFlags flags, + GError **error) { RpmOstreeUnpacker *ret = NULL; glnx_fd_close int fd = -1; @@ -313,7 +344,7 @@ rpmostree_unpacker_new_at (int dfd, const char *path, RpmOstreeUnpackerFlags fla goto out; } - ret = rpmostree_unpacker_new_fd (fd, flags, error); + ret = rpmostree_unpacker_new_fd (fd, pkg, flags, error); if (ret == NULL) goto out; @@ -404,6 +435,21 @@ get_lead_sig_header_as_bytes (RpmOstreeUnpacker *self, return ret; } +static GVariant * +repo_metadata_to_variant (DnfRepo *repo) +{ + g_auto(GVariantBuilder) builder; + g_variant_builder_init (&builder, (GVariantType*)"a{sv}"); + + /* For now, just the id...in the future maybe we'll add more, but this is + * enough to provide useful semantics. + */ + g_variant_builder_add (&builder, "{sv}", + "id", g_variant_new_string (dnf_repo_get_id (repo))); + + return g_variant_builder_end (&builder); +} + static gboolean build_metadata_variant (RpmOstreeUnpacker *self, OstreeSePolicy *sepolicy, @@ -440,6 +486,21 @@ build_metadata_variant (RpmOstreeUnpacker *self, /* let's be nice to our future selves just in case */ g_variant_builder_add (&metadata_builder, "{sv}", "rpmostree.unpack_version", g_variant_new_uint32 (1)); + /* Originally we just had unpack_version = 1, let's add a minor version for + * compatible increments. + */ + g_variant_builder_add (&metadata_builder, "{sv}", "rpmostree.unpack_minor_version", + g_variant_new_uint32 (1)); + + if (self->pkg) + { + DnfRepo *repo = dnf_package_get_repo (self->pkg); + if (repo) + { + g_variant_builder_add (&metadata_builder, "{sv}", "rpmostree.repo", + repo_metadata_to_variant (repo)); + } + } *out_variant = g_variant_builder_end (&metadata_builder); return TRUE; diff --git a/src/libpriv/rpmostree-unpacker.h b/src/libpriv/rpmostree-unpacker.h index 794260ecf2..bf03822306 100644 --- a/src/libpriv/rpmostree-unpacker.h +++ b/src/libpriv/rpmostree-unpacker.h @@ -24,6 +24,7 @@ #include "libglnx.h" #include +#include typedef struct RpmOstreeUnpacker RpmOstreeUnpacker; @@ -45,12 +46,14 @@ typedef enum { RpmOstreeUnpacker* rpmostree_unpacker_new_fd (int fd, + DnfPackage *pkg, RpmOstreeUnpackerFlags flags, GError **error); RpmOstreeUnpacker* rpmostree_unpacker_new_at (int dfd, const char *path, + DnfPackage *pkg, /* for metadata */ RpmOstreeUnpackerFlags flags, GError **error); diff --git a/tests/vmcheck/test-layering-basic.sh b/tests/vmcheck/test-layering-basic.sh index 90a0a98559..e5a43d3ec7 100755 --- a/tests/vmcheck/test-layering-basic.sh +++ b/tests/vmcheck/test-layering-basic.sh @@ -44,6 +44,11 @@ if vm_cmd "runuser -u bin rpm-ostree pkg-add foo-1.0"; then fi vm_rpmostree pkg-add foo-1.0 +vm_cmd ostree --repo=/sysroot/ostree/repo/extensions/rpmostree/pkgcache refs |grep /foo/> refs.txt +pkgref=$(head -1 refs.txt) +vm_cmd ostree --repo=/sysroot/ostree/repo/extensions/rpmostree/pkgcache show --print-metadata-key rpmostree.repo ${pkgref} >refdata.txt +assert_file_has_content refdata.txt 'id.*test-repo' +rm -f refs.txt refdata.txt echo "ok pkg-add foo" vm_reboot